Home | History | Annotate | Download | only in spellchecker
      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 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 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  private:
    107   friend class FeedbackSenderTest;
    108 
    109   // net::URLFetcherDelegate implementation. Takes ownership of |source|.
    110   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
    111 
    112   // Requests the document markers from all of the renderers to determine which
    113   // feedback can be finalized. Finalizes feedback for renderers that are gone.
    114   // Called periodically when |timer_| fires.
    115   void RequestDocumentMarkers();
    116 
    117   // Sends out all feedback data. Resets the session-start timestamp to now.
    118   // Restarts the timer that requests markers from the renderers.
    119   void FlushFeedback();
    120 
    121   // Sends out the |feedback_data|.
    122   void SendFeedback(const std::vector<Misspelling>& feedback_data,
    123                     bool is_first_feedback_batch);
    124 
    125   // URL request context for the feedback senders.
    126   scoped_refptr<net::URLRequestContextGetter> request_context_;
    127 
    128   // The language of text. The string is a BCP 47 language tag.
    129   std::string language_;
    130 
    131   // The country of origin. The string is the ISO 3166-1 alpha-3 code.
    132   std::string country_;
    133 
    134   // Misspelling counter used to generate unique hash identifier for each
    135   // misspelling.
    136   size_t misspelling_counter_;
    137 
    138   // Feedback data.
    139   Feedback feedback_;
    140 
    141   // A set of renderer process IDs for renderers that have sent out feedback in
    142   // this session.
    143   std::set<int> renderers_sent_feedback_;
    144 
    145   // When the session started.
    146   base::Time session_start_;
    147 
    148   // The URL where the feedback data should be sent.
    149   GURL feedback_service_url_;
    150 
    151   // A timer to periodically request a list of document spelling markers from
    152   // all of the renderers. The timer runs while an instance of this class is
    153   // alive.
    154   base::RepeatingTimer<FeedbackSender> timer_;
    155 
    156   // Feedback senders that need to stay alive for the duration of sending data.
    157   // If a sender is destroyed before it finishes, then sending feedback will be
    158   // canceled.
    159   ScopedVector<net::URLFetcher> senders_;
    160 
    161   DISALLOW_COPY_AND_ASSIGN(FeedbackSender);
    162 };
    163 
    164 }  // namespace spellcheck
    165 
    166 #endif  // CHROME_BROWSER_SPELLCHECKER_FEEDBACK_SENDER_H_
    167