Index: chrome/browser/extensions/external_extension_provider_impl.cc |
=================================================================== |
--- chrome/browser/extensions/external_extension_provider_impl.cc (revision 105797) |
+++ chrome/browser/extensions/external_extension_provider_impl.cc (working copy) |
@@ -14,16 +14,20 @@ |
#include "base/values.h" |
#include "base/version.h" |
#include "chrome/browser/browser_process.h" |
+#include "chrome/browser/extensions/crx_installer.h" |
#include "chrome/browser/extensions/default_apps_trial.h" |
#include "chrome/browser/extensions/extension_service.h" |
#include "chrome/browser/extensions/external_extension_provider_interface.h" |
#include "chrome/browser/extensions/external_policy_extension_loader.h" |
#include "chrome/browser/extensions/external_pref_extension_loader.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/common/chrome_notification_types.h" |
#include "chrome/common/chrome_paths.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/pref_names.h" |
#include "content/browser/browser_thread.h" |
+#include "content/common/notification_details.h" |
+#include "content/common/notification_source.h" |
#include "ui/base/l10n/l10n_util.h" |
#if defined(OS_WIN) |
@@ -42,44 +46,123 @@ |
"supported_locales"; |
#if !defined(OS_CHROMEOS) |
-class DefaultAppsProvider : public ExternalExtensionProviderImpl { |
- public: |
- DefaultAppsProvider(VisitorInterface* service, Profile* profile) |
- : ExternalExtensionProviderImpl(service, |
- new ExternalPrefExtensionLoader(chrome::DIR_DEFAULT_APPS, |
- ExternalPrefExtensionLoader::NONE), |
- Extension::EXTERNAL_PREF, Extension::INVALID), |
- profile_(profile) { |
- DCHECK(profile_); |
+DefaultAppsProvider::DefaultAppsProvider(VisitorInterface* service, |
+ ExternalExtensionLoader* loader, |
+ Profile* profile) |
+ : ExternalExtensionProviderImpl(service, loader, |
+ Extension::EXTERNAL_PREF, Extension::INVALID), |
+ profile_(profile) { |
+ DCHECK(profile_); |
+} |
+ |
+DefaultAppsProvider::~DefaultAppsProvider() { |
+} |
+ |
+void DefaultAppsProvider::SetPrefs(base::DictionaryValue* prefs) { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ if (prefs->size() > 0) { |
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, |
+ Source<Profile>(profile_)); |
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, |
+ NotificationService::AllSources()); |
} |
- // ExternalExtensionProviderImpl overrides: |
- virtual void ServiceShutdown() OVERRIDE; |
- virtual void VisitRegisteredExtension() const OVERRIDE; |
+ ExternalExtensionProviderImpl::SetPrefs(prefs); |
- private: |
- Profile* profile_; |
+ // If the number of invalid extension is the same as the total, then we are |
+ // done. |
+ if (prefs->size() == invalid_extensions().size()) { |
Finnur
2011/10/19 10:01:29
Is it safe to rely on the count? Don't you want to
Roger Tawa OOO till Jul 10th
2011/10/19 20:48:25
The invalid_extension set can only come from exten
|
+ profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState, |
+ kInstallDone); |
+ profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
+ } |
+} |
- DISALLOW_COPY_AND_ASSIGN(DefaultAppsProvider); |
-}; |
- |
void DefaultAppsProvider::ServiceShutdown() { |
profile_ = NULL; |
ExternalExtensionProviderImpl::ServiceShutdown(); |
} |
void DefaultAppsProvider::VisitRegisteredExtension() const { |
- // Don't install default apps if the profile already has apps installed. |
if (profile_) { |
- ExtensionService* extension_service = profile_->GetExtensionService(); |
- if (extension_service && extension_service->HasApps()) { |
- service()->OnExternalProviderReady(); |
- return; |
+ int state = profile_->GetPrefs()->GetInteger( |
+ prefs::kDefaultAppsInstallState); |
Finnur
2011/10/19 10:01:29
nit: Is there room in the line above or are my eye
Roger Tawa OOO till Jul 10th
2011/10/19 20:48:25
yup, you need glasses :-)
Finnur
2011/10/20 10:10:43
Awww... :)
On 2011/10/19 20:48:25, Roger Tawa wro
|
+ switch (state) { |
+ case kInstallNotStarted: { |
+ // We never even tried to install the default apps, so try now. |
+ // Don't install default apps if the profile already has apps installed. |
+ ExtensionService* extension_service = profile_->GetExtensionService(); |
+ if (extension_service && extension_service->HasApps()) { |
+ service()->OnExternalProviderReady(); |
Finnur
2011/10/19 10:01:29
nit: Probably doesn't matter, but shouldn't you se
Roger Tawa OOO till Jul 10th
2011/10/19 20:48:25
Done.
|
+ |
+ // Keep track that we are done. |
Finnur
2011/10/19 10:01:29
nit: Keep track of the fact that we are done.
Bet
Roger Tawa OOO till Jul 10th
2011/10/19 20:48:25
Done.
|
+ profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState, |
+ kInstallDone); |
+ profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
+ return; |
+ } |
+ |
+ // Remember that we are now installing the default apps. |
+ profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState, |
+ kInstalling); |
+ profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
+ // No break. |
Finnur
2011/10/19 10:01:29
This is a bit weird... skip the break to fall into
Roger Tawa OOO till Jul 10th
2011/10/19 20:48:25
Done.
|
+ } |
+ case kInstalling: |
+ // The profile was closed while the extensions were being installed. |
+ // Continue the install process. |
Finnur
2011/10/19 10:01:29
This comment is a bit confusing. I think you want
Roger Tawa OOO till Jul 10th
2011/10/19 20:48:25
more verbose explanation.
|
+ break; |
+ case kInstallDone: |
+ // Defaults are installed, so don't need to try again. |
+ service()->OnExternalProviderReady(); |
+ return; |
} |
} |
ExternalExtensionProviderImpl::VisitRegisteredExtension(); |
} |
+ |
+void DefaultAppsProvider::Observe(int type, |
+ const NotificationSource& source, |
+ const NotificationDetails& details) { |
+ if (!profile_) |
+ return; |
+ |
+ // If the notification is for a failed extension, remember its id so that |
+ // we don't wait forever for it to get installed. |
+ if (type == chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR) { |
+ CrxInstaller* crx_installer = Source<CrxInstaller>(source).ptr(); |
+ install_error_extensions_.insert(crx_installer->expected_id()); |
+ } |
+ |
+ ExtensionService* extension_service = profile_->GetExtensionService(); |
+ if (!extension_service) |
+ return; |
+ |
+ for (DictionaryValue::key_iterator i = prefs()->begin_keys(); |
+ i != prefs()->end_keys(); ++i) { |
+ const std::string& extension_id = *i; |
+ |
+ // If the extension id is for one that is invalid or failed to install, |
+ // then consider it "done". |
+ if (invalid_extensions().count(extension_id) || |
+ install_error_extensions_.count(extension_id)) { |
+ continue; |
+ } |
+ |
+ if (!extension_service->GetExtensionById(extension_id, true)) { |
+ // We found an extension that is not yet known to the service. We |
+ // need to keep going. |
+ return; |
+ } |
+ } |
+ |
+ profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState, |
+ kInstallDone); |
+ profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
+ registrar_.RemoveAll(); |
+} |
#endif |
ExternalExtensionProviderImpl::ExternalExtensionProviderImpl( |
@@ -113,6 +196,7 @@ |
// away while |loader_| was working on the FILE thread. |
if (!service_) return; |
+ invalid_extensions_.clear(); |
prefs_.reset(prefs); |
ready_ = true; // Queries for extensions are allowed from this point. |
@@ -125,6 +209,9 @@ |
const std::string& extension_id = *i; |
DictionaryValue* extension; |
+ // Assume the extension is invalid until proven otherwise. |
+ invalid_extensions_.insert(extension_id); |
+ |
if (!Extension::IdIsValid(extension_id)) { |
LOG(WARNING) << "Malformed extension dictionary: key " |
<< extension_id.c_str() << " is not a valid id."; |
@@ -231,6 +318,7 @@ |
<< external_version << "\"."; |
continue; |
} |
+ invalid_extensions_.erase(extension_id); |
service_->OnExternalExtensionFileFound(extension_id, version.get(), path, |
crx_location_); |
} else { // if (has_external_update_url) |
@@ -248,6 +336,7 @@ |
<< "\", which is not a valid URL."; |
continue; |
} |
+ invalid_extensions_.erase(extension_id); |
service_->OnExternalExtensionUpdateUrlFound( |
extension_id, update_url, download_location_); |
} |
@@ -420,7 +509,12 @@ |
if (supported_locale) { |
provider_list->push_back( |
linked_ptr<ExternalExtensionProviderInterface>( |
- new DefaultAppsProvider(service, profile))); |
+ new DefaultAppsProvider( |
+ service, |
+ new ExternalPrefExtensionLoader( |
+ chrome::DIR_DEFAULT_APPS, |
+ ExternalPrefExtensionLoader::NONE), |
+ profile))); |
} |
} |
#endif |