1 // Copyright 2015 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_EXTENSIONS_API_LANGUAGE_SETTINGS_PRIVATE_LANGUAGE_SETTINGS_PRIVATE_DELEGATE_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_LANGUAGE_SETTINGS_PRIVATE_LANGUAGE_SETTINGS_PRIVATE_DELEGATE_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/macros.h"
12 #include "base/memory/weak_ptr.h"
13 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
14 #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h"
15 #include "chrome/common/extensions/api/language_settings_private.h"
16 #include "components/keyed_service/core/keyed_service.h"
17 #include "components/prefs/pref_change_registrar.h"
18 #include "content/public/browser/notification_observer.h"
19 #include "content/public/browser/notification_registrar.h"
20 #include "extensions/browser/event_router.h"
21 
22 #if defined(OS_CHROMEOS)
23 #include "ui/base/ime/chromeos/input_method_manager.h"
24 #endif
25 
26 namespace content {
27 class BrowserContext;
28 }
29 
30 namespace extensions {
31 
32 // Observes language settings and routes changes as events to listeners of the
33 // languageSettingsPrivate API.
34 class LanguageSettingsPrivateDelegate
35     : public KeyedService,
36       public EventRouter::Observer,
37       public content::NotificationObserver,
38 #if defined(OS_CHROMEOS)
39       public chromeos::input_method::InputMethodManager::Observer,
40 #endif  // defined(OS_CHROMEOS)
41       public SpellcheckHunspellDictionary::Observer,
42       public SpellcheckCustomDictionary::Observer {
43  public:
44   static LanguageSettingsPrivateDelegate* Create(
45       content::BrowserContext* browser_context);
46   ~LanguageSettingsPrivateDelegate() override;
47 
48   // Returns the languages and statuses of the enabled spellcheck dictionaries.
49   virtual std::vector<
50       api::language_settings_private::SpellcheckDictionaryStatus>
51   GetHunspellDictionaryStatuses();
52 
53   // Retry downloading the spellcheck dictionary.
54   virtual void RetryDownloadHunspellDictionary(const std::string& language);
55 
56   // content::NotificationObserver implementation.
57   void Observe(int type,
58                const content::NotificationSource& source,
59                const content::NotificationDetails& details) override;
60 
61  protected:
62   explicit LanguageSettingsPrivateDelegate(content::BrowserContext* context);
63 
64   // KeyedService implementation.
65   void Shutdown() override;
66 
67   // EventRouter::Observer implementation.
68   void OnListenerAdded(const EventListenerInfo& details) override;
69   void OnListenerRemoved(const EventListenerInfo& details) override;
70 
71 #if defined(OS_CHROMEOS)
72   // chromeos::input_method::InputMethodManager::Observer implementation.
73   void InputMethodChanged(chromeos::input_method::InputMethodManager* manager,
74                           Profile* profile,
75                           bool show_message) override;
76   void OnInputMethodExtensionAdded(const std::string& extension_id) override;
77   void OnInputMethodExtensionRemoved(const std::string& extension_id) override;
78 #endif  // defined(OS_CHROMEOS)
79 
80   // SpellcheckHunspellDictionary::Observer implementation.
81   void OnHunspellDictionaryInitialized(const std::string& language) override;
82   void OnHunspellDictionaryDownloadBegin(const std::string& language) override;
83   void OnHunspellDictionaryDownloadSuccess(
84       const std::string& language) override;
85   void OnHunspellDictionaryDownloadFailure(
86       const std::string& language) override;
87 
88   // SpellcheckCustomDictionary::Observer implementation.
89   void OnCustomDictionaryLoaded() override;
90   void OnCustomDictionaryChanged(
91       const SpellcheckCustomDictionary::Change& dictionary_change) override;
92 
93  private:
94   typedef std::vector<base::WeakPtr<SpellcheckHunspellDictionary>>
95       WeakDictionaries;
96 
97   // Updates the dictionaries that are used for spellchecking.
98   void RefreshDictionaries(bool was_listening, bool should_listen);
99 
100   // Returns the hunspell dictionaries that are used for spellchecking.
101   const WeakDictionaries& GetHunspellDictionaries();
102 
103   // If there are any JavaScript listeners registered for spellcheck events,
104   // ensures we are registered for change notifications. Otherwise, unregisters
105   // any observers.
106   void StartOrStopListeningForSpellcheckChanges();
107 
108 #if defined(OS_CHROMEOS)
109   // If there are any JavaScript listeners registered for input method events,
110   // ensures we are registered for change notifications. Otherwise, unregisters
111   // any observers.
112   void StartOrStopListeningForInputMethodChanges();
113 #endif  // defined(OS_CHROMEOS)
114 
115   // Handles the preference for which languages should be used for spellcheck
116   // by resetting the dictionaries and broadcasting an event.
117   void OnSpellcheckDictionariesChanged();
118 
119   // Broadcasts an event with the list of spellcheck dictionary statuses.
120   void BroadcastDictionariesChangedEvent();
121 
122   // Removes observers from hunspell_dictionaries_.
123   void RemoveDictionaryObservers();
124 
125   // The hunspell dictionaries that are used for spellchecking.
126   // TODO(aee): Consider replacing with
127   // |SpellcheckService::GetHunspellDictionaries()|.
128   WeakDictionaries hunspell_dictionaries_;
129 
130   // The custom dictionary that is used for spellchecking.
131   SpellcheckCustomDictionary* custom_dictionary_;
132 
133   content::BrowserContext* context_;
134 
135   // True if there are observers listening for spellcheck events.
136   bool listening_spellcheck_;
137   // True if there are observers listening for input method events.
138   bool listening_input_method_;
139 
140   // True if the profile has finished initializing.
141   bool profile_added_;
142 
143   content::NotificationRegistrar notification_registrar_;
144 
145   PrefChangeRegistrar pref_change_registrar_;
146 
147   DISALLOW_COPY_AND_ASSIGN(LanguageSettingsPrivateDelegate);
148 };
149 
150 }  // namespace extensions
151 
152 #endif  // CHROME_BROWSER_EXTENSIONS_API_LANGUAGE_SETTINGS_PRIVATE_LANGUAGE_SETTINGS_PRIVATE_DELEGATE_H_
153