12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_SERVICE_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_SERVICE_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/gtest_prod_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_change_registrar.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/spellchecker/feedback_sender.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/spellcheck_common.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_observer.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_registrar.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Profile;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SpellCheckHostMetrics;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WaitableEvent;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderProcessHost;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Encapsulates the browser side spellcheck service. There is one of these per
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// profile and each is created by the SpellCheckServiceFactory.  The
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// SpellcheckService maintains any per-profile information about spellcheck.
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class SpellcheckService : public BrowserContextKeyedService,
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          public content::NotificationObserver,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          public SpellcheckCustomDictionary::Observer,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          public SpellcheckHunspellDictionary::Observer {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Event types used for reporting the status of this class and its derived
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // classes to browser tests.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum EventType {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BDICT_NOTINITIALIZED,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BDICT_CORRUPTED,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Dictionary format used for loading an external dictionary.
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum DictionaryFormat {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DICT_HUNSPELL,
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DICT_TEXT,
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DICT_UNKNOWN,
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit SpellcheckService(Profile* profile);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SpellcheckService();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This function computes a vector of strings which are to be displayed in
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the context menu over a text area for changing spell check languages. It
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // returns the index of the current spell check language in the vector.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(port): this should take a vector of string16, but the implementation
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // has some dependencies in l10n util that need porting first.
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static int GetSpellCheckLanguages(Profile* profile,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    std::vector<std::string>* languages);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Computes a vector of strings which are to be displayed in the context
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // menu from |accept_languages| and |dictionary_language|.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void GetSpellCheckLanguagesFromAcceptLanguages(
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<std::string>& accept_languages,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& dictionary_language,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::vector<std::string>* languages);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Signals the event attached by AttachTestEvent() to report the specified
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // event to browser tests. This function is called by this class and its
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // derived classes to report their status. This function does not do anything
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // when we do not set an event to |status_event_|.
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool SignalStatusEvent(EventType type);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Instantiates SpellCheckHostMetrics object and makes it ready for recording
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // metrics. This should be called only if the metrics recording is active.
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartRecordingMetrics(bool spellcheck_enabled);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pass the renderer some basic initialization information. Note that the
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // renderer will not load Hunspell until it needs to.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitForRenderer(content::RenderProcessHost* process);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns a metrics counter associated with this object,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or null when metrics recording is disabled.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpellCheckHostMetrics* GetMetrics() const;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the instance of the custom dictionary.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpellcheckCustomDictionary* GetCustomDictionary();
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the instance of the Hunspell dictionary.
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpellcheckHunspellDictionary* GetHunspellDictionary();
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns the instance of the spelling service feedback sender.
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  spellcheck::FeedbackSender* GetFeedbackSender();
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Load a dictionary from a given path. Format specifies how the dictionary
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is stored. Return value is true if successful.
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool LoadExternalDictionary(std::string language,
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              std::string locale,
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              std::string path,
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              DictionaryFormat format);
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Unload a dictionary. The path is given to identify the dictionary.
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Return value is true if successful.
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool UnloadExternalDictionary(std::string path);
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NotificationProfile implementation.
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Observe(int type,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const content::NotificationSource& source,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SpellcheckCustomDictionary::Observer implementation.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnCustomDictionaryLoaded() OVERRIDE;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnCustomDictionaryChanged(
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const SpellcheckCustomDictionary::Change& dictionary_change) OVERRIDE;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SpellcheckHunspellDictionary::Observer implementation.
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnHunspellDictionaryInitialized() OVERRIDE;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnHunspellDictionaryDownloadBegin() OVERRIDE;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnHunspellDictionaryDownloadSuccess() OVERRIDE;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnHunspellDictionaryDownloadFailure() OVERRIDE;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(SpellcheckServiceBrowserTest, DeleteCorruptedBDICT);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Attaches an event so browser tests can listen the status events.
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void AttachStatusEvent(base::WaitableEvent* status_event);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the status event type.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static EventType GetStatusEvent();
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pass all renderers some basic initialization information.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitForAllRenderers();
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Reacts to a change in user preferences on whether auto-spell-correct should
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // be enabled.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnEnableAutoSpellCorrectChanged();
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Reacts to a change in user preference on which language should be used for
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // spellchecking.
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnSpellCheckDictionaryChanged();
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification handler for changes to prefs::kSpellCheckUseSpellingService.
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnUseSpellingServiceChanged();
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefChangeRegistrar pref_change_registrar_;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::NotificationRegistrar registrar_;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A pointer to the profile which this service refers to.
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile_;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpellCheckHostMetrics> metrics_;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpellcheckCustomDictionary> custom_dictionary_;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpellcheckHunspellDictionary> hunspell_dictionary_;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<spellcheck::FeedbackSender> feedback_sender_;
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtrFactory<SpellcheckService> weak_ptr_factory_;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SpellcheckService);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_SERVICE_H_
169