| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/search/hotword_service.h" | 5 #include "chrome/browser/search/hotword_service.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/i18n/case_conversion.h" | 10 #include "base/i18n/case_conversion.h" |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 }; | 90 }; |
| 91 | 91 |
| 92 // Maximum number of retries for installing the hotword shared module from the | 92 // Maximum number of retries for installing the hotword shared module from the |
| 93 // web store. | 93 // web store. |
| 94 static const int kMaxInstallRetries = 2; | 94 static const int kMaxInstallRetries = 2; |
| 95 | 95 |
| 96 // Delay between retries for installing the hotword shared module from the web | 96 // Delay between retries for installing the hotword shared module from the web |
| 97 // store. | 97 // store. |
| 98 static const int kInstallRetryDelaySeconds = 5; | 98 static const int kInstallRetryDelaySeconds = 5; |
| 99 | 99 |
| 100 // The extension id of the old hotword voice search trigger extension. |
| 101 const char kHotwordOldExtensionId[] = "bepbmhgboaologfdajaanbcjmnhjmhfn"; |
| 102 |
| 100 // Enum describing the state of the hotword preference. | 103 // Enum describing the state of the hotword preference. |
| 101 // This is used for UMA stats -- do not reorder or delete items; only add to | 104 // This is used for UMA stats -- do not reorder or delete items; only add to |
| 102 // the end. | 105 // the end. |
| 103 enum HotwordEnabled { | 106 enum HotwordEnabled { |
| 104 UNSET = 0, // No hotword preference has been set. | 107 UNSET = 0, // No hotword preference has been set. |
| 105 ENABLED, // The (classic) hotword preference is enabled. | 108 ENABLED, // The (classic) hotword preference is enabled. |
| 106 DISABLED, // All hotwording is disabled. | 109 DISABLED, // All hotwording is disabled. |
| 107 ALWAYS_ON_ENABLED, // Always-on hotwording is enabled. | 110 ALWAYS_ON_ENABLED, // Always-on hotwording is enabled. |
| 108 NUM_HOTWORD_ENABLED_METRICS | 111 NUM_HOTWORD_ENABLED_METRICS |
| 109 }; | 112 }; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 125 // This is used for UMA stats -- do not reorder or delete items; only add to | 128 // This is used for UMA stats -- do not reorder or delete items; only add to |
| 126 // the end. | 129 // the end. |
| 127 enum HotwordError { | 130 enum HotwordError { |
| 128 NO_HOTWORD_ERROR = 0, | 131 NO_HOTWORD_ERROR = 0, |
| 129 GENERIC_HOTWORD_ERROR, | 132 GENERIC_HOTWORD_ERROR, |
| 130 NACL_HOTWORD_ERROR, | 133 NACL_HOTWORD_ERROR, |
| 131 MICROPHONE_HOTWORD_ERROR, | 134 MICROPHONE_HOTWORD_ERROR, |
| 132 NUM_HOTWORD_ERROR_METRICS | 135 NUM_HOTWORD_ERROR_METRICS |
| 133 }; | 136 }; |
| 134 | 137 |
| 135 void RecordExtensionAvailabilityMetrics( | |
| 136 ExtensionService* service, | |
| 137 const extensions::Extension* extension) { | |
| 138 HotwordExtensionAvailability availability_state = UNAVAILABLE; | |
| 139 if (extension) { | |
| 140 availability_state = AVAILABLE; | |
| 141 } else if (service->pending_extension_manager() && | |
| 142 service->pending_extension_manager()->IsIdPending( | |
| 143 extension_misc::kHotwordExtensionId)) { | |
| 144 availability_state = PENDING_DOWNLOAD; | |
| 145 } else if (!service->IsExtensionEnabled( | |
| 146 extension_misc::kHotwordExtensionId)) { | |
| 147 availability_state = DISABLED_EXTENSION; | |
| 148 } | |
| 149 UMA_HISTOGRAM_ENUMERATION("Hotword.HotwordExtensionAvailability", | |
| 150 availability_state, | |
| 151 NUM_HOTWORD_EXTENSION_AVAILABILITY_METRICS); | |
| 152 } | |
| 153 | |
| 154 void RecordLoggingMetrics(Profile* profile) { | 138 void RecordLoggingMetrics(Profile* profile) { |
| 155 // If the user is not opted in to hotword voice search, the audio logging | 139 // If the user is not opted in to hotword voice search, the audio logging |
| 156 // metric is not valid so it is not recorded. | 140 // metric is not valid so it is not recorded. |
| 157 if (!profile->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled)) | 141 if (!profile->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled)) |
| 158 return; | 142 return; |
| 159 | 143 |
| 160 UMA_HISTOGRAM_BOOLEAN( | 144 UMA_HISTOGRAM_BOOLEAN( |
| 161 "Hotword.HotwordAudioLogging", | 145 "Hotword.HotwordAudioLogging", |
| 162 profile->GetPrefs()->GetBoolean(prefs::kHotwordAudioLoggingEnabled)); | 146 profile->GetPrefs()->GetBoolean(prefs::kHotwordAudioLoggingEnabled)); |
| 163 } | 147 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 182 error, | 166 error, |
| 183 NUM_HOTWORD_ERROR_METRICS); | 167 NUM_HOTWORD_ERROR_METRICS); |
| 184 } | 168 } |
| 185 | 169 |
| 186 void RecordHotwordEnabledMetric(HotwordService *service, Profile* profile) { | 170 void RecordHotwordEnabledMetric(HotwordService *service, Profile* profile) { |
| 187 HotwordEnabled enabled_state = DISABLED; | 171 HotwordEnabled enabled_state = DISABLED; |
| 188 auto prefs = profile->GetPrefs(); | 172 auto prefs = profile->GetPrefs(); |
| 189 if (!prefs->HasPrefPath(prefs::kHotwordSearchEnabled) && | 173 if (!prefs->HasPrefPath(prefs::kHotwordSearchEnabled) && |
| 190 !prefs->HasPrefPath(prefs::kHotwordAlwaysOnSearchEnabled)) { | 174 !prefs->HasPrefPath(prefs::kHotwordAlwaysOnSearchEnabled)) { |
| 191 enabled_state = UNSET; | 175 enabled_state = UNSET; |
| 192 } else if (service->IsExperimentalHotwordingEnabled() && | 176 } else if (service->IsAlwaysOnEnabled()) { |
| 193 service->IsAlwaysOnEnabled()) { | |
| 194 enabled_state = ALWAYS_ON_ENABLED; | 177 enabled_state = ALWAYS_ON_ENABLED; |
| 195 } else if (prefs->GetBoolean(prefs::kHotwordSearchEnabled)) { | 178 } else if (prefs->GetBoolean(prefs::kHotwordSearchEnabled)) { |
| 196 enabled_state = ENABLED; | 179 enabled_state = ENABLED; |
| 197 } | 180 } |
| 198 UMA_HISTOGRAM_ENUMERATION("Hotword.Enabled", enabled_state, | 181 UMA_HISTOGRAM_ENUMERATION("Hotword.Enabled", enabled_state, |
| 199 NUM_HOTWORD_ENABLED_METRICS); | 182 NUM_HOTWORD_ENABLED_METRICS); |
| 200 } | 183 } |
| 201 | 184 |
| 202 ExtensionService* GetExtensionService(Profile* profile) { | 185 ExtensionService* GetExtensionService(Profile* profile) { |
| 203 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 186 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 base::StringToLowerASCII(&normalized_locale); | 274 base::StringToLowerASCII(&normalized_locale); |
| 292 | 275 |
| 293 for (size_t i = 0; i < arraysize(kSupportedLocales); i++) { | 276 for (size_t i = 0; i < arraysize(kSupportedLocales); i++) { |
| 294 if (normalized_locale == kSupportedLocales[i]) | 277 if (normalized_locale == kSupportedLocales[i]) |
| 295 return true; | 278 return true; |
| 296 } | 279 } |
| 297 return false; | 280 return false; |
| 298 } | 281 } |
| 299 | 282 |
| 300 // static | 283 // static |
| 301 bool HotwordService::IsExperimentalHotwordingEnabled() { | |
| 302 return true; | |
| 303 } | |
| 304 | |
| 305 // static | |
| 306 bool HotwordService::IsHotwordHardwareAvailable() { | 284 bool HotwordService::IsHotwordHardwareAvailable() { |
| 307 #if defined(OS_CHROMEOS) | 285 #if defined(OS_CHROMEOS) |
| 308 if (chromeos::CrasAudioHandler::IsInitialized()) { | 286 if (chromeos::CrasAudioHandler::IsInitialized()) { |
| 309 chromeos::AudioDeviceList devices; | 287 chromeos::AudioDeviceList devices; |
| 310 chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices); | 288 chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices); |
| 311 for (size_t i = 0; i < devices.size(); ++i) { | 289 for (size_t i = 0; i < devices.size(); ++i) { |
| 312 if (devices[i].type == chromeos::AUDIO_TYPE_AOKR) { | 290 if (devices[i].type == chromeos::AUDIO_TYPE_AOKR) { |
| 313 DCHECK(devices[i].is_input); | 291 DCHECK(devices[i].is_input); |
| 314 return true; | 292 return true; |
| 315 } | 293 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 346 | 324 |
| 347 HotwordService::HotwordService(Profile* profile) | 325 HotwordService::HotwordService(Profile* profile) |
| 348 : profile_(profile), | 326 : profile_(profile), |
| 349 extension_registry_observer_(this), | 327 extension_registry_observer_(this), |
| 350 client_(NULL), | 328 client_(NULL), |
| 351 error_message_(0), | 329 error_message_(0), |
| 352 reinstall_pending_(false), | 330 reinstall_pending_(false), |
| 353 training_(false), | 331 training_(false), |
| 354 weak_factory_(this) { | 332 weak_factory_(this) { |
| 355 extension_registry_observer_.Add(extensions::ExtensionRegistry::Get(profile)); | 333 extension_registry_observer_.Add(extensions::ExtensionRegistry::Get(profile)); |
| 356 if (IsExperimentalHotwordingEnabled()) { | 334 |
| 357 // Disable the old extension so it doesn't interfere with the new stuff. | 335 // Disable the old extension so it doesn't interfere with the new stuff. |
| 358 DisableHotwordExtension(GetExtensionService(profile_)); | 336 ExtensionService* extension_service = GetExtensionService(profile_); |
| 359 } else { | 337 if (extension_service) { |
| 360 if (!profile_->GetPrefs()->HasPrefPath(prefs::kHotwordSearchEnabled) && | 338 extension_service->DisableExtension( |
| 361 IsHotwordAllowed()) { | 339 kHotwordOldExtensionId, |
| 362 // If the preference has not been set the hotword extension should | 340 extensions::Extension::DISABLE_USER_ACTION); |
| 363 // not be running. However, this should only be done if auto-install | |
| 364 // is enabled which is gated through the IsHotwordAllowed check. | |
| 365 DisableHotwordExtension(GetExtensionService(profile_)); | |
| 366 } | |
| 367 } | 341 } |
| 342 |
| 368 // This will be called during profile initialization which is a good time | 343 // This will be called during profile initialization which is a good time |
| 369 // to check the user's hotword state. | 344 // to check the user's hotword state. |
| 370 RecordHotwordEnabledMetric(this, profile_); | 345 RecordHotwordEnabledMetric(this, profile_); |
| 371 | 346 |
| 372 pref_registrar_.Init(profile_->GetPrefs()); | 347 pref_registrar_.Init(profile_->GetPrefs()); |
| 373 pref_registrar_.Add( | 348 pref_registrar_.Add( |
| 374 prefs::kHotwordSearchEnabled, | |
| 375 base::Bind(&HotwordService::OnHotwordSearchEnabledChanged, | |
| 376 base::Unretained(this))); | |
| 377 pref_registrar_.Add( | |
| 378 prefs::kHotwordAlwaysOnSearchEnabled, | 349 prefs::kHotwordAlwaysOnSearchEnabled, |
| 379 base::Bind(&HotwordService::OnHotwordAlwaysOnSearchEnabledChanged, | 350 base::Bind(&HotwordService::OnHotwordAlwaysOnSearchEnabledChanged, |
| 380 base::Unretained(this))); | 351 base::Unretained(this))); |
| 381 | 352 |
| 382 extensions::ExtensionSystem::Get(profile_)->ready().Post( | 353 extensions::ExtensionSystem::Get(profile_)->ready().Post( |
| 383 FROM_HERE, | 354 FROM_HERE, |
| 384 base::Bind(base::IgnoreResult( | 355 base::Bind(base::IgnoreResult( |
| 385 &HotwordService::MaybeReinstallHotwordExtension), | 356 &HotwordService::MaybeReinstallHotwordExtension), |
| 386 weak_factory_.GetWeakPtr())); | 357 weak_factory_.GetWeakPtr())); |
| 387 | 358 |
| 388 // Clear the old user pref because it became unusable. | 359 // Clear the old user pref because it became unusable. |
| 389 // TODO(rlp): Remove this code per crbug.com/358789. | 360 // TODO(rlp): Remove this code per crbug.com/358789. |
| 390 if (profile_->GetPrefs()->HasPrefPath( | 361 if (profile_->GetPrefs()->HasPrefPath( |
| 391 hotword_internal::kHotwordUnusablePrefName)) { | 362 hotword_internal::kHotwordUnusablePrefName)) { |
| 392 profile_->GetPrefs()->ClearPref(hotword_internal::kHotwordUnusablePrefName); | 363 profile_->GetPrefs()->ClearPref(hotword_internal::kHotwordUnusablePrefName); |
| 393 } | 364 } |
| 394 | 365 |
| 395 SetAudioHistoryHandler(new HotwordAudioHistoryHandler( | 366 SetAudioHistoryHandler(new HotwordAudioHistoryHandler( |
| 396 profile_, base::MessageLoop::current()->task_runner())); | 367 profile_, base::MessageLoop::current()->task_runner())); |
| 397 | 368 |
| 398 if (HotwordServiceFactory::IsAlwaysOnAvailable() && | 369 if (HotwordServiceFactory::IsAlwaysOnAvailable() && |
| 399 IsHotwordAllowed() && | 370 IsHotwordAllowed()) { |
| 400 IsExperimentalHotwordingEnabled()) { | |
| 401 // Show the hotword notification in 5 seconds if the experimental flag is | 371 // Show the hotword notification in 5 seconds if the experimental flag is |
| 402 // on, or in 10 minutes if not. We need to wait at least a few seconds | 372 // on, or in 10 minutes if not. We need to wait at least a few seconds |
| 403 // for the hotword extension to be installed. | 373 // for the hotword extension to be installed. |
| 404 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 374 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 405 if (command_line->HasSwitch(switches::kEnableExperimentalHotwordHardware)) { | 375 if (command_line->HasSwitch(switches::kEnableExperimentalHotwordHardware)) { |
| 406 base::MessageLoop::current()->PostDelayedTask( | 376 base::MessageLoop::current()->PostDelayedTask( |
| 407 FROM_HERE, | 377 FROM_HERE, |
| 408 base::Bind(&HotwordService::ShowHotwordNotification, | 378 base::Bind(&HotwordService::ShowHotwordNotification, |
| 409 weak_factory_.GetWeakPtr()), | 379 weak_factory_.GetWeakPtr()), |
| 410 base::TimeDelta::FromSeconds(5)); | 380 base::TimeDelta::FromSeconds(5)); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 profile_->GetPrefs()->SetBoolean( | 440 profile_->GetPrefs()->SetBoolean( |
| 471 prefs::kHotwordAlwaysOnNotificationSeen, true); | 441 prefs::kHotwordAlwaysOnNotificationSeen, true); |
| 472 } | 442 } |
| 473 | 443 |
| 474 void HotwordService::OnExtensionUninstalled( | 444 void HotwordService::OnExtensionUninstalled( |
| 475 content::BrowserContext* browser_context, | 445 content::BrowserContext* browser_context, |
| 476 const extensions::Extension* extension, | 446 const extensions::Extension* extension, |
| 477 extensions::UninstallReason reason) { | 447 extensions::UninstallReason reason) { |
| 478 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 448 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 479 | 449 |
| 480 if ((extension->id() != extension_misc::kHotwordExtensionId && | 450 if (extension->id() != extension_misc::kHotwordSharedModuleId || |
| 481 extension->id() != extension_misc::kHotwordSharedModuleId) || | 451 profile_ != Profile::FromBrowserContext(browser_context) || |
| 482 profile_ != Profile::FromBrowserContext(browser_context) || | |
| 483 !GetExtensionService(profile_)) | 452 !GetExtensionService(profile_)) |
| 484 return; | 453 return; |
| 485 | 454 |
| 486 // If the extension wasn't uninstalled due to language change, don't try to | 455 // If the extension wasn't uninstalled due to language change, don't try to |
| 487 // reinstall it. | 456 // reinstall it. |
| 488 if (!reinstall_pending_) | 457 if (!reinstall_pending_) |
| 489 return; | 458 return; |
| 490 | 459 |
| 491 InstallHotwordExtensionFromWebstore(kMaxInstallRetries); | 460 InstallHotwordExtensionFromWebstore(kMaxInstallRetries); |
| 492 SetPreviousLanguagePref(); | 461 SetPreviousLanguagePref(); |
| 493 } | 462 } |
| 494 | 463 |
| 495 std::string HotwordService::ReinstalledExtensionId() { | 464 std::string HotwordService::ReinstalledExtensionId() { |
| 496 if (IsExperimentalHotwordingEnabled()) | 465 return extension_misc::kHotwordSharedModuleId; |
| 497 return extension_misc::kHotwordSharedModuleId; | |
| 498 | |
| 499 return extension_misc::kHotwordExtensionId; | |
| 500 } | 466 } |
| 501 | 467 |
| 502 void HotwordService::InstalledFromWebstoreCallback( | 468 void HotwordService::InstalledFromWebstoreCallback( |
| 503 int num_tries, | 469 int num_tries, |
| 504 bool success, | 470 bool success, |
| 505 const std::string& error, | 471 const std::string& error, |
| 506 extensions::webstore_install::Result result) { | 472 extensions::webstore_install::Result result) { |
| 507 if (result != extensions::webstore_install::SUCCESS && num_tries) { | 473 if (result != extensions::webstore_install::SUCCESS && num_tries) { |
| 508 // Try again on failure. | 474 // Try again on failure. |
| 509 content::BrowserThread::PostDelayedTask( | 475 content::BrowserThread::PostDelayedTask( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 524 weak_factory_.GetWeakPtr(), | 490 weak_factory_.GetWeakPtr(), |
| 525 num_tries - 1)); | 491 num_tries - 1)); |
| 526 installer_->BeginInstall(); | 492 installer_->BeginInstall(); |
| 527 } | 493 } |
| 528 | 494 |
| 529 void HotwordService::OnExtensionInstalled( | 495 void HotwordService::OnExtensionInstalled( |
| 530 content::BrowserContext* browser_context, | 496 content::BrowserContext* browser_context, |
| 531 const extensions::Extension* extension, | 497 const extensions::Extension* extension, |
| 532 bool is_update) { | 498 bool is_update) { |
| 533 | 499 |
| 534 if ((extension->id() != extension_misc::kHotwordExtensionId && | 500 if (extension->id() != extension_misc::kHotwordSharedModuleId || |
| 535 extension->id() != extension_misc::kHotwordSharedModuleId) || | 501 profile_ != Profile::FromBrowserContext(browser_context)) |
| 536 profile_ != Profile::FromBrowserContext(browser_context)) | |
| 537 return; | 502 return; |
| 538 | 503 |
| 539 // If the previous locale pref has never been set, set it now since | 504 // If the previous locale pref has never been set, set it now since |
| 540 // the extension has been installed. | 505 // the extension has been installed. |
| 541 if (!profile_->GetPrefs()->HasPrefPath(prefs::kHotwordPreviousLanguage)) | 506 if (!profile_->GetPrefs()->HasPrefPath(prefs::kHotwordPreviousLanguage)) |
| 542 SetPreviousLanguagePref(); | 507 SetPreviousLanguagePref(); |
| 543 | 508 |
| 544 // If MaybeReinstallHotwordExtension already triggered an uninstall, we | 509 // If MaybeReinstallHotwordExtension already triggered an uninstall, we |
| 545 // don't want to loop and trigger another uninstall-install cycle. | 510 // don't want to loop and trigger another uninstall-install cycle. |
| 546 // However, if we arrived here via an uninstall-triggered-install (and in | 511 // However, if we arrived here via an uninstall-triggered-install (and in |
| 547 // that case |reinstall_pending_| will be true) then we know install | 512 // that case |reinstall_pending_| will be true) then we know install |
| 548 // has completed and we can reset |reinstall_pending_|. | 513 // has completed and we can reset |reinstall_pending_|. |
| 549 if (!reinstall_pending_) | 514 if (!reinstall_pending_) |
| 550 MaybeReinstallHotwordExtension(); | 515 MaybeReinstallHotwordExtension(); |
| 551 else | 516 else |
| 552 reinstall_pending_ = false; | 517 reinstall_pending_ = false; |
| 553 | |
| 554 // Now that the extension is installed, if the user has not selected | |
| 555 // the preference on, make sure it is turned off. | |
| 556 // | |
| 557 // Disabling the extension automatically on install should only occur | |
| 558 // if the user is in the field trial for auto-install which is gated | |
| 559 // by the IsHotwordAllowed check. The check for IsHotwordAllowed() here | |
| 560 // can be removed once it's known that few people have manually | |
| 561 // installed extension. | |
| 562 if (IsHotwordAllowed() && !IsSometimesOnEnabled()) | |
| 563 DisableHotwordExtension(GetExtensionService(profile_)); | |
| 564 } | 518 } |
| 565 | 519 |
| 566 bool HotwordService::MaybeReinstallHotwordExtension() { | 520 bool HotwordService::MaybeReinstallHotwordExtension() { |
| 567 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 521 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 568 | 522 |
| 569 ExtensionService* extension_service = GetExtensionService(profile_); | 523 ExtensionService* extension_service = GetExtensionService(profile_); |
| 570 if (!extension_service) | 524 if (!extension_service) |
| 571 return false; | 525 return false; |
| 572 | 526 |
| 573 const extensions::Extension* extension = extension_service->GetExtensionById( | 527 const extensions::Extension* extension = extension_service->GetExtensionById( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 extensions::ExtensionSystem* system = | 590 extensions::ExtensionSystem* system = |
| 637 extensions::ExtensionSystem::Get(profile_); | 591 extensions::ExtensionSystem::Get(profile_); |
| 638 ExtensionService* service = system->extension_service(); | 592 ExtensionService* service = system->extension_service(); |
| 639 // Include disabled extensions (true parameter) since it may not be enabled | 593 // Include disabled extensions (true parameter) since it may not be enabled |
| 640 // if the user opted out. | 594 // if the user opted out. |
| 641 const extensions::Extension* extension = | 595 const extensions::Extension* extension = |
| 642 service->GetExtensionById(ReinstalledExtensionId(), true); | 596 service->GetExtensionById(ReinstalledExtensionId(), true); |
| 643 if (!extension) | 597 if (!extension) |
| 644 error_message_ = IDS_HOTWORD_GENERIC_ERROR_MESSAGE; | 598 error_message_ = IDS_HOTWORD_GENERIC_ERROR_MESSAGE; |
| 645 | 599 |
| 646 RecordExtensionAvailabilityMetrics(service, extension); | 600 // TODO(amistry): Record availability of shared module in UMA. |
| 647 RecordLoggingMetrics(profile_); | 601 RecordLoggingMetrics(profile_); |
| 648 | 602 |
| 649 // Determine if NaCl is available. | 603 // Determine if NaCl is available. |
| 650 bool nacl_enabled = false; | 604 bool nacl_enabled = false; |
| 651 base::FilePath path; | 605 base::FilePath path; |
| 652 if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) { | 606 if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) { |
| 653 content::WebPluginInfo info; | 607 content::WebPluginInfo info; |
| 654 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile_).get(); | 608 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile_).get(); |
| 655 if (content::PluginService::GetInstance()->GetPluginInfoByPath(path, &info)) | 609 if (content::PluginService::GetInstance()->GetPluginInfoByPath(path, &info)) |
| 656 nacl_enabled = plugin_prefs->IsPluginEnabled(info); | 610 nacl_enabled = plugin_prefs->IsPluginEnabled(info); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 profile_->GetPrefs()->GetBoolean(prefs::kHotwordAlwaysOnSearchEnabled) && | 657 profile_->GetPrefs()->GetBoolean(prefs::kHotwordAlwaysOnSearchEnabled) && |
| 704 HotwordServiceFactory::IsAlwaysOnAvailable(); | 658 HotwordServiceFactory::IsAlwaysOnAvailable(); |
| 705 } | 659 } |
| 706 | 660 |
| 707 bool HotwordService::IsSometimesOnEnabled() { | 661 bool HotwordService::IsSometimesOnEnabled() { |
| 708 return profile_->GetPrefs()->HasPrefPath(prefs::kHotwordSearchEnabled) && | 662 return profile_->GetPrefs()->HasPrefPath(prefs::kHotwordSearchEnabled) && |
| 709 profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled) && | 663 profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled) && |
| 710 !HotwordServiceFactory::IsAlwaysOnAvailable(); | 664 !HotwordServiceFactory::IsAlwaysOnAvailable(); |
| 711 } | 665 } |
| 712 | 666 |
| 713 void HotwordService::EnableHotwordExtension( | |
| 714 ExtensionService* extension_service) { | |
| 715 if (extension_service && !IsExperimentalHotwordingEnabled()) | |
| 716 extension_service->EnableExtension(extension_misc::kHotwordExtensionId); | |
| 717 } | |
| 718 | |
| 719 void HotwordService::DisableHotwordExtension( | |
| 720 ExtensionService* extension_service) { | |
| 721 if (extension_service) { | |
| 722 extension_service->DisableExtension( | |
| 723 extension_misc::kHotwordExtensionId, | |
| 724 extensions::Extension::DISABLE_USER_ACTION); | |
| 725 } | |
| 726 } | |
| 727 | |
| 728 void HotwordService::SpeakerModelExistsComplete(bool exists) { | 667 void HotwordService::SpeakerModelExistsComplete(bool exists) { |
| 729 if (exists) { | 668 if (exists) { |
| 730 profile_->GetPrefs()-> | 669 profile_->GetPrefs()-> |
| 731 SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true); | 670 SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true); |
| 732 } else { | 671 } else { |
| 733 LaunchHotwordAudioVerificationApp(HotwordService::HOTWORD_ONLY); | 672 LaunchHotwordAudioVerificationApp(HotwordService::HOTWORD_ONLY); |
| 734 } | 673 } |
| 735 } | 674 } |
| 736 | 675 |
| 737 void HotwordService::OptIntoHotwording( | 676 void HotwordService::OptIntoHotwording( |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 void HotwordService::DisableHotwordPreferences() { | 774 void HotwordService::DisableHotwordPreferences() { |
| 836 if (IsSometimesOnEnabled()) { | 775 if (IsSometimesOnEnabled()) { |
| 837 profile_->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, false); | 776 profile_->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, false); |
| 838 } | 777 } |
| 839 if (IsAlwaysOnEnabled()) { | 778 if (IsAlwaysOnEnabled()) { |
| 840 profile_->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, | 779 profile_->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, |
| 841 false); | 780 false); |
| 842 } | 781 } |
| 843 } | 782 } |
| 844 | 783 |
| 845 void HotwordService::OnHotwordSearchEnabledChanged( | |
| 846 const std::string& pref_name) { | |
| 847 DCHECK_EQ(pref_name, std::string(prefs::kHotwordSearchEnabled)); | |
| 848 | |
| 849 ExtensionService* extension_service = GetExtensionService(profile_); | |
| 850 if (profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled)) | |
| 851 EnableHotwordExtension(extension_service); | |
| 852 else | |
| 853 DisableHotwordExtension(extension_service); | |
| 854 } | |
| 855 | |
| 856 void HotwordService::OnHotwordAlwaysOnSearchEnabledChanged( | 784 void HotwordService::OnHotwordAlwaysOnSearchEnabledChanged( |
| 857 const std::string& pref_name) { | 785 const std::string& pref_name) { |
| 858 // If the pref for always on has been changed in some way, that means that | 786 // If the pref for always on has been changed in some way, that means that |
| 859 // the user is aware of always on (either from settings or another source) | 787 // the user is aware of always on (either from settings or another source) |
| 860 // so they don't need to be shown the notification. | 788 // so they don't need to be shown the notification. |
| 861 profile_->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnNotificationSeen, | 789 profile_->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnNotificationSeen, |
| 862 true); | 790 true); |
| 863 pref_registrar_.Remove(prefs::kHotwordAlwaysOnSearchEnabled); | 791 pref_registrar_.Remove(prefs::kHotwordAlwaysOnSearchEnabled); |
| 864 } | 792 } |
| 865 | 793 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 std::string previous_locale = | 833 std::string previous_locale = |
| 906 profile_->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage); | 834 profile_->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage); |
| 907 std::string locale = GetCurrentLocale(profile_); | 835 std::string locale = GetCurrentLocale(profile_); |
| 908 | 836 |
| 909 // If it's a new locale, then the old extension should be uninstalled. | 837 // If it's a new locale, then the old extension should be uninstalled. |
| 910 return locale != previous_locale && | 838 return locale != previous_locale && |
| 911 HotwordService::DoesHotwordSupportLanguage(profile_); | 839 HotwordService::DoesHotwordSupportLanguage(profile_); |
| 912 } | 840 } |
| 913 | 841 |
| 914 void HotwordService::ActiveUserChanged() { | 842 void HotwordService::ActiveUserChanged() { |
| 915 // Do nothing for old hotwording. | |
| 916 if (!IsExperimentalHotwordingEnabled()) | |
| 917 return; | |
| 918 | |
| 919 // Don't bother notifying the extension if hotwording is completely off. | 843 // Don't bother notifying the extension if hotwording is completely off. |
| 920 if (!IsSometimesOnEnabled() && !IsAlwaysOnEnabled() && !IsTraining()) | 844 if (!IsSometimesOnEnabled() && !IsAlwaysOnEnabled() && !IsTraining()) |
| 921 return; | 845 return; |
| 922 | 846 |
| 923 HotwordPrivateEventService* event_service = | 847 HotwordPrivateEventService* event_service = |
| 924 BrowserContextKeyedAPIFactory<HotwordPrivateEventService>::Get(profile_); | 848 BrowserContextKeyedAPIFactory<HotwordPrivateEventService>::Get(profile_); |
| 925 // "enabled" isn't being changed, but piggy-back off the notification anyway. | 849 // "enabled" isn't being changed, but piggy-back off the notification anyway. |
| 926 if (event_service) | 850 if (event_service) |
| 927 event_service->OnEnabledChanged(prefs::kHotwordSearchEnabled); | 851 event_service->OnEnabledChanged(prefs::kHotwordSearchEnabled); |
| 928 } | 852 } |
| 929 | 853 |
| 930 bool HotwordService::UserIsActive() { | 854 bool HotwordService::UserIsActive() { |
| 931 #if defined(OS_CHROMEOS) | 855 #if defined(OS_CHROMEOS) |
| 932 // Only support multiple profiles and profile switching in ChromeOS. | 856 // Only support multiple profiles and profile switching in ChromeOS. |
| 933 if (user_manager::UserManager::IsInitialized()) { | 857 if (user_manager::UserManager::IsInitialized()) { |
| 934 user_manager::User* user = | 858 user_manager::User* user = |
| 935 user_manager::UserManager::Get()->GetActiveUser(); | 859 user_manager::UserManager::Get()->GetActiveUser(); |
| 936 if (user && user->is_profile_created()) | 860 if (user && user->is_profile_created()) |
| 937 return profile_ == ProfileManager::GetActiveUserProfile(); | 861 return profile_ == ProfileManager::GetActiveUserProfile(); |
| 938 } | 862 } |
| 939 #endif | 863 #endif |
| 940 return true; | 864 return true; |
| 941 } | 865 } |
| OLD | NEW |