f91915595ea4409ed884d72c749df318cd2f7a68
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / salsa_ui.cc
1 // Copyright 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 #include "chrome/browser/ui/webui/chromeos/salsa_ui.h"
6
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/values.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/pref_names.h"
14 #include "chrome/common/url_constants.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/web_ui.h"
17 #include "content/public/browser/web_ui_data_source.h"
18 #include "grit/browser_resources.h"
19
20 // Whitelist of which preferences are possible targets for Salsa treatments.
21 // If new preferences are added and they are to be used in an experiment, then
22 // they must be added to this list as well to keep chrome://salsa from
23 // changing arbitrary values.
24
25 namespace {
26
27 const char* kWhitelist[] = {
28   prefs::kMaxSeparationForGestureTouchesInPixels,
29   prefs::kTabScrubActivationDelayInMs,
30   prefs::kOverscrollHorizontalThresholdComplete,
31   prefs::kOverscrollVerticalThresholdComplete,
32   prefs::kOverscrollMinimumThresholdStart,
33   prefs::kOverscrollVerticalThresholdStart,
34   prefs::kOverscrollHorizontalResistThreshold,
35   prefs::kOverscrollVerticalResistThreshold,
36 };
37
38 void RevertPreferences(PrefService* prefs,
39                        std::map<int, const base::Value*>* vals) {
40   std::map<int, const base::Value*>::const_iterator it;
41   for (it = vals->begin(); it != vals->end(); ++it) {
42     if (!prefs->FindPreference(kWhitelist[it->first]))
43       continue;
44
45     if (!it->second) {
46       prefs->ClearPref(kWhitelist[it->first]);
47     } else {
48       prefs->Set(kWhitelist[it->first], *it->second);
49       delete it->second;
50     }
51   }
52 }
53
54 } // namespace
55
56 SalsaUI::SalsaUI(content::WebUI* web_ui)
57     : content::WebUIController(web_ui) {
58   // Set up the chrome://salsa source.
59   content::WebUIDataSource* html_source =
60       content::WebUIDataSource::Create(chrome::kChromeUISalsaHost);
61
62   // Register callback handlers.
63   web_ui->RegisterMessageCallback(
64       "salsaSetPreferenceValue",
65       base::Bind(&SalsaUI::SetPreferenceValue,
66                  base::Unretained(this)));
67   web_ui->RegisterMessageCallback(
68       "salsaBackupPreferenceValue",
69       base::Bind(&SalsaUI::BackupPreferenceValue,
70                  base::Unretained(this)));
71
72   // Add required resources.
73   html_source->AddResourcePath("salsa.css", IDR_SALSA_CSS);
74   html_source->AddResourcePath("salsa.js", IDR_SALSA_JS);
75   html_source->SetDefaultResource(IDR_SALSA_HTML);
76
77   Profile* profile = Profile::FromWebUI(web_ui);
78   content::WebUIDataSource::Add(profile, html_source);
79 }
80
81 SalsaUI::~SalsaUI() {
82   std::map<int, const base::Value*>* values_to_revert =
83       new std::map<int, const base::Value*>;
84   values_to_revert->swap(orig_values_);
85
86   Profile* profile = Profile::FromWebUI(web_ui());
87   PrefService* prefs = profile->GetPrefs();
88
89   content::BrowserThread::PostTask(
90       content::BrowserThread::UI,
91       FROM_HERE,
92       base::Bind(&RevertPreferences, prefs, base::Owned(values_to_revert))
93     );
94 }
95
96 int SalsaUI::WhitelistIndex(const char* key) const {
97   if (!key)
98     return -1;
99
100   int len = arraysize(kWhitelist);
101   for (int i = 0; i < len; ++i) {
102     if (!strcmp(key, kWhitelist[i]))
103       return i;
104   }
105   return -1;
106 }
107
108 void SalsaUI::SetPreferenceValue(const base::ListValue* args) {
109   std::string pref_name;
110   const base::Value* value;
111   if (!args->GetString(0, &pref_name) || !args->Get(1, &value))
112     return;
113
114   int index = WhitelistIndex(pref_name.c_str());
115   if (index < 0)
116     return;
117
118   Profile* profile = Profile::FromWebUI(web_ui());
119   PrefService* prefs = profile->GetPrefs();
120   const PrefService::Preference* pref =
121       prefs->FindPreference(kWhitelist[index]);
122
123   if (pref->GetType() == value->GetType()) {
124     prefs->Set(kWhitelist[index], *value);
125   } else if (pref->GetType() == base::Value::TYPE_DOUBLE &&
126              value->GetType() == base::Value::TYPE_INTEGER) {
127     int int_val;
128     if (!value->GetAsInteger(&int_val))
129       return;
130     base::FundamentalValue double_val(static_cast<double>(int_val));
131     prefs->Set(kWhitelist[index], double_val);
132   }
133 }
134
135 void SalsaUI::BackupPreferenceValue(const base::ListValue* args) {
136   std::string pref_name;
137   if (!args->GetString(0, &pref_name))
138     return;
139
140   int index = WhitelistIndex(pref_name.c_str());
141   if (index < 0)
142     return;
143
144   Profile* profile = Profile::FromWebUI(web_ui());
145   PrefService* prefs = profile->GetPrefs();
146   const PrefService::Preference* pref =
147       prefs->FindPreference(kWhitelist[index]);
148
149   if (!pref)
150     return;
151
152   // Get our own copy of the user defined value or NULL if they are using the
153   // default. You have to make a copy since they'll be used in the destructor
154   // to restore the values and we need to make sure they're still around.
155   orig_values_[index] =
156       pref->IsDefaultValue() ? NULL : pref->GetValue()->DeepCopy();
157 }