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.
4
5#ifndef CHROME_BROWSER_SEARCH_HOTWORD_SERVICE_H_
6#define CHROME_BROWSER_SEARCH_HOTWORD_SERVICE_H_
7
8#include "base/basictypes.h"
9#include "base/memory/weak_ptr.h"
10#include "base/prefs/pref_change_registrar.h"
11#include "base/scoped_observer.h"
12#include "components/keyed_service/core/keyed_service.h"
13#include "content/public/browser/notification_observer.h"
14#include "content/public/browser/notification_registrar.h"
15#include "extensions/browser/extension_registry.h"
16#include "extensions/browser/extension_registry_observer.h"
17
18class ExtensionService;
19class HotwordClient;
20class Profile;
21
22namespace extensions {
23class Extension;
24class WebstoreStandaloneInstaller;
25}  // namespace extensions
26
27namespace hotword_internal {
28// Constants for the hotword field trial.
29extern const char kHotwordFieldTrialName[];
30extern const char kHotwordFieldTrialDisabledGroupName[];
31}  // namespace hotword_internal
32
33// Provides an interface for the Hotword component that does voice triggered
34// search.
35class HotwordService : public content::NotificationObserver,
36                       public extensions::ExtensionRegistryObserver,
37                       public KeyedService {
38 public:
39  // Returns true if the hotword supports the current system language.
40  static bool DoesHotwordSupportLanguage(Profile* profile);
41
42  // Returns true if the "enable-experimental-hotwording" flag is set.
43  static bool IsExperimentalHotwordingEnabled();
44
45  explicit HotwordService(Profile* profile);
46  virtual ~HotwordService();
47
48  // Overridden from content::NotificationObserver:
49  virtual void Observe(int type,
50                       const content::NotificationSource& source,
51                       const content::NotificationDetails& details) OVERRIDE;
52
53  // Overridden from ExtensionRegisterObserver:
54  virtual void OnExtensionInstalled(
55      content::BrowserContext* browser_context,
56      const extensions::Extension* extension,
57      bool is_update) OVERRIDE;
58  virtual void OnExtensionUninstalled(
59      content::BrowserContext* browser_context,
60      const extensions::Extension* extension,
61      extensions::UninstallReason reason) OVERRIDE;
62
63  // Checks for whether all the necessary files have downloaded to allow for
64  // using the extension.
65  virtual bool IsServiceAvailable();
66
67  // Determine if hotwording is allowed in this profile based on field trials
68  // and language.
69  virtual bool IsHotwordAllowed();
70
71  // Checks if the user has opted into audio logging. Returns true if the user
72  // is opted in, false otherwise..
73  bool IsOptedIntoAudioLogging();
74
75  // Control the state of the hotword extension.
76  void EnableHotwordExtension(ExtensionService* extension_service);
77  void DisableHotwordExtension(ExtensionService* extension_service);
78
79  // Handles enabling/disabling the hotword extension when the user
80  // turns it off via the settings menu.
81  void OnHotwordSearchEnabledChanged(const std::string& pref_name);
82
83  // Called to handle the hotword session from |client|.
84  void RequestHotwordSession(HotwordClient* client);
85  void StopHotwordSession(HotwordClient* client);
86  HotwordClient* client() { return client_; }
87
88  // Checks if the current version of the hotword extension should be
89  // uninstalled in order to update to a different language version.
90  // Returns true if the extension was uninstalled.
91  bool MaybeReinstallHotwordExtension();
92
93  // Checks based on locale if the current version should be uninstalled so that
94  // a version with a different language can be installed.
95  bool ShouldReinstallHotwordExtension();
96
97  // Helper functions pulled out for testing purposes.
98  // UninstallHotwordExtension returns true if the extension was uninstalled.
99  virtual bool UninstallHotwordExtension(ExtensionService* extension_service);
100  virtual void InstallHotwordExtensionFromWebstore();
101
102  // Sets the pref value of the previous language.
103  void SetPreviousLanguagePref();
104
105  // Returns the current error message id. A value of 0 indicates
106  // no error.
107  int error_message() { return error_message_; }
108
109  // These methods are for launching, and getting and setting the launch mode of
110  // the Hotword Audio Verification App.
111  //
112  // TODO(kcarattini): Remove this when
113  // https://code.google.com/p/chromium/issues/detail?id=165573 is fixed,
114  // at which time we can simply launch the app in the given mode instead of
115  // having to check for it here.
116  enum LaunchMode {
117    AUDIO_HISTORY_ONLY,
118    HOTWORD_ONLY,
119    HOTWORD_AND_AUDIO_HISTORY,
120    SPEECH_TRAINING
121  };
122  void LaunchHotwordAudioVerificationApp(const LaunchMode& launch_mode);
123  virtual LaunchMode GetHotwordAudioVerificationLaunchMode();
124
125 private:
126  Profile* profile_;
127
128  PrefChangeRegistrar pref_registrar_;
129
130  content::NotificationRegistrar registrar_;
131
132  // For observing the ExtensionRegistry.
133  ScopedObserver<extensions::ExtensionRegistry,
134                 extensions::ExtensionRegistryObserver>
135      extension_registry_observer_;
136
137  scoped_refptr<extensions::WebstoreStandaloneInstaller> installer_;
138
139  HotwordClient* client_;
140  int error_message_;
141  bool reinstall_pending_;
142
143  base::WeakPtrFactory<HotwordService> weak_factory_;
144
145  // Stores the launch mode for the Hotword Audio Verification App.
146  LaunchMode hotword_audio_verification_launch_mode_;
147
148  DISALLOW_COPY_AND_ASSIGN(HotwordService);
149};
150
151#endif  // CHROME_BROWSER_SEARCH_HOTWORD_SERVICE_H_
152