Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdint.h> | 5 #include <stdint.h> |
| 6 #include <string.h> | 6 #include <string.h> |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/base_paths.h" | 9 #include "base/base_paths.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 | 83 |
| 84 // The base directory on Windows looks like: | 84 // The base directory on Windows looks like: |
| 85 // <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\. | 85 // <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\. |
| 86 base::FilePath GetPepperFlashBaseDirectory() { | 86 base::FilePath GetPepperFlashBaseDirectory() { |
| 87 base::FilePath result; | 87 base::FilePath result; |
| 88 PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, &result); | 88 PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, &result); |
| 89 return result; | 89 return result; |
| 90 } | 90 } |
| 91 | 91 |
| 92 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) | 92 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) |
| 93 // Install directory for pepper flash debugger dlls will be like | |
| 94 // c:\windows\system32\macromed\flash\, or basically the Macromed\Flash | |
| 95 // subdirectory of the Windows system directory. | |
| 96 base::FilePath GetPepperFlashDebuggerDirectory() { | |
| 97 base::FilePath result; | |
| 98 PathService::Get(chrome::DIR_PEPPER_FLASH_DEBUGGER_PLUGIN, &result); | |
| 99 return result; | |
| 100 } | |
| 101 | |
| 102 // Pepper Flash plugins have the version encoded in the path itself | 93 // Pepper Flash plugins have the version encoded in the path itself |
| 103 // so we need to enumerate the directories to find the full path. | 94 // so we need to enumerate the directories to find the full path. |
| 104 // On success, |latest_dir| returns something like: | 95 // On success, |latest_dir| returns something like: |
| 105 // <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\10.3.44.555\. | 96 // <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\10.3.44.555\. |
| 106 // |latest_version| returns the corresponding version number. |older_dirs| | 97 // |latest_version| returns the corresponding version number. |older_dirs| |
| 107 // returns directories of all older versions. | 98 // returns directories of all older versions. |
| 108 bool GetPepperFlashDirectory(base::FilePath* latest_dir, | 99 bool GetPepperFlashDirectory(base::FilePath* latest_dir, |
| 109 Version* latest_version, | 100 Version* latest_version, |
| 110 std::vector<base::FilePath>* older_dirs) { | 101 std::vector<base::FilePath>* older_dirs) { |
| 111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 127 older_dirs->push_back(path); | 118 older_dirs->push_back(path); |
| 128 } | 119 } |
| 129 } else { | 120 } else { |
| 130 *latest_dir = path; | 121 *latest_dir = path; |
| 131 *latest_version = version; | 122 *latest_version = version; |
| 132 found = true; | 123 found = true; |
| 133 } | 124 } |
| 134 } | 125 } |
| 135 return found; | 126 return found; |
| 136 } | 127 } |
| 137 | |
| 138 #if defined(OS_WIN) | |
| 139 const wchar_t kPepperFlashDebuggerDLLSearchString[] = | |
| 140 #if defined(ARCH_CPU_X86) | |
| 141 L"pepflashplayer32*.dll"; | |
| 142 #elif defined(ARCH_CPU_X86_64) | |
| 143 L"pepflashplayer64*.dll"; | |
| 144 #else | |
| 145 #error Unsupported Windows CPU architecture. | |
| 146 #endif // defined(ARCH_CPU_X86) | |
| 147 #endif // defined(OS_WIN) | |
| 148 | |
| 149 bool GetPepperFlashDebuggerPath(base::FilePath* dll_path, | |
| 150 Version* dll_version) { | |
| 151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 152 base::FilePath debugger_dir = GetPepperFlashDebuggerDirectory(); | |
| 153 // If path doesn't exist they simply don't have the flash debugger installed. | |
| 154 if (!base::PathExists(debugger_dir)) | |
| 155 return false; | |
| 156 | |
| 157 bool found = false; | |
| 158 #if defined(OS_WIN) | |
| 159 // Enumerate any DLLs that match the appropriate pattern for this DLL, and | |
| 160 // pick the highest version number we find. | |
| 161 base::FileEnumerator file_enumerator(debugger_dir, | |
| 162 false, | |
| 163 base::FileEnumerator::FILES, | |
| 164 kPepperFlashDebuggerDLLSearchString); | |
| 165 for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); | |
| 166 path = file_enumerator.Next()) { | |
| 167 // Version number is embedded in file name like basename_x_y_z.dll. Extract. | |
| 168 std::string file_name(path.BaseName().RemoveExtension().MaybeAsASCII()); | |
| 169 // file_name should now be basename_x_y_z. Split along '_' for version. | |
| 170 std::vector<std::string> components; | |
| 171 base::SplitString(file_name, '_', &components); | |
| 172 // Should have at least one version number. | |
| 173 if (components.size() <= 1) | |
| 174 continue; | |
| 175 // Meld version components back into a string, now separated by periods, so | |
| 176 // Version can parse it. | |
| 177 std::string version_string(components[1]); | |
| 178 for (size_t i = 2; i < components.size(); ++i) { | |
| 179 version_string += "." + components[i]; | |
| 180 } | |
| 181 Version version(version_string); | |
| 182 if (!version.IsValid()) | |
| 183 continue; | |
| 184 if (found) { | |
| 185 if (version.CompareTo(*dll_version) > 0) { | |
| 186 *dll_path = path; | |
| 187 *dll_version = version; | |
| 188 } | |
| 189 } else { | |
| 190 *dll_path = path; | |
| 191 *dll_version = version; | |
| 192 found = true; | |
| 193 } | |
| 194 } | |
| 195 #endif | |
| 196 return found; | |
| 197 } | |
| 198 #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) | 128 #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) |
| 199 | 129 |
| 200 // Returns true if the Pepper |interface_name| is implemented by this browser. | 130 // Returns true if the Pepper |interface_name| is implemented by this browser. |
| 201 // It does not check if the interface is proxied. | 131 // It does not check if the interface is proxied. |
| 202 bool SupportsPepperInterface(const char* interface_name) { | 132 bool SupportsPepperInterface(const char* interface_name) { |
| 203 if (IsSupportedPepperInterface(interface_name)) | 133 if (IsSupportedPepperInterface(interface_name)) |
| 204 return true; | 134 return true; |
| 205 // The PDF interface is invisible to SupportsInterface() on the browser | 135 // The PDF interface is invisible to SupportsInterface() on the browser |
| 206 // process because it is provided using PpapiInterfaceFactoryManager. We need | 136 // process because it is provided using PpapiInterfaceFactoryManager. We need |
| 207 // to check for that as well. | 137 // to check for that as well. |
| 208 // TODO(cpu): make this more sane. | 138 // TODO(cpu): make this more sane. |
| 209 return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0); | 139 return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0); |
| 210 } | 140 } |
| 211 | 141 |
| 212 bool MakePepperFlashPluginInfo(const base::FilePath& flash_path, | 142 bool MakePepperFlashPluginInfo(const base::FilePath& flash_path, |
| 213 const Version& flash_version, | 143 const Version& flash_version, |
| 214 bool out_of_process, | 144 bool out_of_process, |
| 215 bool is_debugger, | |
| 216 content::PepperPluginInfo* plugin_info) { | 145 content::PepperPluginInfo* plugin_info) { |
| 217 if (!flash_version.IsValid()) | 146 if (!flash_version.IsValid()) |
| 218 return false; | 147 return false; |
| 219 const std::vector<uint16_t> ver_nums = flash_version.components(); | 148 const std::vector<uint16_t> ver_nums = flash_version.components(); |
| 220 if (ver_nums.size() < 3) | 149 if (ver_nums.size() < 3) |
| 221 return false; | 150 return false; |
| 222 | 151 |
| 223 plugin_info->is_internal = false; | 152 plugin_info->is_internal = false; |
| 224 plugin_info->is_out_of_process = out_of_process; | 153 plugin_info->is_out_of_process = out_of_process; |
| 225 plugin_info->path = flash_path; | 154 plugin_info->path = flash_path; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 248 | 177 |
| 249 bool IsPepperFlash(const content::WebPluginInfo& plugin) { | 178 bool IsPepperFlash(const content::WebPluginInfo& plugin) { |
| 250 // We try to recognize Pepper Flash by the following criteria: | 179 // We try to recognize Pepper Flash by the following criteria: |
| 251 // * It is a Pepper plug-in. | 180 // * It is a Pepper plug-in. |
| 252 // * It has the special Flash permissions. | 181 // * It has the special Flash permissions. |
| 253 return plugin.is_pepper_plugin() && | 182 return plugin.is_pepper_plugin() && |
| 254 (plugin.pepper_permissions & ppapi::PERMISSION_FLASH); | 183 (plugin.pepper_permissions & ppapi::PERMISSION_FLASH); |
| 255 } | 184 } |
| 256 | 185 |
| 257 void RegisterPepperFlashWithChrome(const base::FilePath& path, | 186 void RegisterPepperFlashWithChrome(const base::FilePath& path, |
| 258 const Version& version, | 187 const Version& version) { |
| 259 bool is_debugger) { | |
| 260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 261 content::PepperPluginInfo plugin_info; | 189 content::PepperPluginInfo plugin_info; |
| 262 if (!MakePepperFlashPluginInfo( | 190 if (!MakePepperFlashPluginInfo(path, version, true, &plugin_info)) |
| 263 path, version, true, is_debugger, &plugin_info)) | |
| 264 return; | 191 return; |
| 265 | 192 |
| 266 // If this is the non-debugger version, we enumerate any installed versions of | 193 std::vector<content::WebPluginInfo> plugins; |
| 267 // pepper flash to make sure we only replace the installed version with a | 194 PluginService::GetInstance()->GetInternalPlugins(&plugins); |
| 268 // newer version. | 195 for (std::vector<content::WebPluginInfo>::const_iterator it = |
| 269 if (!is_debugger) { | 196 plugins.begin(); |
| 270 std::vector<content::WebPluginInfo> plugins; | 197 it != plugins.end(); |
| 271 PluginService::GetInstance()->GetInternalPlugins(&plugins); | 198 ++it) { |
| 272 for (std::vector<content::WebPluginInfo>::const_iterator it = | 199 if (!IsPepperFlash(*it)) |
| 273 plugins.begin(); | 200 continue; |
| 274 it != plugins.end(); | |
| 275 ++it) { | |
| 276 if (!IsPepperFlash(*it)) | |
| 277 continue; | |
| 278 | 201 |
| 279 // Do it only if the version we're trying to register is newer. | 202 // Do it only if the version we're trying to register is newer. |
| 280 Version registered_version(base::UTF16ToUTF8(it->version)); | 203 Version registered_version(base::UTF16ToUTF8(it->version)); |
| 281 if (registered_version.IsValid() && | 204 if (registered_version.IsValid() && |
| 282 version.CompareTo(registered_version) <= 0) { | 205 version.CompareTo(registered_version) <= 0) { |
| 283 return; | 206 return; |
| 284 } | 207 } |
| 285 | 208 |
| 286 // If the version is newer, remove the old one first. | 209 // If the version is newer, remove the old one first. |
| 287 PluginService::GetInstance()->UnregisterInternalPlugin(it->path); | 210 PluginService::GetInstance()->UnregisterInternalPlugin(it->path); |
| 288 break; | 211 break; |
| 289 } | |
| 290 } | 212 } |
| 291 | 213 |
| 292 // We only ask for registration at the beginning for the non-debugger plugin, | |
| 293 // that way the debugger plugin doesn't automatically clobber the built-in or | |
| 294 // updated non-debugger version. | |
| 295 PluginService::GetInstance()->RegisterInternalPlugin( | 214 PluginService::GetInstance()->RegisterInternalPlugin( |
| 296 plugin_info.ToWebPluginInfo(), !is_debugger); | 215 plugin_info.ToWebPluginInfo(), true); |
| 297 PluginService::GetInstance()->RefreshPlugins(); | 216 PluginService::GetInstance()->RefreshPlugins(); |
| 298 } | 217 } |
| 299 | 218 |
| 300 // Returns true if this browser implements one of the interfaces given in | 219 // Returns true if this browser implements one of the interfaces given in |
| 301 // |interface_string|, which is a '|'-separated string of interface names. | 220 // |interface_string|, which is a '|'-separated string of interface names. |
| 302 bool CheckPepperFlashInterfaceString(const std::string& interface_string) { | 221 bool CheckPepperFlashInterfaceString(const std::string& interface_string) { |
| 303 std::vector<std::string> interface_names; | 222 std::vector<std::string> interface_names; |
| 304 base::SplitString(interface_string, '|', &interface_names); | 223 base::SplitString(interface_string, '|', &interface_names); |
| 305 for (size_t i = 0; i < interface_names.size(); i++) { | 224 for (size_t i = 0; i < interface_names.size(); i++) { |
|
cpu_(ooo_6.6-7.5)
2015/02/03 18:58:03
this code needs to be run before we decide to regi
Will Harris
2015/02/16 03:39:42
Done.
| |
| 306 if (SupportsPepperInterface(interface_names[i].c_str())) | 225 if (SupportsPepperInterface(interface_names[i].c_str())) |
| 307 return true; | 226 return true; |
| 308 } | 227 } |
| 309 return false; | 228 return false; |
| 310 } | 229 } |
| 311 | 230 |
| 312 // Returns true if this browser implements all the interfaces that Flash | 231 // Returns true if this browser implements all the interfaces that Flash |
| 313 // specifies in its component installer manifest. | 232 // specifies in its component installer manifest. |
| 314 bool CheckPepperFlashInterfaces(const base::DictionaryValue& manifest) { | 233 bool CheckPepperFlashInterfaces(const base::DictionaryValue& manifest) { |
| 315 const base::ListValue* interface_list = NULL; | 234 const base::ListValue* interface_list = NULL; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 if (!base::Move(unpack_path, path)) | 296 if (!base::Move(unpack_path, path)) |
| 378 return false; | 297 return false; |
| 379 // Installation is done. Now tell the rest of chrome. Both the path service | 298 // Installation is done. Now tell the rest of chrome. Both the path service |
| 380 // and to the plugin service. | 299 // and to the plugin service. |
| 381 current_version_ = version; | 300 current_version_ = version; |
| 382 PathService::Override(chrome::DIR_PEPPER_FLASH_PLUGIN, path); | 301 PathService::Override(chrome::DIR_PEPPER_FLASH_PLUGIN, path); |
| 383 path = path.Append(chrome::kPepperFlashPluginFilename); | 302 path = path.Append(chrome::kPepperFlashPluginFilename); |
| 384 BrowserThread::PostTask( | 303 BrowserThread::PostTask( |
| 385 BrowserThread::UI, | 304 BrowserThread::UI, |
| 386 FROM_HERE, | 305 FROM_HERE, |
| 387 base::Bind(&RegisterPepperFlashWithChrome, path, version, false)); | 306 base::Bind(&RegisterPepperFlashWithChrome, path, version)); |
| 388 return true; | 307 return true; |
| 389 } | 308 } |
| 390 | 309 |
| 391 bool PepperFlashComponentInstaller::GetInstalledFile( | 310 bool PepperFlashComponentInstaller::GetInstalledFile( |
| 392 const std::string& file, | 311 const std::string& file, |
| 393 base::FilePath* installed_file) { | 312 base::FilePath* installed_file) { |
| 394 return false; | 313 return false; |
| 395 } | 314 } |
| 396 | 315 |
| 397 bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, | 316 bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 460 } | 379 } |
| 461 | 380 |
| 462 Version version(kNullVersion); | 381 Version version(kNullVersion); |
| 463 std::vector<base::FilePath> older_dirs; | 382 std::vector<base::FilePath> older_dirs; |
| 464 if (GetPepperFlashDirectory(&path, &version, &older_dirs)) { | 383 if (GetPepperFlashDirectory(&path, &version, &older_dirs)) { |
| 465 path = path.Append(chrome::kPepperFlashPluginFilename); | 384 path = path.Append(chrome::kPepperFlashPluginFilename); |
| 466 if (base::PathExists(path)) { | 385 if (base::PathExists(path)) { |
| 467 BrowserThread::PostTask( | 386 BrowserThread::PostTask( |
| 468 BrowserThread::UI, | 387 BrowserThread::UI, |
| 469 FROM_HERE, | 388 FROM_HERE, |
| 470 base::Bind(&RegisterPepperFlashWithChrome, path, version, false)); | 389 base::Bind(&RegisterPepperFlashWithChrome, path, version)); |
| 471 } else { | 390 } else { |
| 472 version = Version(kNullVersion); | 391 version = Version(kNullVersion); |
| 473 } | 392 } |
| 474 } | 393 } |
| 475 | 394 |
| 476 BrowserThread::PostTask( | 395 BrowserThread::PostTask( |
| 477 BrowserThread::UI, | 396 BrowserThread::UI, |
| 478 FROM_HERE, | 397 FROM_HERE, |
| 479 base::Bind(&FinishPepperFlashUpdateRegistration, cus, version)); | 398 base::Bind(&FinishPepperFlashUpdateRegistration, cus, version)); |
| 480 | 399 |
| 481 // Remove older versions of Pepper Flash. | 400 // Remove older versions of Pepper Flash. |
| 482 for (std::vector<base::FilePath>::iterator iter = older_dirs.begin(); | 401 for (std::vector<base::FilePath>::iterator iter = older_dirs.begin(); |
| 483 iter != older_dirs.end(); | 402 iter != older_dirs.end(); |
| 484 ++iter) { | 403 ++iter) { |
| 485 base::DeleteFile(*iter, true); | 404 base::DeleteFile(*iter, true); |
| 486 } | 405 } |
| 487 | |
| 488 // Check for Debugging version of Flash and register if present. | |
| 489 base::FilePath debugger_path; | |
| 490 Version debugger_version(kNullVersion); | |
| 491 if (GetPepperFlashDebuggerPath(&debugger_path, &debugger_version)) { | |
| 492 BrowserThread::PostTask(BrowserThread::UI, | |
| 493 FROM_HERE, | |
| 494 base::Bind(&RegisterPepperFlashWithChrome, | |
| 495 debugger_path, | |
| 496 debugger_version, | |
| 497 true)); | |
| 498 } | |
| 499 } | 406 } |
| 500 #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) | 407 #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) |
| 501 | 408 |
| 502 } // namespace | 409 } // namespace |
| 503 | 410 |
| 504 void RegisterPepperFlashComponent(ComponentUpdateService* cus) { | 411 void RegisterPepperFlashComponent(ComponentUpdateService* cus) { |
| 505 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) | 412 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) |
| 506 // Component updated flash supersedes bundled flash therefore if that one | 413 // Component updated flash supersedes bundled flash therefore if that one |
| 507 // is disabled then this one should never install. | 414 // is disabled then this one should never install. |
| 508 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 415 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| 509 if (cmd_line->HasSwitch(switches::kDisableBundledPpapiFlash)) | 416 if (cmd_line->HasSwitch(switches::kDisableBundledPpapiFlash)) |
| 510 return; | 417 return; |
| 511 BrowserThread::PostTask(BrowserThread::FILE, | 418 BrowserThread::PostTask(BrowserThread::FILE, |
| 512 FROM_HERE, | 419 FROM_HERE, |
| 513 base::Bind(&StartPepperFlashUpdateRegistration, cus)); | 420 base::Bind(&StartPepperFlashUpdateRegistration, cus)); |
| 514 #endif | 421 #endif |
| 515 } | 422 } |
| 516 | 423 |
| 517 } // namespace component_updater | 424 } // namespace component_updater |
| OLD | NEW |