summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-15 20:36:54 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-15 20:36:54 +0000
commita4c1eb2d00a9c66b4fc809916081cc727c998414 (patch)
tree3f2c99c52bf2f8b25a8ea243e7c238304f7ff844 /chrome
parent1ed78a31b405c4b85a3747d697e464508e7c4399 (diff)
downloadchromium_src-a4c1eb2d00a9c66b4fc809916081cc727c998414.zip
chromium_src-a4c1eb2d00a9c66b4fc809916081cc727c998414.tar.gz
chromium_src-a4c1eb2d00a9c66b4fc809916081cc727c998414.tar.bz2
Forgot to svn add files when landing patch.
BUG=none TEST=none Review URL: http://codereview.chromium.org/193115 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26261 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/chromeos/settings_contents_view.cc507
-rw-r--r--chrome/browser/chromeos/settings_contents_view.h23
-rw-r--r--chrome/browser/chromeos/touchpad.cc98
-rw-r--r--chrome/browser/chromeos/touchpad.h57
4 files changed, 685 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/settings_contents_view.cc b/chrome/browser/chromeos/settings_contents_view.cc
new file mode 100644
index 0000000..467c037
--- /dev/null
+++ b/chrome/browser/chromeos/settings_contents_view.cc
@@ -0,0 +1,507 @@
+// Copyright (c) 2009 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.
+
+#include "chrome/browser/chromeos/settings_contents_view.h"
+
+#include <map>
+#include <vector>
+
+#include "app/combobox_model.h"
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/basictypes.h"
+#include "base/string_util.h"
+#include "chrome/common/pref_member.h"
+#include "chrome/common/pref_names.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "views/background.h"
+#include "views/controls/button/checkbox.h"
+#include "views/controls/combobox/combobox.h"
+#include "views/controls/textfield/textfield.h"
+#include "views/grid_layout.h"
+#include "views/standard_layout.h"
+#include "views/window/dialog_delegate.h"
+#include "views/window/window.h"
+
+using views::GridLayout;
+using views::ColumnSet;
+
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+// WifiSSIDComboModel
+
+// The Combobox model for the list of wifi networks
+class WifiSSIDComboModel : public ComboboxModel {
+ public:
+ struct NetworkData {
+ NetworkData() { }
+ NetworkData(const string16& encryption, const int& strength)
+ : encryption(encryption),
+ strength(strength) { }
+
+ string16 encryption;
+ int strength;
+ };
+ typedef std::map<string16, NetworkData> NetworkDataMap;
+
+ WifiSSIDComboModel();
+
+ virtual int GetItemCount();
+ virtual std::wstring GetItemAt(int index);
+
+ const string16& GetSSIDAt(int index);
+ bool RequiresPassword(const string16& ssid);
+
+ private:
+ std::vector<string16> ssids_;
+
+ // A map of some extra data (NetworkData) keyed off the ssids.
+ NetworkDataMap ssids_map_;
+
+ void AddWifiNetwork(const string16& ssid,
+ const string16& encryption,
+ int strength);
+
+ DISALLOW_COPY_AND_ASSIGN(WifiSSIDComboModel);
+};
+
+WifiSSIDComboModel::WifiSSIDComboModel() {
+ // TODO(chocobo): Load wifi info from conman.
+ // This is just temporary data until we hook this up to real data.
+ AddWifiNetwork(ASCIIToUTF16("Wifi Combobox Mock"), string16(), 80);
+ AddWifiNetwork(ASCIIToUTF16("Wifi WPA-PSK Password is chronos"),
+ ASCIIToUTF16("WPA-PSK"), 60);
+ AddWifiNetwork(ASCIIToUTF16("Wifi No Encryption"), string16(), 90);
+}
+
+int WifiSSIDComboModel::GetItemCount() {
+ return static_cast<int>(ssids_.size());
+}
+
+std::wstring WifiSSIDComboModel::GetItemAt(int index) {
+ DCHECK(static_cast<int>(ssids_.size()) > index);
+
+ NetworkDataMap::const_iterator it = ssids_map_.find(ssids_[index]);
+ DCHECK(it != ssids_map_.end());
+
+ // TODO(chocobo): Finalize UI, then put strings in resource file.
+ std::vector<string16> subst;
+ subst.push_back(it->first); // $1
+ // The "None" string is just temporary for now. Have not finalized the UI yet.
+ if (it->second.encryption.empty())
+ subst.push_back(ASCIIToUTF16("None")); // $2
+ else
+ subst.push_back(it->second.encryption); // $2
+ subst.push_back(IntToString16(it->second.strength)); // $3
+
+ return UTF16ToWide(
+ ReplaceStringPlaceholders(ASCIIToUTF16("$1 ($2, $3)"), subst, NULL));
+}
+
+const string16& WifiSSIDComboModel::GetSSIDAt(int index) {
+ DCHECK(static_cast<int>(ssids_.size()) > index);
+ return ssids_[index];
+}
+
+bool WifiSSIDComboModel::RequiresPassword(const string16& ssid) {
+ NetworkDataMap::const_iterator it = ssids_map_.find(ssid);
+ DCHECK(it != ssids_map_.end());
+ return !it->second.encryption.empty();
+}
+
+void WifiSSIDComboModel::AddWifiNetwork(const string16& ssid,
+ const string16& encryption,
+ int strength) {
+ ssids_.push_back(ssid);
+ ssids_map_[ssid] = NetworkData(encryption, strength);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NetworkSection
+
+// Network section for wifi settings
+class NetworkSection : public OptionsPageView,
+ public views::Combobox::Listener {
+ public:
+ explicit NetworkSection(Profile* profile);
+ virtual ~NetworkSection() {}
+
+ // Overridden from views::Combobox::Listener:
+ virtual void ItemChanged(views::Combobox* sender,
+ int prev_index,
+ int new_index);
+
+ bool OnPasswordWindowCancel();
+ bool OnPasswordWindowAccept(const string16& password);
+ bool ConnectToWifi(const string16& ssid, const string16& password);
+
+ protected:
+ // OptionsPageView overrides:
+ virtual void InitControlLayout();
+ virtual void InitContents();
+
+ private:
+ // The View that contains the contents of the section.
+ views::View* contents_;
+
+ // Controls for this section:
+ views::Combobox* wifi_ssid_combobox_;
+
+ // Used to store the index (in combobox) of the currently connected wifi.
+ int last_selected_wifi_ssid_index_;
+
+ // Dummy for now. Used to populate wifi ssid models.
+ WifiSSIDComboModel wifi_ssid_model_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkSection);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// PasswordWindowView
+
+static const int kDialogPadding = 7;
+
+// A view for showing a password textfield
+class PasswordWindowView : public views::View,
+ public views::DialogDelegate {
+ public:
+ PasswordWindowView(NetworkSection* network_delegate, Profile* profile);
+ views::Window* container() const { return container_; }
+ void set_container(views::Window* container) {
+ container_ = container;
+ }
+
+ // views::DialogDelegate methods.
+ virtual bool Cancel();
+ virtual bool Accept();
+ virtual std::wstring GetWindowTitle() const;
+
+ // views::WindowDelegate method.
+ virtual bool IsModal() const { return true; }
+ virtual views::View* GetContentsView() { return this; }
+
+ // views::View overrides.
+ virtual void Layout();
+ virtual gfx::Size GetPreferredSize();
+
+ protected:
+ virtual void ViewHierarchyChanged(bool is_add, views::View* parent,
+ views::View* child);
+
+ private:
+ void Init();
+
+ // The Options dialog window.
+ views::Window* container_;
+
+ // Used for Call back to NetworkSection that password has been entered.
+ NetworkSection* network_delegate_;
+
+ // Combobox and its corresponding model.
+ views::Textfield* password_textfield_;
+
+ DISALLOW_COPY_AND_ASSIGN(PasswordWindowView);
+};
+
+PasswordWindowView::PasswordWindowView(
+ NetworkSection* network_delegate,
+ Profile* profile)
+ : network_delegate_(network_delegate),
+ password_textfield_(NULL) {
+ Init();
+}
+
+std::wstring PasswordWindowView::GetWindowTitle() const {
+ return l10n_util::GetString(IDS_OPTIONS_SETTINGS_SECTION_TITLE_PASSWORD);
+}
+
+bool PasswordWindowView::Cancel() {
+ return network_delegate_->OnPasswordWindowCancel();
+}
+
+bool PasswordWindowView::Accept() {
+ // TODO(chocobo): we should not need to call SyncText ourself here.
+ password_textfield_->SyncText();
+ return network_delegate_->OnPasswordWindowAccept(password_textfield_->text());
+}
+
+void PasswordWindowView::Layout() {
+ gfx::Size sz = password_textfield_->GetPreferredSize();
+ password_textfield_->SetBounds(kDialogPadding, kDialogPadding,
+ width() - 2*kDialogPadding,
+ sz.height());
+}
+
+gfx::Size PasswordWindowView::GetPreferredSize() {
+ // TODO(chocobo): Create our own localized content size once the UI is done.
+ return gfx::Size(views::Window::GetLocalizedContentsSize(
+ IDS_ABOUT_DIALOG_WIDTH_CHARS,
+ IDS_ABOUT_DIALOG_MINIMUM_HEIGHT_LINES));
+}
+
+void PasswordWindowView::ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
+ if (is_add && child == this)
+ Init();
+}
+
+void PasswordWindowView::Init() {
+ password_textfield_ = new views::Textfield(views::Textfield::STYLE_PASSWORD);
+ AddChildView(password_textfield_);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NetworkSection
+
+NetworkSection::NetworkSection(Profile* profile)
+ : OptionsPageView(profile),
+ contents_(NULL),
+ wifi_ssid_combobox_(NULL),
+ last_selected_wifi_ssid_index_(0) {
+}
+
+void NetworkSection::ItemChanged(views::Combobox* sender,
+ int prev_index,
+ int new_index) {
+ if (new_index == prev_index)
+ return;
+ if (sender == wifi_ssid_combobox_) {
+ last_selected_wifi_ssid_index_ = prev_index;
+ string16 ssid = wifi_ssid_model_.GetSSIDAt(new_index);
+ // Connect to wifi here. Open password page if appropriate
+ if (wifi_ssid_model_.RequiresPassword(ssid)) {
+ views::Window* window = views::Window::CreateChromeWindow(
+ NULL,
+ gfx::Rect(),
+ new PasswordWindowView(this, profile()));
+ window->Show();
+ } else {
+ ConnectToWifi(ssid, string16());
+ }
+ }
+}
+
+bool NetworkSection::OnPasswordWindowCancel() {
+ // Change combobox to previous setting
+ wifi_ssid_combobox_->SetSelectedItem(last_selected_wifi_ssid_index_);
+ return true;
+}
+
+bool NetworkSection::OnPasswordWindowAccept(const string16& password) {
+ // Try connecting to wifi
+ return ConnectToWifi(wifi_ssid_model_.GetSSIDAt(
+ wifi_ssid_combobox_->selected_item()), password);
+}
+
+bool NetworkSection::ConnectToWifi(const string16& ssid,
+ const string16& password) {
+ // TODO(chocobo): Connect to wifi
+ return password == ASCIIToUTF16("chronos");
+}
+
+void NetworkSection::InitControlLayout() {
+ GridLayout* layout = new GridLayout(this);
+ SetLayoutManager(layout);
+
+ int single_column_layout_id = 0;
+ ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
+ GridLayout::USE_PREF, 0, 0);
+ int inset_column_layout_id = 1;
+ column_set = layout->AddColumnSet(inset_column_layout_id);
+ column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, single_column_layout_id);
+ views::Label* title_label = new views::Label(
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SECTION_TITLE_NETWORK));
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ gfx::Font title_font =
+ rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD);
+ title_label->SetFont(title_font);
+ layout->AddView(title_label);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ layout->StartRow(0, inset_column_layout_id);
+ InitContents();
+ layout->AddView(contents_);
+}
+
+void NetworkSection::InitContents() {
+ contents_ = new views::View;
+ GridLayout* layout = new GridLayout(contents_);
+ contents_->SetLayoutManager(layout);
+
+ wifi_ssid_combobox_ = new views::Combobox(&wifi_ssid_model_);
+ wifi_ssid_combobox_->set_listener(this);
+
+ int single_column_view_set_id = 0;
+ ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, single_column_view_set_id);
+ layout->AddView(wifi_ssid_combobox_);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TouchpadSection
+
+class TouchpadSection : public OptionsPageView,
+ public views::ButtonListener {
+ public:
+ explicit TouchpadSection(Profile* profile);
+ virtual ~TouchpadSection() {}
+
+ // Overridden from views::ButtonListener:
+ virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+
+ protected:
+ // OptionsPageView overrides:
+ virtual void InitControlLayout();
+ virtual void InitContents();
+ virtual void NotifyPrefChanged(const std::wstring* pref_name);
+
+ private:
+ // The View that contains the contents of the section.
+ views::View* contents_;
+
+ // Controls for this section:
+ views::Checkbox* enable_tap_to_click_checkbox_;
+ views::Checkbox* enable_vert_edge_scroll_checkbox_;
+
+ // Preferences for this section:
+ BooleanPrefMember tap_to_click_enabled_;
+ BooleanPrefMember vert_edge_scroll_enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchpadSection);
+};
+
+TouchpadSection::TouchpadSection(Profile* profile)
+ : OptionsPageView(profile),
+ contents_(NULL),
+ enable_tap_to_click_checkbox_(NULL),
+ enable_vert_edge_scroll_checkbox_(NULL) {
+}
+
+void TouchpadSection::ButtonPressed(
+ views::Button* sender, const views::Event& event) {
+ if (sender == enable_tap_to_click_checkbox_) {
+ bool enabled = enable_tap_to_click_checkbox_->checked();
+ UserMetricsRecordAction(enabled ?
+ L"Options_TapToClickCheckbox_Enable" :
+ L"Options_TapToClickCheckbox_Disable",
+ profile()->GetPrefs());
+ tap_to_click_enabled_.SetValue(enabled);
+ } else if (sender == enable_vert_edge_scroll_checkbox_) {
+ bool enabled = enable_vert_edge_scroll_checkbox_->checked();
+ UserMetricsRecordAction(enabled ?
+ L"Options_VertEdgeScrollCheckbox_Enable" :
+ L"Options_VertEdgeScrollCheckbox_Disable",
+ profile()->GetPrefs());
+ vert_edge_scroll_enabled_.SetValue(enabled);
+ }
+}
+
+void TouchpadSection::InitControlLayout() {
+ GridLayout* layout = new GridLayout(this);
+ SetLayoutManager(layout);
+
+ int single_column_layout_id = 0;
+ ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
+ GridLayout::USE_PREF, 0, 0);
+ int inset_column_layout_id = 1;
+ column_set = layout->AddColumnSet(inset_column_layout_id);
+ column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, single_column_layout_id);
+ views::Label* title_label = new views::Label(
+ l10n_util::GetString(IDS_OPTIONS_SETTINGS_SECTION_TITLE_TOUCHPAD));
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ gfx::Font title_font =
+ rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD);
+ title_label->SetFont(title_font);
+ layout->AddView(title_label);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ layout->StartRow(0, inset_column_layout_id);
+ InitContents();
+ layout->AddView(contents_);
+}
+
+void TouchpadSection::InitContents() {
+ contents_ = new views::View;
+ GridLayout* layout = new GridLayout(contents_);
+ contents_->SetLayoutManager(layout);
+
+ enable_tap_to_click_checkbox_ = new views::Checkbox(l10n_util::GetString(
+ IDS_OPTIONS_SETTINGS_TAP_TO_CLICK_ENABLED_DESCRIPTION));
+ enable_tap_to_click_checkbox_->set_listener(this);
+ enable_tap_to_click_checkbox_->SetMultiLine(true);
+ enable_vert_edge_scroll_checkbox_ = new views::Checkbox(l10n_util::GetString(
+ IDS_OPTIONS_SETTINGS_VERT_EDGE_SCROLL_ENABLED_DESCRIPTION));
+ enable_vert_edge_scroll_checkbox_->set_listener(this);
+ enable_vert_edge_scroll_checkbox_->SetMultiLine(true);
+
+ int single_column_view_set_id = 0;
+ ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, single_column_view_set_id);
+ layout->AddView(enable_tap_to_click_checkbox_);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ layout->StartRow(0, single_column_view_set_id);
+ layout->AddView(enable_vert_edge_scroll_checkbox_);
+ layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
+
+ // Init member prefs so we can update the controls if prefs change.
+ tap_to_click_enabled_.Init(prefs::kTapToClickEnabled,
+ profile()->GetPrefs(), this);
+ vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled,
+ profile()->GetPrefs(), this);
+}
+
+void TouchpadSection::NotifyPrefChanged(const std::wstring* pref_name) {
+ if (!pref_name || *pref_name == prefs::kTapToClickEnabled) {
+ bool enabled = tap_to_click_enabled_.GetValue();
+ enable_tap_to_click_checkbox_->SetChecked(enabled);
+ }
+ if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled) {
+ bool enabled = vert_edge_scroll_enabled_.GetValue();
+ enable_vert_edge_scroll_checkbox_->SetChecked(enabled);
+ }
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// SettingsContentsView
+
+////////////////////////////////////////////////////////////////////////////////
+// SettingsContentsView, OptionsPageView implementation:
+
+void SettingsContentsView::InitControlLayout() {
+ GridLayout* layout = CreatePanelGridLayout(this);
+ SetLayoutManager(layout);
+
+ int single_column_view_set_id = 0;
+ ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, single_column_view_set_id);
+ layout->AddView(new NetworkSection(profile()));
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ layout->StartRow(0, single_column_view_set_id);
+ layout->AddView(new TouchpadSection(profile()));
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+}
diff --git a/chrome/browser/chromeos/settings_contents_view.h b/chrome/browser/chromeos/settings_contents_view.h
new file mode 100644
index 0000000..2a35028
--- /dev/null
+++ b/chrome/browser/chromeos/settings_contents_view.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2006-2008 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_CHROMEOS_SETTINGS_CONTENTS_VIEW_H_
+#define CHROME_BROWSER_CHROMEOS_SETTINGS_CONTENTS_VIEW_H_
+
+#include "chrome/browser/views/options/options_page_view.h"
+
+// Contents of the settings page for Chrome OS
+class SettingsContentsView : public OptionsPageView {
+ public:
+ explicit SettingsContentsView(Profile* profile) : OptionsPageView(profile) {}
+ virtual ~SettingsContentsView() {}
+
+ protected:
+ // OptionsPageView implementation:
+ virtual void InitControlLayout();
+
+ DISALLOW_COPY_AND_ASSIGN(SettingsContentsView);
+};
+
+#endif // CHROME_BROWSER_CHROMEOS_SETTINGS_CONTENTS_VIEW_H_
diff --git a/chrome/browser/chromeos/touchpad.cc b/chrome/browser/chromeos/touchpad.cc
new file mode 100644
index 0000000..f0ae97b
--- /dev/null
+++ b/chrome/browser/chromeos/touchpad.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2009 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.
+
+#include "chrome/browser/chromeos/touchpad.h"
+
+#include <stdlib.h>
+#include <string>
+#include <vector>
+
+#include "base/string_util.h"
+#include "base/process_util.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/pref_member.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+
+// Allows InvokeLater without adding refcounting. The object is only deleted
+// when its last InvokeLater is run anyway.
+template<>
+void RunnableMethodTraits<Touchpad>::RetainCallee(
+ Touchpad* remover) {
+}
+template<>
+void RunnableMethodTraits<Touchpad>::ReleaseCallee(
+ Touchpad* remover) {
+}
+
+// static
+void Touchpad::RegisterUserPrefs(PrefService* prefs) {
+ prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, true);
+ prefs->RegisterBooleanPref(prefs::kVertEdgeScrollEnabled, true);
+}
+
+void Touchpad::Init(PrefService* prefs) {
+ tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, this);
+ vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled, prefs, this);
+
+ // Initialize touchpad settings to what's saved in user preferences.
+ SetTapToClick();
+ SetVertEdgeScroll();
+}
+
+void Touchpad::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::PREF_CHANGED)
+ NotifyPrefChanged(Details<std::wstring>(details).ptr());
+}
+
+void Touchpad::NotifyPrefChanged(const std::wstring* pref_name) {
+ if (!pref_name || *pref_name == prefs::kTapToClickEnabled)
+ SetTapToClick();
+ if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled)
+ SetVertEdgeScroll();
+}
+
+void Touchpad::SetSynclientParam(const std::string& param,
+ const std::string& value) {
+ // If not running on the file thread, then re-run on the file thread.
+ if (!ChromeThread::CurrentlyOn(ChromeThread::FILE)) {
+ base::Thread* file_thread = g_browser_process->file_thread();
+ if (file_thread)
+ file_thread->message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &Touchpad::SetSynclientParam, param, value));
+ } else {
+ // launch binary synclient to set the parameter
+ std::vector<std::string> argv;
+ argv.push_back("/usr/bin/synclient");
+ argv.push_back(param + "=" + value);
+ base::file_handle_mapping_vector no_files;
+ base::ProcessHandle handle;
+ if (!base::LaunchApp(argv, no_files, true, &handle))
+ LOG(ERROR) << "Failed to call /usr/bin/synclient";
+ }
+}
+
+void Touchpad::SetTapToClick() {
+ // To disable tap-to-click (i.e. a tap on the touchpad is recognized as a left
+ // mouse click event), we set MaxTapTime to 0. MaxTapTime is the maximum time
+ // (in milliseconds) for detecting a tap. The default is 180.
+ if (tap_to_click_enabled_.GetValue())
+ SetSynclientParam("MaxTapTime", "180");
+ else
+ SetSynclientParam("MaxTapTime", "0");
+}
+
+void Touchpad::SetVertEdgeScroll() {
+ // To disable vertical edge scroll, we set VertEdgeScroll to 0. Vertical edge
+ // scroll lets you use the right edge of the touchpad to control the movement
+ // of the vertical scroll bar.
+ if (vert_edge_scroll_enabled_.GetValue())
+ SetSynclientParam("VertEdgeScroll", "1");
+ else
+ SetSynclientParam("VertEdgeScroll", "0");
+}
diff --git a/chrome/browser/chromeos/touchpad.h b/chrome/browser/chromeos/touchpad.h
new file mode 100644
index 0000000..92679d2
--- /dev/null
+++ b/chrome/browser/chromeos/touchpad.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2006-2008 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_CHROMEOS_TOUCHPAD_H_
+#define CHROME_BROWSER_CHROMEOS_TOUCHPAD_H_
+
+#include <string>
+
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/pref_member.h"
+
+class PrefService;
+
+// The Touchpad class handles touchpad preferences. When the class is first
+// initialized, it will initialize the touchpad settings to what's stored in the
+// preferences. And whenever the preference changes, we change the touchpad
+// setting to reflect the new value.
+//
+// For Synaptics touchpads, we use synclient to change settings on-the-fly.
+// See "man synaptics" for a list of settings that can be changed
+// Since we are doing a system call to run the synclient binary, we make sure
+// that we are running on the IO thread so that we don't block the UI thread.
+class Touchpad : public NotificationObserver {
+ public:
+ explicit Touchpad() {}
+ virtual ~Touchpad() {}
+
+ // This method will register the prefs associated with touchpad settings.
+ static void RegisterUserPrefs(PrefService* prefs);
+
+ // This method will initialize touchpad settings to values in user prefs.
+ virtual void Init(PrefService* prefs);
+
+ // Overridden from NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ protected:
+ virtual void NotifyPrefChanged(const std::wstring* pref_name);
+
+ private:
+ // This methods makes a system call to synclient to change touchpad settings.
+ // The system call will be invoked on the file thread.
+ void SetSynclientParam(const std::string& param, const std::string& value);
+
+ void SetTapToClick();
+ void SetVertEdgeScroll();
+
+ BooleanPrefMember tap_to_click_enabled_;
+ BooleanPrefMember vert_edge_scroll_enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(Touchpad);
+};
+
+#endif // CHROME_BROWSER_CHROMEOS_TOUCHPAD_H_