OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/extensions/extensions_service.h" | 5 #include "chrome/browser/extensions/extensions_service.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 return true; | 75 return true; |
76 } else { | 76 } else { |
77 return false; | 77 return false; |
78 } | 78 } |
79 } | 79 } |
80 | 80 |
81 ExtensionsService::ExtensionsService(Profile* profile, | 81 ExtensionsService::ExtensionsService(Profile* profile, |
82 const CommandLine* command_line, | 82 const CommandLine* command_line, |
83 PrefService* prefs, | 83 PrefService* prefs, |
84 const FilePath& install_directory, | 84 const FilePath& install_directory, |
85 MessageLoop* frontend_loop, | |
86 MessageLoop* backend_loop, | |
87 bool autoupdate_enabled) | 85 bool autoupdate_enabled) |
88 : profile_(profile), | 86 : profile_(profile), |
89 extension_prefs_(new ExtensionPrefs(prefs, install_directory)), | 87 extension_prefs_(new ExtensionPrefs(prefs, install_directory)), |
90 backend_loop_(backend_loop), | |
91 install_directory_(install_directory), | 88 install_directory_(install_directory), |
92 extensions_enabled_(true), | 89 extensions_enabled_(true), |
93 show_extensions_prompts_(true), | 90 show_extensions_prompts_(true), |
94 ready_(false) { | 91 ready_(false) { |
95 // Figure out if extension installation should be enabled. | 92 // Figure out if extension installation should be enabled. |
96 if (command_line->HasSwitch(switches::kDisableExtensions)) { | 93 if (command_line->HasSwitch(switches::kDisableExtensions)) { |
97 extensions_enabled_ = false; | 94 extensions_enabled_ = false; |
98 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { | 95 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { |
99 extensions_enabled_ = false; | 96 extensions_enabled_ = false; |
100 } | 97 } |
101 | 98 |
102 // Set up the ExtensionUpdater | 99 // Set up the ExtensionUpdater |
103 if (autoupdate_enabled) { | 100 if (autoupdate_enabled) { |
104 int update_frequency = kDefaultUpdateFrequencySeconds; | 101 int update_frequency = kDefaultUpdateFrequencySeconds; |
105 if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { | 102 if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { |
106 update_frequency = StringToInt(WideToASCII(command_line->GetSwitchValue( | 103 update_frequency = StringToInt(WideToASCII(command_line->GetSwitchValue( |
107 switches::kExtensionsUpdateFrequency))); | 104 switches::kExtensionsUpdateFrequency))); |
108 } | 105 } |
109 updater_ = new ExtensionUpdater(this, prefs, update_frequency, | 106 updater_ = new ExtensionUpdater(this, prefs, update_frequency); |
110 backend_loop_, g_browser_process->io_thread()->message_loop()); | |
111 } | 107 } |
112 | 108 |
113 backend_ = new ExtensionsServiceBackend(install_directory_, frontend_loop); | 109 backend_ = new ExtensionsServiceBackend(install_directory_); |
114 } | 110 } |
115 | 111 |
116 ExtensionsService::~ExtensionsService() { | 112 ExtensionsService::~ExtensionsService() { |
117 UnloadAllExtensions(); | 113 UnloadAllExtensions(); |
118 if (updater_.get()) { | 114 if (updater_.get()) { |
119 updater_->Stop(); | 115 updater_->Stop(); |
120 } | 116 } |
121 } | 117 } |
122 | 118 |
123 void ExtensionsService::Init() { | 119 void ExtensionsService::Init() { |
(...skipping 12 matching lines...) Expand all Loading... |
136 | 132 |
137 // TODO(erikkay) this should probably be deferred as well. | 133 // TODO(erikkay) this should probably be deferred as well. |
138 GarbageCollectExtensions(); | 134 GarbageCollectExtensions(); |
139 } | 135 } |
140 | 136 |
141 void ExtensionsService::InstallExtension(const FilePath& extension_path) { | 137 void ExtensionsService::InstallExtension(const FilePath& extension_path) { |
142 CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, | 138 CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, |
143 "", // no expected id | 139 "", // no expected id |
144 false, // don't delete crx when complete | 140 false, // don't delete crx when complete |
145 true, // allow privilege increase | 141 true, // allow privilege increase |
146 backend_loop_, | |
147 this, | 142 this, |
148 NULL); // no client (silent install) | 143 NULL); // no client (silent install) |
149 } | 144 } |
150 | 145 |
151 void ExtensionsService::UpdateExtension(const std::string& id, | 146 void ExtensionsService::UpdateExtension(const std::string& id, |
152 const FilePath& extension_path) { | 147 const FilePath& extension_path) { |
153 if (!GetExtensionByIdInternal(id, true, true)) { | 148 if (!GetExtensionByIdInternal(id, true, true)) { |
154 LOG(WARNING) << "Will not update extension " << id << " because it is not " | 149 LOG(WARNING) << "Will not update extension " << id << " because it is not " |
155 << "installed"; | 150 << "installed"; |
156 return; | 151 return; |
157 } | 152 } |
158 | 153 |
159 CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, | 154 CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, |
160 id, | 155 id, |
161 true, // delete crx when complete | 156 true, // delete crx when complete |
162 false, // do not allow upgrade of privileges | 157 false, // do not allow upgrade of privileges |
163 backend_loop_, | |
164 this, | 158 this, |
165 NULL); // no client (silent install) | 159 NULL); // no client (silent install) |
166 } | 160 } |
167 | 161 |
168 void ExtensionsService::ReloadExtension(const std::string& extension_id) { | 162 void ExtensionsService::ReloadExtension(const std::string& extension_id) { |
169 FilePath path; | 163 FilePath path; |
170 Extension* current_extension = GetExtensionById(extension_id); | 164 Extension* current_extension = GetExtensionById(extension_id); |
171 | 165 |
172 // Unload the extension if it's loaded. It might not be loaded if it crashed. | 166 // Unload the extension if it's loaded. It might not be loaded if it crashed. |
173 if (current_extension) { | 167 if (current_extension) { |
(...skipping 15 matching lines...) Expand all Loading... |
189 bool external_uninstall) { | 183 bool external_uninstall) { |
190 Extension* extension = GetExtensionByIdInternal(extension_id, true, true); | 184 Extension* extension = GetExtensionByIdInternal(extension_id, true, true); |
191 | 185 |
192 // Callers should not send us nonexistant extensions. | 186 // Callers should not send us nonexistant extensions. |
193 DCHECK(extension); | 187 DCHECK(extension); |
194 | 188 |
195 extension_prefs_->OnExtensionUninstalled(extension, external_uninstall); | 189 extension_prefs_->OnExtensionUninstalled(extension, external_uninstall); |
196 | 190 |
197 // Tell the backend to start deleting installed extensions on the file thread. | 191 // Tell the backend to start deleting installed extensions on the file thread. |
198 if (Extension::LOAD != extension->location()) { | 192 if (Extension::LOAD != extension->location()) { |
199 backend_loop_->PostTask(FROM_HERE, NewRunnableFunction( | 193 ChromeThread::PostTask( |
200 &extension_file_util::UninstallExtension, extension_id, | 194 ChromeThread::FILE, FROM_HERE, |
201 install_directory_)); | 195 NewRunnableFunction( |
| 196 &extension_file_util::UninstallExtension, extension_id, |
| 197 install_directory_)); |
202 } | 198 } |
203 | 199 |
204 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, | 200 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, |
205 extension->GetChromeURLOverrides()); | 201 extension->GetChromeURLOverrides()); |
206 | 202 |
207 UnloadExtension(extension_id); | 203 UnloadExtension(extension_id); |
208 } | 204 } |
209 | 205 |
210 void ExtensionsService::EnableExtension(const std::string& extension_id) { | 206 void ExtensionsService::EnableExtension(const std::string& extension_id) { |
211 Extension* extension = GetExtensionByIdInternal(extension_id, false, true); | 207 Extension* extension = GetExtensionByIdInternal(extension_id, false, true); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 extension); | 245 extension); |
250 extensions_.erase(iter); | 246 extensions_.erase(iter); |
251 | 247 |
252 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, | 248 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, |
253 extension->GetChromeURLOverrides()); | 249 extension->GetChromeURLOverrides()); |
254 | 250 |
255 NotifyExtensionUnloaded(extension); | 251 NotifyExtensionUnloaded(extension); |
256 } | 252 } |
257 | 253 |
258 void ExtensionsService::LoadExtension(const FilePath& extension_path) { | 254 void ExtensionsService::LoadExtension(const FilePath& extension_path) { |
259 backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(), | 255 ChromeThread::PostTask( |
260 &ExtensionsServiceBackend::LoadSingleExtension, | 256 ChromeThread::FILE, FROM_HERE, |
261 extension_path, scoped_refptr<ExtensionsService>(this))); | 257 NewRunnableMethod( |
| 258 backend_.get(), |
| 259 &ExtensionsServiceBackend::LoadSingleExtension, |
| 260 extension_path, scoped_refptr<ExtensionsService>(this))); |
262 } | 261 } |
263 | 262 |
264 void ExtensionsService::LoadAllExtensions() { | 263 void ExtensionsService::LoadAllExtensions() { |
265 // Load the previously installed extensions. | 264 // Load the previously installed extensions. |
266 scoped_ptr<InstalledExtensions> installed( | 265 scoped_ptr<InstalledExtensions> installed( |
267 new InstalledExtensions(extension_prefs_.get())); | 266 new InstalledExtensions(extension_prefs_.get())); |
268 installed->VisitInstalledExtensions( | 267 installed->VisitInstalledExtensions( |
269 NewCallback(this, &ExtensionsService::LoadInstalledExtension)); | 268 NewCallback(this, &ExtensionsService::LoadInstalledExtension)); |
270 OnLoadedInstalledExtensions(); | 269 OnLoadedInstalledExtensions(); |
271 } | 270 } |
(...skipping 18 matching lines...) Expand all Loading... |
290 NotificationType::EXTENSION_INSTALL_ERROR, | 289 NotificationType::EXTENSION_INSTALL_ERROR, |
291 false); | 290 false); |
292 return; | 291 return; |
293 } | 292 } |
294 | 293 |
295 extension->set_location(location); | 294 extension->set_location(location); |
296 OnExtensionLoaded(extension, true); | 295 OnExtensionLoaded(extension, true); |
297 | 296 |
298 if (location == Extension::EXTERNAL_PREF || | 297 if (location == Extension::EXTERNAL_PREF || |
299 location == Extension::EXTERNAL_REGISTRY) { | 298 location == Extension::EXTERNAL_REGISTRY) { |
300 backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(), | 299 ChromeThread::PostTask( |
301 &ExtensionsServiceBackend::CheckExternalUninstall, | 300 ChromeThread::FILE, FROM_HERE, |
302 scoped_refptr<ExtensionsService>(this), id, location)); | 301 NewRunnableMethod( |
| 302 backend_.get(), |
| 303 &ExtensionsServiceBackend::CheckExternalUninstall, |
| 304 scoped_refptr<ExtensionsService>(this), id, location)); |
303 } | 305 } |
304 } | 306 } |
305 | 307 |
306 void ExtensionsService::NotifyExtensionLoaded(Extension* extension) { | 308 void ExtensionsService::NotifyExtensionLoaded(Extension* extension) { |
307 LOG(INFO) << "Sending EXTENSION_LOADED"; | 309 LOG(INFO) << "Sending EXTENSION_LOADED"; |
308 | 310 |
309 // The ChromeURLRequestContext needs to be first to know that the extension | 311 // The ChromeURLRequestContext needs to be first to know that the extension |
310 // was loaded, otherwise a race can arise where a renderer that is created | 312 // was loaded, otherwise a race can arise where a renderer that is created |
311 // for the extension may try to load an extension URL with an extension id | 313 // for the extension may try to load an extension URL with an extension id |
312 // that the request context doesn't yet know about. | 314 // that the request context doesn't yet know about. |
313 if (profile_ && !profile_->IsOffTheRecord()) { | 315 if (profile_ && !profile_->IsOffTheRecord()) { |
314 ChromeURLRequestContextGetter* context_getter = | 316 ChromeURLRequestContextGetter* context_getter = |
315 static_cast<ChromeURLRequestContextGetter*>( | 317 static_cast<ChromeURLRequestContextGetter*>( |
316 profile_->GetRequestContext()); | 318 profile_->GetRequestContext()); |
317 if (context_getter) { | 319 if (context_getter) { |
318 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, | 320 ChromeThread::PostTask( |
319 NewRunnableMethod(context_getter, | 321 ChromeThread::IO, FROM_HERE, |
320 &ChromeURLRequestContextGetter::OnNewExtensions, | 322 NewRunnableMethod( |
321 extension->id(), | 323 context_getter, |
322 extension->path())); | 324 &ChromeURLRequestContextGetter::OnNewExtensions, |
| 325 extension->id(), |
| 326 extension->path())); |
323 } | 327 } |
324 } | 328 } |
325 | 329 |
326 NotificationService::current()->Notify( | 330 NotificationService::current()->Notify( |
327 NotificationType::EXTENSION_LOADED, | 331 NotificationType::EXTENSION_LOADED, |
328 Source<ExtensionsService>(this), | 332 Source<ExtensionsService>(this), |
329 Details<Extension>(extension)); | 333 Details<Extension>(extension)); |
330 } | 334 } |
331 | 335 |
332 void ExtensionsService::NotifyExtensionUnloaded(Extension* extension) { | 336 void ExtensionsService::NotifyExtensionUnloaded(Extension* extension) { |
333 LOG(INFO) << "Sending EXTENSION_UNLOADED"; | 337 LOG(INFO) << "Sending EXTENSION_UNLOADED"; |
334 | 338 |
335 NotificationService::current()->Notify( | 339 NotificationService::current()->Notify( |
336 NotificationType::EXTENSION_UNLOADED, | 340 NotificationType::EXTENSION_UNLOADED, |
337 Source<ExtensionsService>(this), | 341 Source<ExtensionsService>(this), |
338 Details<Extension>(extension)); | 342 Details<Extension>(extension)); |
339 | 343 |
340 if (profile_ && !profile_->IsOffTheRecord()) { | 344 if (profile_ && !profile_->IsOffTheRecord()) { |
341 ChromeURLRequestContextGetter* context_getter = | 345 ChromeURLRequestContextGetter* context_getter = |
342 static_cast<ChromeURLRequestContextGetter*>( | 346 static_cast<ChromeURLRequestContextGetter*>( |
343 profile_->GetRequestContext()); | 347 profile_->GetRequestContext()); |
344 if (context_getter) { | 348 if (context_getter) { |
345 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, | 349 ChromeThread::PostTask( |
| 350 ChromeThread::IO, FROM_HERE, |
346 NewRunnableMethod( | 351 NewRunnableMethod( |
347 context_getter, | 352 context_getter, |
348 &ChromeURLRequestContextGetter::OnUnloadedExtension, | 353 &ChromeURLRequestContextGetter::OnUnloadedExtension, |
349 extension->id())); | 354 extension->id())); |
350 } | 355 } |
351 } | 356 } |
352 } | 357 } |
353 | 358 |
354 void ExtensionsService::UpdateExtensionBlacklist( | 359 void ExtensionsService::UpdateExtensionBlacklist( |
355 const std::vector<std::string>& blacklist) { | 360 const std::vector<std::string>& blacklist) { |
(...skipping 21 matching lines...) Expand all Loading... |
377 UnloadExtension(to_be_removed[i]); | 382 UnloadExtension(to_be_removed[i]); |
378 } | 383 } |
379 } | 384 } |
380 | 385 |
381 void ExtensionsService::CheckForExternalUpdates() { | 386 void ExtensionsService::CheckForExternalUpdates() { |
382 // This installs or updates externally provided extensions. | 387 // This installs or updates externally provided extensions. |
383 // TODO(aa): Why pass this list into the provider, why not just filter it | 388 // TODO(aa): Why pass this list into the provider, why not just filter it |
384 // later? | 389 // later? |
385 std::set<std::string> killed_extensions; | 390 std::set<std::string> killed_extensions; |
386 extension_prefs_->GetKilledExtensionIds(&killed_extensions); | 391 extension_prefs_->GetKilledExtensionIds(&killed_extensions); |
387 backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(), | 392 ChromeThread::PostTask( |
388 &ExtensionsServiceBackend::CheckForExternalUpdates, | 393 ChromeThread::FILE, FROM_HERE, |
389 killed_extensions, | 394 NewRunnableMethod( |
390 scoped_refptr<ExtensionsService>(this))); | 395 backend_.get(), &ExtensionsServiceBackend::CheckForExternalUpdates, |
| 396 killed_extensions, scoped_refptr<ExtensionsService>(this))); |
391 } | 397 } |
392 | 398 |
393 void ExtensionsService::UnloadExtension(const std::string& extension_id) { | 399 void ExtensionsService::UnloadExtension(const std::string& extension_id) { |
394 scoped_ptr<Extension> extension( | 400 scoped_ptr<Extension> extension( |
395 GetExtensionByIdInternal(extension_id, true, true)); | 401 GetExtensionByIdInternal(extension_id, true, true)); |
396 | 402 |
397 // Callers should not send us nonexistant extensions. | 403 // Callers should not send us nonexistant extensions. |
398 CHECK(extension.get()); | 404 CHECK(extension.get()); |
399 | 405 |
400 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, | 406 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 } | 438 } |
433 | 439 |
434 void ExtensionsService::ReloadExtensions() { | 440 void ExtensionsService::ReloadExtensions() { |
435 UnloadAllExtensions(); | 441 UnloadAllExtensions(); |
436 LoadAllExtensions(); | 442 LoadAllExtensions(); |
437 } | 443 } |
438 | 444 |
439 void ExtensionsService::GarbageCollectExtensions() { | 445 void ExtensionsService::GarbageCollectExtensions() { |
440 InstalledExtensionSet installed( | 446 InstalledExtensionSet installed( |
441 new InstalledExtensions(extension_prefs_.get())); | 447 new InstalledExtensions(extension_prefs_.get())); |
442 backend_loop_->PostTask(FROM_HERE, NewRunnableFunction( | 448 ChromeThread::PostTask( |
443 &extension_file_util::GarbageCollectExtensions, install_directory_, | 449 ChromeThread::FILE, FROM_HERE, |
444 installed.extensions())); | 450 NewRunnableFunction( |
| 451 &extension_file_util::GarbageCollectExtensions, install_directory_, |
| 452 installed.extensions())); |
445 } | 453 } |
446 | 454 |
447 void ExtensionsService::OnLoadedInstalledExtensions() { | 455 void ExtensionsService::OnLoadedInstalledExtensions() { |
448 ready_ = true; | 456 ready_ = true; |
449 if (updater_.get()) { | 457 if (updater_.get()) { |
450 updater_->Start(); | 458 updater_->Start(); |
451 } | 459 } |
452 NotificationService::current()->Notify( | 460 NotificationService::current()->Notify( |
453 NotificationType::EXTENSIONS_READY, | 461 NotificationType::EXTENSIONS_READY, |
454 Source<ExtensionsService>(this), | 462 Source<ExtensionsService>(this), |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 } | 602 } |
595 return NULL; | 603 return NULL; |
596 } | 604 } |
597 | 605 |
598 Extension* ExtensionsService::GetExtensionByURL(const GURL& url) { | 606 Extension* ExtensionsService::GetExtensionByURL(const GURL& url) { |
599 std::string host = url.host(); | 607 std::string host = url.host(); |
600 return GetExtensionById(host); | 608 return GetExtensionById(host); |
601 } | 609 } |
602 | 610 |
603 void ExtensionsService::ClearProvidersForTesting() { | 611 void ExtensionsService::ClearProvidersForTesting() { |
604 backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(), | 612 ChromeThread::PostTask( |
605 &ExtensionsServiceBackend::ClearProvidersForTesting)); | 613 ChromeThread::FILE, FROM_HERE, |
| 614 NewRunnableMethod( |
| 615 backend_.get(), &ExtensionsServiceBackend::ClearProvidersForTesting)); |
606 } | 616 } |
607 | 617 |
608 void ExtensionsService::SetProviderForTesting( | 618 void ExtensionsService::SetProviderForTesting( |
609 Extension::Location location, ExternalExtensionProvider* test_provider) { | 619 Extension::Location location, ExternalExtensionProvider* test_provider) { |
610 backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(), | 620 ChromeThread::PostTask( |
611 &ExtensionsServiceBackend::SetProviderForTesting, | 621 ChromeThread::FILE, FROM_HERE, |
612 location, test_provider)); | 622 NewRunnableMethod( |
| 623 backend_.get(), &ExtensionsServiceBackend::SetProviderForTesting, |
| 624 location, test_provider)); |
613 } | 625 } |
614 | 626 |
615 void ExtensionsService::OnExternalExtensionFound(const std::string& id, | 627 void ExtensionsService::OnExternalExtensionFound(const std::string& id, |
616 const std::string& version, | 628 const std::string& version, |
617 const FilePath& path, | 629 const FilePath& path, |
618 Extension::Location location) { | 630 Extension::Location location) { |
619 // Before even bothering to unpack, check and see if we already have this | 631 // Before even bothering to unpack, check and see if we already have this |
620 // version. This is important because these extensions are going to get | 632 // version. This is important because these extensions are going to get |
621 // installed on every startup. | 633 // installed on every startup. |
622 Extension* existing = GetExtensionById(id); | 634 Extension* existing = GetExtensionById(id); |
623 scoped_ptr<Version> other(Version::GetVersionFromString(version)); | 635 scoped_ptr<Version> other(Version::GetVersionFromString(version)); |
624 if (existing) { | 636 if (existing) { |
625 switch (existing->version()->CompareTo(*other)) { | 637 switch (existing->version()->CompareTo(*other)) { |
626 case -1: // existing version is older, we should upgrade | 638 case -1: // existing version is older, we should upgrade |
627 break; | 639 break; |
628 case 0: // existing version is same, do nothing | 640 case 0: // existing version is same, do nothing |
629 return; | 641 return; |
630 case 1: // existing version is newer, uh-oh | 642 case 1: // existing version is newer, uh-oh |
631 LOG(WARNING) << "Found external version of extension " << id | 643 LOG(WARNING) << "Found external version of extension " << id |
632 << "that is older than current version. Current version " | 644 << "that is older than current version. Current version " |
633 << "is: " << existing->VersionString() << ". New version " | 645 << "is: " << existing->VersionString() << ". New version " |
634 << "is: " << version << ". Keeping current version."; | 646 << "is: " << version << ". Keeping current version."; |
635 return; | 647 return; |
636 } | 648 } |
637 } | 649 } |
638 | 650 |
639 CrxInstaller::Start(path, install_directory_, location, id, | 651 CrxInstaller::Start(path, install_directory_, location, id, |
640 false, // don't delete crx when complete | 652 false, // don't delete crx when complete |
641 true, // allow privilege increase | 653 true, // allow privilege increase |
642 backend_loop_, | |
643 this, | 654 this, |
644 NULL); // no client (silent install) | 655 NULL); // no client (silent install) |
645 } | 656 } |
646 | 657 |
647 void ExtensionsService::ReportExtensionLoadError( | 658 void ExtensionsService::ReportExtensionLoadError( |
648 const FilePath& extension_path, | 659 const FilePath& extension_path, |
649 const std::string &error, | 660 const std::string &error, |
650 NotificationType type, | 661 NotificationType type, |
651 bool be_noisy) { | 662 bool be_noisy) { |
652 NotificationService* service = NotificationService::current(); | 663 NotificationService* service = NotificationService::current(); |
653 service->Notify(type, | 664 service->Notify(type, |
654 Source<ExtensionsService>(this), | 665 Source<ExtensionsService>(this), |
655 Details<const std::string>(&error)); | 666 Details<const std::string>(&error)); |
656 | 667 |
657 // TODO(port): note that this isn't guaranteed to work properly on Linux. | 668 // TODO(port): note that this isn't guaranteed to work properly on Linux. |
658 std::string path_str = WideToASCII(extension_path.ToWStringHack()); | 669 std::string path_str = WideToASCII(extension_path.ToWStringHack()); |
659 std::string message = StringPrintf("Could not load extension from '%s'. %s", | 670 std::string message = StringPrintf("Could not load extension from '%s'. %s", |
660 path_str.c_str(), error.c_str()); | 671 path_str.c_str(), error.c_str()); |
661 ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy); | 672 ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy); |
662 } | 673 } |
663 | 674 |
664 // ExtensionsServicesBackend | 675 // ExtensionsServicesBackend |
665 | 676 |
666 ExtensionsServiceBackend::ExtensionsServiceBackend( | 677 ExtensionsServiceBackend::ExtensionsServiceBackend( |
667 const FilePath& install_directory, MessageLoop* frontend_loop) | 678 const FilePath& install_directory) |
668 : frontend_(NULL), | 679 : frontend_(NULL), |
669 install_directory_(install_directory), | 680 install_directory_(install_directory), |
670 alert_on_error_(false), | 681 alert_on_error_(false) { |
671 frontend_loop_(frontend_loop) { | |
672 // TODO(aa): This ends up doing blocking IO on the UI thread because it reads | 682 // TODO(aa): This ends up doing blocking IO on the UI thread because it reads |
673 // pref data in the ctor and that is called on the UI thread. Would be better | 683 // pref data in the ctor and that is called on the UI thread. Would be better |
674 // to re-read data each time we list external extensions, anyway. | 684 // to re-read data each time we list external extensions, anyway. |
675 external_extension_providers_[Extension::EXTERNAL_PREF] = | 685 external_extension_providers_[Extension::EXTERNAL_PREF] = |
676 linked_ptr<ExternalExtensionProvider>( | 686 linked_ptr<ExternalExtensionProvider>( |
677 new ExternalPrefExtensionProvider()); | 687 new ExternalPrefExtensionProvider()); |
678 #if defined(OS_WIN) | 688 #if defined(OS_WIN) |
679 external_extension_providers_[Extension::EXTERNAL_REGISTRY] = | 689 external_extension_providers_[Extension::EXTERNAL_REGISTRY] = |
680 linked_ptr<ExternalExtensionProvider>( | 690 linked_ptr<ExternalExtensionProvider>( |
681 new ExternalRegistryExtensionProvider()); | 691 new ExternalRegistryExtensionProvider()); |
(...skipping 26 matching lines...) Expand all Loading... |
708 ReportExtensionLoadError(extension_path, error); | 718 ReportExtensionLoadError(extension_path, error); |
709 return; | 719 return; |
710 } | 720 } |
711 | 721 |
712 extension->set_location(Extension::LOAD); | 722 extension->set_location(Extension::LOAD); |
713 ReportExtensionLoaded(extension); | 723 ReportExtensionLoaded(extension); |
714 } | 724 } |
715 | 725 |
716 void ExtensionsServiceBackend::ReportExtensionLoadError( | 726 void ExtensionsServiceBackend::ReportExtensionLoadError( |
717 const FilePath& extension_path, const std::string &error) { | 727 const FilePath& extension_path, const std::string &error) { |
718 // In the unit tests, frontend_loop_ may be null. | 728 ChromeThread::PostTask( |
719 if (frontend_loop_ == NULL) { | 729 ChromeThread::UI, FROM_HERE, |
720 frontend_->ReportExtensionLoadError( | 730 NewRunnableMethod( |
721 extension_path, | 731 frontend_, |
722 error, | |
723 NotificationType::EXTENSION_INSTALL_ERROR, | |
724 alert_on_error_); | |
725 return; | |
726 } | |
727 | |
728 frontend_loop_->PostTask(FROM_HERE, | |
729 NewRunnableMethod(frontend_, | |
730 &ExtensionsService::ReportExtensionLoadError, extension_path, | 732 &ExtensionsService::ReportExtensionLoadError, extension_path, |
731 error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_)); | 733 error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_)); |
732 } | 734 } |
733 | 735 |
734 void ExtensionsServiceBackend::ReportExtensionLoaded(Extension* extension) { | 736 void ExtensionsServiceBackend::ReportExtensionLoaded(Extension* extension) { |
735 frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 737 ChromeThread::PostTask( |
736 frontend_, &ExtensionsService::OnExtensionLoaded, extension, true)); | 738 ChromeThread::UI, FROM_HERE, |
| 739 NewRunnableMethod( |
| 740 frontend_, &ExtensionsService::OnExtensionLoaded, extension, true)); |
737 } | 741 } |
738 | 742 |
739 bool ExtensionsServiceBackend::LookupExternalExtension( | 743 bool ExtensionsServiceBackend::LookupExternalExtension( |
740 const std::string& id, Version** version, Extension::Location* location) { | 744 const std::string& id, Version** version, Extension::Location* location) { |
741 scoped_ptr<Version> extension_version; | 745 scoped_ptr<Version> extension_version; |
742 for (ProviderMap::const_iterator i = external_extension_providers_.begin(); | 746 for (ProviderMap::const_iterator i = external_extension_providers_.begin(); |
743 i != external_extension_providers_.end(); ++i) { | 747 i != external_extension_providers_.end(); ++i) { |
744 const ExternalExtensionProvider* provider = i->second.get(); | 748 const ExternalExtensionProvider* provider = i->second.get(); |
745 extension_version.reset(provider->RegisteredVersion(id, location)); | 749 extension_version.reset(provider->RegisteredVersion(id, location)); |
746 if (extension_version.get()) { | 750 if (extension_version.get()) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 << location; | 792 << location; |
789 return; | 793 return; |
790 } | 794 } |
791 | 795 |
792 scoped_ptr<Version> version; | 796 scoped_ptr<Version> version; |
793 version.reset(i->second->RegisteredVersion(id, NULL)); | 797 version.reset(i->second->RegisteredVersion(id, NULL)); |
794 if (version.get()) | 798 if (version.get()) |
795 return; // Yup, known extension, don't uninstall. | 799 return; // Yup, known extension, don't uninstall. |
796 | 800 |
797 // This is an external extension that we don't have registered. Uninstall. | 801 // This is an external extension that we don't have registered. Uninstall. |
798 frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 802 ChromeThread::PostTask( |
799 frontend.get(), &ExtensionsService::UninstallExtension, | 803 ChromeThread::UI, FROM_HERE, |
800 id, true)); | 804 NewRunnableMethod( |
| 805 frontend.get(), &ExtensionsService::UninstallExtension, id, true)); |
801 } | 806 } |
802 | 807 |
803 void ExtensionsServiceBackend::ClearProvidersForTesting() { | 808 void ExtensionsServiceBackend::ClearProvidersForTesting() { |
804 external_extension_providers_.clear(); | 809 external_extension_providers_.clear(); |
805 } | 810 } |
806 | 811 |
807 void ExtensionsServiceBackend::SetProviderForTesting( | 812 void ExtensionsServiceBackend::SetProviderForTesting( |
808 Extension::Location location, | 813 Extension::Location location, |
809 ExternalExtensionProvider* test_provider) { | 814 ExternalExtensionProvider* test_provider) { |
810 DCHECK(test_provider); | 815 DCHECK(test_provider); |
811 external_extension_providers_[location] = | 816 external_extension_providers_[location] = |
812 linked_ptr<ExternalExtensionProvider>(test_provider); | 817 linked_ptr<ExternalExtensionProvider>(test_provider); |
813 } | 818 } |
814 | 819 |
815 void ExtensionsServiceBackend::OnExternalExtensionFound( | 820 void ExtensionsServiceBackend::OnExternalExtensionFound( |
816 const std::string& id, const Version* version, const FilePath& path, | 821 const std::string& id, const Version* version, const FilePath& path, |
817 Extension::Location location) { | 822 Extension::Location location) { |
818 frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(frontend_, | 823 ChromeThread::PostTask( |
819 &ExtensionsService::OnExternalExtensionFound, id, version->GetString(), | 824 ChromeThread::UI, FROM_HERE, |
820 path, location)); | 825 NewRunnableMethod( |
| 826 frontend_, &ExtensionsService::OnExternalExtensionFound, id, |
| 827 version->GetString(), path, location)); |
821 } | 828 } |
OLD | NEW |