summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host/translation_service.h
blob: 666265bb94ee994883ab363f1c5d9a0c1ba2b6f4 (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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Copyright (c) 2010 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_RENDERER_HOST_TRANSLATION_SERVICE_H_
#define CHROME_BROWSER_RENDERER_HOST_TRANSLATION_SERVICE_H_

#include <map>
#include <set>
#include <string>
#include <vector>

#include "base/lazy_instance.h"
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "chrome/browser/net/url_fetcher.h"
#include "ipc/ipc_message.h"
#include "testing/gtest/include/gtest/gtest_prod.h"

class DictionaryValue;
class TranslationServiceTest;
class TranslateURLFetcherDelegate;
class URLFetcher;

// The TranslationService class is used to translate text.
// There is one TranslationService per renderer process.
// It receives requests to translate text from the different render views of the
// render process, provided in lists (text chunks), where the words should be
// translated without changing the chunks order.
// It groups multiple such requests and sends them for translation to the Google
// translation server.  When it receives the response, it dispatches it to the
// appropriate render view.

class TranslationService : public URLFetcher::Delegate {
 public:
  explicit TranslationService(IPC::Message::Sender* message_sender);
  virtual ~TranslationService();

  // Sends the specified text for translation, from |source_language| to
  // |target_language|.  If |secure| is true, a secure connection is used when
  // sending the text to the external translation server.
  // When the translation results have been received, it sends a
  // ViewMsg_TranslateTextReponse message on the renderer at |routing_id|.
  void Translate(int routing_id,
                 int page_id,
                 int work_id,
                 const std::vector<string16>& text_chunks,
                 const std::string& source_language,
                 const std::string& target_language,
                 bool secure);

  // Sends the pending translation request for the specified renderer to the
  // translation server.
  void SendTranslationRequestForRenderer(int renderer_id, bool secure);

  // URLFetcher::Delegate implementation.
  virtual void OnURLFetchComplete(const URLFetcher* source,
                                  const GURL& url,
                                  const URLRequestStatus& status,
                                  int response_code,
                                  const ResponseCookies& cookies,
                                  const std::string& data);

  // Returns true if the TranslationService is enabled.
  static bool IsTranslationEnabled();

  // Fills |languages| with the list of languages that the translate server can
  // translate to and from.
  static void GetSupportedLanguages(std::vector<std::string>* languages);

  // Returns the language code that can be used with the Translate method for a
  // specified |chrome_locale|.
  static std::string GetLanguageCode(const std::string& chrome_locale);

  // Returns true if |page_language| is supported by the translation server.
  static bool IsSupportedLanguage(const std::string& page_language);

 protected:
  // The amount of time in ms after which a pending request is sent if no other
  // translation request has been received.
  // Overriden in tests.
  virtual int GetSendRequestDelay() const;

 private:
  friend class TranslationServiceTest;
  friend class TranslateURLFetcherDelegate;
  FRIEND_TEST(TranslationServiceTest, MergeTestChunks);
  FRIEND_TEST(TranslationServiceTest, SplitIntoTextChunks);
  FRIEND_TEST(TranslationServiceTest, RemoveTag);

  struct TranslationRequest;

  // The information necessary to return the translated text to the renderer.
  struct RendererRequestInfo {
    RendererRequestInfo() : routing_id(0), work_id(0) {}
    RendererRequestInfo(int routing_id, int work_id)
        : routing_id(routing_id),
          work_id(work_id) {
    }
    int routing_id;
    int work_id;
  };

  typedef std::vector<RendererRequestInfo> RendererRequestInfoList;

  typedef std::vector<string16> TextChunks;
  typedef std::vector<TextChunks> TextChunksList;
  // Maps from a RenderView routing id to the pending request for the
  // translation server.
  typedef std::map<int, TranslationRequest*> TranslationRequestMap;

  typedef std::map<const URLFetcher*, RendererRequestInfoList*>
      RendererRequestInfoMap;

  // Sends the passed request to the translations server.
  // Warning: the request is deleted when this call returns.
  void SendRequestToTranslationServer(TranslationRequest* request);

  // Called by the URLFetcherDelegate when the translation associated with
  // |url_fetcher| has been performed.  Sends the appropriate message back to
  // the renderer and deletes the URLFetcher.
  void SendResponseToRenderer(const URLFetcher* url_fetcher,
                              int error_code,
                              const TextChunksList& text_chunks_list);

  // Notifies the renderer that we failed to translate the request associated
  // with |url_fetcher|.
  void TranslationFailed(const URLFetcher* source);

  // Merges all text chunks to be translated into a single string that can be
  // sent to the translate server, surrounding each chunk with an anchor tag
  // to preserve chunk order in the translated version.
  string16 MergeTextChunks(const TextChunks& text_chunks);

  // Splits the translated text into its original text chunks, removing the
  // anchor tags wrapper that were added to preserve order.
  void SplitIntoTextChunks(const string16& translated_text,
                           TextChunks* text_chunks);

  // Removes the HTML anchor tag surrounding |text| and returns the resulting
  // string.
  string16 RemoveTag(const string16& text);

  // Find the next anchor tag in |text| starting at |start_index|.
  // Sets |id| (which must be non NULL) to the id property of the tag (which is
  // expected to be an int). Sets |tag_start_index| and |tag_end_index| to the
  // index of the beginning/end of the next tag.
  // Returns true if a tag was found and it is not at the end of the string,
  // false otherwise in which case |id|, |tag_start_index| and |tag_end_index|
  // are not set.
  bool FindOpenTagIndex(const string16& text,
                        size_t start_index,
                        size_t* tag_start_index,
                        size_t* tag_end_index,
                        int* id);

  // Adds |text| to the string request in/out param |request|.  If |request| is
  // empty, then the source, target language as well as the secure parameters
  // are also added.
  static void AddTextToRequestString(std::string* request,
                                     const std::string& text,
                                     const std::string& source_language,
                                     const std::string& target_language,
                                     bool secure);

  // The channel used to communicate with the renderer.
  IPC::Message::Sender* message_sender_;

  // Map used to retrieve the context of requests when the URLFetcher notifies
  // that it got a response.
  RendererRequestInfoMap renderer_request_infos_;

  TranslationRequestMap pending_translation_requests_;
  TranslationRequestMap pending_secure_translation_requests_;

  // Strings used for parsing.
  const string16 kCRAnchorTagStart;
  const string16 kAnchorTagStart;
  const string16 kClosingAnchorTag;
  const string16 kQuote;
  const string16 kGreaterThan;
  const string16 kLessThan;
  const string16 kQuoteGreaterThan;

  // The size taken by the parameters and separators needed when adding text to
  // a request string.
  static size_t text_param_length_;

  // The language supported by the translation server.
  static base::LazyInstance<std::set<std::string> > supported_languages_;

  DISALLOW_COPY_AND_ASSIGN(TranslationService);
};

#endif  // CHROME_BROWSER_RENDERER_HOST_TRANSLATION_SERVICE_H_