Home | History | Annotate | Download | only in webui
      1 // Copyright (c) 2011 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 #include "chrome/browser/ui/webui/flags_ui.h"
      6 
      7 #include <string>
      8 
      9 #include "base/memory/singleton.h"
     10 #include "base/values.h"
     11 #include "chrome/browser/about_flags.h"
     12 #include "chrome/browser/browser_process.h"
     13 #include "chrome/browser/prefs/pref_service.h"
     14 #include "chrome/browser/profiles/profile.h"
     15 #include "chrome/browser/ui/browser_list.h"
     16 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
     17 #include "chrome/common/jstemplate_builder.h"
     18 #include "chrome/common/pref_names.h"
     19 #include "chrome/common/url_constants.h"
     20 #include "content/browser/browser_thread.h"
     21 #include "content/browser/tab_contents/tab_contents.h"
     22 #include "grit/browser_resources.h"
     23 #include "grit/chromium_strings.h"
     24 #include "grit/generated_resources.h"
     25 #include "grit/theme_resources.h"
     26 #include "ui/base/l10n/l10n_util.h"
     27 #include "ui/base/resource/resource_bundle.h"
     28 
     29 #if defined(OS_CHROMEOS)
     30 #include "chrome/browser/chromeos/user_cros_settings_provider.h"
     31 #include "chrome/browser/chromeos/login/user_manager.h"
     32 #endif
     33 
     34 namespace {
     35 
     36 ///////////////////////////////////////////////////////////////////////////////
     37 //
     38 // FlagsUIHTMLSource
     39 //
     40 ///////////////////////////////////////////////////////////////////////////////
     41 
     42 class FlagsUIHTMLSource : public ChromeURLDataManager::DataSource {
     43  public:
     44   FlagsUIHTMLSource()
     45       : DataSource(chrome::kChromeUIFlagsHost, MessageLoop::current()) {}
     46 
     47   // Called when the network layer has requested a resource underneath
     48   // the path we registered.
     49   virtual void StartDataRequest(const std::string& path,
     50                                 bool is_incognito,
     51                                 int request_id);
     52   virtual std::string GetMimeType(const std::string&) const {
     53     return "text/html";
     54   }
     55 
     56  private:
     57   ~FlagsUIHTMLSource() {}
     58 
     59   DISALLOW_COPY_AND_ASSIGN(FlagsUIHTMLSource);
     60 };
     61 
     62 void FlagsUIHTMLSource::StartDataRequest(const std::string& path,
     63                                         bool is_incognito,
     64                                         int request_id) {
     65   // Strings used in the JsTemplate file.
     66   DictionaryValue localized_strings;
     67   localized_strings.SetString("flagsLongTitle",
     68       l10n_util::GetStringUTF16(IDS_FLAGS_LONG_TITLE));
     69   localized_strings.SetString("flagsTableTitle",
     70       l10n_util::GetStringUTF16(IDS_FLAGS_TABLE_TITLE));
     71   localized_strings.SetString("flagsNoExperimentsAvailable",
     72       l10n_util::GetStringUTF16(IDS_FLAGS_NO_EXPERIMENTS_AVAILABLE));
     73   localized_strings.SetString("flagsWarningHeader", l10n_util::GetStringUTF16(
     74       IDS_FLAGS_WARNING_HEADER));
     75   localized_strings.SetString("flagsBlurb", l10n_util::GetStringUTF16(
     76       IDS_FLAGS_WARNING_TEXT));
     77   localized_strings.SetString("flagsRestartNotice", l10n_util::GetStringFUTF16(
     78       IDS_FLAGS_RELAUNCH_NOTICE,
     79       l10n_util::GetStringUTF16(
     80 #if defined(OS_CHROMEOS)
     81           IDS_PRODUCT_OS_NAME
     82 #else
     83           IDS_PRODUCT_NAME
     84 #endif
     85           )));
     86   localized_strings.SetString("flagsRestartButton",
     87       l10n_util::GetStringUTF16(IDS_FLAGS_RELAUNCH_BUTTON));
     88   localized_strings.SetString("disable",
     89       l10n_util::GetStringUTF16(IDS_FLAGS_DISABLE));
     90   localized_strings.SetString("enable",
     91       l10n_util::GetStringUTF16(IDS_FLAGS_ENABLE));
     92 
     93   base::StringPiece html =
     94       ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_FLAGS_HTML);
     95 #if defined (OS_CHROMEOS)
     96   if (!chromeos::UserManager::Get()->current_user_is_owner()) {
     97     html = ResourceBundle::GetSharedInstance().GetRawDataResource(
     98         IDR_FLAGS_HTML_WARNING);
     99 
    100     // Set the strings to show which user can actually change the flags
    101     localized_strings.SetString("ownerOnly", l10n_util::GetStringUTF16(
    102         IDS_OPTIONS_ACCOUNTS_OWNER_ONLY));
    103     localized_strings.SetString("ownerUserId", UTF8ToUTF16(
    104         chromeos::UserCrosSettingsProvider::cached_owner()));
    105   }
    106 #endif
    107   static const base::StringPiece flags_html(html);
    108   ChromeURLDataManager::DataSource::SetFontAndTextDirection(&localized_strings);
    109 
    110   std::string full_html(flags_html.data(), flags_html.size());
    111   jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html);
    112   jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html);
    113   jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html);
    114   jstemplate_builder::AppendJsTemplateSourceHtml(&full_html);
    115 
    116   scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
    117   html_bytes->data.resize(full_html.size());
    118   std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
    119 
    120   SendResponse(request_id, html_bytes);
    121 }
    122 
    123 ////////////////////////////////////////////////////////////////////////////////
    124 //
    125 // FlagsDOMHandler
    126 //
    127 ////////////////////////////////////////////////////////////////////////////////
    128 
    129 // The handler for Javascript messages for the about:flags page.
    130 class FlagsDOMHandler : public WebUIMessageHandler {
    131  public:
    132   FlagsDOMHandler() {}
    133   virtual ~FlagsDOMHandler() {}
    134 
    135   // WebUIMessageHandler implementation.
    136   virtual void RegisterMessages();
    137 
    138   // Callback for the "requestFlagsExperiments" message.
    139   void HandleRequestFlagsExperiments(const ListValue* args);
    140 
    141   // Callback for the "enableFlagsExperiment" message.
    142   void HandleEnableFlagsExperimentMessage(const ListValue* args);
    143 
    144   // Callback for the "restartBrowser" message. Restores all tabs on restart.
    145   void HandleRestartBrowser(const ListValue* args);
    146 
    147  private:
    148   DISALLOW_COPY_AND_ASSIGN(FlagsDOMHandler);
    149 };
    150 
    151 void FlagsDOMHandler::RegisterMessages() {
    152   web_ui_->RegisterMessageCallback("requestFlagsExperiments",
    153       NewCallback(this, &FlagsDOMHandler::HandleRequestFlagsExperiments));
    154   web_ui_->RegisterMessageCallback("enableFlagsExperiment",
    155       NewCallback(this, &FlagsDOMHandler::HandleEnableFlagsExperimentMessage));
    156   web_ui_->RegisterMessageCallback("restartBrowser",
    157       NewCallback(this, &FlagsDOMHandler::HandleRestartBrowser));
    158 }
    159 
    160 void FlagsDOMHandler::HandleRequestFlagsExperiments(const ListValue* args) {
    161   DictionaryValue results;
    162   results.Set("flagsExperiments",
    163               about_flags::GetFlagsExperimentsData(
    164                   g_browser_process->local_state()));
    165   results.SetBoolean("needsRestart",
    166                      about_flags::IsRestartNeededToCommitChanges());
    167   web_ui_->CallJavascriptFunction("returnFlagsExperiments", results);
    168 }
    169 
    170 void FlagsDOMHandler::HandleEnableFlagsExperimentMessage(
    171     const ListValue* args) {
    172   DCHECK_EQ(2u, args->GetSize());
    173   if (args->GetSize() != 2)
    174     return;
    175 
    176   std::string experiment_internal_name;
    177   std::string enable_str;
    178   if (!args->GetString(0, &experiment_internal_name) ||
    179       !args->GetString(1, &enable_str))
    180     return;
    181 
    182   about_flags::SetExperimentEnabled(
    183       g_browser_process->local_state(),
    184       experiment_internal_name,
    185       enable_str == "true");
    186 }
    187 
    188 void FlagsDOMHandler::HandleRestartBrowser(const ListValue* args) {
    189 #if !defined(OS_CHROMEOS)
    190   // Set the flag to restore state after the restart.
    191   PrefService* pref_service = g_browser_process->local_state();
    192   pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true);
    193   BrowserList::CloseAllBrowsersAndExit();
    194 #else
    195   // For CrOS instead of browser restart (which is not supported) perform a full
    196   // sign out. Session will be only restored is user has that setting set.
    197   // Same session restore behavior happens in case of full restart after update.
    198   BrowserList::GetLastActive()->Exit();
    199 #endif
    200 }
    201 
    202 }  // namespace
    203 
    204 ///////////////////////////////////////////////////////////////////////////////
    205 //
    206 // FlagsUI
    207 //
    208 ///////////////////////////////////////////////////////////////////////////////
    209 
    210 FlagsUI::FlagsUI(TabContents* contents) : WebUI(contents) {
    211   AddMessageHandler((new FlagsDOMHandler())->Attach(this));
    212 
    213   FlagsUIHTMLSource* html_source = new FlagsUIHTMLSource();
    214 
    215   // Set up the about:flags source.
    216   contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
    217 }
    218 
    219 // static
    220 RefCountedMemory* FlagsUI::GetFaviconResourceBytes() {
    221   return ResourceBundle::GetSharedInstance().
    222       LoadDataResourceBytes(IDR_FLAGS);
    223 }
    224 
    225 // static
    226 void FlagsUI::RegisterPrefs(PrefService* prefs) {
    227   prefs->RegisterListPref(prefs::kEnabledLabsExperiments);
    228 }
    229