Home | History | Annotate | Download | only in speech
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/speech/tts_extension_loader_chromeos.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/memory/singleton.h"
      9 #include "chrome/browser/extensions/component_loader.h"
     10 #include "chrome/browser/extensions/event_router.h"
     11 #include "chrome/browser/extensions/extension_service.h"
     12 #include "chrome/browser/extensions/extension_system.h"
     13 #include "chrome/browser/profiles/incognito_helpers.h"
     14 #include "chrome/browser/profiles/profile.h"
     15 #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h"
     16 #include "chrome/browser/speech/tts_controller.h"
     17 #include "chrome/common/extensions/extension_constants.h"
     18 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
     19 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
     20 #include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
     21 #include "grit/browser_resources.h"
     22 
     23 // Factory to load one instance of TtsExtensionLoaderChromeOs per profile.
     24 class TtsExtensionLoaderChromeOsFactory
     25     : public BrowserContextKeyedServiceFactory {
     26  public:
     27   static TtsExtensionLoaderChromeOs* GetForProfile(Profile* profile) {
     28     return static_cast<TtsExtensionLoaderChromeOs*>(
     29         GetInstance()->GetServiceForBrowserContext(profile, true));
     30   }
     31 
     32   static TtsExtensionLoaderChromeOsFactory* GetInstance() {
     33     return Singleton<TtsExtensionLoaderChromeOsFactory>::get();
     34   }
     35 
     36  private:
     37   friend struct DefaultSingletonTraits<TtsExtensionLoaderChromeOsFactory>;
     38 
     39   TtsExtensionLoaderChromeOsFactory() : BrowserContextKeyedServiceFactory(
     40       "TtsExtensionLoaderChromeOs",
     41       BrowserContextDependencyManager::GetInstance())
     42   {}
     43 
     44   virtual ~TtsExtensionLoaderChromeOsFactory() {}
     45 
     46   virtual content::BrowserContext* GetBrowserContextToUse(
     47       content::BrowserContext* context) const OVERRIDE{
     48     // If given an incognito profile (including the Chrome OS login
     49     // profile), share the service with the original profile.
     50     return chrome::GetBrowserContextRedirectedInIncognito(context);
     51   }
     52 
     53   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
     54       content::BrowserContext* profile) const OVERRIDE {
     55     return new TtsExtensionLoaderChromeOs(static_cast<Profile*>(profile));
     56   }
     57 };
     58 
     59 TtsExtensionLoaderChromeOs*
     60 TtsExtensionLoaderChromeOs::GetInstance(Profile* profile) {
     61   return TtsExtensionLoaderChromeOsFactory::GetInstance()
     62       ->GetForProfile(profile);
     63 }
     64 
     65 TtsExtensionLoaderChromeOs::TtsExtensionLoaderChromeOs(
     66     Profile* profile)
     67     : profile_(profile) {
     68   tts_state_ = IsTtsLoadedInThisProfile() ? TTS_LOADED : TTS_NOT_LOADED;
     69 
     70   extensions::ExtensionSystem* system =
     71       extensions::ExtensionSystem::Get(profile_);
     72   DCHECK(system);
     73   extensions::EventRouter* event_router = system->event_router();
     74   DCHECK(event_router);
     75   event_router->RegisterObserver(this, tts_engine_events::kOnSpeak);
     76   event_router->RegisterObserver(this, tts_engine_events::kOnStop);
     77 }
     78 
     79 bool TtsExtensionLoaderChromeOs::LoadTtsExtension() {
     80   if (tts_state_ == TTS_LOADED || tts_state_ == TTS_LOADING)
     81     return false;
     82 
     83   // Load the component extension into this profile.
     84   LOG(INFO) << "Loading TTS component extension.";
     85   tts_state_ = TTS_LOADING;
     86   ExtensionService* extension_service = profile_->GetExtensionService();
     87   DCHECK(extension_service);
     88   base::FilePath path =
     89       base::FilePath(extension_misc::kSpeechSynthesisExtensionPath);
     90   extension_service->component_loader()->Add(IDR_SPEECH_SYNTHESIS_MANIFEST,
     91                                              path);
     92   return true;
     93 }
     94 
     95 bool TtsExtensionLoaderChromeOs::IsTtsLoadedInThisProfile() {
     96   extensions::ExtensionSystem* system =
     97       extensions::ExtensionSystem::Get(profile_);
     98   DCHECK(system);
     99   extensions::EventRouter* event_router = system->event_router();
    100   DCHECK(event_router);
    101   if (event_router->ExtensionHasEventListener(
    102           extension_misc::kSpeechSynthesisExtensionId,
    103           tts_engine_events::kOnSpeak) &&
    104       event_router->ExtensionHasEventListener(
    105           extension_misc::kSpeechSynthesisExtensionId,
    106           tts_engine_events::kOnStop)) {
    107     return true;
    108   }
    109 
    110   return false;
    111 }
    112 
    113 void TtsExtensionLoaderChromeOs::OnListenerAdded(
    114     const extensions::EventListenerInfo& details) {
    115   if (details.extension_id != extension_misc::kSpeechSynthesisExtensionId)
    116     return;
    117 
    118   if (!IsTtsLoadedInThisProfile())
    119     return;
    120 
    121   if (tts_state_ == TTS_LOADING) {
    122     LOG(INFO) << "TTS component extension loaded, retrying queued utterances.";
    123     tts_state_ = TTS_LOADED;
    124     TtsController::GetInstance()->RetrySpeakingQueuedUtterances();
    125   }
    126 }
    127