Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(437)

Unified Diff: chrome/browser/search/hotword_service.cc

Issue 330193005: [Hotword] Uninstall and reinstall the extension upon language change. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more cleanup Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/search/hotword_service.cc
diff --git a/chrome/browser/search/hotword_service.cc b/chrome/browser/search/hotword_service.cc
index 7e67c647ad8d040c6e2421367063ef9a757136e7..0800f2642e81bbd518a9d3d031ec8a23fad19663 100644
--- a/chrome/browser/search/hotword_service.cc
+++ b/chrome/browser/search/hotword_service.cc
@@ -12,6 +12,9 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/pending_extension_manager.h"
+#include "chrome/browser/extensions/updater/extension_updater.h"
+#include "chrome/browser/extensions/webstore_startup_installer.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/hotword_service_factory.h"
@@ -24,6 +27,7 @@
#include "content/public/common/webplugininfo.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
+#include "extensions/common/one_shot_event.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -145,6 +149,18 @@ ExtensionService* GetExtensionService(Profile* profile) {
return NULL;
}
+// static
+std::string GetCurrentLocale(Profile* profile) {
+ std::string locale =
+#if defined(OS_CHROMEOS)
+ // On ChromeOS locale is per-profile.
+ profile->GetPrefs()->GetString(prefs::kApplicationLocale);
+#else
+ g_browser_process->GetApplicationLocale();
+#endif
+ return locale;
+}
+
} // namespace
namespace hotword_internal {
@@ -157,14 +173,8 @@ const char kHotwordUnusablePrefName[] = "hotword.search_enabled";
// static
bool HotwordService::DoesHotwordSupportLanguage(Profile* profile) {
- std::string locale =
-#if defined(OS_CHROMEOS)
- // On ChromeOS locale is per-profile.
- profile->GetPrefs()->GetString(prefs::kApplicationLocale);
-#else
- g_browser_process->GetApplicationLocale();
-#endif
- std::string normalized_locale = l10n_util::NormalizeLocale(locale);
+ std::string normalized_locale =
+ l10n_util::NormalizeLocale(GetCurrentLocale(profile));
StringToLowerASCII(&normalized_locale);
for (size_t i = 0; i < arraysize(kSupportedLocales); i++) {
@@ -176,8 +186,12 @@ bool HotwordService::DoesHotwordSupportLanguage(Profile* profile) {
HotwordService::HotwordService(Profile* profile)
: profile_(profile),
+ extension_registry_observer_(this),
client_(NULL),
- error_message_(0) {
+ error_message_(0),
+ uninstall_pending_(false),
+ weak_factory_(this) {
+ extension_registry_observer_.Add(extensions::ExtensionRegistry::Get(profile));
// This will be called during profile initialization which is a good time
// to check the user's hotword state.
HotwordEnabled enabled_state = UNSET;
@@ -203,12 +217,15 @@ HotwordService::HotwordService(Profile* profile)
base::Unretained(this)));
registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED,
- content::Source<Profile>(profile_));
- registrar_.Add(this,
chrome::NOTIFICATION_BROWSER_WINDOW_READY,
content::NotificationService::AllSources());
+ extensions::ExtensionSystem::Get(profile_)->ready().Post(
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(
+ &HotwordService::MaybeUninstallHotwordExtension),
+ weak_factory_.GetWeakPtr()));
+
// Clear the old user pref because it became unusable.
// TODO(rlp): Remove this code per crbug.com/358789.
if (profile_->GetPrefs()->HasPrefPath(
@@ -223,25 +240,7 @@ HotwordService::~HotwordService() {
void HotwordService::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
- if (type == chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED) {
- const extensions::Extension* extension =
- content::Details<const extensions::InstalledExtensionInfo>(details)
- ->extension;
- // Disabling the extension automatically on install should only occur
- // if the user is in the field trial for auto-install which is gated
- // by the IsHotwordAllowed check.
- if (IsHotwordAllowed() &&
- extension->id() == extension_misc::kHotwordExtensionId &&
- !profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled)) {
- DisableHotwordExtension(GetExtensionService(profile_));
- // Once the extension is disabled, it will not be enabled until the
- // user opts in at which point the pref registrar will take over
- // enabling and disabling.
- registrar_.Remove(this,
- chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED,
- content::Source<Profile>(profile_));
- }
- } else if (type == chrome::NOTIFICATION_BROWSER_WINDOW_READY) {
+ if (type == chrome::NOTIFICATION_BROWSER_WINDOW_READY) {
// The microphone monitor must be initialized as the page is loading
// so that the state of the microphone is available when the page
// loads. The Ok Google Hotword setting will display an error if there
@@ -257,6 +256,120 @@ void HotwordService::Observe(int type,
}
}
+void HotwordService::OnExtensionUninstalled(
+ content::BrowserContext* browser_context,
+ const extensions::Extension* extension) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ if (extension->id() != extension_misc::kHotwordExtensionId ||
+ profile_ != static_cast<Profile*>(browser_context) ||
Yoyo Zhou 2014/06/18 00:33:21 Profile::FromBrowserContext
rpetterson 2014/06/18 02:08:44 Done.
+ !GetExtensionService(profile_))
+ return;
+
+ // Verify that the extension was uninstalled because of a locale mismatch.
+ // If that's the case, reinstall and reset the saved locale.
+ if (!ShouldUninstallHotwordExtension())
Yoyo Zhou 2014/06/18 00:33:21 Does uninstall_pending_ serve as well here?
rpetterson 2014/06/18 02:08:44 You mean just replace the check ShouldUninstallHot
+ return;
+
+ InstallHotwordExtensionFromWebstore();
+ SetPreviousLocalePref();
+}
+
+void HotwordService::InstallHotwordExtensionFromWebstore() {
+ extensions::WebstoreStandaloneInstaller::Callback callback =
+ base::Bind(&HotwordService::OnHotwordExtensionInstalled,
+ base::Unretained(this));
+ installer_ = new extensions::WebstoreStartupInstaller(
Yoyo Zhou 2014/06/18 00:33:21 I'm not confident that this is the right choice of
rpetterson 2014/06/18 02:08:44 This is the same one used by ChromeOS to install t
+ extension_misc::kHotwordExtensionId,
+ profile_,
+ false,
+ callback);
+ installer_->BeginInstall();
+}
+
+void HotwordService::OnExtensionInstalled(
+ content::BrowserContext* browser_context,
+ const extensions::Extension* extension) {
+
+ if (extension->id() != extension_misc::kHotwordExtensionId ||
+ profile_ != static_cast<Profile*>(browser_context))
+ return;
+
+ // If the previous locale pref has never been set, set it now since
+ // the extension has been installed.
+ if (!profile_->GetPrefs()->HasPrefPath(prefs::kHotwordPreviousLanguage))
+ SetPreviousLocalePref();
+
+ // If MaybeUninstallHotwordExtension already triggered an uninstall, we
+ // don't want to loop and trigger another uninstall-install cycle.
+ // However, if we arrived her via an uninstall-triggered-install (and in
+ // that case |uninstall_pending_| will be true) then we know install
+ // has completed and we can reset |uninstall_pending_|.
+ if (!uninstall_pending_)
Yoyo Zhou 2014/06/18 00:33:21 What do you think about calling this reinstall_pen
rpetterson 2014/06/18 02:08:44 sgtm. done.
+ MaybeUninstallHotwordExtension();
+ else
+ uninstall_pending_ = false;
+
+ // Now that the extension is installed, if the user has not selected
+ // the preference on, make sure it is turned off.
+ //
+ // Disabling the extension automatically on install should only occur
+ // if the user is in the field trial for auto-install which is gated
+ // by the IsHotwordAllowed check. The check for IsHotwordAllowed() here
+ // can be removed once it's known that few people have manually
+ // installed extension.
+ if (IsHotwordAllowed() &&
Yoyo Zhou 2014/06/18 00:33:21 This check/disable looks repeated from the constru
rpetterson 2014/06/18 02:08:44 Yes, but we have to repeat it because the HotwordS
+ !profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled)) {
+ DisableHotwordExtension(GetExtensionService(profile_));
+ }
+}
+
+bool HotwordService::MaybeUninstallHotwordExtension() {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ ExtensionService* extension_service = GetExtensionService(profile_);
+ if (!extension_service)
+ return false;
+
+ const extensions::Extension* extension = extension_service->GetExtensionById(
+ extension_misc::kHotwordExtensionId, true);
+ if (!extension)
+ return false;
+
+ // If the extension is currently pending, return and we'll check again
+ // after the install is finished.
+ extensions::PendingExtensionManager* pending_manager =
+ extension_service->pending_extension_manager();
+ if (pending_manager->IsIdPending(extension->id()))
+ return false;
+
+ // If there is already a pending request from HotwordService, don't try
+ // to uninstall either.
+ if (uninstall_pending_)
+ return false;
+
+ // Check if the current locale matches the previous. If they don't match,
+ // uninstall the extension.
+ if (!ShouldUninstallHotwordExtension())
+ return false;
+
+ uninstall_pending_ = true;
+ return UninstallHotwordExtension(extension_service);
+}
+
+bool HotwordService::UninstallHotwordExtension(
+ ExtensionService* extension_service) {
+ base::string16 error;
+ if (!extension_service->UninstallExtension(
+ extension_misc::kHotwordExtensionId, true, &error)) {
+ LOG(WARNING) << "Cannot uninstall extension with id "
+ << extension_misc::kHotwordExtensionId
+ << ": " << error;
+ return false;
+ }
+ return true;
+}
+
bool HotwordService::IsServiceAvailable() {
error_message_ = 0;
@@ -371,3 +484,29 @@ void HotwordService::StopHotwordSession(HotwordClient* client) {
event_service->OnHotwordSessionStopped();
#endif
}
+
+void HotwordService::SetPreviousLocalePref() {
+ profile_->GetPrefs()->SetString(prefs::kHotwordPreviousLanguage,
+ GetCurrentLocale(profile_));
+}
+
+bool HotwordService::ShouldUninstallHotwordExtension() {
+ std::string previous_locale =
+ profile_->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage);
+ std::string locale = GetCurrentLocale(profile_);
+
+ // If it's a new locale, then the old extension should be uninstalled.
+ // If there is no previous locale pref, then this is the first install
+ // so no need to uninstall first.
+ return locale != previous_locale &&
+ profile_->GetPrefs()->HasPrefPath(prefs::kHotwordPreviousLanguage) &&
Yoyo Zhou 2014/06/18 00:33:21 nit: seems like the no-previous-locale check shoul
rpetterson 2014/06/18 02:08:44 Done.
+ HotwordService::DoesHotwordSupportLanguage(profile_);
+}
+
+void HotwordService::OnHotwordExtensionInstalled(bool success,
Yoyo Zhou 2014/06/18 00:33:21 This callback doesn't really do anything. Is it ne
rpetterson 2014/06/18 02:08:44 I agree. Removed.
+ const std::string& error) {
+ if (!success)
+ LOG(WARNING) << "Cannot install extension with id "
+ << extension_misc::kHotwordExtensionId
+ << ": " << error;
+}

Powered by Google App Engine
This is Rietveld 408576698