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
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_SEARCH_HOTWORD_SERVICE_H_
6 #define CHROME_BROWSER_SEARCH_HOTWORD_SERVICE_H_
10 #include "base/basictypes.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/prefs/pref_change_registrar.h"
13 #include "base/scoped_observer.h"
14 #include "chrome/browser/extensions/webstore_startup_installer.h"
15 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
16 #include "chrome/common/extensions/webstore_install_result.h"
17 #include "components/keyed_service/core/keyed_service.h"
18 #include "content/public/browser/notification_observer.h"
19 #include "content/public/browser/notification_registrar.h"
20 #include "extensions/browser/extension_registry.h"
21 #include "extensions/browser/extension_registry_observer.h"
23 class ExtensionService
;
24 class HotwordAudioHistoryHandler
;
28 namespace extensions
{
30 } // namespace extensions
32 namespace hotword_internal
{
33 // String passed to indicate the training state has changed.
34 extern const char kHotwordTrainingEnabled
[];
35 } // namespace hotword_internal
37 // Provides an interface for the Hotword component that does voice triggered
39 class HotwordService
: public MediaCaptureDevicesDispatcher::Observer
,
40 public extensions::ExtensionRegistryObserver
,
43 // A simple subclass to allow for aborting an install during shutdown.
44 // HotwordWebstoreInstaller class is public for testing.
45 class HotwordWebstoreInstaller
: public extensions::WebstoreStartupInstaller
{
47 HotwordWebstoreInstaller(const std::string
& webstore_item_id
,
49 const Callback
& callback
)
50 : extensions::WebstoreStartupInstaller(webstore_item_id
,
56 ~HotwordWebstoreInstaller() override
{}
59 // Returns true if the hotword supports the current system language.
60 static bool DoesHotwordSupportLanguage(Profile
* profile
);
62 // Returns true if hotwording hardware is available.
63 static bool IsHotwordHardwareAvailable();
65 explicit HotwordService(Profile
* profile
);
66 ~HotwordService() override
;
68 // Overridden from ExtensionRegisterObserver:
69 void OnExtensionInstalled(content::BrowserContext
* browser_context
,
70 const extensions::Extension
* extension
,
71 bool is_update
) override
;
72 void OnExtensionUninstalled(content::BrowserContext
* browser_context
,
73 const extensions::Extension
* extension
,
74 extensions::UninstallReason reason
) override
;
76 // Overriden from KeyedService
77 void Shutdown() override
;
79 // Checks for whether all the necessary files have downloaded to allow for
80 // using the extension.
81 virtual bool IsServiceAvailable();
83 // Determine if hotwording is allowed in this profile based on field trials
85 virtual bool IsHotwordAllowed();
87 // Checks if the user has opted into audio logging. Returns true if the user
88 // is opted in, false otherwise..
89 bool IsOptedIntoAudioLogging();
91 // Returns whether always-on hotwording is enabled.
92 bool IsAlwaysOnEnabled();
94 // Returns whether google.com/NTP/launcher hotwording is enabled.
95 bool IsSometimesOnEnabled();
97 // Handles enabling/disabling the hotword notification when the user
98 // changes the always on search settings.
99 void OnHotwordAlwaysOnSearchEnabledChanged(const std::string
& pref_name
);
101 // Called to handle the hotword session from |client|.
102 void RequestHotwordSession(HotwordClient
* client
);
103 void StopHotwordSession(HotwordClient
* client
);
104 HotwordClient
* client() { return client_
; }
106 // Checks if the current version of the hotword extension should be
107 // uninstalled in order to update to a different language version.
108 // Returns true if the extension was uninstalled.
109 bool MaybeReinstallHotwordExtension();
111 // Checks based on locale if the current version should be uninstalled so that
112 // a version with a different language can be installed.
113 bool ShouldReinstallHotwordExtension();
115 // Helper functions pulled out for testing purposes.
116 // UninstallHotwordExtension returns true if the extension was uninstalled.
117 virtual bool UninstallHotwordExtension(ExtensionService
* extension_service
);
118 virtual void InstallHotwordExtensionFromWebstore(int num_tries
);
120 // Sets the pref value of the previous language.
121 void SetPreviousLanguagePref();
123 // Returns the current error message id. A value of 0 indicates
125 int error_message() { return error_message_
; }
127 bool microphone_available() { return microphone_available_
; }
129 // These methods are for launching, and getting and setting the launch mode of
130 // the Hotword Audio Verification App.
132 // OptIntoHotwording first determines if the app needs to be launched, and if
133 // so, launches the app (if Audio History is on and a speaker model exists,
134 // then we don't need to launch the app).
136 // LaunchHotwordAudioVerificationApp launches the app without the above
137 // check in the specified |launch_mode|.
140 HOTWORD_AND_AUDIO_HISTORY
,
143 void OptIntoHotwording(const LaunchMode
& launch_mode
);
144 void LaunchHotwordAudioVerificationApp(const LaunchMode
& launch_mode
);
145 virtual LaunchMode
GetHotwordAudioVerificationLaunchMode();
147 // Called when the SpeakerModelExists request is complete. Either
148 // sets the always-on hotword pref to true, or launches the Hotword
149 // Audio Verification App, depending on the value of |exists|.
150 void SpeakerModelExistsComplete(bool exists
);
152 // These methods control the speaker training communication between
153 // the Hotword Audio Verification App and the Hotword Extension that
154 // contains the NaCl module.
155 void StartTraining();
156 void FinalizeSpeakerModel();
158 void NotifyHotwordTriggered();
160 // Returns true if speaker training is currently in progress.
163 // Indicate that the currently active user has changed.
164 void ActiveUserChanged();
166 // Return true if this profile corresponds to the currently active user.
169 // Returns a pointer to the audio history handler.
170 HotwordAudioHistoryHandler
* GetAudioHistoryHandler();
172 // Sets the audio history handler. Used for tests.
173 void SetAudioHistoryHandler(HotwordAudioHistoryHandler
* handler
);
175 // Turn off the currently enabled version of hotwording if one exists.
176 void DisableHotwordPreferences();
178 // Overridden from MediaCaptureDevicesDispatcher::Observer
179 void OnUpdateAudioDevices(
180 const content::MediaStreamDevices
& devices
) override
;
183 // Used in test subclasses.
184 scoped_refptr
<HotwordWebstoreInstaller
> installer_
;
187 class HotwordUserSessionStateObserver
;
189 // Must be called from the UI thread since the instance of
190 // MediaCaptureDevicesDispatcher can only be accessed on the UI thread.
191 void InitializeMicrophoneObserver();
193 // Callback for webstore extension installer.
194 void InstalledFromWebstoreCallback(
197 const std::string
& error
,
198 extensions::webstore_install::Result result
);
200 // Returns the ID of the extension that may need to be reinstalled.
201 std::string
ReinstalledExtensionId();
203 // Creates a notification for always-on hotwording.
204 void ShowHotwordNotification();
208 PrefChangeRegistrar pref_registrar_
;
210 content::NotificationRegistrar registrar_
;
212 // For observing the ExtensionRegistry.
213 ScopedObserver
<extensions::ExtensionRegistry
,
214 extensions::ExtensionRegistryObserver
>
215 extension_registry_observer_
;
217 scoped_ptr
<HotwordAudioHistoryHandler
> audio_history_handler_
;
219 bool microphone_available_
;
221 // Indicates if the check for audio devices has been run such that it can be
222 // included in the error checking. Audio checking is not done immediately
223 // upon start up because of the negative impact on performance.
224 bool audio_device_state_updated_
;
226 HotwordClient
* client_
;
228 bool reinstall_pending_
;
229 // Whether we are currently in the process of training the speaker model.
231 scoped_ptr
<HotwordUserSessionStateObserver
> session_observer_
;
233 // Stores the launch mode for the Hotword Audio Verification App.
234 LaunchMode hotword_audio_verification_launch_mode_
;
236 // The WeakPtrFactory should be the last member, so the weak pointer
237 // gets invalidated before the destructors for other members run,
238 // to avoid callbacks into a half-destroyed object.
239 base::WeakPtrFactory
<HotwordService
> weak_factory_
;
241 DISALLOW_COPY_AND_ASSIGN(HotwordService
);
244 #endif // CHROME_BROWSER_SEARCH_HOTWORD_SERVICE_H_