summaryrefslogtreecommitdiffstats
path: root/chrome/browser/spellchecker/spellcheck_host_impl.h
blob: 30c217cb61023afbbd1f7844c4e2b03a83be3988 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_HOST_IMPL_H_
#define CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_HOST_IMPL_H_
#pragma once

#include <string>
#include <vector>

#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/spellchecker/spellcheck_host.h"
#include "chrome/browser/spellchecker/spellcheck_profile_provider.h"
#include "content/common/net/url_fetcher.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"

// This class implements the SpellCheckHost interface to provide the
// functionalities listed below:
// * Adding a word to the custom dictionary;
// * Storing the custom dictionary to the file, and read it back
//   from the file during the initialization.
// * Downloading a dictionary and map it for the renderer, and;
// * Calling the platform spellchecker attached to the browser;
//
// To download a dictionary and initialize it without blocking the UI thread,
// this class also implements the URLFetcher::Delegate() interface. This
// initialization status is notified to the UI thread through the
// SpellCheckProfileProvider interface.
//
// We expect a profile creates an instance of this class through a factory
// method, SpellCheckHost::Create() and uses only the SpellCheckHost interface
// provided by this class.
//   spell_check_host_ = SpellCheckHost::Create(...)
//
// Available languages for the checker, which we need to specify via Create(),
// can be listed using SpellCheckHost::GetAvailableLanguages() static method.
class SpellCheckHostImpl : public SpellCheckHost,
                           public URLFetcher::Delegate,
                           public content::NotificationObserver {
 public:
  SpellCheckHostImpl(SpellCheckProfileProvider* profile,
                     const std::string& language,
                     net::URLRequestContextGetter* request_context_getter,
                     SpellCheckHostMetrics* metrics);

  void Initialize();

  // SpellCheckHost implementation
  virtual void UnsetProfile();
  virtual void InitForRenderer(RenderProcessHost* process);
  virtual void AddWord(const std::string& word);
  virtual const base::PlatformFile& GetDictionaryFile() const;
  virtual const std::string& GetLanguage() const;
  virtual bool IsUsingPlatformChecker() const;

 private:
  typedef SpellCheckProfileProvider::CustomWordList CustomWordList;

  // These two classes can destruct us.
  friend class BrowserThread;
  friend class DeleteTask<SpellCheckHostImpl>;

  virtual ~SpellCheckHostImpl();

  // Figure out the location for the dictionary. This is only non-trivial for
  // Windows:
  // The default place whether the spellcheck dictionary can reside is
  // chrome::DIR_APP_DICTIONARIES. However, for systemwide installations,
  // this directory may not have permissions for download. In that case, the
  // alternate directory for download is chrome::DIR_USER_DATA.
  void InitializeDictionaryLocation();

  // Load and parse the custom words dictionary and open the bdic file.
  // Executed on the file thread.
  void InitializeInternal();

  void InitializeOnFileThread();

  // Inform |profile_| that initialization has finished.
  // |custom_words| holds the custom word list which was
  // loaded at the file thread.
  void InformProfileOfInitializationWithCustomWords(
      CustomWordList* custom_words);

  // An alternative version of InformProfileOfInitializationWithCustomWords()
  // which implies empty |custom_words|.
  void InformProfileOfInitialization();

  // If |dictionary_file_| is missing, we attempt to download it.
  void DownloadDictionary();

  // Write a custom dictionary addition to disk.
  void WriteWordToCustomDictionary(const std::string& word);

  // Returns a metrics counter associated with this object,
  // or null when metrics recording is disabled.
  virtual SpellCheckHostMetrics* GetMetrics() const;

  // Returns true if the dictionary is ready to use.
  virtual bool IsReady() const;

  // URLFetcher::Delegate implementation.  Called when we finish downloading the
  // spellcheck dictionary; saves the dictionary to |data_|.
  virtual void OnURLFetchComplete(const URLFetcher* source,
                                  const GURL& url,
                                  const net::URLRequestStatus& status,
                                  int response_code,
                                  const net::ResponseCookies& cookies,
                                  const std::string& data);

  // NotificationProfile implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details);

  // Saves |data_| to disk. Run on the file thread.
  void SaveDictionaryData();

  // Verifies the specified BDict file exists and it is sane. This function
  // should be called before opening the file so we can delete it and download a
  // new dictionary if it is corrupted.
  bool VerifyBDict(const FilePath& path) const;

  // May be NULL.
  SpellCheckProfileProvider* profile_;

  // The desired location of the dictionary file (whether or not t exists yet).
  FilePath bdict_file_path_;

  // The location of the custom words file.
  FilePath custom_dictionary_file_;

  // The language of the dictionary file.
  std::string language_;

  // The file descriptor/handle for the dictionary file.
  base::PlatformFile file_;

  // We don't want to attempt to download a missing dictionary file more than
  // once.
  bool tried_to_download_;

  // Whether we should use the platform spellchecker instead of Hunspell.
  bool use_platform_spellchecker_;

  // Data received from the dictionary download.
  std::string data_;

  // Used for downloading the dictionary file. We don't hold a reference, and
  // it is only valid to use it on the UI thread.
  net::URLRequestContextGetter* request_context_getter_;

  // Used for downloading the dictionary file.
  scoped_ptr<URLFetcher> fetcher_;

  content::NotificationRegistrar registrar_;

  // An optional metrics counter given by the constructor.
  SpellCheckHostMetrics* metrics_;

  DISALLOW_COPY_AND_ASSIGN(SpellCheckHostImpl);
};

#endif  // CHROME_BROWSER_SPELLCHECKER_SPELLCHECK_HOST_IMPL_H_