summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormichaelpg@chromium.org <michaelpg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-28 05:47:00 +0000
committermichaelpg@chromium.org <michaelpg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-28 05:47:00 +0000
commitdd0bf461376beee097367a82c78ab70abc41744e (patch)
tree70e576cff99599a320c6d087c950a67bc6858d25
parent3e9fc2f543b884e8cd35417605abf1075205e8e8 (diff)
downloadchromium_src-dd0bf461376beee097367a82c78ab70abc41744e.zip
chromium_src-dd0bf461376beee097367a82c78ab70abc41744e.tar.gz
chromium_src-dd0bf461376beee097367a82c78ab70abc41744e.tar.bz2
Date and Time dialog for when the clock isn't synced.
If the time has not been set automatically via network syncing, the system clock can be changed. This dialog allows the user to change the date, time and time zone when possible. The motivation is to unbrick devices with the wrong time that need to be rolled out into time-sensitive networks. Documentation of the changes to Chrome OS and Ash for this CL is here: https://docs.google.com/a/google.com/drawings/d/1T3demthtROnXf1iE31p5aIPcQzK9SmjfE9EjnJbZ4zs System Time Manual Update UI design doc: https://docs.google.com/a/google.com/document/d/1djzhBrtbx-52Gctp3Fd5MIosARbTwQh_lMmd_qUnqgo Screenshot with timezone: https://drive.google.com/a/google.com/file/d/0B6HSBrih6pNUd3p2SFBoVktjVzQ Screenshot from settings page, no timezone: https://drive.google.com/a/google.com/file/d/0B6HSBrih6pNUXzk0TjNiT0tKMTQ BUG=232066 TEST=SetTimeWebUITest, DateTimeOptionsWebUITest R=stevenjb@chromium.org,nkostylev@chromium.org,dbeam@chromium.org,derat@chromium.org,asvitkine@chromium.org TBR=sky@chromium.org # TBR for adding resources to chrome/browser/chrome_resources.grd Please review: stevenjb@chromium.org - ash/system - chromeos/dbus derat@chromium.org: - chrome/browser/chromeos - chrome/browser/ui/ash - chromeos/dbus (optional) nkostylev@chromium.org: - chrome/app - chrome/browser/chromeos - chrome/browser/resources/chromeos - chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc - chrome/browser/ui/webui/chromeos - chrome/browser/ui/webui/options/chromeos - chrome/browser/browser_resources.grd - chrome/chrome_*.gypi - chrome/common dbeam@chromium.org: - chrome/browser/resources/options - chrome/browser/ui/webui/options/*.cc sky@chromium.org: - chrome/browser/browser_resources.grd Review URL: https://codereview.chromium.org/247663003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266431 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/system/chromeos/system_clock_observer.cc9
-rw-r--r--ash/system/chromeos/system_clock_observer.h5
-rw-r--r--ash/system/date/clock_observer.h1
-rw-r--r--ash/system/date/date_default_view.cc2
-rw-r--r--ash/system/date/date_view.cc22
-rw-r--r--ash/system/date/date_view.h8
-rw-r--r--ash/system/date/tray_date.cc19
-rw-r--r--ash/system/date/tray_date.h13
-rw-r--r--ash/system/tray/default_system_tray_delegate.cc3
-rw-r--r--ash/system/tray/default_system_tray_delegate.h1
-rw-r--r--ash/system/tray/system_tray_delegate.h3
-rw-r--r--ash/system/tray/system_tray_notifier.cc6
-rw-r--r--ash/system/tray/system_tray_notifier.h1
-rw-r--r--chrome/app/chromeos_strings.grdp22
-rw-r--r--chrome/browser/browser_resources.grd5
-rw-r--r--chrome/browser/chromeos/set_time_dialog.cc85
-rw-r--r--chrome/browser/chromeos/set_time_dialog.h46
-rw-r--r--chrome/browser/resources/chromeos/set_time.css45
-rw-r--r--chrome/browser/resources/chromeos/set_time.html39
-rw-r--r--chrome/browser/resources/chromeos/set_time.js200
-rw-r--r--chrome/browser/resources/options/browser_options.html8
-rw-r--r--chrome/browser/resources/options/browser_options.js26
-rw-r--r--chrome/browser/ui/ash/system_tray_delegate_chromeos.cc5
-rw-r--r--chrome/browser/ui/ash/system_tray_delegate_chromeos.h1
-rw-r--r--chrome/browser/ui/ash/system_tray_delegate_win.cc3
-rw-r--r--chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc3
-rw-r--r--chrome/browser/ui/webui/chromeos/set_time_ui.cc146
-rw-r--r--chrome/browser/ui/webui/chromeos/set_time_ui.h25
-rw-r--r--chrome/browser/ui/webui/chromeos/set_time_ui_browsertest.js37
-rw-r--r--chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js38
-rw-r--r--chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc81
-rw-r--r--chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h47
-rw-r--r--chrome/browser/ui/webui/options/options_ui.cc3
-rw-r--r--chrome/chrome_browser_chromeos.gypi2
-rw-r--r--chrome/chrome_browser_ui.gypi4
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--chrome/common/url_constants.cc2
-rw-r--r--chrome/common/url_constants.h2
-rw-r--r--chromeos/dbus/fake_system_clock_client.cc7
-rw-r--r--chromeos/dbus/fake_system_clock_client.h2
-rw-r--r--chromeos/dbus/system_clock_client.cc76
-rw-r--r--chromeos/dbus/system_clock_client.h18
-rw-r--r--tools/metrics/actions/actions.xml5
43 files changed, 1051 insertions, 27 deletions
diff --git a/ash/system/chromeos/system_clock_observer.cc b/ash/system/chromeos/system_clock_observer.cc
index d154d5e..5ed6330 100644
--- a/ash/system/chromeos/system_clock_observer.cc
+++ b/ash/system/chromeos/system_clock_observer.cc
@@ -14,6 +14,8 @@ SystemClockObserver::SystemClockObserver() {
chromeos::DBusThreadManager::Get()->GetSystemClockClient()
->AddObserver(this);
chromeos::system::TimezoneSettings::GetInstance()->AddObserver(this);
+ can_set_time_ =
+ chromeos::DBusThreadManager::Get()->GetSystemClockClient()->CanSetTime();
}
SystemClockObserver::~SystemClockObserver() {
@@ -23,8 +25,13 @@ SystemClockObserver::~SystemClockObserver() {
}
void SystemClockObserver::SystemClockUpdated() {
+ Shell::GetInstance()->system_tray_notifier()->NotifySystemClockTimeUpdated();
+}
+
+void SystemClockObserver::SystemClockCanSetTimeChanged(bool can_set_time) {
+ can_set_time_ = can_set_time;
Shell::GetInstance()->system_tray_notifier()
- ->NotifySystemClockTimeUpdated();
+ ->NotifySystemClockCanSetTimeChanged(can_set_time_);
}
void SystemClockObserver::TimezoneChanged(const icu::TimeZone& timezone) {
diff --git a/ash/system/chromeos/system_clock_observer.h b/ash/system/chromeos/system_clock_observer.h
index dcc11ee..5d4c4d6 100644
--- a/ash/system/chromeos/system_clock_observer.h
+++ b/ash/system/chromeos/system_clock_observer.h
@@ -19,11 +19,16 @@ class SystemClockObserver
// chromeos::SystemClockClient::Observer
virtual void SystemClockUpdated() OVERRIDE;
+ virtual void SystemClockCanSetTimeChanged(bool can_set_time) OVERRIDE;
// chromeos::system::TimezoneSettings::Observer
virtual void TimezoneChanged(const icu::TimeZone& timezone) OVERRIDE;
+ bool can_set_time() { return can_set_time_; }
+
private:
+ bool can_set_time_;
+
DISALLOW_COPY_AND_ASSIGN(SystemClockObserver);
};
diff --git a/ash/system/date/clock_observer.h b/ash/system/date/clock_observer.h
index b3d9ece..a62e2be 100644
--- a/ash/system/date/clock_observer.h
+++ b/ash/system/date/clock_observer.h
@@ -15,6 +15,7 @@ class ASH_EXPORT ClockObserver {
virtual void OnDateFormatChanged() = 0;
virtual void OnSystemClockTimeUpdated() = 0;
+ virtual void OnSystemClockCanSetTimeChanged(bool can_set_time) = 0;
// Force a refresh (e.g. after the system is resumed).
virtual void Refresh() = 0;
diff --git a/ash/system/date/date_default_view.cc b/ash/system/date/date_default_view.cc
index e72e048..389485f 100644
--- a/ash/system/date/date_default_view.cc
+++ b/ash/system/date/date_default_view.cc
@@ -46,7 +46,7 @@ DateDefaultView::DateDefaultView(ash::user::LoginStatus login)
login == ash::user::LOGGED_IN_NONE)
return;
- date_view_->SetActionable(true);
+ date_view_->SetAction(TrayDate::SHOW_DATE_SETTINGS);
help_ = new TrayPopupHeaderButton(this,
IDR_AURA_UBER_TRAY_HELP,
diff --git a/ash/system/date/date_view.cc b/ash/system/date/date_view.cc
index 26f910d..6bdd83e 100644
--- a/ash/system/date/date_view.cc
+++ b/ash/system/date/date_view.cc
@@ -128,7 +128,7 @@ void BaseDateTimeView::OnLocaleChanged() {
DateView::DateView()
: hour_type_(ash::Shell::GetInstance()->system_tray_delegate()->
GetHourClockType()),
- actionable_(false) {
+ action_(TrayDate::NONE) {
SetLayoutManager(
new views::BoxLayout(
views::BoxLayout::kVertical, 0, 0, 0));
@@ -136,15 +136,15 @@ DateView::DateView()
date_label_->SetEnabledColor(kHeaderTextColorNormal);
UpdateTextInternal(base::Time::Now());
AddChildView(date_label_);
- SetFocusable(actionable_);
+ SetFocusable(false);
}
DateView::~DateView() {
}
-void DateView::SetActionable(bool actionable) {
- actionable_ = actionable;
- SetFocusable(actionable_);
+void DateView::SetAction(TrayDate::DateAction action) {
+ action_ = action;
+ SetFocusable(action_ != TrayDate::NONE);
}
void DateView::UpdateTimeFormat() {
@@ -169,22 +169,24 @@ void DateView::UpdateTextInternal(const base::Time& now) {
}
bool DateView::PerformAction(const ui::Event& event) {
- if (!actionable_)
+ if (action_ == TrayDate::NONE)
return false;
-
- ash::Shell::GetInstance()->system_tray_delegate()->ShowDateSettings();
+ if (action_ == TrayDate::SHOW_DATE_SETTINGS)
+ ash::Shell::GetInstance()->system_tray_delegate()->ShowDateSettings();
+ else if (action_ == TrayDate::SET_SYSTEM_TIME)
+ ash::Shell::GetInstance()->system_tray_delegate()->ShowSetTimeDialog();
return true;
}
void DateView::OnMouseEntered(const ui::MouseEvent& event) {
- if (!actionable_)
+ if (action_ == TrayDate::NONE)
return;
date_label_->SetEnabledColor(kHeaderTextColorHover);
SchedulePaint();
}
void DateView::OnMouseExited(const ui::MouseEvent& event) {
- if (!actionable_)
+ if (action_ == TrayDate::NONE)
return;
date_label_->SetEnabledColor(kHeaderTextColorNormal);
SchedulePaint();
diff --git a/ash/system/date/date_view.h b/ash/system/date/date_view.h
index 7d03a9a..1f4377a 100644
--- a/ash/system/date/date_view.h
+++ b/ash/system/date/date_view.h
@@ -55,10 +55,10 @@ class ASH_EXPORT DateView : public BaseDateTimeView {
DateView();
virtual ~DateView();
- // Sets whether the view is actionable. An actionable date view gives visual
+ // Sets the action the view should take. An actionable date view gives visual
// feedback on hover, can be focused by keyboard, and clicking/pressing space
- // or enter on the view shows date-related settings.
- void SetActionable(bool actionable);
+ // or enter on the view executes the action.
+ void SetAction(TrayDate::DateAction action);
// Updates the format of the displayed time.
void UpdateTimeFormat();
@@ -81,7 +81,7 @@ class ASH_EXPORT DateView : public BaseDateTimeView {
// Time format (12/24hr) used for accessibility string.
base::HourClockType hour_type_;
- bool actionable_;
+ TrayDate::DateAction action_;
DISALLOW_COPY_AND_ASSIGN(DateView);
};
diff --git a/ash/system/date/tray_date.cc b/ash/system/date/tray_date.cc
index 156d355..8a574fe 100644
--- a/ash/system/date/tray_date.cc
+++ b/ash/system/date/tray_date.cc
@@ -20,7 +20,8 @@ namespace ash {
TrayDate::TrayDate(SystemTray* system_tray)
: SystemTrayItem(system_tray),
time_tray_(NULL),
- default_view_(NULL) {
+ default_view_(NULL),
+ login_status_(user::LOGGED_IN_NONE) {
#if defined(OS_CHROMEOS)
system_clock_observer_.reset(new SystemClockObserver());
#endif
@@ -63,6 +64,13 @@ views::View* TrayDate::CreateTrayView(user::LoginStatus status) {
views::View* TrayDate::CreateDefaultView(user::LoginStatus status) {
default_view_ = new DateDefaultView(status);
+
+#if defined(OS_CHROMEOS)
+ // Save the login status we created the view with.
+ login_status_ = status;
+
+ OnSystemClockCanSetTimeChanged(system_clock_observer_->can_set_time());
+#endif
return default_view_;
}
@@ -107,6 +115,15 @@ void TrayDate::OnSystemClockTimeUpdated() {
default_view_->GetDateView()->UpdateTimeFormat();
}
+void TrayDate::OnSystemClockCanSetTimeChanged(bool can_set_time) {
+ // Outside of a logged-in session, the date button should launch the set time
+ // dialog if the time can be set.
+ if (default_view_ && login_status_ == user::LOGGED_IN_NONE) {
+ default_view_->GetDateView()->SetAction(
+ can_set_time ? TrayDate::SET_SYSTEM_TIME : TrayDate::NONE);
+ }
+}
+
void TrayDate::Refresh() {
if (time_tray_)
time_tray_->UpdateText();
diff --git a/ash/system/date/tray_date.h b/ash/system/date/tray_date.h
index 90c02e2..c84e86e 100644
--- a/ash/system/date/tray_date.h
+++ b/ash/system/date/tray_date.h
@@ -27,9 +27,16 @@ class TimeView;
class ASH_EXPORT TrayDate : public SystemTrayItem, public ClockObserver {
public:
enum ClockLayout {
- HORIZONTAL_CLOCK,
- VERTICAL_CLOCK,
+ HORIZONTAL_CLOCK,
+ VERTICAL_CLOCK,
};
+
+ enum DateAction {
+ NONE,
+ SET_SYSTEM_TIME,
+ SHOW_DATE_SETTINGS,
+ };
+
explicit TrayDate(SystemTray* system_tray);
virtual ~TrayDate();
@@ -55,12 +62,14 @@ class ASH_EXPORT TrayDate : public SystemTrayItem, public ClockObserver {
// Overridden from ClockObserver.
virtual void OnDateFormatChanged() OVERRIDE;
virtual void OnSystemClockTimeUpdated() OVERRIDE;
+ virtual void OnSystemClockCanSetTimeChanged(bool can_set_time) OVERRIDE;
virtual void Refresh() OVERRIDE;
void SetupLabelForTimeTray(views::Label* label);
tray::TimeView* time_tray_;
DateDefaultView* default_view_;
+ user::LoginStatus login_status_;
#if defined(OS_CHROMEOS)
scoped_ptr<SystemClockObserver> system_clock_observer_;
diff --git a/ash/system/tray/default_system_tray_delegate.cc b/ash/system/tray/default_system_tray_delegate.cc
index 2c20da7..5b254c1 100644
--- a/ash/system/tray/default_system_tray_delegate.cc
+++ b/ash/system/tray/default_system_tray_delegate.cc
@@ -104,6 +104,9 @@ bool DefaultSystemTrayDelegate::ShouldShowSettings() {
void DefaultSystemTrayDelegate::ShowDateSettings() {
}
+void DefaultSystemTrayDelegate::ShowSetTimeDialog() {
+}
+
void DefaultSystemTrayDelegate::ShowNetworkSettings(
const std::string& service_path) {
}
diff --git a/ash/system/tray/default_system_tray_delegate.h b/ash/system/tray/default_system_tray_delegate.h
index 0f0a63f..004d143 100644
--- a/ash/system/tray/default_system_tray_delegate.h
+++ b/ash/system/tray/default_system_tray_delegate.h
@@ -34,6 +34,7 @@ class ASH_EXPORT DefaultSystemTrayDelegate : public SystemTrayDelegate {
virtual void ShowSettings() OVERRIDE;
virtual bool ShouldShowSettings() OVERRIDE;
virtual void ShowDateSettings() OVERRIDE;
+ virtual void ShowSetTimeDialog() OVERRIDE;
virtual void ShowNetworkSettings(const std::string& service_path) OVERRIDE;
virtual void ShowBluetoothSettings() OVERRIDE;
virtual void ShowDisplaySettings() OVERRIDE;
diff --git a/ash/system/tray/system_tray_delegate.h b/ash/system/tray/system_tray_delegate.h
index 7e22f22..3e399eb 100644
--- a/ash/system/tray/system_tray_delegate.h
+++ b/ash/system/tray/system_tray_delegate.h
@@ -165,6 +165,9 @@ class ASH_EXPORT SystemTrayDelegate {
// Shows the settings related to date, timezone etc.
virtual void ShowDateSettings() = 0;
+ // Shows the dialog to set system time, date, and timezone.
+ virtual void ShowSetTimeDialog() = 0;
+
// Shows the settings related to network. If |service_path| is not empty,
// show the settings for that network.
virtual void ShowNetworkSettings(const std::string& service_path) = 0;
diff --git a/ash/system/tray/system_tray_notifier.cc b/ash/system/tray/system_tray_notifier.cc
index 3adafe1..ed858c3 100644
--- a/ash/system/tray/system_tray_notifier.cc
+++ b/ash/system/tray/system_tray_notifier.cc
@@ -260,6 +260,12 @@ void SystemTrayNotifier::NotifySystemClockTimeUpdated() {
OnSystemClockTimeUpdated());
}
+void SystemTrayNotifier::NotifySystemClockCanSetTimeChanged(bool can_set_time) {
+ FOR_EACH_OBSERVER(ClockObserver,
+ clock_observers_,
+ OnSystemClockCanSetTimeChanged(can_set_time));
+}
+
void SystemTrayNotifier::NotifyDriveJobUpdated(
const DriveOperationStatus& status) {
FOR_EACH_OBSERVER(DriveObserver,
diff --git a/ash/system/tray/system_tray_notifier.h b/ash/system/tray/system_tray_notifier.h
index 219b1a1..29cd9d2 100644
--- a/ash/system/tray/system_tray_notifier.h
+++ b/ash/system/tray/system_tray_notifier.h
@@ -115,6 +115,7 @@ class ASH_EXPORT SystemTrayNotifier {
void NotifyRefreshClock();
void NotifyDateFormatChanged();
void NotifySystemClockTimeUpdated();
+ void NotifySystemClockCanSetTimeChanged(bool can_set_time);
void NotifyDriveJobUpdated(const DriveOperationStatus& status);
void NotifyRefreshIME();
void NotifyLocaleChanged(LocaleObserver::Delegate* delegate,
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 0deeebb..bcff7a7 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1788,6 +1788,12 @@ Press any key to continue exploring.
<message name="IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY">
Accessibility
</message>
+ <message name="IDS_OPTIONS_SETTINGS_TIME_SYNCED_EXPLANATION" desc="In the settings tab, the text indicating that the date and time are set automatically.">
+ Date and time are set automatically.
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_SET_TIME_BUTTON" desc="In the settings tab, the prompt on the button to open a dialog to set date and time.">
+ Set date and time
+ </message>
<message name="IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION" desc="In the settings tab, the text next to the timezone combobox.">
Time zone:
</message>
@@ -5394,4 +5400,20 @@ All users must sign out to continue.
Enroll
</message>
+ <!-- Set time/date UI display strings -->
+ <message name="IDS_SET_TIME_TITLE" desc="Title of the set time/date UI.">
+ Check your system time
+ </message>
+ <message name="IDS_SET_TIME_PROMPT" desc="Text prompting the user to check and set the system time.">
+ Chrome was unable to set the system time. Please check the time below and correct it if needed.
+ </message>
+ <message name="IDS_SET_TIME_BUTTON_CLOSE" desc="Text for the button to close the window.">
+ Done
+ </message>
+ <message name="IDS_SET_TIME_DATE_LABEL" desc="Label for the date input element.">
+ System date
+ </message>
+ <message name="IDS_SET_TIME_TIME_LABEL" desc="Label for the time input element.">
+ System time
+ </message>
</grit-part>
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 6d50d5a..24bc6d9 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -409,6 +409,11 @@
<include name="IDR_GCM_INTERNALS_CSS" file="resources\gcm_internals.css" type="BINDATA" />
<include name="IDR_GCM_INTERNALS_JS" file="resources\gcm_internals.js" type="BINDATA" />
<include name="IDR_EASY_UNLOCK_MANIFEST" file="resources\easy_unlock\manifest.json" type="BINDATA" />
+ <if expr="chromeos">
+ <include name="IDR_SET_TIME_HTML" file="resources\chromeos\set_time.html" type="BINDATA" />
+ <include name="IDR_SET_TIME_CSS" file="resources\chromeos\set_time.css" type="BINDATA" />
+ <include name="IDR_SET_TIME_JS" file="resources\chromeos\set_time.js" type="BINDATA" />
+ </if>
</includes>
</release>
</grit>
diff --git a/chrome/browser/chromeos/set_time_dialog.cc b/chrome/browser/chromeos/set_time_dialog.cc
new file mode 100644
index 0000000..fb68b8d
--- /dev/null
+++ b/chrome/browser/chromeos/set_time_dialog.cc
@@ -0,0 +1,85 @@
+// Copyright 2014 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/set_time_dialog.h"
+
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/common/url_constants.h"
+#include "content/public/browser/user_metrics.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/size.h"
+
+using content::WebContents;
+using content::WebUIMessageHandler;
+
+namespace chromeos {
+
+namespace {
+
+const int kDefaultWidth = 490;
+const int kDefaultHeight = 235;
+
+} // namespace
+
+// static
+void SetTimeDialog::ShowDialog(gfx::NativeWindow owning_window) {
+ content::RecordAction(base::UserMetricsAction("Options_SetTimeDialog_Show"));
+ chrome::ShowWebDialog(owning_window,
+ ProfileManager::GetActiveUserProfile(),
+ new SetTimeDialog());
+}
+
+SetTimeDialog::SetTimeDialog() {
+}
+
+SetTimeDialog::~SetTimeDialog() {
+}
+
+ui::ModalType SetTimeDialog::GetDialogModalType() const {
+ return ui::MODAL_TYPE_SYSTEM;
+}
+
+base::string16 SetTimeDialog::GetDialogTitle() const {
+ return base::string16();
+}
+
+GURL SetTimeDialog::GetDialogContentURL() const {
+ return GURL(chrome::kChromeUISetTimeURL);
+}
+
+void SetTimeDialog::GetWebUIMessageHandlers(
+ std::vector<WebUIMessageHandler*>* handlers) const {
+}
+
+void SetTimeDialog::GetDialogSize(gfx::Size* size) const {
+ size->SetSize(kDefaultWidth, kDefaultHeight);
+}
+
+std::string SetTimeDialog::GetDialogArgs() const {
+ return std::string();
+}
+
+void SetTimeDialog::OnDialogClosed(const std::string& json_retval) {
+ delete this;
+}
+
+void SetTimeDialog::OnCloseContents(WebContents* source,
+ bool* out_close_dialog) {
+ if (out_close_dialog)
+ *out_close_dialog = true;
+}
+
+bool SetTimeDialog::ShouldShowDialogTitle() const {
+ return false;
+}
+
+bool SetTimeDialog::HandleContextMenu(
+ const content::ContextMenuParams& params) {
+ // Disable context menu.
+ return true;
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/set_time_dialog.h b/chrome/browser/chromeos/set_time_dialog.h
new file mode 100644
index 0000000..11cf4b6
--- /dev/null
+++ b/chrome/browser/chromeos/set_time_dialog.h
@@ -0,0 +1,46 @@
+// Copyright 2014 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_SET_TIME_DIALOG_H_
+#define CHROME_BROWSER_CHROMEOS_SET_TIME_DIALOG_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/values.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/web_dialogs/web_dialog_delegate.h"
+
+namespace chromeos {
+
+// Set Time dialog for setting the system time, date and time zone.
+class SetTimeDialog : public ui::WebDialogDelegate {
+ public:
+ SetTimeDialog();
+ virtual ~SetTimeDialog();
+
+ static void ShowDialog(gfx::NativeWindow owning_window);
+
+ private:
+ // ui::WebDialogDelegate:
+ virtual ui::ModalType GetDialogModalType() const OVERRIDE;
+ virtual base::string16 GetDialogTitle() const OVERRIDE;
+ virtual GURL GetDialogContentURL() const OVERRIDE;
+ virtual void GetWebUIMessageHandlers(
+ std::vector<content::WebUIMessageHandler*>* handlers) const OVERRIDE;
+ virtual void GetDialogSize(gfx::Size* size) const OVERRIDE;
+ virtual std::string GetDialogArgs() const OVERRIDE;
+ virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE;
+ virtual void OnCloseContents(content::WebContents* source,
+ bool* out_close_dialog) OVERRIDE;
+ virtual bool ShouldShowDialogTitle() const OVERRIDE;
+ virtual bool HandleContextMenu(
+ const content::ContextMenuParams& params) OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(SetTimeDialog);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_SET_TIME_DIALOG_H_
diff --git a/chrome/browser/resources/chromeos/set_time.css b/chrome/browser/resources/chromeos/set_time.css
new file mode 100644
index 0000000..fcc2e4f
--- /dev/null
+++ b/chrome/browser/resources/chromeos/set_time.css
@@ -0,0 +1,45 @@
+/* Copyright 2014 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. */
+
+body {
+ overflow: hidden; /* Hide scrollbars for accurate size calculation. */
+ padding: 8px 20px;
+}
+
+h2 {
+ margin-bottom: 20px;
+}
+
+.button-strip {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 25px;
+}
+
+.row {
+ align-items: center;
+ display: flex;
+ margin: 0.65em 0;
+}
+
+input[type='date'],
+input[type='time'] {
+ font-family: inherit;
+ font-size: 16px;
+ letter-spacing: 1px;
+ margin-bottom: 4px;
+}
+
+input[type='date']::-webkit-clear-button,
+input[type='time']::-webkit-clear-button {
+ display: none;
+}
+
+label {
+ -webkit-margin-end: 5px;
+}
+
+#timezone-select {
+ flex: 1;
+}
diff --git a/chrome/browser/resources/chromeos/set_time.html b/chrome/browser/resources/chromeos/set_time.html
new file mode 100644
index 0000000..590f47e
--- /dev/null
+++ b/chrome/browser/resources/chromeos/set_time.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html i18n-values="dir:textdirection;">
+<head>
+<meta charset="utf-8">
+<title i18n-content="setTimeTitle"></title>
+
+<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
+<link rel="stylesheet" href="set_time.css">
+</head>
+
+<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
+<form id="set-time">
+ <h2 i18n-content="setTimeTitle"></h2>
+ <p id="prompt" i18n-content="prompt" class="row"></p>
+
+ <div class="timeControl">
+ <input id="date" type="date" i18n-values="title:dateLabel">
+ <input id="time" type="time" i18n-values="title:timeLabel">
+ </div>
+
+ <div id="timezone" class="row" hidden>
+ <label id="timezone-label" for="timezone-select" i18n-content="timezone">
+ </label>
+ <select id="timezone-select" i18n-options="timezoneList"></select>
+ </div>
+
+ <div class="button-strip">
+ <button id="done" type="submit" i18n-content="doneButton"></button>
+ </div>
+</form>
+
+<script src="chrome://resources/js/cr.js"></script>
+<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://resources/js/util.js"></script>
+<script src="strings.js"></script>
+<script src="set_time.js"></script>
+<script src="chrome://resources/js/i18n_template2.js"></script>
+</body>
+</html>
diff --git a/chrome/browser/resources/chromeos/set_time.js b/chrome/browser/resources/chromeos/set_time.js
new file mode 100644
index 0000000..9ff4d8b
--- /dev/null
+++ b/chrome/browser/resources/chromeos/set_time.js
@@ -0,0 +1,200 @@
+// Copyright 2014 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.
+
+cr.define('settime', function() {
+ /**
+ * TimeSetter handles a dialog to check and set system time. It can also
+ * include a timezone dropdown if timezoneId is provided.
+ *
+ * TimeSetter uses the system time to populate the controls initially and
+ * update them as the system time or timezone changes, and notifies Chrome
+ * when the user changes the time or timezone.
+ * @constructor
+ */
+ function TimeSetter() {}
+
+ cr.addSingletonGetter(TimeSetter);
+
+ /** @const */ var BODY_PADDING_PX = 20;
+ /** @const */ var LABEL_PADDING_PX = 5;
+
+ TimeSetter.prototype = {
+ /**
+ * Performs initial setup.
+ */
+ initialize: function() {
+ // Store values for reverting inputs when the user's date/time is invalid.
+ this.prevValues_ = {};
+
+ // The build time doesn't include a timezone, so subtract 1 day to get a
+ // safe minimum date.
+ this.minDate_ = new Date(loadTimeData.getValue('buildTime'));
+ this.minDate_.setDate(this.minDate_.getDate() - 1);
+
+ // Set the max date to the min date plus 20 years.
+ this.maxDate_ = new Date(this.minDate_);
+ this.maxDate_.setYear(this.minDate_.getFullYear() + 20);
+
+ // Make sure the ostensible date is within this range.
+ var now = new Date();
+ if (now > this.maxDate_)
+ this.maxDate_ = now;
+ else if (now < this.minDate_)
+ this.minDate_ = now;
+
+ $('date').setAttribute('min', this.toHtmlValues_(this.minDate_).date);
+ $('date').setAttribute('max', this.toHtmlValues_(this.maxDate_).date);
+
+ this.updateTime_();
+
+ // Show the timezone select if we have a timezone ID.
+ var currentTimezoneId = loadTimeData.getValue('currentTimezoneId');
+ if (currentTimezoneId) {
+ this.setTimezone_(currentTimezoneId);
+ $('timezone-select').addEventListener(
+ 'change', this.onTimezoneChange_.bind(this), false);
+ $('timezone').hidden = false;
+ }
+
+ this.sizeToFit_();
+
+ $('time').addEventListener('blur', this.onTimeBlur_.bind(this), false);
+ $('date').addEventListener('blur', this.onTimeBlur_.bind(this), false);
+
+ $('set-time').addEventListener(
+ 'submit', this.onSubmit_.bind(this), false);
+ },
+
+ /**
+ * Sets the current timezone.
+ * @param {string} timezoneId The timezone ID to select.
+ * @private
+ */
+ setTimezone_: function(timezoneId) {
+ $('timezone-select').value = timezoneId;
+ this.updateTime_();
+ },
+
+ /**
+ * Updates the date/time controls to the current local time.
+ * Called initially, then called again once a minute.
+ * @private
+ */
+ updateTime_: function() {
+ var now = new Date();
+
+ // Only update time controls if neither is focused.
+ if (document.activeElement.id != 'date' &&
+ document.activeElement.id != 'time') {
+ var htmlValues = this.toHtmlValues_(now);
+ this.prevValues_.date = $('date').value = htmlValues.date;
+ this.prevValues_.time = $('time').value = htmlValues.time;
+ }
+
+ window.clearTimeout(this.timeTimeout_);
+
+ // Start timer to update these inputs every minute.
+ var secondsRemaining = 60 - now.getSeconds();
+ this.timeTimeout_ = window.setTimeout(this.updateTime_.bind(this),
+ secondsRemaining * 1000);
+ },
+
+ /**
+ * Sets the system time from the UI.
+ * @private
+ */
+ applyTime_: function() {
+ var date = $('date').valueAsDate;
+ date.setMilliseconds(date.getMilliseconds() + $('time').valueAsNumber);
+
+ // Add timezone offset to get real time.
+ date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
+
+ var seconds = Math.floor(date / 1000);
+ chrome.send('setTimeInSeconds', [seconds]);
+ },
+
+ /**
+ * Called when focus is lost on date/time controls.
+ * @param {Event} e The blur event.
+ * @private
+ */
+ onTimeBlur_: function(e) {
+ if (e.target.validity.valid && e.target.value) {
+ // Make this the new fallback time in case of future invalid input.
+ this.prevValues_[e.target.id] = e.target.value;
+ this.applyTime_();
+ } else {
+ // Restore previous value.
+ e.target.value = this.prevValues_[e.target.id];
+ }
+ },
+
+ /**
+ * @param {Event} e The change event.
+ * @private
+ */
+ onTimezoneChange_: function(e) {
+ chrome.send('setTimezone', [e.currentTarget.value]);
+ },
+
+ /**
+ * Closes the dialog window.
+ * @param {Event} e The submit event.
+ * @private
+ */
+ onSubmit_: function(e) {
+ e.preventDefault();
+ chrome.send('dialogClose');
+ },
+
+ /**
+ * Resizes the window if necessary to show the entire contents.
+ * @private
+ */
+ sizeToFit_: function() {
+ // Because of l10n, we should check that the vertical content can fit
+ // within the window.
+ if (window.innerHeight < document.body.scrollHeight) {
+ // Resize window to fit scrollHeight and the title bar.
+ var newHeight = document.body.scrollHeight +
+ window.outerHeight - window.innerHeight;
+ window.resizeTo(window.outerWidth, newHeight);
+ }
+ },
+
+ /**
+ * Builds date and time strings suitable for the values of HTML date and
+ * time elements.
+ * @param {Date} date The date object to represent.
+ * @return {{date: string, time: string}} Date is an RFC 3339 formatted date
+ * and time is an HH:MM formatted time.
+ * @private
+ */
+ toHtmlValues_: function(date) {
+ // Get the current time and subtract the timezone offset, so the
+ // JSON string is in local time.
+ var localDate = new Date(date);
+ localDate.setMinutes(date.getMinutes() - date.getTimezoneOffset());
+ return {date: localDate.toISOString().slice(0, 10),
+ time: localDate.toISOString().slice(11, 16)};
+ },
+ };
+
+ TimeSetter.setTimezone = function(timezoneId) {
+ TimeSetter.getInstance().setTimezone_(timezoneId);
+ };
+
+ TimeSetter.updateTime = function() {
+ TimeSetter.getInstance().updateTime_();
+ };
+
+ return {
+ TimeSetter: TimeSetter
+ };
+});
+
+document.addEventListener('DOMContentLoaded', function() {
+ settime.TimeSetter.getInstance().initialize();
+});
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index 4cea7dc..3423293 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -210,13 +210,19 @@
</select>
</div>
</div>
- <div class="checkbox">
+ <div class="checkbox settings-row">
<label>
<input id="use-24hour-clock" pref="settings.clock.use_24hour_clock"
type="checkbox">
<span i18n-content="use24HourClock"></span>
</label>
</div>
+ <div id="time-synced-explanation" class="settings-row"
+ i18n-content="timeSyncedExplanation"></div>
+ <div id="set-time" class="settings-row" hidden>
+ <button id="set-time-button"
+ i18n-content="setTimeButton"></button>
+ </div>
</div>
</section>
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js
index c057e66..361a31c 100644
--- a/chrome/browser/resources/options/browser_options.js
+++ b/chrome/browser/resources/options/browser_options.js
@@ -295,6 +295,10 @@ cr.define('options', function() {
}
}
+ // Date and time section (CrOS only).
+ if ($('set-time-button'))
+ $('set-time-button').onclick = this.handleSetTime_.bind(this);
+
// Default browser section.
if (!cr.isChromeOS) {
if (!loadTimeData.getBoolean('showSetDefault')) {
@@ -1727,7 +1731,26 @@ cr.define('options', function() {
$('profiles-section').hidden &&
$('sync-section').hidden &&
$('profiles-supervised-dashboard-tip').hidden;
- }
+ },
+
+ /**
+ * Updates the date and time section with time sync information.
+ * @param {boolean} canSetTime Whether the system time can be set.
+ * @private
+ */
+ setCanSetTime_: function(canSetTime) {
+ // If the time has been network-synced, it cannot be set manually.
+ $('time-synced-explanation').hidden = canSetTime;
+ $('set-time').hidden = !canSetTime;
+ },
+
+ /**
+ * Handle the 'set date and time' button click.
+ * @private
+ */
+ handleSetTime_: function() {
+ chrome.send('showSetTime');
+ },
};
//Forward public APIs to private implementations.
@@ -1745,6 +1768,7 @@ cr.define('options', function() {
'setWallpaperManaged',
'setAutoOpenFileTypesDisplayed',
'setBluetoothState',
+ 'setCanSetTime',
'setFontSize',
'setNativeThemeButtonEnabled',
'setHighContrastCheckboxState',
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
index 01e8e37..000bd67 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -67,6 +67,7 @@
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
#include "chrome/browser/chromeos/profiles/multiprofiles_intro_dialog.h"
+#include "chrome/browser/chromeos/set_time_dialog.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/sim_dialog_delegate.h"
#include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
@@ -481,6 +482,10 @@ void SystemTrayDelegateChromeOS::ShowDateSettings() {
ShowSettingsSubPageForActiveUser(sub_page);
}
+void SystemTrayDelegateChromeOS::ShowSetTimeDialog() {
+ SetTimeDialog::ShowDialog(GetNativeWindow());
+}
+
void SystemTrayDelegateChromeOS::ShowNetworkSettings(
const std::string& service_path) {
if (!LoginState::Get()->IsUserLoggedIn())
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
index 418af2e..8a1fc30 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
@@ -74,6 +74,7 @@ class SystemTrayDelegateChromeOS
virtual void ShowSettings() OVERRIDE;
virtual bool ShouldShowSettings() OVERRIDE;
virtual void ShowDateSettings() OVERRIDE;
+ virtual void ShowSetTimeDialog() OVERRIDE;
virtual void ShowNetworkSettings(const std::string& service_path) OVERRIDE;
virtual void ShowBluetoothSettings() OVERRIDE;
virtual void ShowDisplaySettings() OVERRIDE;
diff --git a/chrome/browser/ui/ash/system_tray_delegate_win.cc b/chrome/browser/ui/ash/system_tray_delegate_win.cc
index 1e900b5..9b15bbe 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_win.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_win.cc
@@ -103,6 +103,9 @@ class SystemTrayDelegateWin : public ash::SystemTrayDelegate,
virtual void ShowDateSettings() OVERRIDE {
}
+ virtual void ShowSetTimeDialog() OVERRIDE {
+ }
+
virtual void ShowNetworkSettings(const std::string& service_path) OVERRIDE {
}
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 27b3e2f..d64f4db 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -123,6 +123,7 @@
#include "chrome/browser/ui/webui/chromeos/power_ui.h"
#include "chrome/browser/ui/webui/chromeos/proxy_settings_ui.h"
#include "chrome/browser/ui/webui/chromeos/salsa_ui.h"
+#include "chrome/browser/ui/webui/chromeos/set_time_ui.h"
#include "chrome/browser/ui/webui/chromeos/sim_unlock_ui.h"
#include "chrome/browser/ui/webui/chromeos/slow_trace_ui.h"
#include "chrome/browser/ui/webui/chromeos/slow_ui.h"
@@ -430,6 +431,8 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
return &NewWebUI<chromeos::ProxySettingsUI>;
if (url.host() == chrome::kChromeUISalsaHost)
return &NewWebUI<SalsaUI>;
+ if (url.host() == chrome::kChromeUISetTimeHost)
+ return &NewWebUI<chromeos::SetTimeUI>;
if (url.host() == chrome::kChromeUISimUnlockHost)
return &NewWebUI<chromeos::SimUnlockUI>;
if (url.host() == chrome::kChromeUISlowHost)
diff --git a/chrome/browser/ui/webui/chromeos/set_time_ui.cc b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
new file mode 100644
index 0000000..6568d0c
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
@@ -0,0 +1,146 @@
+// Copyright 2014 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/ui/webui/chromeos/set_time_ui.h"
+
+#include "ash/shell.h"
+#include "ash/system/tray/system_tray_delegate.h"
+#include "ash/system/user/login_status.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/build_time.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/system/timezone_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/url_constants.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/settings/timezone_settings.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/browser/web_ui_message_handler.h"
+#include "grit/browser_resources.h"
+#include "grit/generated_resources.h"
+
+namespace chromeos {
+
+namespace {
+
+class SetTimeMessageHandler : public content::WebUIMessageHandler,
+ public chromeos::SystemClockClient::Observer,
+ public system::TimezoneSettings::Observer {
+ public:
+ SetTimeMessageHandler() {
+ system::TimezoneSettings::GetInstance()->AddObserver(this);
+ chromeos::DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(
+ this);
+ };
+
+ virtual ~SetTimeMessageHandler() {
+ system::TimezoneSettings::GetInstance()->RemoveObserver(this);
+ chromeos::DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(
+ this);
+ }
+
+ // WebUIMessageHandler:
+ virtual void RegisterMessages() OVERRIDE {
+ web_ui()->RegisterMessageCallback(
+ "setTimeInSeconds",
+ base::Bind(&SetTimeMessageHandler::OnSetTime, base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "setTimezone",
+ base::Bind(&SetTimeMessageHandler::OnSetTimezone,
+ base::Unretained(this)));
+ }
+
+ private:
+ // system::SystemClockClient::Observer:
+ virtual void SystemClockUpdated() OVERRIDE {
+ web_ui()->CallJavascriptFunction("settime.TimeSetter.updateTime");
+ }
+
+ // system::TimezoneSettings::Observer:
+ virtual void TimezoneChanged(const icu::TimeZone& timezone) OVERRIDE {
+ base::StringValue timezone_id(
+ system::TimezoneSettings::GetTimezoneID(timezone));
+ web_ui()->CallJavascriptFunction("settime.TimeSetter.setTimezone",
+ timezone_id);
+ }
+
+ // Handler for Javascript call to set the system clock when the user sets a
+ // new time. Expects the time as the number of seconds since the Unix
+ // epoch, treated as a double.
+ void OnSetTime(const base::ListValue* args) {
+ double seconds;
+ if (!args->GetDouble(0, &seconds)) {
+ NOTREACHED();
+ return;
+ }
+
+ chromeos::DBusThreadManager::Get()->GetSystemClockClient()->SetTime(
+ static_cast<int64>(seconds));
+ }
+
+ // Handler for Javascript call to change the system time zone when the user
+ // selects a new time zone. Expects the time zone ID as a string, as it
+ // appears in the time zone option values.
+ void OnSetTimezone(const base::ListValue* args) {
+ std::string timezone_id;
+ if (!args->GetString(0, &timezone_id)) {
+ NOTREACHED();
+ return;
+ }
+
+ CrosSettings::Get()->SetString(kSystemTimezone, timezone_id);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(SetTimeMessageHandler);
+};
+
+} // namespace
+
+SetTimeUI::SetTimeUI(content::WebUI* web_ui) : WebDialogUI(web_ui) {
+ web_ui->AddMessageHandler(new SetTimeMessageHandler());
+
+ // Set up the chrome://set-time source.
+ content::WebUIDataSource* source =
+ content::WebUIDataSource::Create(chrome::kChromeUISetTimeHost);
+ source->SetUseJsonJSFormatV2();
+
+ source->AddLocalizedString("setTimeTitle", IDS_SET_TIME_TITLE);
+ source->AddLocalizedString("prompt", IDS_SET_TIME_PROMPT);
+ source->AddLocalizedString("doneButton", IDS_SET_TIME_BUTTON_CLOSE);
+ source->AddLocalizedString("timezone",
+ IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION);
+ source->AddLocalizedString("dateLabel", IDS_SET_TIME_DATE_LABEL);
+ source->AddLocalizedString("timeLabel", IDS_SET_TIME_TIME_LABEL);
+
+ base::DictionaryValue values;
+ values.Set("timezoneList", chromeos::system::GetTimezoneList().release());
+
+ // If we are not logged in, we need to show the time zone dropdown.
+ // Otherwise, we can leave |currentTimezoneId| blank.
+ std::string current_timezone_id;
+ if (ash::Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() ==
+ ash::user::LOGGED_IN_NONE) {
+ CrosSettings::Get()->GetString(kSystemTimezone, &current_timezone_id);
+ }
+ values.SetString("currentTimezoneId", current_timezone_id);
+ values.SetDouble("buildTime", base::GetBuildTime().ToJsTime());
+
+ source->AddLocalizedStrings(values);
+ source->SetJsonPath("strings.js");
+
+ source->AddResourcePath("set_time.css", IDR_SET_TIME_CSS);
+ source->AddResourcePath("set_time.js", IDR_SET_TIME_JS);
+ source->SetDefaultResource(IDR_SET_TIME_HTML);
+
+ content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source);
+}
+
+SetTimeUI::~SetTimeUI() {
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/set_time_ui.h b/chrome/browser/ui/webui/chromeos/set_time_ui.h
new file mode 100644
index 0000000..38091df
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/set_time_ui.h
@@ -0,0 +1,25 @@
+// Copyright 2014 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_UI_WEBUI_CHROMEOS_SET_TIME_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_SET_TIME_UI_H_
+
+#include "base/basictypes.h"
+#include "ui/web_dialogs/web_dialog_ui.h"
+
+namespace chromeos {
+
+// The WebUI for chrome://set-time.
+class SetTimeUI : public ui::WebDialogUI {
+ public:
+ explicit SetTimeUI(content::WebUI* web_ui);
+ virtual ~SetTimeUI();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SetTimeUI);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_SET_TIME_UI_H_
diff --git a/chrome/browser/ui/webui/chromeos/set_time_ui_browsertest.js b/chrome/browser/ui/webui/chromeos/set_time_ui_browsertest.js
new file mode 100644
index 0000000..1249c87
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/set_time_ui_browsertest.js
@@ -0,0 +1,37 @@
+// Copyright 2014 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.
+
+GEN('#if defined(OS_CHROMEOS)');
+
+/**
+ * SetTimeWebUITest tests loading and interacting with the SetTimeUI web UI,
+ * which is normally shown as a dialog.
+ * @constructor
+ * @extends {testing.Test}
+ */
+function SetTimeWebUITest() {}
+
+SetTimeWebUITest.prototype = {
+ __proto__: testing.Test.prototype,
+
+ /**
+ * Browse to set time dialog.
+ * @override
+ */
+ browsePreload: 'chrome://set-time/',
+};
+
+TEST_F('SetTimeWebUITest', 'testChangeTimezone', function() {
+ assertEquals(this.browsePreload, document.location.href);
+
+ var TimeSetter = settime.TimeSetter;
+
+ // Verify timezone.
+ TimeSetter.setTimezone('America/New_York');
+ expectEquals('America/New_York', $('timezone-select').value);
+ TimeSetter.setTimezone('Europe/Moscow');
+ expectEquals('Europe/Moscow', $('timezone-select').value);
+});
+
+GEN('#endif');
diff --git a/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js b/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js
new file mode 100644
index 0000000..bce9a16
--- /dev/null
+++ b/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js
@@ -0,0 +1,38 @@
+// Copyright 2014 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.
+
+GEN('#if defined(OS_CHROMEOS)');
+
+/**
+ * DateTimeOptionsWebUITest tests the date and time section of the options page.
+ * @constructor
+ * @extends {testing.Test}
+ */
+function DateTimeOptionsWebUITest() {}
+
+DateTimeOptionsWebUITest.prototype = {
+ __proto__: testing.Test.prototype,
+
+ /**
+ * Browse to date/time options.
+ * @override
+ */
+ browsePreload: 'chrome://settings-frame/search#date',
+};
+
+TEST_F('DateTimeOptionsWebUITest', 'testShowSetTimeButton', function() {
+ assertEquals(this.browsePreload, document.location.href);
+
+ // Hide label and show button.
+ BrowserOptions.setCanSetTime(true);
+ expectTrue($('time-synced-explanation').hidden);
+ expectFalse($('set-time').hidden);
+
+ // Show label and hide button.
+ BrowserOptions.setCanSetTime(false);
+ expectFalse($('time-synced-explanation').hidden);
+ expectTrue($('set-time').hidden);
+});
+
+GEN('#endif');
diff --git a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc
new file mode 100644
index 0000000..f78d184
--- /dev/null
+++ b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc
@@ -0,0 +1,81 @@
+// Copyright 2014 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/ui/webui/options/chromeos/date_time_options_handler.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/set_time_dialog.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/system_clock_client.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
+#include "content/public/browser/web_ui.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace chromeos {
+namespace options {
+
+DateTimeOptionsHandler::DateTimeOptionsHandler()
+ : can_set_time_(false), page_initialized_(false) {
+}
+
+DateTimeOptionsHandler::~DateTimeOptionsHandler() {
+ DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(this);
+}
+
+void DateTimeOptionsHandler::GetLocalizedValues(
+ base::DictionaryValue* localized_strings) {
+ DCHECK(localized_strings);
+
+ localized_strings->SetString(
+ "setTimeButton",
+ l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_SET_TIME_BUTTON));
+ localized_strings->SetString(
+ "timeSyncedExplanation",
+ l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_TIME_SYNCED_EXPLANATION));
+};
+
+void DateTimeOptionsHandler::InitializeHandler() {
+ SystemClockClient* system_clock_client =
+ DBusThreadManager::Get()->GetSystemClockClient();
+ system_clock_client->AddObserver(this);
+
+ can_set_time_ = system_clock_client->CanSetTime();
+ SystemClockCanSetTimeChanged(can_set_time_);
+}
+
+void DateTimeOptionsHandler::InitializePage() {
+ page_initialized_ = true;
+ SystemClockCanSetTimeChanged(can_set_time_);
+}
+
+void DateTimeOptionsHandler::RegisterMessages() {
+ // Callback for set time button.
+ web_ui()->RegisterMessageCallback(
+ "showSetTime",
+ base::Bind(&DateTimeOptionsHandler::HandleShowSetTime,
+ base::Unretained(this)));
+}
+
+void DateTimeOptionsHandler::SystemClockCanSetTimeChanged(bool can_set_time) {
+ if (page_initialized_) {
+ web_ui()->CallJavascriptFunction("BrowserOptions.setCanSetTime",
+ base::FundamentalValue(can_set_time));
+ }
+ can_set_time_ = can_set_time;
+}
+
+void DateTimeOptionsHandler::HandleShowSetTime(const base::ListValue* args) {
+ // Make sure the clock status hasn't changed since the button was clicked.
+ if (can_set_time_) {
+ SetTimeDialog::ShowDialog(
+ web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow());
+ }
+}
+
+} // namespace options
+} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h
new file mode 100644
index 0000000..5a4003e
--- /dev/null
+++ b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h
@@ -0,0 +1,47 @@
+// Copyright 2014 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_UI_WEBUI_OPTIONS_CHROMEOS_DATE_TIME_OPTIONS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DATE_TIME_OPTIONS_HANDLER_H_
+
+#include "base/compiler_specific.h"
+#include "chrome/browser/ui/webui/options/options_ui.h"
+#include "chromeos/dbus/system_clock_client.h"
+
+namespace chromeos {
+namespace options {
+
+// Chrome OS handler for the set date/time link in the Advanced settings page.
+class DateTimeOptionsHandler : public ::options::OptionsPageUIHandler,
+ public SystemClockClient::Observer {
+ public:
+ DateTimeOptionsHandler();
+ virtual ~DateTimeOptionsHandler();
+
+ // OptionsPageUIHandler:
+ virtual void GetLocalizedValues(
+ base::DictionaryValue* localized_strings) OVERRIDE;
+ virtual void InitializeHandler() OVERRIDE;
+ virtual void InitializePage() OVERRIDE;
+ virtual void RegisterMessages() OVERRIDE;
+
+ private:
+ // SystemClockClient::Observer:
+ virtual void SystemClockCanSetTimeChanged(bool can_set_time) OVERRIDE;
+
+ // Callback for the "showSetTime" message to show the set time dialog. No
+ // arguments are expected.
+ void HandleShowSetTime(const base::ListValue* args);
+
+ // Only expose the button and dialog if the system time can be set.
+ bool can_set_time_;
+ bool page_initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(DateTimeOptionsHandler);
+};
+
+} // namespace options
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_DATE_TIME_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc
index 0d78636..9abdda5 100644
--- a/chrome/browser/ui/webui/options/options_ui.cc
+++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -75,6 +75,7 @@
#include "chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h"
#include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
#include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h"
+#include "chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h"
#include "chrome/browser/ui/webui/options/chromeos/display_options_handler.h"
#include "chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h"
#include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h"
@@ -299,6 +300,8 @@ OptionsUI::OptionsUI(content::WebUI* web_ui)
AddOptionsPageUIHandler(localized_strings,
new chromeos::options::BluetoothOptionsHandler());
AddOptionsPageUIHandler(localized_strings,
+ new chromeos::options::DateTimeOptionsHandler());
+ AddOptionsPageUIHandler(localized_strings,
new chromeos::options::DisplayOptionsHandler());
AddOptionsPageUIHandler(localized_strings,
new chromeos::options::DisplayOverscanHandler());
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index 1285027..36663bd 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -848,6 +848,8 @@
'browser/chromeos/reset/metrics.h',
'browser/chromeos/session_length_limiter.cc',
'browser/chromeos/session_length_limiter.h',
+ 'browser/chromeos/set_time_dialog.cc',
+ 'browser/chromeos/set_time_dialog.h',
'browser/chromeos/settings/cros_settings.cc',
'browser/chromeos/settings/cros_settings.h',
'browser/chromeos/settings/device_identity_provider.cc',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 1828f21f..c38ac17 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -2069,6 +2069,8 @@
'browser/ui/webui/chromeos/power_ui.h',
'browser/ui/webui/chromeos/proxy_settings_ui.cc',
'browser/ui/webui/chromeos/proxy_settings_ui.h',
+ 'browser/ui/webui/chromeos/set_time_ui.cc',
+ 'browser/ui/webui/chromeos/set_time_ui.h',
'browser/ui/webui/chromeos/sim_unlock_ui.cc',
'browser/ui/webui/chromeos/sim_unlock_ui.h',
'browser/ui/webui/chromeos/slow_trace_ui.cc',
@@ -2239,6 +2241,8 @@
'browser/ui/webui/options/chromeos/core_chromeos_options_handler.h',
'browser/ui/webui/options/chromeos/cros_language_options_handler.cc',
'browser/ui/webui/options/chromeos/cros_language_options_handler.h',
+ 'browser/ui/webui/options/chromeos/date_time_options_handler.cc',
+ 'browser/ui/webui/options/chromeos/date_time_options_handler.h',
'browser/ui/webui/options/chromeos/display_options_handler.cc',
'browser/ui/webui/options/chromeos/display_options_handler.h',
'browser/ui/webui/options/chromeos/display_overscan_handler.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 67337c8..abd8ca9 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1386,6 +1386,7 @@
'browser/ui/webui/bidi_checker_web_ui_test.h',
'browser/ui/webui/bookmarks_ui_browsertest.cc',
'browser/ui/webui/chrome_url_data_manager_browsertest.cc',
+ 'browser/ui/webui/chromeos/set_time_ui_browsertest.js',
'browser/ui/webui/constrained_web_dialog_ui_browsertest.cc',
'browser/ui/webui/downloads_dom_handler_browsertest.cc',
'browser/ui/webui/downloads_ui_browsertest.cc',
@@ -1413,6 +1414,7 @@
'browser/ui/webui/options/chromeos/accounts_options_browsertest.cc',
'browser/ui/webui/options/chromeos/accounts_options_browsertest.js',
'browser/ui/webui/options/chromeos/bluetooth_options_browsertest.js',
+ 'browser/ui/webui/options/chromeos/date_time_options_browsertest.js',
'browser/ui/webui/options/chromeos/guest_mode_options_ui_browsertest.cc',
'browser/ui/webui/options/chromeos/shared_options_browsertest.cc',
'browser/ui/webui/options/content_options_browsertest.js',
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 6f8a339..1623791 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -119,6 +119,7 @@ const char kChromeUIOobeURL[] = "chrome://oobe/";
const char kChromeUIOSCreditsURL[] = "chrome://os-credits/";
const char kChromeUIProxySettingsURL[] = "chrome://proxy-settings/";
const char kChromeUIScreenlockIconURL[] = "chrome://screenlock-icon/";
+const char kChromeUISetTimeURL[] = "chrome://set-time/";
const char kChromeUISimUnlockURL[] = "chrome://sim-unlock/";
const char kChromeUISlideshowURL[] = "chrome://slideshow/";
const char kChromeUISlowURL[] = "chrome://slow/";
@@ -282,6 +283,7 @@ const char kChromeUIPowerHost[] = "power";
const char kChromeUIProxySettingsHost[] = "proxy-settings";
const char kChromeUIRotateHost[] = "rotate";
const char kChromeUIScreenlockIconHost[] = "screenlock-icon";
+const char kChromeUISetTimeHost[] = "set-time";
const char kChromeUISimUnlockHost[] = "sim-unlock";
const char kChromeUISlideshowHost[] = "slideshow";
const char kChromeUISlowHost[] = "slow";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index f12ea11..7379724 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -113,6 +113,7 @@ extern const char kChromeUIOobeURL[];
extern const char kChromeUIOSCreditsURL[];
extern const char kChromeUIProxySettingsURL[];
extern const char kChromeUIScreenlockIconURL[];
+extern const char kChromeUISetTimeURL[];
extern const char kChromeUISimUnlockURL[];
extern const char kChromeUISlideshowURL[];
extern const char kChromeUISlowURL[];
@@ -273,6 +274,7 @@ extern const char kChromeUIPowerHost[];
extern const char kChromeUIProxySettingsHost[];
extern const char kChromeUIRotateHost[];
extern const char kChromeUIScreenlockIconHost[];
+extern const char kChromeUISetTimeHost[];
extern const char kChromeUISimUnlockHost[];
extern const char kChromeUISlideshowHost[];
extern const char kChromeUISlowHost[];
diff --git a/chromeos/dbus/fake_system_clock_client.cc b/chromeos/dbus/fake_system_clock_client.cc
index 92a8dd3..c744bdd 100644
--- a/chromeos/dbus/fake_system_clock_client.cc
+++ b/chromeos/dbus/fake_system_clock_client.cc
@@ -25,4 +25,11 @@ bool FakeSystemClockClient::HasObserver(Observer* observer) {
return false;
}
+void FakeSystemClockClient::SetTime(int64 time_in_seconds) {
+}
+
+bool FakeSystemClockClient::CanSetTime() {
+ return true;
+}
+
} // namespace chromeos
diff --git a/chromeos/dbus/fake_system_clock_client.h b/chromeos/dbus/fake_system_clock_client.h
index 18c8b2d..c109611 100644
--- a/chromeos/dbus/fake_system_clock_client.h
+++ b/chromeos/dbus/fake_system_clock_client.h
@@ -20,6 +20,8 @@ class CHROMEOS_EXPORT FakeSystemClockClient : public SystemClockClient {
virtual void AddObserver(Observer* observer) OVERRIDE;
virtual void RemoveObserver(Observer* observer) OVERRIDE;
virtual bool HasObserver(Observer* observer) OVERRIDE;
+ virtual void SetTime(int64 time_in_seconds) OVERRIDE;
+ virtual bool CanSetTime() OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(FakeSystemClockClient);
diff --git a/chromeos/dbus/system_clock_client.cc b/chromeos/dbus/system_clock_client.cc
index 7d5f4a4..199a6ac 100644
--- a/chromeos/dbus/system_clock_client.cc
+++ b/chromeos/dbus/system_clock_client.cc
@@ -5,6 +5,8 @@
#include "chromeos/dbus/system_clock_client.h"
#include "base/bind.h"
+#include "base/callback.h"
+#include "base/observer_list.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
@@ -17,7 +19,10 @@ namespace chromeos {
class SystemClockClientImpl : public SystemClockClient {
public:
SystemClockClientImpl()
- : system_clock_proxy_(NULL), weak_ptr_factory_(this) {}
+ : can_set_time_(false),
+ can_set_time_initialized_(false),
+ system_clock_proxy_(NULL),
+ weak_ptr_factory_(this) {}
virtual ~SystemClockClientImpl() {
}
@@ -34,12 +39,28 @@ class SystemClockClientImpl : public SystemClockClient {
return observers_.HasObserver(observer);
}
+ virtual void SetTime(int64 time_in_seconds) OVERRIDE {
+ // Always try to set the time, because |can_set_time_| may be stale.
+ dbus::MethodCall method_call(system_clock::kSystemClockInterface,
+ system_clock::kSystemClockSet);
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendInt64(time_in_seconds);
+ system_clock_proxy_->CallMethod(&method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ dbus::ObjectProxy::EmptyResponseCallback());
+ }
+
+ virtual bool CanSetTime() OVERRIDE { return can_set_time_; }
+
protected:
virtual void Init(dbus::Bus* bus) OVERRIDE {
system_clock_proxy_ = bus->GetObjectProxy(
system_clock::kSystemClockServiceName,
dbus::ObjectPath(system_clock::kSystemClockServicePath));
+ // Check whether the system clock can be set.
+ GetCanSet();
+
// Monitor the D-Bus signal for TimeUpdated changes.
system_clock_proxy_->ConnectToSignal(
system_clock::kSystemClockInterface,
@@ -56,6 +77,9 @@ class SystemClockClientImpl : public SystemClockClient {
VLOG(1) << "TimeUpdated signal received: " << signal->ToString();
dbus::MessageReader reader(signal);
FOR_EACH_OBSERVER(Observer, observers_, SystemClockUpdated());
+
+ // Check if the system clock can be changed now.
+ GetCanSet();
}
// Called when the TimeUpdated signal is initially connected.
@@ -66,16 +90,62 @@ class SystemClockClientImpl : public SystemClockClient {
<< "Failed to connect to TimeUpdated signal.";
}
+ // Callback for CanSetTime method.
+ void OnGetCanSet(dbus::Response* response) {
+ if (!response) {
+ LOG(WARNING) << "CanSetTime request failed.";
+ return;
+ }
+
+ dbus::MessageReader reader(response);
+ bool can_set_time;
+ if (!reader.PopBool(&can_set_time)) {
+ LOG(ERROR) << "CanSetTime response invalid: " << response->ToString();
+ return;
+ }
+
+ // Nothing to do if the CanSetTime response hasn't changed.
+ if (can_set_time_initialized_ && can_set_time_ == can_set_time)
+ return;
+
+ can_set_time_initialized_ = true;
+ can_set_time_ = can_set_time;
+
+ FOR_EACH_OBSERVER(
+ Observer, observers_, SystemClockCanSetTimeChanged(can_set_time));
+ }
+
+ // Check whether the time can be set.
+ void GetCanSet() {
+ dbus::MethodCall method_call(system_clock::kSystemClockInterface,
+ system_clock::kSystemClockCanSet);
+ dbus::MessageWriter writer(&method_call);
+ system_clock_proxy_->CallMethod(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&SystemClockClientImpl::OnGetCanSet,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+
+ // Whether the time can be set. Value is false until the first
+ // CanSetTime response is received.
+ bool can_set_time_;
+ bool can_set_time_initialized_;
dbus::ObjectProxy* system_clock_proxy_;
ObserverList<Observer> observers_;
- // Note: This should remain the last member so it'll be destroyed and
- // invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<SystemClockClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(SystemClockClientImpl);
};
+void SystemClockClient::Observer::SystemClockUpdated() {
+}
+
+void SystemClockClient::Observer::SystemClockCanSetTimeChanged(
+ bool can_set_time) {
+}
+
SystemClockClient::SystemClockClient() {
}
diff --git a/chromeos/dbus/system_clock_client.h b/chromeos/dbus/system_clock_client.h
index 849612d..1757853 100644
--- a/chromeos/dbus/system_clock_client.h
+++ b/chromeos/dbus/system_clock_client.h
@@ -5,7 +5,7 @@
#ifndef CHROMEOS_DBUS_SYSTEM_CLOCK_CLIENT_H_
#define CHROMEOS_DBUS_SYSTEM_CLOCK_CLIENT_H_
-#include "base/observer_list.h"
+#include "base/callback.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
@@ -18,19 +18,31 @@ class CHROMEOS_EXPORT SystemClockClient : public DBusClient {
class Observer {
public:
// Called when the status is updated.
- virtual void SystemClockUpdated() {}
+ virtual void SystemClockUpdated();
+
+ // Called when the system clock has become settable or unsettable, e.g.,
+ // when the clock syncs with or goes out of sync with the network.
+ virtual void SystemClockCanSetTimeChanged(bool can_set_time);
+
protected:
virtual ~Observer() {}
};
virtual ~SystemClockClient();
- // Adds and removes the observer.
+ // Adds the given observer.
virtual void AddObserver(Observer* observer) = 0;
+ // Removes the given observer if this object has the observer.
virtual void RemoveObserver(Observer* observer) = 0;
// Returns true if this object has the given observer.
virtual bool HasObserver(Observer* observer) = 0;
+ // Sets the system clock.
+ virtual void SetTime(int64 time_in_seconds) = 0;
+
+ // Checks if the system time can be set.
+ virtual bool CanSetTime() = 0;
+
// Creates the instance.
static SystemClockClient* Create();
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 8c21bfd..cacb05fa 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -8690,6 +8690,11 @@ should be able to be added at any place in this file.
<description>Please enter the description of this user action.</description>
</action>
+<action name="Options_SetTimeDialog_Show">
+ <owner>michaelpg@chromium.org</owner>
+ <description>Set system time dialog was launched.</description>
+</action>
+
<action name="Options_ShowAutoFillSettings">
<owner>Please list the metric's owners. Add more owner tags as needed.</owner>
<description>Please enter the description of this user action.</description>