1// Copyright (c) 2011 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_SPELLCHECK_HOST_IMPL_H_
6#define CHROME_BROWSER_SPELLCHECK_HOST_IMPL_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/file_path.h"
13#include "base/memory/scoped_ptr.h"
14#include "chrome/browser/spellcheck_host.h"
15#include "chrome/browser/spellcheck_host_observer.h"
16#include "chrome/common/net/url_fetcher.h"
17
18// This class implements the SpellCheckHost interface to provide the
19// functionalities listed below:
20// * Adding a word to the custom dictionary;
21// * Storing the custom dictionary to the file, and read it back
22//   from the file during the initialization.
23// * Downloading a dictionary and map it for the renderer, and;
24// * Calling the platform spellchecker attached to the browser;
25//
26// To download a dictionary and initialize it without blocking the UI thread,
27// this class also implements the URLFetcher::Delegate() interface. This
28// initialization status is notified to the UI thread through the
29// SpellCheckHostObserver interface.
30//
31// We expect a profile creates an instance of this class through a factory
32// method, SpellCheckHost::Create() and uses only the SpellCheckHost interface
33// provided by this class.
34//   spell_check_host_ = SpellCheckHost::Create(...)
35//
36// Available languages for the checker, which we need to specify via Create(),
37// can be listed using SpellCheckHost::GetAvailableLanguages() static method.
38class SpellCheckHostImpl : public SpellCheckHost,
39                           public URLFetcher::Delegate {
40 public:
41  SpellCheckHostImpl(SpellCheckHostObserver* observer,
42                     const std::string& language,
43                     net::URLRequestContextGetter* request_context_getter);
44
45  void Initialize();
46
47  // SpellCheckHost implementation
48
49  virtual void UnsetObserver();
50
51  virtual void AddWord(const std::string& word);
52
53  virtual const base::PlatformFile& GetDictionaryFile() const;
54
55  virtual const std::vector<std::string>& GetCustomWords() const;
56
57  virtual const std::string& GetLastAddedFile() const;
58
59  virtual const std::string& GetLanguage() const;
60
61  virtual bool IsUsingPlatformChecker() const;
62
63 private:
64  // These two classes can destruct us.
65  friend class BrowserThread;
66  friend class DeleteTask<SpellCheckHostImpl>;
67
68  virtual ~SpellCheckHostImpl();
69
70  // Figure out the location for the dictionary. This is only non-trivial for
71  // Windows:
72  // The default place whether the spellcheck dictionary can reside is
73  // chrome::DIR_APP_DICTIONARIES. However, for systemwide installations,
74  // this directory may not have permissions for download. In that case, the
75  // alternate directory for download is chrome::DIR_USER_DATA.
76  void InitializeDictionaryLocation();
77
78  // Load and parse the custom words dictionary and open the bdic file.
79  // Executed on the file thread.
80  void InitializeInternal();
81
82  void InitializeOnFileThread();
83
84  // Inform |observer_| that initialization has finished.
85  void InformObserverOfInitialization();
86
87  // If |dictionary_file_| is missing, we attempt to download it.
88  void DownloadDictionary();
89
90  // Write a custom dictionary addition to disk.
91  void WriteWordToCustomDictionary(const std::string& word);
92
93  // URLFetcher::Delegate implementation.  Called when we finish downloading the
94  // spellcheck dictionary; saves the dictionary to |data_|.
95  virtual void OnURLFetchComplete(const URLFetcher* source,
96                                  const GURL& url,
97                                  const net::URLRequestStatus& status,
98                                  int response_code,
99                                  const ResponseCookies& cookies,
100                                  const std::string& data);
101
102  // Saves |data_| to disk. Run on the file thread.
103  void SaveDictionaryData();
104
105  // May be NULL.
106  SpellCheckHostObserver* observer_;
107
108  // The desired location of the dictionary file (whether or not t exists yet).
109  FilePath bdict_file_path_;
110
111  // The location of the custom words file.
112  FilePath custom_dictionary_file_;
113
114  // The language of the dictionary file.
115  std::string language_;
116
117  // The file descriptor/handle for the dictionary file.
118  base::PlatformFile file_;
119
120  // In-memory cache of the custom words file.
121  std::vector<std::string> custom_words_;
122
123  // We don't want to attempt to download a missing dictionary file more than
124  // once.
125  bool tried_to_download_;
126
127  // Whether we should use the platform spellchecker instead of Hunspell.
128  bool use_platform_spellchecker_;
129
130  // Data received from the dictionary download.
131  std::string data_;
132
133  // Used for downloading the dictionary file. We don't hold a reference, and
134  // it is only valid to use it on the UI thread.
135  net::URLRequestContextGetter* request_context_getter_;
136
137  // Used for downloading the dictionary file.
138  scoped_ptr<URLFetcher> fetcher_;
139};
140
141#endif  // CHROME_BROWSER_SPELLCHECK_HOST_IMPL_H_
142