1 // Copyright 2014 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.
5 #include "chrome/browser/speech/extension_api/tts_engine_extension_observer.h"
7 #include "base/logging.h"
8 #include "base/memory/singleton.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/profiles/incognito_helpers.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h"
13 #include "chrome/browser/speech/tts_controller.h"
14 #include "components/keyed_service/content/browser_context_dependency_manager.h"
15 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
16 #include "components/keyed_service/core/keyed_service.h"
17 #include "extensions/browser/event_router.h"
18 #include "extensions/browser/event_router_factory.h"
20 // Factory to load one instance of TtsExtensionLoaderChromeOs per profile.
21 class TtsEngineExtensionObserverFactory
22 : public BrowserContextKeyedServiceFactory
{
24 static TtsEngineExtensionObserver
* GetForProfile(Profile
* profile
) {
25 return static_cast<TtsEngineExtensionObserver
*>(
26 GetInstance()->GetServiceForBrowserContext(profile
, true));
29 static TtsEngineExtensionObserverFactory
* GetInstance() {
30 return base::Singleton
<TtsEngineExtensionObserverFactory
>::get();
34 friend struct base::DefaultSingletonTraits
<TtsEngineExtensionObserverFactory
>;
36 TtsEngineExtensionObserverFactory()
37 : BrowserContextKeyedServiceFactory(
38 "TtsEngineExtensionObserver",
39 BrowserContextDependencyManager::GetInstance()) {
40 DependsOn(extensions::EventRouterFactory::GetInstance());
43 ~TtsEngineExtensionObserverFactory() override
{}
45 content::BrowserContext
* GetBrowserContextToUse(
46 content::BrowserContext
* context
) const override
{
47 // If given an incognito profile (including the Chrome OS login
48 // profile), share the service with the original profile.
49 return chrome::GetBrowserContextRedirectedInIncognito(context
);
52 KeyedService
* BuildServiceInstanceFor(
53 content::BrowserContext
* profile
) const override
{
54 return new TtsEngineExtensionObserver(static_cast<Profile
*>(profile
));
58 TtsEngineExtensionObserver
* TtsEngineExtensionObserver::GetInstance(
60 return TtsEngineExtensionObserverFactory::GetInstance()->GetForProfile(
64 TtsEngineExtensionObserver::TtsEngineExtensionObserver(Profile
* profile
)
65 : extension_registry_observer_(this), profile_(profile
) {
66 extension_registry_observer_
.Add(
67 extensions::ExtensionRegistry::Get(profile_
));
69 extensions::EventRouter
* event_router
=
70 extensions::EventRouter::Get(profile_
);
72 event_router
->RegisterObserver(this, tts_engine_events::kOnSpeak
);
73 event_router
->RegisterObserver(this, tts_engine_events::kOnStop
);
76 TtsEngineExtensionObserver::~TtsEngineExtensionObserver() {
79 bool TtsEngineExtensionObserver::SawExtensionLoad(
80 const std::string
& extension_id
,
82 bool previously_loaded
=
83 engine_extension_ids_
.find(extension_id
) != engine_extension_ids_
.end();
86 engine_extension_ids_
.insert(extension_id
);
88 return previously_loaded
;
91 void TtsEngineExtensionObserver::Shutdown() {
92 extensions::EventRouter::Get(profile_
)->UnregisterObserver(this);
95 bool TtsEngineExtensionObserver::IsLoadedTtsEngine(
96 const std::string
& extension_id
) {
97 extensions::EventRouter
* event_router
=
98 extensions::EventRouter::Get(profile_
);
100 if (event_router
->ExtensionHasEventListener(extension_id
,
101 tts_engine_events::kOnSpeak
) &&
102 event_router
->ExtensionHasEventListener(extension_id
,
103 tts_engine_events::kOnStop
)) {
110 void TtsEngineExtensionObserver::OnListenerAdded(
111 const extensions::EventListenerInfo
& details
) {
112 if (!IsLoadedTtsEngine(details
.extension_id
))
115 TtsController::GetInstance()->VoicesChanged();
116 engine_extension_ids_
.insert(details
.extension_id
);
119 void TtsEngineExtensionObserver::OnExtensionUnloaded(
120 content::BrowserContext
* browser_context
,
121 const extensions::Extension
* extension
,
122 extensions::UnloadedExtensionInfo::Reason reason
) {
123 if (engine_extension_ids_
.find(extension
->id()) !=
124 engine_extension_ids_
.end()) {
125 engine_extension_ids_
.erase(extension
->id());
126 TtsController::GetInstance()->VoicesChanged();