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 "content/public/browser/browser_thread.h" 11 #include "extensions/common/extension.h" 12 #include "extensions/common/extension_set.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 18 using content::BrowserThread; 19 20 namespace { 21 // Prefix for message parameters indicating that the parameter needs to 22 // be translated from an extension id to the extension name. 23 const char kTranslate[] = "TO_TRANSLATE:"; 24 const size_t kMaxNumberOfParameters = 4; 25 } 26 27 namespace extensions { 28 29 // 30 // ExtensionWarning 31 // 32 33 ExtensionWarning::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 49 ExtensionWarning::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 55 ExtensionWarning::~ExtensionWarning() { 56 } 57 58 ExtensionWarning& 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 67 ExtensionWarning 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 79 ExtensionWarning 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 90 ExtensionWarning 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 107 ExtensionWarning 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 122 ExtensionWarning 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 137 ExtensionWarning 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 150 ExtensionWarning 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 162 ExtensionWarning 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(base::UTF16ToUTF8( 169 losing_filename.LossyDisplayName())); 170 message_parameters.push_back(kTranslate + winning_extension_id); 171 message_parameters.push_back(base::UTF16ToUTF8( 172 winning_filename.LossyDisplayName())); 173 return ExtensionWarning( 174 kDownloadFilenameConflict, 175 losing_extension_id, 176 IDS_EXTENSION_WARNINGS_DOWNLOAD_FILENAME_CONFLICT, 177 message_parameters); 178 } 179 180 // static 181 ExtensionWarning ExtensionWarning::CreateReloadTooFrequentWarning( 182 const std::string& extension_id) { 183 std::vector<std::string> message_parameters; 184 return ExtensionWarning(kReloadTooFrequent, 185 extension_id, 186 IDS_EXTENSION_WARNING_RELOAD_TOO_FREQUENT, 187 message_parameters); 188 } 189 190 std::string ExtensionWarning::GetLocalizedMessage( 191 const ExtensionSet* extensions) const { 192 DCHECK_CURRENTLY_ON(BrowserThread::UI); 193 194 // These parameters may be unsafe (URLs and Extension names) and need 195 // to be HTML-escaped before being embedded in the UI. Also extension IDs 196 // are translated to full extension names. 197 std::vector<base::string16> final_parameters; 198 for (size_t i = 0; i < message_parameters_.size(); ++i) { 199 std::string message = message_parameters_[i]; 200 if (StartsWithASCII(message, kTranslate, true)) { 201 std::string extension_id = message.substr(sizeof(kTranslate) - 1); 202 const extensions::Extension* extension = 203 extensions->GetByID(extension_id); 204 message = extension ? extension->name() : extension_id; 205 } 206 final_parameters.push_back(base::UTF8ToUTF16(net::EscapeForHTML(message))); 207 } 208 209 COMPILE_ASSERT(kMaxNumberOfParameters == 4u, YouNeedToAddMoreCaseStatements); 210 switch (final_parameters.size()) { 211 case 0: 212 return l10n_util::GetStringUTF8(message_id_); 213 case 1: 214 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0]); 215 case 2: 216 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 217 final_parameters[1]); 218 case 3: 219 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 220 final_parameters[1], final_parameters[2]); 221 case 4: 222 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 223 final_parameters[1], final_parameters[2], final_parameters[3]); 224 default: 225 NOTREACHED(); 226 return std::string(); 227 } 228 } 229 230 bool operator<(const ExtensionWarning& a, const ExtensionWarning& b) { 231 if (a.extension_id() != b.extension_id()) 232 return a.extension_id() < b.extension_id(); 233 return a.warning_type() < b.warning_type(); 234 } 235 236 } // namespace extensions 237