summaryrefslogtreecommitdiffstats
path: root/chrome/browser/speech/tts_extension_loader_chromeos.cc
blob: 39c53cd57ab7b9a076fba2cb03e2d1c44135feb5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/speech/tts_extension_loader_chromeos.h"

#include "base/logging.h"
#include "base/memory/singleton.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/event_router.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/speech/extension_api/tts_engine_extension_api.h"
#include "chrome/browser/speech/tts_controller.h"
#include "chrome/common/extensions/extension_constants.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
#include "grit/browser_resources.h"

// Factory to load one instance of TtsExtensionLoaderChromeOs per profile.
class TtsExtensionLoaderChromeOsFactory
    : public BrowserContextKeyedServiceFactory {
 public:
  static TtsExtensionLoaderChromeOs* GetForProfile(Profile* profile) {
    return static_cast<TtsExtensionLoaderChromeOs*>(
        GetInstance()->GetServiceForBrowserContext(profile, true));
  }

  static TtsExtensionLoaderChromeOsFactory* GetInstance() {
    return Singleton<TtsExtensionLoaderChromeOsFactory>::get();
  }

 private:
  friend struct DefaultSingletonTraits<TtsExtensionLoaderChromeOsFactory>;

  TtsExtensionLoaderChromeOsFactory() : BrowserContextKeyedServiceFactory(
      "TtsExtensionLoaderChromeOs",
      BrowserContextDependencyManager::GetInstance())
  {}

  virtual ~TtsExtensionLoaderChromeOsFactory() {}

  virtual content::BrowserContext* GetBrowserContextToUse(
      content::BrowserContext* context) const OVERRIDE{
    // If given an incognito profile (including the Chrome OS login
    // profile), share the service with the original profile.
    return chrome::GetBrowserContextRedirectedInIncognito(context);
  }

  virtual BrowserContextKeyedService* BuildServiceInstanceFor(
      content::BrowserContext* profile) const OVERRIDE {
    return new TtsExtensionLoaderChromeOs(static_cast<Profile*>(profile));
  }
};

TtsExtensionLoaderChromeOs*
TtsExtensionLoaderChromeOs::GetInstance(Profile* profile) {
  return TtsExtensionLoaderChromeOsFactory::GetInstance()
      ->GetForProfile(profile);
}

TtsExtensionLoaderChromeOs::TtsExtensionLoaderChromeOs(
    Profile* profile)
    : profile_(profile) {
  tts_state_ = IsTtsLoadedInThisProfile() ? TTS_LOADED : TTS_NOT_LOADED;

  extensions::ExtensionSystem* system =
      extensions::ExtensionSystem::Get(profile_);
  DCHECK(system);
  extensions::EventRouter* event_router = system->event_router();
  DCHECK(event_router);
  event_router->RegisterObserver(this, tts_engine_events::kOnSpeak);
  event_router->RegisterObserver(this, tts_engine_events::kOnStop);
}

bool TtsExtensionLoaderChromeOs::LoadTtsExtension() {
  if (tts_state_ == TTS_LOADED || tts_state_ == TTS_LOADING)
    return false;

  // Load the component extension into this profile.
  LOG(INFO) << "Loading TTS component extension.";
  tts_state_ = TTS_LOADING;
  ExtensionService* extension_service = profile_->GetExtensionService();
  DCHECK(extension_service);
  base::FilePath path =
      base::FilePath(extension_misc::kSpeechSynthesisExtensionPath);
  extension_service->component_loader()->Add(IDR_SPEECH_SYNTHESIS_MANIFEST,
                                             path);
  return true;
}

bool TtsExtensionLoaderChromeOs::IsTtsLoadedInThisProfile() {
  extensions::ExtensionSystem* system =
      extensions::ExtensionSystem::Get(profile_);
  DCHECK(system);
  extensions::EventRouter* event_router = system->event_router();
  DCHECK(event_router);
  if (event_router->ExtensionHasEventListener(
          extension_misc::kSpeechSynthesisExtensionId,
          tts_engine_events::kOnSpeak) &&
      event_router->ExtensionHasEventListener(
          extension_misc::kSpeechSynthesisExtensionId,
          tts_engine_events::kOnStop)) {
    return true;
  }

  return false;
}

void TtsExtensionLoaderChromeOs::OnListenerAdded(
    const extensions::EventListenerInfo& details) {
  if (details.extension_id != extension_misc::kSpeechSynthesisExtensionId)
    return;

  if (!IsTtsLoadedInThisProfile())
    return;

  if (tts_state_ == TTS_LOADING) {
    LOG(INFO) << "TTS component extension loaded, retrying queued utterances.";
    tts_state_ = TTS_LOADED;
    TtsController::GetInstance()->RetrySpeakingQueuedUtterances();
  }
}