• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 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 // An object to record and send user feedback to spelling service. The spelling
6 // service uses the feedback to improve its suggestions.
7 //
8 // Assigns uint32 hash identifiers to spelling suggestions from spelling service
9 // and stores these suggestions. Records user's actions on these suggestions.
10 // Periodically sends batches of user feedback to the spelling service.
11 
12 #ifndef CHROME_BROWSER_SPELLCHECKER_FEEDBACK_SENDER_H_
13 #define CHROME_BROWSER_SPELLCHECKER_FEEDBACK_SENDER_H_
14 
15 #include <map>
16 #include <set>
17 #include <vector>
18 
19 #include "base/memory/scoped_vector.h"
20 #include "base/memory/weak_ptr.h"
21 #include "base/timer/timer.h"
22 #include "chrome/browser/spellchecker/feedback.h"
23 #include "chrome/browser/spellchecker/misspelling.h"
24 #include "net/url_request/url_fetcher_delegate.h"
25 #include "url/gurl.h"
26 
27 class SpellCheckMarker;
28 struct SpellCheckResult;
29 
30 namespace net {
31 class URLFetcher;
32 class URLRequestContextGetter;
33 }
34 
35 namespace spellcheck {
36 
37 namespace {
38 
39 // Constants for the feedback field trial.
40 const char kFeedbackFieldTrialName[] = "SpellingServiceFeedback";
41 const char kFeedbackFieldTrialEnabledGroupName[] = "Enabled";
42 
43 }  // namespace
44 
45 // Stores and sends user feedback to the spelling service. Sample usage:
46 //    FeedbackSender sender(profile.GetRequestContext(), language, country);
47 //    sender.OnSpellcheckResults(spellcheck_results_from_spelling_service,
48 //                               renderer_process_id,
49 //                               spellchecked_text,
50 //                               existing_hashes);
51 //    sender.SelectedSuggestion(hash, suggestion_index);
52 class FeedbackSender : public base::SupportsWeakPtr<FeedbackSender>,
53                        public net::URLFetcherDelegate {
54  public:
55   // Constructs a feedback sender. Keeps |request_context| in a scoped_refptr,
56   // because URLRequestContextGetter implements RefcountedThreadSafe.
57   FeedbackSender(net::URLRequestContextGetter* request_context,
58                  const std::string& language,
59                  const std::string& country);
60   virtual ~FeedbackSender();
61 
62   // Records that user selected suggestion |suggestion_index| for the
63   // misspelling identified by |hash|.
64   void SelectedSuggestion(uint32 hash, int suggestion_index);
65 
66   // Records that user added the misspelling identified by |hash| to the
67   // dictionary.
68   void AddedToDictionary(uint32 hash);
69 
70   // Records that user right-clicked on the misspelling identified by |hash|,
71   // but did not select any suggestion.
72   void IgnoredSuggestions(uint32 hash);
73 
74   // Records that user did not choose any suggestion but manually corrected the
75   // misspelling identified by |hash| to string |correction|, which is not in
76   // the list of suggestions.
77   void ManuallyCorrected(uint32 hash, const base::string16& correction);
78 
79   // Records that user has the misspelling in the custom dictionary. The user
80   // will never see the spellcheck suggestions for the misspelling.
81   void RecordInDictionary(uint32 hash);
82 
83   // Receives document markers for renderer with process ID |render_process_id|
84   // when the renderer responds to a RequestDocumentMarkers() call. Finalizes
85   // feedback for the markers that are gone from the renderer. Sends feedback
86   // data for the renderer with process ID |renderer_process_id| to the spelling
87   // service. If the current session has expired, then refreshes the session
88   // start timestamp and sends out all of the feedback data.
89   void OnReceiveDocumentMarkers(int renderer_process_id,
90                                 const std::vector<uint32>& markers);
91 
92   // Generates feedback data based on spellcheck results. The new feedback data
93   // is pending. Sets hash identifiers for |results|. Called when spelling
94   // service client receives results from the spelling service. Does not take
95   // ownership of |results|.
96   void OnSpellcheckResults(int renderer_process_id,
97                            const base::string16& text,
98                            const std::vector<SpellCheckMarker>& markers,
99                            std::vector<SpellCheckResult>* results);
100 
101   // Receives updated language and country code for feedback. Finalizes and
102   // sends out all of the feedback data.
103   void OnLanguageCountryChange(const std::string& language,
104                                const std::string& country);
105 
106   // Starts collecting feedback, if it's not already being collected.
107   void StartFeedbackCollection();
108 
109   // Sends out all previously collected data and stops collecting feedback, if
110   // it was being collected.
111   void StopFeedbackCollection();
112 
113  private:
114   friend class FeedbackSenderTest;
115 
116   // net::URLFetcherDelegate implementation. Takes ownership of |source|.
117   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
118 
119   // Requests the document markers from all of the renderers to determine which
120   // feedback can be finalized. Finalizes feedback for renderers that are gone.
121   // Called periodically when |timer_| fires.
122   void RequestDocumentMarkers();
123 
124   // Sends out all feedback data. Resets the session-start timestamp to now.
125   // Restarts the timer that requests markers from the renderers.
126   void FlushFeedback();
127 
128   // Sends out the |feedback_data|.
129   void SendFeedback(const std::vector<Misspelling>& feedback_data,
130                     bool is_first_feedback_batch);
131 
132   // URL request context for the feedback senders.
133   scoped_refptr<net::URLRequestContextGetter> request_context_;
134 
135   // The feedback API version.
136   const std::string api_version_;
137 
138   // The language of text. The string is a BCP 47 language tag.
139   std::string language_;
140 
141   // The country of origin. The string is the ISO 3166-1 alpha-3 code.
142   std::string country_;
143 
144   // Misspelling counter used to generate unique hash identifier for each
145   // misspelling.
146   size_t misspelling_counter_;
147 
148   // Feedback data.
149   Feedback feedback_;
150 
151   // A set of renderer process IDs for renderers that have sent out feedback in
152   // this session.
153   std::set<int> renderers_sent_feedback_;
154 
155   // When the session started.
156   base::Time session_start_;
157 
158   // The URL where the feedback data should be sent.
159   GURL feedback_service_url_;
160 
161   // A timer to periodically request a list of document spelling markers from
162   // all of the renderers. The timer starts in StartFeedbackCollection() and
163   // stops in StopFeedbackCollection(). The timer stops and abandons its tasks
164   // on destruction.
165   base::RepeatingTimer<FeedbackSender> timer_;
166 
167   // Feedback senders that need to stay alive for the duration of sending data.
168   // If a sender is destroyed before it finishes, then sending feedback will be
169   // canceled.
170   ScopedVector<net::URLFetcher> senders_;
171 
172   DISALLOW_COPY_AND_ASSIGN(FeedbackSender);
173 };
174 
175 }  // namespace spellcheck
176 
177 #endif  // CHROME_BROWSER_SPELLCHECKER_FEEDBACK_SENDER_H_
178