// 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_TRANSLATE_TRANSLATE_MANAGER_H_
#define CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_
#pragma once
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/lazy_instance.h"
#include "base/task.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/common/net/url_fetcher.h"
#include "chrome/common/translate_errors.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
template <typename T> struct DefaultSingletonTraits;
class GURL;
struct PageTranslatedDetails;
class PrefService;
class TabContents;
class TranslateInfoBarDelegate;
// The TranslateManager class is responsible for showing an info-bar when a page
// in a language different than the user language is loaded. It triggers the
// page translation the user requests.
// It is a singleton.
class TranslateManager : public NotificationObserver,
public URLFetcher::Delegate {
public:
// Returns the singleton instance.
static TranslateManager* GetInstance();
virtual ~TranslateManager();
// Translates the page contents from |source_lang| to |target_lang|.
// The actual translation might be performed asynchronously if the translate
// script is not yet available.
void TranslatePage(TabContents* tab_contents,
const std::string& source_lang,
const std::string& target_lang);
// Reverts the contents of the page in |tab_contents| to its original
// language.
void RevertTranslation(TabContents* tab_contents);
// Reports to the Google translate server that a page language was incorrectly
// detected. This call is initiated by the user selecting the "report" menu
// under options in the translate infobar.
void ReportLanguageDetectionError(TabContents* tab_contents);
// Clears the translate script, so it will be fetched next time we translate.
void ClearTranslateScript() { translate_script_.clear(); }
// NotificationObserver implementation:
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);
// URLFetcher::Delegate implementation:
virtual void OnURLFetchComplete(const URLFetcher* source,
const GURL& url,
const net::URLRequestStatus& status,
int response_code,
const ResponseCookies& cookies,
const std::string& data);
// Used by unit-tests to override the default delay after which the translate
// script is fetched again from the translation server.
void set_translate_script_expiration_delay(int delay_ms) {
translate_script_expiration_delay_ = delay_ms;
}
// Convenience method to know if a tab is showing a translate infobar.
static bool IsShowingTranslateInfobar(TabContents* tab);
// Returns true if the URL can be translated.
static bool IsTranslatableURL(const GURL& url);
// 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 |language| is supported by the translation server.
static bool IsSupportedLanguage(const std::string& language);
protected:
TranslateManager();
private:
friend struct DefaultSingletonTraits<TranslateManager>;
// Structure that describes a translate request.
// Translation may be deferred while the translate script is being retrieved
// from the translate server.
struct PendingRequest {
int render_process_id;
int render_view_id;
int page_id;
std::string source_lang;
std::string target_lang;
};
// Starts the translation process on |tab| containing the page in the
// |page_lang| language.
void InitiateTranslation(TabContents* tab, const std::string& page_lang);
// If the tab identified by |process_id| and |render_id| has been closed, this
// does nothing, otherwise it calls InitiateTranslation.
void InitiateTranslationPosted(int process_id,
int render_id,
const std::string& page_lang);
// Sends a translation request to the RenderView of |tab_contents|.
void DoTranslatePage(TabContents* tab_contents,
const std::string& translate_script,
const std::string& source_lang,
const std::string& target_lang);
// Shows the after translate or error infobar depending on the details.
void PageTranslated(TabContents* tab, PageTranslatedDetails* details);
// Returns true if the passed language has been configured by the user as an
// accept language.
bool IsAcceptLanguage(TabContents* tab, const std::string& language);
// Initializes the |accept_languages_| language table based on the associated
// preference in |prefs|.
void InitAcceptLanguages(PrefService* prefs);
// Fetches the JS translate script (the script that is injected in the page
// to translate it).
void RequestTranslateScript();
// Shows the specified translate |infobar| in the given |tab|. If a current
// translate infobar is showing, it just replaces it with the new one.
void ShowInfoBar(TabContents* tab, TranslateInfoBarDelegate* infobar);
// Returns the language to translate to, which is the language the UI is
// configured in. Returns an empty string if that language is not supported
// by the translation service.
static std::string GetTargetLanguage();
// Returns the translate info bar showing in |tab| or NULL if none is showing.
static TranslateInfoBarDelegate* GetTranslateInfoBarDelegate(
TabContents* tab);
NotificationRegistrar notification_registrar_;
PrefChangeRegistrar pref_change_registrar_;
// A map that associates a profile with its parsed "accept languages".
typedef std::set<std::string> LanguageSet;
typedef std::map<PrefService*, LanguageSet> PrefServiceLanguagesMap;
PrefServiceLanguagesMap accept_languages_;
ScopedRunnableMethodFactory<TranslateManager> method_factory_;
// The JS injected in the page to do the translation.
std::string translate_script_;
// Delay in milli-seconds after which the translate script is fetched again
// from the translate server.
int translate_script_expiration_delay_;
// Whether the translate JS is currently being retrieved.
bool translate_script_request_pending_;
// The list of pending translate requests. Translate requests are queued when
// the translate script is not ready and has to be fetched from the translate
// server.
std::vector<PendingRequest> pending_requests_;
// The languages supported by the translation server.
static base::LazyInstance<std::set<std::string> > supported_languages_;
DISALLOW_COPY_AND_ASSIGN(TranslateManager);
};
#endif // CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_