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 "chrome/browser/component_updater/flash_component_installer.h" | 5 #include "chrome/browser/component_updater/flash_component_installer.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 } | 89 } |
90 | 90 |
91 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) | 91 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) |
92 // Pepper Flash plugins have the version encoded in the path itself | 92 // Pepper Flash plugins have the version encoded in the path itself |
93 // so we need to enumerate the directories to find the full path. | 93 // so we need to enumerate the directories to find the full path. |
94 // On success, |latest_dir| returns something like: | 94 // On success, |latest_dir| returns something like: |
95 // <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\10.3.44.555\. | 95 // <profile>\AppData\Local\Google\Chrome\User Data\PepperFlash\10.3.44.555\. |
96 // |latest_version| returns the corresponding version number. |older_dirs| | 96 // |latest_version| returns the corresponding version number. |older_dirs| |
97 // returns directories of all older versions. | 97 // returns directories of all older versions. |
98 bool GetPepperFlashDirectory(base::FilePath* latest_dir, | 98 bool GetPepperFlashDirectory(base::FilePath* latest_dir, |
99 Version* latest_version, | 99 base::Version* latest_version, |
100 std::vector<base::FilePath>* older_dirs) { | 100 std::vector<base::FilePath>* older_dirs) { |
101 base::FilePath base_dir = GetPepperFlashBaseDirectory(); | 101 base::FilePath base_dir = GetPepperFlashBaseDirectory(); |
102 bool found = false; | 102 bool found = false; |
103 base::FileEnumerator | 103 base::FileEnumerator |
104 file_enumerator(base_dir, false, base::FileEnumerator::DIRECTORIES); | 104 file_enumerator(base_dir, false, base::FileEnumerator::DIRECTORIES); |
105 for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); | 105 for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); |
106 path = file_enumerator.Next()) { | 106 path = file_enumerator.Next()) { |
107 Version version(path.BaseName().MaybeAsASCII()); | 107 base::Version version(path.BaseName().MaybeAsASCII()); |
108 if (!version.IsValid()) | 108 if (!version.IsValid()) |
109 continue; | 109 continue; |
110 if (found) { | 110 if (found) { |
111 if (version.CompareTo(*latest_version) > 0) { | 111 if (version.CompareTo(*latest_version) > 0) { |
112 older_dirs->push_back(*latest_dir); | 112 older_dirs->push_back(*latest_dir); |
113 *latest_dir = path; | 113 *latest_dir = path; |
114 *latest_version = version; | 114 *latest_version = version; |
115 } else { | 115 } else { |
116 older_dirs->push_back(path); | 116 older_dirs->push_back(path); |
117 } | 117 } |
(...skipping 13 matching lines...) Expand all Loading... |
131 if (IsSupportedPepperInterface(interface_name)) | 131 if (IsSupportedPepperInterface(interface_name)) |
132 return true; | 132 return true; |
133 // The PDF interface is invisible to SupportsInterface() on the browser | 133 // The PDF interface is invisible to SupportsInterface() on the browser |
134 // process because it is provided using PpapiInterfaceFactoryManager. We need | 134 // process because it is provided using PpapiInterfaceFactoryManager. We need |
135 // to check for that as well. | 135 // to check for that as well. |
136 // TODO(cpu): make this more sane. | 136 // TODO(cpu): make this more sane. |
137 return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0); | 137 return (strcmp(interface_name, PPB_PDF_INTERFACE) == 0); |
138 } | 138 } |
139 | 139 |
140 bool MakePepperFlashPluginInfo(const base::FilePath& flash_path, | 140 bool MakePepperFlashPluginInfo(const base::FilePath& flash_path, |
141 const Version& flash_version, | 141 const base::Version& flash_version, |
142 bool out_of_process, | 142 bool out_of_process, |
143 content::PepperPluginInfo* plugin_info) { | 143 content::PepperPluginInfo* plugin_info) { |
144 if (!flash_version.IsValid()) | 144 if (!flash_version.IsValid()) |
145 return false; | 145 return false; |
146 const std::vector<uint16> ver_nums = flash_version.components(); | 146 const std::vector<uint16> ver_nums = flash_version.components(); |
147 if (ver_nums.size() < 3) | 147 if (ver_nums.size() < 3) |
148 return false; | 148 return false; |
149 | 149 |
150 plugin_info->is_internal = false; | 150 plugin_info->is_internal = false; |
151 plugin_info->is_out_of_process = out_of_process; | 151 plugin_info->is_out_of_process = out_of_process; |
(...skipping 20 matching lines...) Expand all Loading... |
172 | 172 |
173 bool IsPepperFlash(const content::WebPluginInfo& plugin) { | 173 bool IsPepperFlash(const content::WebPluginInfo& plugin) { |
174 // We try to recognize Pepper Flash by the following criteria: | 174 // We try to recognize Pepper Flash by the following criteria: |
175 // * It is a Pepper plug-in. | 175 // * It is a Pepper plug-in. |
176 // * It has the special Flash permissions. | 176 // * It has the special Flash permissions. |
177 return plugin.is_pepper_plugin() && | 177 return plugin.is_pepper_plugin() && |
178 (plugin.pepper_permissions & ppapi::PERMISSION_FLASH); | 178 (plugin.pepper_permissions & ppapi::PERMISSION_FLASH); |
179 } | 179 } |
180 | 180 |
181 void RegisterPepperFlashWithChrome(const base::FilePath& path, | 181 void RegisterPepperFlashWithChrome(const base::FilePath& path, |
182 const Version& version) { | 182 const base::Version& version) { |
183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
184 content::PepperPluginInfo plugin_info; | 184 content::PepperPluginInfo plugin_info; |
185 if (!MakePepperFlashPluginInfo(path, version, true, &plugin_info)) | 185 if (!MakePepperFlashPluginInfo(path, version, true, &plugin_info)) |
186 return; | 186 return; |
187 | 187 |
188 std::vector<content::WebPluginInfo> plugins; | 188 std::vector<content::WebPluginInfo> plugins; |
189 PluginService::GetInstance()->GetInternalPlugins(&plugins); | 189 PluginService::GetInstance()->GetInternalPlugins(&plugins); |
190 for (std::vector<content::WebPluginInfo>::const_iterator it = plugins.begin(); | 190 for (std::vector<content::WebPluginInfo>::const_iterator it = plugins.begin(); |
191 it != plugins.end(); ++it) { | 191 it != plugins.end(); ++it) { |
192 if (!IsPepperFlash(*it)) | 192 if (!IsPepperFlash(*it)) |
193 continue; | 193 continue; |
194 | 194 |
195 // Do it only if the version we're trying to register is newer. | 195 // Do it only if the version we're trying to register is newer. |
196 Version registered_version(UTF16ToUTF8(it->version)); | 196 base::Version registered_version(UTF16ToUTF8(it->version)); |
197 if (registered_version.IsValid() && | 197 if (registered_version.IsValid() && |
198 version.CompareTo(registered_version) <= 0) { | 198 version.CompareTo(registered_version) <= 0) { |
199 return; | 199 return; |
200 } | 200 } |
201 | 201 |
202 // If the version is newer, remove the old one first. | 202 // If the version is newer, remove the old one first. |
203 PluginService::GetInstance()->UnregisterInternalPlugin(it->path); | 203 PluginService::GetInstance()->UnregisterInternalPlugin(it->path); |
204 break; | 204 break; |
205 } | 205 } |
206 | 206 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 return false; | 238 return false; |
239 } | 239 } |
240 | 240 |
241 return true; | 241 return true; |
242 } | 242 } |
243 | 243 |
244 } // namespace | 244 } // namespace |
245 | 245 |
246 class PepperFlashComponentInstaller : public ComponentInstaller { | 246 class PepperFlashComponentInstaller : public ComponentInstaller { |
247 public: | 247 public: |
248 explicit PepperFlashComponentInstaller(const Version& version); | 248 explicit PepperFlashComponentInstaller(const base::Version& version); |
249 | 249 |
250 virtual ~PepperFlashComponentInstaller() {} | 250 virtual ~PepperFlashComponentInstaller() {} |
251 | 251 |
252 virtual void OnUpdateError(int error) OVERRIDE; | 252 virtual void OnUpdateError(int error) OVERRIDE; |
253 | 253 |
254 virtual bool Install(const base::DictionaryValue& manifest, | 254 virtual bool Install(const base::DictionaryValue& manifest, |
255 const base::FilePath& unpack_path) OVERRIDE; | 255 const base::FilePath& unpack_path) OVERRIDE; |
256 | 256 |
257 virtual bool GetInstalledFile(const std::string& file, | 257 virtual bool GetInstalledFile(const std::string& file, |
258 base::FilePath* installed_file) OVERRIDE; | 258 base::FilePath* installed_file) OVERRIDE; |
259 | 259 |
260 private: | 260 private: |
261 Version current_version_; | 261 base::Version current_version_; |
262 }; | 262 }; |
263 | 263 |
264 PepperFlashComponentInstaller::PepperFlashComponentInstaller( | 264 PepperFlashComponentInstaller::PepperFlashComponentInstaller( |
265 const Version& version) : current_version_(version) { | 265 const base::Version& version) : current_version_(version) { |
266 DCHECK(version.IsValid()); | 266 DCHECK(version.IsValid()); |
267 } | 267 } |
268 | 268 |
269 void PepperFlashComponentInstaller::OnUpdateError(int error) { | 269 void PepperFlashComponentInstaller::OnUpdateError(int error) { |
270 NOTREACHED() << "Pepper Flash update error: " << error; | 270 NOTREACHED() << "Pepper Flash update error: " << error; |
271 } | 271 } |
272 | 272 |
273 bool PepperFlashComponentInstaller::Install( | 273 bool PepperFlashComponentInstaller::Install( |
274 const base::DictionaryValue& manifest, | 274 const base::DictionaryValue& manifest, |
275 const base::FilePath& unpack_path) { | 275 const base::FilePath& unpack_path) { |
276 Version version; | 276 base::Version version; |
277 if (!CheckPepperFlashManifest(manifest, &version)) | 277 if (!CheckPepperFlashManifest(manifest, &version)) |
278 return false; | 278 return false; |
279 if (current_version_.CompareTo(version) > 0) | 279 if (current_version_.CompareTo(version) > 0) |
280 return false; | 280 return false; |
281 if (!base::PathExists(unpack_path.Append( | 281 if (!base::PathExists(unpack_path.Append( |
282 chrome::kPepperFlashPluginFilename))) | 282 chrome::kPepperFlashPluginFilename))) |
283 return false; | 283 return false; |
284 // Passed the basic tests. Time to install it. | 284 // Passed the basic tests. Time to install it. |
285 base::FilePath path = | 285 base::FilePath path = |
286 GetPepperFlashBaseDirectory().AppendASCII(version.GetString()); | 286 GetPepperFlashBaseDirectory().AppendASCII(version.GetString()); |
(...skipping 11 matching lines...) Expand all Loading... |
298 base::Bind(&RegisterPepperFlashWithChrome, path, version)); | 298 base::Bind(&RegisterPepperFlashWithChrome, path, version)); |
299 return true; | 299 return true; |
300 } | 300 } |
301 | 301 |
302 bool PepperFlashComponentInstaller::GetInstalledFile( | 302 bool PepperFlashComponentInstaller::GetInstalledFile( |
303 const std::string& file, base::FilePath* installed_file) { | 303 const std::string& file, base::FilePath* installed_file) { |
304 return false; | 304 return false; |
305 } | 305 } |
306 | 306 |
307 bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, | 307 bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, |
308 Version* version_out) { | 308 base::Version* version_out) { |
309 std::string name; | 309 std::string name; |
310 manifest.GetStringASCII("name", &name); | 310 manifest.GetStringASCII("name", &name); |
311 // TODO(viettrungluu): Support WinFlapper for now, while we change the format | 311 // TODO(viettrungluu): Support WinFlapper for now, while we change the format |
312 // of the manifest. (Should be safe to remove checks for "WinFlapper" in, say, | 312 // of the manifest. (Should be safe to remove checks for "WinFlapper" in, say, |
313 // Nov. 2011.) crbug.com/98458 | 313 // Nov. 2011.) crbug.com/98458 |
314 if (name != kPepperFlashManifestName && name != "WinFlapper") | 314 if (name != kPepperFlashManifestName && name != "WinFlapper") |
315 return false; | 315 return false; |
316 | 316 |
317 std::string proposed_version; | 317 std::string proposed_version; |
318 manifest.GetStringASCII("version", &proposed_version); | 318 manifest.GetStringASCII("version", &proposed_version); |
319 Version version(proposed_version.c_str()); | 319 base::Version version(proposed_version.c_str()); |
320 if (!version.IsValid()) | 320 if (!version.IsValid()) |
321 return false; | 321 return false; |
322 | 322 |
323 if (!CheckPepperFlashInterfaces(manifest)) | 323 if (!CheckPepperFlashInterfaces(manifest)) |
324 return false; | 324 return false; |
325 | 325 |
326 // TODO(viettrungluu): See above TODO. | 326 // TODO(viettrungluu): See above TODO. |
327 if (name == "WinFlapper") { | 327 if (name == "WinFlapper") { |
328 *version_out = version; | 328 *version_out = version; |
329 return true; | 329 return true; |
(...skipping 10 matching lines...) Expand all Loading... |
340 return false; | 340 return false; |
341 | 341 |
342 *version_out = version; | 342 *version_out = version; |
343 return true; | 343 return true; |
344 } | 344 } |
345 | 345 |
346 namespace { | 346 namespace { |
347 | 347 |
348 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) | 348 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) |
349 void FinishPepperFlashUpdateRegistration(ComponentUpdateService* cus, | 349 void FinishPepperFlashUpdateRegistration(ComponentUpdateService* cus, |
350 const Version& version) { | 350 const base::Version& version) { |
351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
352 CrxComponent pepflash; | 352 CrxComponent pepflash; |
353 pepflash.name = "pepper_flash"; | 353 pepflash.name = "pepper_flash"; |
354 pepflash.installer = new PepperFlashComponentInstaller(version); | 354 pepflash.installer = new PepperFlashComponentInstaller(version); |
355 pepflash.version = version; | 355 pepflash.version = version; |
356 pepflash.pk_hash.assign(kSha2Hash, &kSha2Hash[sizeof(kSha2Hash)]); | 356 pepflash.pk_hash.assign(kSha2Hash, &kSha2Hash[sizeof(kSha2Hash)]); |
357 if (cus->RegisterComponent(pepflash) != ComponentUpdateService::kOk) { | 357 if (cus->RegisterComponent(pepflash) != ComponentUpdateService::kOk) { |
358 NOTREACHED() << "Pepper Flash component registration failed."; | 358 NOTREACHED() << "Pepper Flash component registration failed."; |
359 } | 359 } |
360 } | 360 } |
361 | 361 |
362 void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) { | 362 void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) { |
363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
364 base::FilePath path = GetPepperFlashBaseDirectory(); | 364 base::FilePath path = GetPepperFlashBaseDirectory(); |
365 if (!base::PathExists(path)) { | 365 if (!base::PathExists(path)) { |
366 if (!base::CreateDirectory(path)) { | 366 if (!base::CreateDirectory(path)) { |
367 NOTREACHED() << "Could not create Pepper Flash directory."; | 367 NOTREACHED() << "Could not create Pepper Flash directory."; |
368 return; | 368 return; |
369 } | 369 } |
370 } | 370 } |
371 | 371 |
372 Version version(kNullVersion); | 372 base::Version version(kNullVersion); |
373 std::vector<base::FilePath> older_dirs; | 373 std::vector<base::FilePath> older_dirs; |
374 if (GetPepperFlashDirectory(&path, &version, &older_dirs)) { | 374 if (GetPepperFlashDirectory(&path, &version, &older_dirs)) { |
375 path = path.Append(chrome::kPepperFlashPluginFilename); | 375 path = path.Append(chrome::kPepperFlashPluginFilename); |
376 if (base::PathExists(path)) { | 376 if (base::PathExists(path)) { |
377 BrowserThread::PostTask( | 377 BrowserThread::PostTask( |
378 BrowserThread::UI, FROM_HERE, | 378 BrowserThread::UI, FROM_HERE, |
379 base::Bind(&RegisterPepperFlashWithChrome, path, version)); | 379 base::Bind(&RegisterPepperFlashWithChrome, path, version)); |
380 } else { | 380 } else { |
381 version = Version(kNullVersion); | 381 version = base::Version(kNullVersion); |
382 } | 382 } |
383 } | 383 } |
384 | 384 |
385 BrowserThread::PostTask( | 385 BrowserThread::PostTask( |
386 BrowserThread::UI, FROM_HERE, | 386 BrowserThread::UI, FROM_HERE, |
387 base::Bind(&FinishPepperFlashUpdateRegistration, cus, version)); | 387 base::Bind(&FinishPepperFlashUpdateRegistration, cus, version)); |
388 | 388 |
389 // Remove older versions of Pepper Flash. | 389 // Remove older versions of Pepper Flash. |
390 for (std::vector<base::FilePath>::iterator iter = older_dirs.begin(); | 390 for (std::vector<base::FilePath>::iterator iter = older_dirs.begin(); |
391 iter != older_dirs.end(); ++iter) { | 391 iter != older_dirs.end(); ++iter) { |
392 base::DeleteFile(*iter, true); | 392 base::DeleteFile(*iter, true); |
393 } | 393 } |
394 } | 394 } |
395 #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) | 395 #endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) |
396 | 396 |
397 } // namespace | 397 } // namespace |
398 | 398 |
399 void RegisterPepperFlashComponent(ComponentUpdateService* cus) { | 399 void RegisterPepperFlashComponent(ComponentUpdateService* cus) { |
400 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) | 400 #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX) |
401 // Component updated flash supersedes bundled flash therefore if that one | 401 // Component updated flash supersedes bundled flash therefore if that one |
402 // is disabled then this one should never install. | 402 // is disabled then this one should never install. |
403 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 403 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
404 if (cmd_line->HasSwitch(switches::kDisableBundledPpapiFlash)) | 404 if (cmd_line->HasSwitch(switches::kDisableBundledPpapiFlash)) |
405 return; | 405 return; |
406 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 406 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
407 base::Bind(&StartPepperFlashUpdateRegistration, cus)); | 407 base::Bind(&StartPepperFlashUpdateRegistration, cus)); |
408 #endif | 408 #endif |
409 } | 409 } |
OLD | NEW |