C++程序  |  178行  |  6.8 KB

// Copyright (c) 2013 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.
//
// An object to record and send user feedback to spelling service. The spelling
// service uses the feedback to improve its suggestions.
//
// Assigns uint32 hash identifiers to spelling suggestions from spelling service
// and stores these suggestions. Records user's actions on these suggestions.
// Periodically sends batches of user feedback to the spelling service.

#ifndef CHROME_BROWSER_SPELLCHECKER_FEEDBACK_SENDER_H_
#define CHROME_BROWSER_SPELLCHECKER_FEEDBACK_SENDER_H_

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

#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "chrome/browser/spellchecker/feedback.h"
#include "chrome/browser/spellchecker/misspelling.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "url/gurl.h"

class SpellCheckMarker;
struct SpellCheckResult;

namespace net {
class URLFetcher;
class URLRequestContextGetter;
}

namespace spellcheck {

namespace {

// Constants for the feedback field trial.
const char kFeedbackFieldTrialName[] = "SpellingServiceFeedback";
const char kFeedbackFieldTrialEnabledGroupName[] = "Enabled";

}  // namespace

// Stores and sends user feedback to the spelling service. Sample usage:
//    FeedbackSender sender(profile.GetRequestContext(), language, country);
//    sender.OnSpellcheckResults(spellcheck_results_from_spelling_service,
//                               renderer_process_id,
//                               spellchecked_text,
//                               existing_hashes);
//    sender.SelectedSuggestion(hash, suggestion_index);
class FeedbackSender : public base::SupportsWeakPtr<FeedbackSender>,
                       public net::URLFetcherDelegate {
 public:
  // Constructs a feedback sender. Keeps |request_context| in a scoped_refptr,
  // because URLRequestContextGetter implements RefcountedThreadSafe.
  FeedbackSender(net::URLRequestContextGetter* request_context,
                 const std::string& language,
                 const std::string& country);
  virtual ~FeedbackSender();

  // Records that user selected suggestion |suggestion_index| for the
  // misspelling identified by |hash|.
  void SelectedSuggestion(uint32 hash, int suggestion_index);

  // Records that user added the misspelling identified by |hash| to the
  // dictionary.
  void AddedToDictionary(uint32 hash);

  // Records that user right-clicked on the misspelling identified by |hash|,
  // but did not select any suggestion.
  void IgnoredSuggestions(uint32 hash);

  // Records that user did not choose any suggestion but manually corrected the
  // misspelling identified by |hash| to string |correction|, which is not in
  // the list of suggestions.
  void ManuallyCorrected(uint32 hash, const base::string16& correction);

  // Records that user has the misspelling in the custom dictionary. The user
  // will never see the spellcheck suggestions for the misspelling.
  void RecordInDictionary(uint32 hash);

  // Receives document markers for renderer with process ID |render_process_id|
  // when the renderer responds to a RequestDocumentMarkers() call. Finalizes
  // feedback for the markers that are gone from the renderer. Sends feedback
  // data for the renderer with process ID |renderer_process_id| to the spelling
  // service. If the current session has expired, then refreshes the session
  // start timestamp and sends out all of the feedback data.
  void OnReceiveDocumentMarkers(int renderer_process_id,
                                const std::vector<uint32>& markers);

  // Generates feedback data based on spellcheck results. The new feedback data
  // is pending. Sets hash identifiers for |results|. Called when spelling
  // service client receives results from the spelling service. Does not take
  // ownership of |results|.
  void OnSpellcheckResults(int renderer_process_id,
                           const base::string16& text,
                           const std::vector<SpellCheckMarker>& markers,
                           std::vector<SpellCheckResult>* results);

  // Receives updated language and country code for feedback. Finalizes and
  // sends out all of the feedback data.
  void OnLanguageCountryChange(const std::string& language,
                               const std::string& country);

  // Starts collecting feedback, if it's not already being collected.
  void StartFeedbackCollection();

  // Sends out all previously collected data and stops collecting feedback, if
  // it was being collected.
  void StopFeedbackCollection();

 private:
  friend class FeedbackSenderTest;

  // net::URLFetcherDelegate implementation. Takes ownership of |source|.
  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;

  // Requests the document markers from all of the renderers to determine which
  // feedback can be finalized. Finalizes feedback for renderers that are gone.
  // Called periodically when |timer_| fires.
  void RequestDocumentMarkers();

  // Sends out all feedback data. Resets the session-start timestamp to now.
  // Restarts the timer that requests markers from the renderers.
  void FlushFeedback();

  // Sends out the |feedback_data|.
  void SendFeedback(const std::vector<Misspelling>& feedback_data,
                    bool is_first_feedback_batch);

  // URL request context for the feedback senders.
  scoped_refptr<net::URLRequestContextGetter> request_context_;

  // The feedback API version.
  const std::string api_version_;

  // The language of text. The string is a BCP 47 language tag.
  std::string language_;

  // The country of origin. The string is the ISO 3166-1 alpha-3 code.
  std::string country_;

  // Misspelling counter used to generate unique hash identifier for each
  // misspelling.
  size_t misspelling_counter_;

  // Feedback data.
  Feedback feedback_;

  // A set of renderer process IDs for renderers that have sent out feedback in
  // this session.
  std::set<int> renderers_sent_feedback_;

  // When the session started.
  base::Time session_start_;

  // The URL where the feedback data should be sent.
  GURL feedback_service_url_;

  // A timer to periodically request a list of document spelling markers from
  // all of the renderers. The timer starts in StartFeedbackCollection() and
  // stops in StopFeedbackCollection(). The timer stops and abandons its tasks
  // on destruction.
  base::RepeatingTimer<FeedbackSender> timer_;

  // Feedback senders that need to stay alive for the duration of sending data.
  // If a sender is destroyed before it finishes, then sending feedback will be
  // canceled.
  ScopedVector<net::URLFetcher> senders_;

  DISALLOW_COPY_AND_ASSIGN(FeedbackSender);
};

}  // namespace spellcheck

#endif  // CHROME_BROWSER_SPELLCHECKER_FEEDBACK_SENDER_H_