From be0d312bf397dfd4e3ca89e39a234cf3c1af7657 Mon Sep 17 00:00:00 2001 From: "alemate@chromium.org" Date: Mon, 10 Feb 2014 15:29:42 +0000 Subject: [PATCH] Implemented SystemUse24HourClockPolicyTest browser test. Fixed bug in chromeos::SystemTrayDelegate - added PropertyChangeComplete() notification. Moved chromeos::SystemTrayDelegate to separate header file and renamed to chromeos::SystemTrayDelegateChromeOS (from anonymous namespace). Moved DateDefaultView to separate header. BUG=269802 TEST=browsertest Review URL: https://codereview.chromium.org/132383004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250101 0039d316-1c4b-4281-b951-d872f2087c98 --- ash/ash.gyp | 2 + ash/system/date/clock_observer.h | 6 +- ash/system/date/date_default_view.cc | 122 + ash/system/date/date_default_view.h | 51 + ash/system/date/date_view.cc | 8 + ash/system/date/date_view.h | 6 +- ash/system/date/tray_date.cc | 355 +-- ash/system/date/tray_date.h | 8 +- ash/system/tray/system_tray.cc | 4 + ash/system/tray/system_tray.h | 3 + .../device_system_use_24hour_clock_browsertest.cc | 161 ++ .../ui/ash/system_tray_delegate_chromeos.cc | 2647 ++++++++++---------- .../browser/ui/ash/system_tray_delegate_chromeos.h | 236 +- chrome/chrome_tests.gypi | 1 + 14 files changed, 2022 insertions(+), 1588 deletions(-) create mode 100644 ash/system/date/date_default_view.cc create mode 100644 ash/system/date/date_default_view.h rewrite ash/system/date/tray_date.cc (61%) create mode 100644 chrome/browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc rewrite chrome/browser/ui/ash/system_tray_delegate_chromeos.cc (79%) diff --git a/ash/ash.gyp b/ash/ash.gyp index 901505b6799e..98582608afa4 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -330,6 +330,8 @@ 'system/chromeos/tray_tracing.cc', 'system/chromeos/tray_tracing.h', 'system/date/clock_observer.h', + 'system/date/date_default_view.cc', + 'system/date/date_default_view.h', 'system/date/date_view.cc', 'system/date/date_view.h', 'system/date/tray_date.cc', diff --git a/ash/system/date/clock_observer.h b/ash/system/date/clock_observer.h index 30465288bf7d..b3d9ece493aa 100644 --- a/ash/system/date/clock_observer.h +++ b/ash/system/date/clock_observer.h @@ -5,9 +5,11 @@ #ifndef ASH_SYSTEM_DATE_CLOCK_OBSERVER_H_ #define ASH_SYSTEM_DATE_CLOCK_OBSERVER_H_ +#include "ash/ash_export.h" + namespace ash { -class ClockObserver { +class ASH_EXPORT ClockObserver { public: virtual ~ClockObserver() {} @@ -18,6 +20,6 @@ class ClockObserver { virtual void Refresh() = 0; }; -}; +} // namespace ash #endif // ASH_SYSTEM_DATE_CLOCK_OBSERVER_H_ diff --git a/ash/system/date/date_default_view.cc b/ash/system/date/date_default_view.cc new file mode 100644 index 000000000000..33a0f4fd95a2 --- /dev/null +++ b/ash/system/date/date_default_view.cc @@ -0,0 +1,122 @@ +// 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 "ash/system/date/date_default_view.h" + +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/session_state_delegate.h" +#include "ash/shell.h" +#include "ash/system/date/date_view.h" +#include "ash/system/tray/special_popup_row.h" +#include "ash/system/tray/system_tray_delegate.h" +#include "ash/system/tray/tray_constants.h" +#include "ash/system/tray/tray_popup_header_button.h" +#include "grit/ash_resources.h" +#include "grit/ash_strings.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/views/border.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/view.h" + +namespace { + +const int kPaddingVertical = 19; + +} // namespace + +namespace ash { +namespace internal { + +DateDefaultView::DateDefaultView(ash::user::LoginStatus login) + : help_(NULL), + shutdown_(NULL), + lock_(NULL), + date_view_(NULL) { + SetLayoutManager(new views::FillLayout); + + date_view_ = new tray::DateView(); + date_view_->SetBorder(views::Border::CreateEmptyBorder( + kPaddingVertical, ash::kTrayPopupPaddingHorizontal, 0, 0)); + SpecialPopupRow* view = new SpecialPopupRow(); + view->SetContent(date_view_); + AddChildView(view); + + if (login == ash::user::LOGGED_IN_LOCKED || + login == ash::user::LOGGED_IN_NONE) + return; + + date_view_->SetActionable(true); + + help_ = new TrayPopupHeaderButton(this, + IDR_AURA_UBER_TRAY_HELP, + IDR_AURA_UBER_TRAY_HELP, + IDR_AURA_UBER_TRAY_HELP_HOVER, + IDR_AURA_UBER_TRAY_HELP_HOVER, + IDS_ASH_STATUS_TRAY_HELP); + help_->SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_HELP)); + view->AddButton(help_); + +#if !defined(OS_WIN) + if (login != ash::user::LOGGED_IN_LOCKED && + login != ash::user::LOGGED_IN_RETAIL_MODE) { + shutdown_ = new TrayPopupHeaderButton(this, + IDR_AURA_UBER_TRAY_SHUTDOWN, + IDR_AURA_UBER_TRAY_SHUTDOWN, + IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, + IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, + IDS_ASH_STATUS_TRAY_SHUTDOWN); + shutdown_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SHUTDOWN)); + view->AddButton(shutdown_); + } + + if (ash::Shell::GetInstance()->session_state_delegate()->CanLockScreen()) { + lock_ = new TrayPopupHeaderButton(this, + IDR_AURA_UBER_TRAY_LOCKSCREEN, + IDR_AURA_UBER_TRAY_LOCKSCREEN, + IDR_AURA_UBER_TRAY_LOCKSCREEN_HOVER, + IDR_AURA_UBER_TRAY_LOCKSCREEN_HOVER, + IDS_ASH_STATUS_TRAY_LOCK); + lock_->SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_LOCK)); + view->AddButton(lock_); + } +#endif // !defined(OS_WIN) +} + +DateDefaultView::~DateDefaultView() { +} + +views::View* DateDefaultView::GetHelpButtonView() { + return help_; +} + +tray::DateView* DateDefaultView::GetDateView() { + return date_view_; +} + +const tray::DateView* DateDefaultView::GetDateView() const { + return date_view_; +} + +void DateDefaultView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + ash::Shell* shell = ash::Shell::GetInstance(); + ash::SystemTrayDelegate* tray_delegate = shell->system_tray_delegate(); + if (sender == help_) { + shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_HELP); + tray_delegate->ShowHelp(); + } else if (sender == shutdown_) { + shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_SHUT_DOWN); + tray_delegate->ShutDown(); + } else if (sender == lock_) { + shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_LOCK_SCREEN); + tray_delegate->RequestLockScreen(); + } else { + NOTREACHED(); + } +} + +} // namespace internal +} // namespace ash diff --git a/ash/system/date/date_default_view.h b/ash/system/date/date_default_view.h new file mode 100644 index 000000000000..3cfe42c53e6d --- /dev/null +++ b/ash/system/date/date_default_view.h @@ -0,0 +1,51 @@ +// 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 ASH_SYSTEM_DATE_DATE_DEFAULT_VIEW_H_ +#define ASH_SYSTEM_DATE_DATE_DEFAULT_VIEW_H_ + +#include "ash/ash_export.h" +#include "ash/system/user/login_status.h" +#include "base/macros.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/view.h" + +namespace ash { +namespace internal { + +namespace tray { +class DateView; +} // namespace tray + +class TrayPopupHeaderButton; + +class ASH_EXPORT DateDefaultView : public views::View, + public views::ButtonListener { + public: + explicit DateDefaultView(ash::user::LoginStatus login); + + virtual ~DateDefaultView(); + + views::View* GetHelpButtonView(); + + tray::DateView* GetDateView(); + const tray::DateView* GetDateView() const; + + private: + // Overridden from views::ButtonListener. + virtual void ButtonPressed(views::Button* sender, + const ui::Event& event) OVERRIDE; + + TrayPopupHeaderButton* help_; + TrayPopupHeaderButton* shutdown_; + TrayPopupHeaderButton* lock_; + tray::DateView* date_view_; + + DISALLOW_COPY_AND_ASSIGN(DateDefaultView); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_SYSTEM_DATE_DATE_DEFAULT_VIEW_H_ diff --git a/ash/system/date/date_view.cc b/ash/system/date/date_view.cc index 10a5ed14d48f..9453837aa6e2 100644 --- a/ash/system/date/date_view.cc +++ b/ash/system/date/date_view.cc @@ -155,6 +155,10 @@ void DateView::UpdateTimeFormat() { UpdateText(); } +base::HourClockType DateView::GetHourTypeForTesting() const { + return hour_type_; +} + void DateView::UpdateTextInternal(const base::Time& now) { SetAccessibleName( base::TimeFormatFriendlyDate(now) + @@ -208,6 +212,10 @@ void TimeView::UpdateTimeFormat() { UpdateText(); } +base::HourClockType TimeView::GetHourTypeForTesting() const { + return hour_type_; +} + void TimeView::UpdateTextInternal(const base::Time& now) { // Just in case |now| is null, do NOT update time; otherwise, it will // crash icu code by calling into base::TimeFormatTimeOfDayWithHourClockType, diff --git a/ash/system/date/date_view.h b/ash/system/date/date_view.h index 92042fb80107..ed7fadb6fef1 100644 --- a/ash/system/date/date_view.h +++ b/ash/system/date/date_view.h @@ -51,7 +51,7 @@ class ASH_EXPORT BaseDateTimeView : public ActionableView { }; // Popup view used to display the date and day of week. -class DateView : public BaseDateTimeView { +class ASH_EXPORT DateView : public BaseDateTimeView { public: DateView(); virtual ~DateView(); @@ -64,6 +64,8 @@ class DateView : public BaseDateTimeView { // Updates the format of the displayed time. void UpdateTimeFormat(); + base::HourClockType GetHourTypeForTesting() const; + private: // Overridden from BaseDateTimeView. virtual void UpdateTextInternal(const base::Time& now) OVERRIDE; @@ -98,6 +100,8 @@ class ASH_EXPORT TimeView : public BaseDateTimeView { // Updates clock layout. void UpdateClockLayout(TrayDate::ClockLayout clock_layout); + base::HourClockType GetHourTypeForTesting() const; + private: friend class TimeViewTest; diff --git a/ash/system/date/tray_date.cc b/ash/system/date/tray_date.cc dissimilarity index 61% index 42e36a925791..ac6754a8555d 100644 --- a/ash/system/date/tray_date.cc +++ b/ash/system/date/tray_date.cc @@ -1,238 +1,117 @@ -// Copyright (c) 2012 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 "ash/system/date/tray_date.h" - -#include "ash/metrics/user_metrics_recorder.h" -#include "ash/session_state_delegate.h" -#include "ash/shell.h" -#include "ash/shell_delegate.h" -#include "ash/system/date/date_view.h" -#include "ash/system/tray/system_tray.h" -#include "ash/system/tray/system_tray_delegate.h" -#include "ash/system/tray/system_tray_notifier.h" -#include "ash/system/tray/tray_constants.h" -#include "ash/system/tray/tray_item_view.h" -#include "ash/system/tray/tray_popup_header_button.h" -#include "base/i18n/time_formatting.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "grit/ash_resources.h" -#include "grit/ash_strings.h" -#include "third_party/icu/source/i18n/unicode/datefmt.h" -#include "third_party/icu/source/i18n/unicode/fieldpos.h" -#include "third_party/icu/source/i18n/unicode/fmtable.h" -#include "third_party/skia/include/core/SkRect.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/size.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/fill_layout.h" -#include "ui/views/painter.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" - -#if defined(OS_CHROMEOS) -#include "ash/system/chromeos/system_clock_observer.h" -#endif - -namespace { - -const int kPaddingVertical = 19; - -} // namespace - -namespace ash { -namespace internal { - -class DateDefaultView : public views::View, - public views::ButtonListener { - public: - explicit DateDefaultView(ash::user::LoginStatus login) - : help_(NULL), - shutdown_(NULL), - lock_(NULL), - date_view_(NULL) { - SetLayoutManager(new views::FillLayout); - - date_view_ = new tray::DateView(); - date_view_->SetBorder(views::Border::CreateEmptyBorder( - kPaddingVertical, ash::kTrayPopupPaddingHorizontal, 0, 0)); - SpecialPopupRow* view = new SpecialPopupRow(); - view->SetContent(date_view_); - AddChildView(view); - - if (login == ash::user::LOGGED_IN_LOCKED || - login == ash::user::LOGGED_IN_NONE) - return; - - date_view_->SetActionable(true); - - help_ = new TrayPopupHeaderButton(this, - IDR_AURA_UBER_TRAY_HELP, - IDR_AURA_UBER_TRAY_HELP, - IDR_AURA_UBER_TRAY_HELP_HOVER, - IDR_AURA_UBER_TRAY_HELP_HOVER, - IDS_ASH_STATUS_TRAY_HELP); - help_->SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_HELP)); - view->AddButton(help_); - -#if !defined(OS_WIN) - if (login != ash::user::LOGGED_IN_LOCKED && - login != ash::user::LOGGED_IN_RETAIL_MODE) { - shutdown_ = new TrayPopupHeaderButton(this, - IDR_AURA_UBER_TRAY_SHUTDOWN, - IDR_AURA_UBER_TRAY_SHUTDOWN, - IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, - IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, - IDS_ASH_STATUS_TRAY_SHUTDOWN); - shutdown_->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SHUTDOWN)); - view->AddButton(shutdown_); - } - - if (ash::Shell::GetInstance()->session_state_delegate()->CanLockScreen()) { - lock_ = new TrayPopupHeaderButton(this, - IDR_AURA_UBER_TRAY_LOCKSCREEN, - IDR_AURA_UBER_TRAY_LOCKSCREEN, - IDR_AURA_UBER_TRAY_LOCKSCREEN_HOVER, - IDR_AURA_UBER_TRAY_LOCKSCREEN_HOVER, - IDS_ASH_STATUS_TRAY_LOCK); - lock_->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_LOCK)); - view->AddButton(lock_); - } -#endif // !defined(OS_WIN) - } - - virtual ~DateDefaultView() {} - - views::View* GetHelpButtonView() const { - return help_; - } - - tray::DateView* GetDateView() const { - return date_view_; - } - - private: - // Overridden from views::ButtonListener. - virtual void ButtonPressed(views::Button* sender, - const ui::Event& event) OVERRIDE { - ash::Shell* shell = ash::Shell::GetInstance(); - ash::SystemTrayDelegate* tray_delegate = shell->system_tray_delegate(); - if (sender == help_) { - shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_HELP); - tray_delegate->ShowHelp(); - } else if (sender == shutdown_) { - shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_SHUT_DOWN); - tray_delegate->ShutDown(); - } else if (sender == lock_) { - shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_LOCK_SCREEN); - tray_delegate->RequestLockScreen(); - } else { - NOTREACHED(); - } - } - - TrayPopupHeaderButton* help_; - TrayPopupHeaderButton* shutdown_; - TrayPopupHeaderButton* lock_; - tray::DateView* date_view_; - - DISALLOW_COPY_AND_ASSIGN(DateDefaultView); -}; - -TrayDate::TrayDate(SystemTray* system_tray) - : SystemTrayItem(system_tray), - time_tray_(NULL), - default_view_(NULL) { -#if defined(OS_CHROMEOS) - system_clock_observer_.reset(new SystemClockObserver()); -#endif - Shell::GetInstance()->system_tray_notifier()->AddClockObserver(this); -} - -TrayDate::~TrayDate() { - Shell::GetInstance()->system_tray_notifier()->RemoveClockObserver(this); -} - -views::View* TrayDate::GetHelpButtonView() const { - if (!default_view_) - return NULL; - return default_view_->GetHelpButtonView(); -} - -views::View* TrayDate::CreateTrayView(user::LoginStatus status) { - CHECK(time_tray_ == NULL); - ClockLayout clock_layout = - (system_tray()->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM || - system_tray()->shelf_alignment() == SHELF_ALIGNMENT_TOP) ? - HORIZONTAL_CLOCK : VERTICAL_CLOCK; - time_tray_ = new tray::TimeView(clock_layout); - views::View* view = new TrayItemView(this); - view->AddChildView(time_tray_); - return view; -} - -views::View* TrayDate::CreateDefaultView(user::LoginStatus status) { - default_view_ = new DateDefaultView(status); - return default_view_; -} - -views::View* TrayDate::CreateDetailedView(user::LoginStatus status) { - return NULL; -} - -void TrayDate::DestroyTrayView() { - time_tray_ = NULL; -} - -void TrayDate::DestroyDefaultView() { - default_view_ = NULL; -} - -void TrayDate::DestroyDetailedView() { -} - -void TrayDate::UpdateAfterLoginStatusChange(user::LoginStatus status) { -} - -void TrayDate::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { - if (time_tray_) { - ClockLayout clock_layout = (alignment == SHELF_ALIGNMENT_BOTTOM || - alignment == SHELF_ALIGNMENT_TOP) ? - HORIZONTAL_CLOCK : VERTICAL_CLOCK; - time_tray_->UpdateClockLayout(clock_layout); - } -} - -void TrayDate::OnDateFormatChanged() { - if (time_tray_) - time_tray_->UpdateTimeFormat(); - if (default_view_) - default_view_->GetDateView()->UpdateTimeFormat(); -} - -void TrayDate::OnSystemClockTimeUpdated() { - if (time_tray_) - time_tray_->UpdateTimeFormat(); - if (default_view_) - default_view_->GetDateView()->UpdateTimeFormat(); -} - -void TrayDate::Refresh() { - if (time_tray_) - time_tray_->UpdateText(); -} - -} // namespace internal -} // namespace ash +// Copyright (c) 2012 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 "ash/system/date/tray_date.h" + +#include "ash/shell.h" +#include "ash/system/date/date_default_view.h" +#include "ash/system/date/date_view.h" +#include "ash/system/tray/system_tray.h" +#include "ash/system/tray/system_tray_notifier.h" +#include "ash/system/tray/tray_item_view.h" + +#if defined(OS_CHROMEOS) +#include "ash/system/chromeos/system_clock_observer.h" +#endif + +namespace ash { +namespace internal { + +TrayDate::TrayDate(SystemTray* system_tray) + : SystemTrayItem(system_tray), + time_tray_(NULL), + default_view_(NULL) { +#if defined(OS_CHROMEOS) + system_clock_observer_.reset(new SystemClockObserver()); +#endif + Shell::GetInstance()->system_tray_notifier()->AddClockObserver(this); +} + +TrayDate::~TrayDate() { + Shell::GetInstance()->system_tray_notifier()->RemoveClockObserver(this); +} + +views::View* TrayDate::GetHelpButtonView() const { + if (!default_view_) + return NULL; + return default_view_->GetHelpButtonView(); +} + +const tray::TimeView* TrayDate::GetTimeTrayForTesting() const { + return time_tray_; +} + +const DateDefaultView* TrayDate::GetDefaultViewForTesting() const { + return default_view_; +} + +views::View* TrayDate::CreateDefaultViewForTesting(user::LoginStatus status) { + return CreateDefaultView(status); +} + +views::View* TrayDate::CreateTrayView(user::LoginStatus status) { + CHECK(time_tray_ == NULL); + ClockLayout clock_layout = + (system_tray()->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM || + system_tray()->shelf_alignment() == SHELF_ALIGNMENT_TOP) ? + HORIZONTAL_CLOCK : VERTICAL_CLOCK; + time_tray_ = new tray::TimeView(clock_layout); + views::View* view = new TrayItemView(this); + view->AddChildView(time_tray_); + return view; +} + +views::View* TrayDate::CreateDefaultView(user::LoginStatus status) { + default_view_ = new DateDefaultView(status); + return default_view_; +} + +views::View* TrayDate::CreateDetailedView(user::LoginStatus status) { + return NULL; +} + +void TrayDate::DestroyTrayView() { + time_tray_ = NULL; +} + +void TrayDate::DestroyDefaultView() { + default_view_ = NULL; +} + +void TrayDate::DestroyDetailedView() { +} + +void TrayDate::UpdateAfterLoginStatusChange(user::LoginStatus status) { +} + +void TrayDate::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { + if (time_tray_) { + ClockLayout clock_layout = (alignment == SHELF_ALIGNMENT_BOTTOM || + alignment == SHELF_ALIGNMENT_TOP) ? + HORIZONTAL_CLOCK : VERTICAL_CLOCK; + time_tray_->UpdateClockLayout(clock_layout); + } +} + +void TrayDate::OnDateFormatChanged() { + if (time_tray_) + time_tray_->UpdateTimeFormat(); + if (default_view_) + default_view_->GetDateView()->UpdateTimeFormat(); +} + +void TrayDate::OnSystemClockTimeUpdated() { + if (time_tray_) + time_tray_->UpdateTimeFormat(); + if (default_view_) + default_view_->GetDateView()->UpdateTimeFormat(); +} + +void TrayDate::Refresh() { + if (time_tray_) + time_tray_->UpdateText(); +} + +} // namespace internal +} // namespace ash diff --git a/ash/system/date/tray_date.h b/ash/system/date/tray_date.h index 6d5825b58800..6ba6e032018c 100644 --- a/ash/system/date/tray_date.h +++ b/ash/system/date/tray_date.h @@ -5,6 +5,7 @@ #ifndef ASH_SYSTEM_DATE_TRAY_DATE_H_ #define ASH_SYSTEM_DATE_TRAY_DATE_H_ +#include "ash/ash_export.h" #include "ash/system/date/clock_observer.h" #include "ash/system/tray/system_tray_item.h" #include "base/memory/scoped_ptr.h" @@ -25,8 +26,7 @@ namespace tray { class TimeView; } -class TrayDate : public SystemTrayItem, - public ClockObserver { +class ASH_EXPORT TrayDate : public SystemTrayItem, public ClockObserver { public: enum ClockLayout { HORIZONTAL_CLOCK, @@ -38,6 +38,10 @@ class TrayDate : public SystemTrayItem, // Returns view for help button if it is exists. Returns NULL otherwise. views::View* GetHelpButtonView() const; + const tray::TimeView* GetTimeTrayForTesting() const; + const DateDefaultView* GetDefaultViewForTesting() const; + views::View* CreateDefaultViewForTesting(user::LoginStatus status); + private: // Overridden from SystemTrayItem. virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE; diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index 48d90c51e277..942b15c0b49c 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc @@ -697,6 +697,10 @@ void SystemTray::AddTrayUserItemForTest(internal::TrayUser* tray_user) { user_items_.push_back(tray_user); } +internal::TrayDate* SystemTray::GetTrayDateForTesting() const { + return tray_date_; +} + bool SystemTray::PerformAction(const ui::Event& event) { // If we're already showing the default view, hide it; otherwise, show it // (and hide any popup that's currently shown). diff --git a/ash/system/tray/system_tray.h b/ash/system/tray/system_tray.h index afe6100f5659..abbbbd694cf7 100644 --- a/ash/system/tray/system_tray.h +++ b/ash/system/tray/system_tray.h @@ -158,6 +158,9 @@ class ASH_EXPORT SystemTray : public internal::TrayBackgroundView, // will be owned by the SystemTray after the call. void AddTrayUserItemForTest(internal::TrayUser* tray_user); + // Gets tray_date_ for browser tests. + internal::TrayDate* GetTrayDateForTesting() const; + private: // Creates the default set of items for the sytem tray. void CreateItems(SystemTrayDelegate* delegate); diff --git a/chrome/browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc b/chrome/browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc new file mode 100644 index 000000000000..3be5289aa322 --- /dev/null +++ b/chrome/browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc @@ -0,0 +1,161 @@ +// 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 "ash/shell.h" +#include "ash/system/date/date_default_view.h" +#include "ash/system/date/date_view.h" +#include "ash/system/user/login_status.h" +#include "base/command_line.h" +#include "base/message_loop/message_loop.h" +#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/browser/ui/ash/system_tray_delegate_chromeos.h" +#include "chromeos/chromeos_switches.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace em = enterprise_management; + +namespace chromeos { + +class SystemUse24HourClockPolicyTest + : public policy::DevicePolicyCrosBrowserTest { + public: + SystemUse24HourClockPolicyTest() { + } + + virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { + command_line->AppendSwitch(switches::kLoginManager); + command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); + } + + virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { + InstallOwnerKey(); + MarkAsEnterpriseOwned(); + DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); + } + + protected: + void RefreshPolicyAndWaitDeviceSettingsUpdated() { + scoped_ptr observer = + CrosSettings::Get()->AddSettingsObserver( + kSystemUse24HourClock, + base::MessageLoop::current()->QuitWhenIdleClosure()); + + RefreshDevicePolicy(); + base::MessageLoop::current()->Run(); + } + + static bool GetSystemTrayDelegateShouldUse24HourClock() { + chromeos::SystemTrayDelegateChromeOS* tray_delegate = + static_cast( + ash::Shell::GetInstance()->system_tray_delegate()); + return tray_delegate->GetShouldUse24HourClockForTesting(); + } + + static base::HourClockType TestGetPrimarySystemTrayTimeHourType() { + const ash::internal::TrayDate* tray_date = ash::Shell::GetInstance()-> + GetPrimarySystemTray()-> + GetTrayDateForTesting(); + const ash::internal::tray::TimeView* time_tray = + tray_date->GetTimeTrayForTesting(); + + return time_tray->GetHourTypeForTesting(); + } + + static bool TestPrimarySystemTrayHasDateDefaultView() { + const ash::internal::TrayDate* tray_date = ash::Shell::GetInstance()-> + GetPrimarySystemTray()-> + GetTrayDateForTesting(); + const ash::internal::DateDefaultView* date_default_view = + tray_date->GetDefaultViewForTesting(); + return (date_default_view != NULL); + } + + static void TestPrimarySystemTrayCreateDefaultView() { + ash::internal::TrayDate* tray_date = ash::Shell::GetInstance()-> + GetPrimarySystemTray()-> + GetTrayDateForTesting(); + tray_date->CreateDefaultViewForTesting(ash::user::LOGGED_IN_NONE); + } + + static base::HourClockType TestGetPrimarySystemTrayDateHourType() { + const ash::internal::TrayDate* tray_date = ash::Shell::GetInstance()-> + GetPrimarySystemTray()-> + GetTrayDateForTesting(); + const ash::internal::DateDefaultView* date_default_view = + tray_date->GetDefaultViewForTesting(); + + return date_default_view->GetDateView()->GetHourTypeForTesting(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(SystemUse24HourClockPolicyTest); +}; + +IN_PROC_BROWSER_TEST_F(SystemUse24HourClockPolicyTest, CheckUnset) { + bool system_use_24hour_clock; + EXPECT_FALSE(CrosSettings::Get()->GetBoolean(kSystemUse24HourClock, + &system_use_24hour_clock)); + + EXPECT_FALSE(GetSystemTrayDelegateShouldUse24HourClock()); + EXPECT_EQ(base::k12HourClock, TestGetPrimarySystemTrayTimeHourType()); + EXPECT_FALSE(TestPrimarySystemTrayHasDateDefaultView()); + + TestPrimarySystemTrayCreateDefaultView(); + EXPECT_EQ(base::k12HourClock, TestGetPrimarySystemTrayDateHourType()); +} + +IN_PROC_BROWSER_TEST_F(SystemUse24HourClockPolicyTest, CheckTrue) { + bool system_use_24hour_clock = true; + EXPECT_FALSE(CrosSettings::Get()->GetBoolean(kSystemUse24HourClock, + &system_use_24hour_clock)); + EXPECT_FALSE(TestPrimarySystemTrayHasDateDefaultView()); + + EXPECT_FALSE(GetSystemTrayDelegateShouldUse24HourClock()); + EXPECT_EQ(base::k12HourClock, TestGetPrimarySystemTrayTimeHourType()); + TestPrimarySystemTrayCreateDefaultView(); + EXPECT_EQ(base::k12HourClock, TestGetPrimarySystemTrayDateHourType()); + + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + proto.mutable_use_24hour_clock()->set_use_24hour_clock(true); + RefreshPolicyAndWaitDeviceSettingsUpdated(); + + system_use_24hour_clock = false; + EXPECT_TRUE(CrosSettings::Get()->GetBoolean(kSystemUse24HourClock, + &system_use_24hour_clock)); + EXPECT_TRUE(system_use_24hour_clock); + EXPECT_TRUE(GetSystemTrayDelegateShouldUse24HourClock()); + EXPECT_EQ(base::k24HourClock, TestGetPrimarySystemTrayTimeHourType()); + + EXPECT_TRUE(TestPrimarySystemTrayHasDateDefaultView()); + EXPECT_EQ(base::k24HourClock, TestGetPrimarySystemTrayDateHourType()); +} + +IN_PROC_BROWSER_TEST_F(SystemUse24HourClockPolicyTest, CheckFalse) { + bool system_use_24hour_clock = true; + EXPECT_FALSE(CrosSettings::Get()->GetBoolean(kSystemUse24HourClock, + &system_use_24hour_clock)); + EXPECT_FALSE(TestPrimarySystemTrayHasDateDefaultView()); + + EXPECT_FALSE(GetSystemTrayDelegateShouldUse24HourClock()); + EXPECT_EQ(base::k12HourClock, TestGetPrimarySystemTrayTimeHourType()); + TestPrimarySystemTrayCreateDefaultView(); + EXPECT_EQ(base::k12HourClock, TestGetPrimarySystemTrayDateHourType()); + + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + proto.mutable_use_24hour_clock()->set_use_24hour_clock(false); + RefreshPolicyAndWaitDeviceSettingsUpdated(); + + system_use_24hour_clock = true; + EXPECT_TRUE(CrosSettings::Get()->GetBoolean(kSystemUse24HourClock, + &system_use_24hour_clock)); + EXPECT_FALSE(system_use_24hour_clock); + EXPECT_FALSE(GetSystemTrayDelegateShouldUse24HourClock()); + EXPECT_EQ(base::k12HourClock, TestGetPrimarySystemTrayTimeHourType()); + EXPECT_TRUE(TestPrimarySystemTrayHasDateDefaultView()); + EXPECT_EQ(base::k12HourClock, TestGetPrimarySystemTrayDateHourType()); +} + +} // namespace chromeos diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc dissimilarity index 79% index c8c1cc42e332..a8edb5b83a52 100644 --- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc @@ -1,1341 +1,1306 @@ -// Copyright 2013 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/ash/system_tray_delegate_chromeos.h" - -#include -#include -#include -#include - -#include "ash/ash_switches.h" -#include "ash/desktop_background/desktop_background_controller.h" -#include "ash/metrics/user_metrics_recorder.h" -#include "ash/session_state_delegate.h" -#include "ash/session_state_observer.h" -#include "ash/shell.h" -#include "ash/shell_delegate.h" -#include "ash/shell_window_ids.h" -#include "ash/system/bluetooth/bluetooth_observer.h" -#include "ash/system/date/clock_observer.h" -#include "ash/system/drive/drive_observer.h" -#include "ash/system/ime/ime_observer.h" -#include "ash/system/logout_button/logout_button_observer.h" -#include "ash/system/tray/system_tray.h" -#include "ash/system/tray/system_tray_delegate.h" -#include "ash/system/tray/system_tray_notifier.h" -#include "ash/system/tray_accessibility.h" -#include "ash/system/tray_caps_lock.h" -#include "ash/system/user/login_status.h" -#include "ash/system/user/update_observer.h" -#include "ash/system/user/user_observer.h" -#include "ash/volume_control_delegate.h" -#include "ash/wm/lock_state_controller.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "base/memory/weak_ptr.h" -#include "base/prefs/pref_service.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/sys_info.h" -#include "base/time/time.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#include "chrome/browser/chromeos/accessibility/magnification_manager.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h" -#include "chrome/browser/chromeos/charger_replace/charger_replacement_dialog.h" -#include "chrome/browser/chromeos/choose_mobile_network_dialog.h" -#include "chrome/browser/chromeos/drive/drive_integration_service.h" -#include "chrome/browser/chromeos/drive/job_list.h" -#include "chrome/browser/chromeos/enrollment_dialog_view.h" -#include "chrome/browser/chromeos/input_method/input_method_util.h" -#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" -#include "chrome/browser/chromeos/login/help_app_launcher.h" -#include "chrome/browser/chromeos/login/login_display_host.h" -#include "chrome/browser/chromeos/login/login_display_host_impl.h" -#include "chrome/browser/chromeos/login/login_wizard.h" -#include "chrome/browser/chromeos/login/startup_utils.h" -#include "chrome/browser/chromeos/login/supervised_user_manager.h" -#include "chrome/browser/chromeos/login/user.h" -#include "chrome/browser/chromeos/login/user_adding_screen.h" -#include "chrome/browser/chromeos/login/user_manager.h" -#include "chrome/browser/chromeos/options/network_config_view.h" -#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/settings/cros_settings.h" -#include "chrome/browser/chromeos/sim_dialog_delegate.h" -#include "chrome/browser/chromeos/system_key_event_listener.h" -#include "chrome/browser/drive/drive_service_interface.h" -#include "chrome/browser/feedback/tracing_manager.h" -#include "chrome/browser/google/google_util.h" -#include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" -#include "chrome/browser/ui/ash/volume_controller_chromeos.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/ui/host_desktop.h" -#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" -#include "chrome/browser/ui/singleton_tabs.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/webui/chromeos/charger_replacement_handler.h" -#include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h" -#include "chrome/browser/upgrade_detector.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chromeos/chromeos_switches.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/session_manager_client.h" -#include "chromeos/ime/extension_ime_util.h" -#include "chromeos/ime/input_method_manager.h" -#include "chromeos/ime/xkeyboard.h" -#include "chromeos/login/login_state.h" -#include "components/policy/core/common/cloud/cloud_policy_store.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/user_metrics.h" -#include "content/public/browser/web_contents.h" -#include "device/bluetooth/bluetooth_adapter.h" -#include "device/bluetooth/bluetooth_adapter_factory.h" -#include "device/bluetooth/bluetooth_device.h" -#include "grit/ash_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "net/base/escape.h" -#include "third_party/cros_system_api/dbus/service_constants.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/l10n/time_format.h" - -using drive::DriveIntegrationService; -using drive::DriveIntegrationServiceFactory; - -namespace chromeos { - -namespace { - -// The minimum session length limit that can be set. -const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds. - -// The maximum session length limit that can be set. -const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours. - -const char kDisplaySettingsSubPageName[] = "display"; -const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan"; - -// The URL for the Google Drive settings page. -const char kDriveSettingsPageURL[] = "https://drive.google.com"; - -void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime, - const input_method::InputMethodUtil& util, - ash::IMEInfo* info) { - info->id = ime.id(); - info->name = util.GetInputMethodLongName(ime); - info->medium_name = util.GetInputMethodMediumName(ime); - info->short_name = util.GetInputMethodShortName(ime); - info->third_party = extension_ime_util::IsExtensionIME(ime.id()); -} - -gfx::NativeWindow GetNativeWindowByStatus( - ash::user::LoginStatus login_status, - bool session_started) { - int container_id = - (!session_started || - login_status == ash::user::LOGGED_IN_NONE || - login_status == ash::user::LOGGED_IN_LOCKED) ? - ash::internal::kShellWindowId_LockSystemModalContainer : - ash::internal::kShellWindowId_SystemModalContainer; - return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), - container_id); -} - -// Converts drive::JobInfo to ash::DriveOperationStatus. -// If the job is not of type that ash tray is interested, returns false. -bool ConvertToDriveOperationStatus(const drive::JobInfo& info, - ash::DriveOperationStatus* status) { - if (info.job_type == drive::TYPE_DOWNLOAD_FILE) { - status->type = ash::DriveOperationStatus::OPERATION_DOWNLOAD; - } else if (info.job_type == drive::TYPE_UPLOAD_NEW_FILE || - info.job_type == drive::TYPE_UPLOAD_EXISTING_FILE) { - status->type = ash::DriveOperationStatus::OPERATION_UPLOAD; - } else { - return false; - } - - if (info.state == drive::STATE_NONE) - status->state = ash::DriveOperationStatus::OPERATION_NOT_STARTED; - else - status->state = ash::DriveOperationStatus::OPERATION_IN_PROGRESS; - - status->id = info.job_id; - status->file_path = info.file_path; - status->progress = info.num_total_bytes == 0 ? 0.0 : - static_cast(info.num_completed_bytes) / - static_cast(info.num_total_bytes); - return true; -} - -// Converts drive::JobInfo that has finished in |error| state -// to ash::DriveOperationStatus. -// If the job is not of type that ash tray is interested, returns false. -bool ConvertToFinishedDriveOperationStatus(const drive::JobInfo& info, - drive::FileError error, - ash::DriveOperationStatus* status) { - if (!ConvertToDriveOperationStatus(info, status)) - return false; - status->state = (error == drive::FILE_ERROR_OK) ? - ash::DriveOperationStatus::OPERATION_COMPLETED : - ash::DriveOperationStatus::OPERATION_FAILED; - return true; -} - -// Converts a list of drive::JobInfo to a list of ash::DriveOperationStatusList. -ash::DriveOperationStatusList ConvertToDriveStatusList( - const std::vector& list) { - ash::DriveOperationStatusList results; - for (size_t i = 0; i < list.size(); ++i) { - ash::DriveOperationStatus status; - if (ConvertToDriveOperationStatus(list[i], &status)) - results.push_back(status); - } - return results; -} - -void BluetoothPowerFailure() { - // TODO(sad): Show an error bubble? -} - -void BluetoothSetDiscoveringError() { - LOG(ERROR) << "BluetoothSetDiscovering failed."; -} - -void BluetoothDeviceConnectError( - device::BluetoothDevice::ConnectErrorCode error_code) { - // TODO(sad): Do something? -} - -// Shows the settings sub page in the last active browser. If there is no such -// browser, creates a new browser with the settings sub page. -void ShowSettingsSubPageForAppropriateBrowser( - const std::string& sub_page, - Profile* profile) { - chrome::ScopedTabbedBrowserDisplayer displayer(profile, - chrome::HOST_DESKTOP_TYPE_ASH); - chrome::ShowSettingsSubPage(displayer.browser(), sub_page); -} - -void ShowNetworkSettingsPage(const std::string& service_path) { - std::string page = chrome::kInternetOptionsSubPage; - page += "?servicePath=" + net::EscapeUrlEncodedData(service_path, true); - content::RecordAction( - base::UserMetricsAction("OpenInternetOptionsDialog")); - ShowSettingsSubPageForAppropriateBrowser( - page, - ProfileManager::GetPrimaryUserProfile()); -} - -void OnAcceptMultiprofilesIntro(bool no_show_again) { - PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); - prefs->SetBoolean(prefs::kMultiProfileNeverShowIntro, no_show_again); - UserAddingScreen::Get()->Start(); -} - -class SystemTrayDelegate : public ash::SystemTrayDelegate, - public SessionManagerClient::Observer, - public drive::JobListObserver, - public content::NotificationObserver, - public input_method::InputMethodManager::Observer, - public chromeos::LoginState::Observer, - public device::BluetoothAdapter::Observer, - public SystemKeyEventListener::CapsLockObserver, - public policy::CloudPolicyStore::Observer, - public ash::SessionStateObserver { - public: - SystemTrayDelegate() - : ui_weak_ptr_factory_( - new base::WeakPtrFactory(this)), - user_profile_(NULL), - clock_type_(base::GetHourClockType()), - search_key_mapped_to_(input_method::kSearchKey), - screen_locked_(false), - have_session_start_time_(false), - have_session_length_limit_(false), - volume_control_delegate_(new VolumeController()) { - // Register notifications on construction so that events such as - // PROFILE_CREATED do not get missed if they happen before Initialize(). - registrar_.reset(new content::NotificationRegistrar); - registrar_->Add(this, - chrome::NOTIFICATION_UPGRADE_RECOMMENDED, - content::NotificationService::AllSources()); - registrar_->Add(this, - chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, - content::NotificationService::AllSources()); - if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) { - registrar_->Add(this, - chrome::NOTIFICATION_SESSION_STARTED, - content::NotificationService::AllSources()); - } - registrar_->Add(this, - chrome::NOTIFICATION_PROFILE_CREATED, - content::NotificationService::AllSources()); - registrar_->Add(this, - chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); - registrar_->Add( - this, - chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER, - content::NotificationService::AllSources()); - registrar_->Add( - this, - chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK, - content::NotificationService::AllSources()); - registrar_->Add( - this, - chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE, - content::NotificationService::AllSources()); - registrar_->Add( - this, - chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, - content::NotificationService::AllSources()); - } - - virtual void Initialize() OVERRIDE { - DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this); - - input_method::InputMethodManager::Get()->AddObserver(this); - UpdateClockType(); - - if (SystemKeyEventListener::GetInstance()) - SystemKeyEventListener::GetInstance()->AddCapsLockObserver(this); - - device::BluetoothAdapterFactory::GetAdapter( - base::Bind(&SystemTrayDelegate::InitializeOnAdapterReady, - ui_weak_ptr_factory_->GetWeakPtr())); - - ash::Shell::GetInstance()->session_state_delegate()-> - AddSessionStateObserver(this); - - if (LoginState::IsInitialized()) - LoginState::Get()->AddObserver(this); - } - - virtual void Shutdown() OVERRIDE { - } - - void InitializeOnAdapterReady( - scoped_refptr adapter) { - bluetooth_adapter_ = adapter; - CHECK(bluetooth_adapter_.get()); - bluetooth_adapter_->AddObserver(this); - - local_state_registrar_.reset(new PrefChangeRegistrar); - local_state_registrar_->Init(g_browser_process->local_state()); - - UpdateSessionStartTime(); - UpdateSessionLengthLimit(); - - local_state_registrar_->Add( - prefs::kSessionStartTime, - base::Bind(&SystemTrayDelegate::UpdateSessionStartTime, - base::Unretained(this))); - local_state_registrar_->Add( - prefs::kSessionLengthLimit, - base::Bind(&SystemTrayDelegate::UpdateSessionLengthLimit, - base::Unretained(this))); - - policy::BrowserPolicyConnectorChromeOS* policy_connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - policy::DeviceCloudPolicyManagerChromeOS* policy_manager = - policy_connector->GetDeviceCloudPolicyManager(); - if (policy_manager) - policy_manager->core()->store()->AddObserver(this); - UpdateEnterpriseDomain(); - } - - virtual ~SystemTrayDelegate() { - // Unregister PrefChangeRegistrars. - local_state_registrar_.reset(); - user_pref_registrar_.reset(); - - // Unregister content notifications befure destroying any components. - registrar_.reset(); - - DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this); - input_method::InputMethodManager::Get()->RemoveObserver(this); - if (SystemKeyEventListener::GetInstance()) - SystemKeyEventListener::GetInstance()->RemoveCapsLockObserver(this); - bluetooth_adapter_->RemoveObserver(this); - ash::Shell::GetInstance()->session_state_delegate()-> - RemoveSessionStateObserver(this); - LoginState::Get()->RemoveObserver(this); - - // Stop observing Drive operations. - UnobserveDriveUpdates(); - - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - policy::DeviceCloudPolicyManagerChromeOS* policy_manager = - connector->GetDeviceCloudPolicyManager(); - if (policy_manager) - policy_manager->core()->store()->RemoveObserver(this); - } - - // Overridden from ash::SystemTrayDelegate: - virtual bool GetTrayVisibilityOnStartup() OVERRIDE { - // In case of OOBE / sign in screen tray will be shown later. - return LoginState::Get()->IsUserLoggedIn(); - } - - virtual ash::user::LoginStatus GetUserLoginStatus() const OVERRIDE { - // All non-logged in ChromeOS specific LOGGED_IN states map to the same - // Ash specific LOGGED_IN state. - if (!LoginState::Get()->IsUserLoggedIn()) - return ash::user::LOGGED_IN_NONE; - - if (screen_locked_) - return ash::user::LOGGED_IN_LOCKED; - - LoginState::LoggedInUserType user_type = - LoginState::Get()->GetLoggedInUserType(); - switch (user_type) { - case LoginState::LOGGED_IN_USER_NONE: - return ash::user::LOGGED_IN_NONE; - case LoginState::LOGGED_IN_USER_REGULAR: - return ash::user::LOGGED_IN_USER; - case LoginState::LOGGED_IN_USER_OWNER: - return ash::user::LOGGED_IN_OWNER; - case LoginState::LOGGED_IN_USER_GUEST: - return ash::user::LOGGED_IN_GUEST; - case LoginState::LOGGED_IN_USER_RETAIL_MODE: - return ash::user::LOGGED_IN_RETAIL_MODE; - case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT: - return ash::user::LOGGED_IN_PUBLIC; - case LoginState::LOGGED_IN_USER_LOCALLY_MANAGED: - return ash::user::LOGGED_IN_LOCALLY_MANAGED; - case LoginState::LOGGED_IN_USER_KIOSK_APP: - return ash::user::LOGGED_IN_KIOSK_APP; - } - NOTREACHED(); - return ash::user::LOGGED_IN_NONE; - } - - virtual bool IsOobeCompleted() const OVERRIDE { - if (!base::SysInfo::IsRunningOnChromeOS() && - LoginState::Get()->IsUserLoggedIn()) - return true; - return StartupUtils::IsOobeCompleted(); - } - - virtual void ChangeProfilePicture() OVERRIDE { - content::RecordAction( - base::UserMetricsAction("OpenChangeProfilePictureDialog")); - ShowSettingsSubPageForAppropriateBrowser( - chrome::kChangeProfilePictureSubPage, - ProfileManager::GetActiveUserProfile()); - } - - virtual const std::string GetEnterpriseDomain() const OVERRIDE { - return enterprise_domain_; - } - - virtual const base::string16 GetEnterpriseMessage() const OVERRIDE { - if (GetEnterpriseDomain().empty()) - return base::string16(); - return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE, - base::UTF8ToUTF16(GetEnterpriseDomain())); - } - - virtual const std::string GetLocallyManagedUserManager() const OVERRIDE { - if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) - return std::string(); - return UserManager::Get()->GetSupervisedUserManager()-> - GetManagerDisplayEmail( - chromeos::UserManager::Get()->GetActiveUser()->email()); - } - - virtual const base::string16 - GetLocallyManagedUserManagerName() const OVERRIDE { - if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) - return base::string16(); - return UserManager::Get()->GetSupervisedUserManager()-> - GetManagerDisplayName( - chromeos::UserManager::Get()->GetActiveUser()->email()); - } - - virtual const base::string16 GetLocallyManagedUserMessage() const OVERRIDE { - if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) - return base::string16(); - return l10n_util::GetStringFUTF16( - IDS_USER_IS_LOCALLY_MANAGED_BY_NOTICE, - base::UTF8ToUTF16(GetLocallyManagedUserManager())); - } - - virtual bool SystemShouldUpgrade() const OVERRIDE { - return UpgradeDetector::GetInstance()->notify_upgrade(); - } - - virtual base::HourClockType GetHourClockType() const OVERRIDE { - return clock_type_; - } - - virtual void ShowSettings() OVERRIDE { - chrome::ScopedTabbedBrowserDisplayer displayer( - ProfileManager::GetActiveUserProfile(), - chrome::HOST_DESKTOP_TYPE_ASH); - chrome::ShowSettings(displayer.browser()); - } - - virtual bool ShouldShowSettings() OVERRIDE { - return UserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings(); - } - - virtual void ShowDateSettings() OVERRIDE { - content::RecordAction(base::UserMetricsAction("ShowDateOptions")); - std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + - l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME); - // Everybody can change the time zone (even though it is a device setting). - ShowSettingsSubPageForAppropriateBrowser( - sub_page, - ProfileManager::GetActiveUserProfile()); - } - - virtual void ShowNetworkSettings(const std::string& service_path) OVERRIDE { - if (!LoginState::Get()->IsUserLoggedIn()) - return; - ShowNetworkSettingsPage(service_path); - } - - virtual void ShowBluetoothSettings() OVERRIDE { - // TODO(sad): Make this work. - } - - virtual void ShowDisplaySettings() OVERRIDE { - content::RecordAction(base::UserMetricsAction("ShowDisplayOptions")); - ShowSettingsSubPageForAppropriateBrowser( - kDisplaySettingsSubPageName, - ProfileManager::GetActiveUserProfile()); - } - - virtual void ShowChromeSlow() OVERRIDE { - chrome::ScopedTabbedBrowserDisplayer displayer( - ProfileManager::GetPrimaryUserProfile(), - chrome::HOST_DESKTOP_TYPE_ASH); - chrome::ShowSlow(displayer.browser()); - } - - virtual bool ShouldShowDisplayNotification() OVERRIDE { - // Packaged app is not counted as 'last active', so if a browser opening the - // display settings is in background of a packaged app, it will return true. - // TODO(mukai): fix this. - Browser* active_browser = chrome::FindLastActiveWithHostDesktopType( - chrome::HOST_DESKTOP_TYPE_ASH); - if (!active_browser) - return true; - - content::WebContents* active_contents = - active_browser->tab_strip_model()->GetActiveWebContents(); - if (!active_contents) - return true; - - GURL visible_url = active_contents->GetLastCommittedURL(); - std::string display_settings_url = - std::string(chrome::kChromeUISettingsURL) + kDisplaySettingsSubPageName; - std::string display_overscan_url = - std::string(chrome::kChromeUISettingsURL) + - kDisplayOverscanSettingsSubPageName; - return (visible_url.spec() != display_settings_url) && - (visible_url.spec() != display_overscan_url); - } - - virtual void ShowDriveSettings() OVERRIDE { - // TODO(tengs): Open the drive-specific settings page once we put it in. - // For now just show Google Drive main page. - chrome::ScopedTabbedBrowserDisplayer displayer( - ProfileManager::GetActiveUserProfile(), - chrome::HOST_DESKTOP_TYPE_ASH); - chrome::ShowSingletonTabOverwritingNTP( - displayer.browser(), - chrome::GetSingletonTabNavigateParams(displayer.browser(), - GURL(kDriveSettingsPageURL))); - } - - virtual void ShowIMESettings() OVERRIDE { - content::RecordAction( - base::UserMetricsAction("OpenLanguageOptionsDialog")); - ShowSettingsSubPageForAppropriateBrowser( - chrome::kLanguageOptionsSubPage, - ProfileManager::GetActiveUserProfile()); - } - - virtual void ShowHelp() OVERRIDE { - chrome::ShowHelpForProfile(ProfileManager::GetActiveUserProfile(), - chrome::HOST_DESKTOP_TYPE_ASH, - chrome::HELP_SOURCE_MENU); - } - - virtual void ShowAccessibilityHelp() OVERRIDE { - chrome::ScopedTabbedBrowserDisplayer displayer( - ProfileManager::GetActiveUserProfile(), - chrome::HOST_DESKTOP_TYPE_ASH); - accessibility::ShowAccessibilityHelp(displayer.browser()); - } - - virtual void ShowAccessibilitySettings() OVERRIDE { - content::RecordAction( - base::UserMetricsAction("ShowAccessibilitySettings")); - std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + - l10n_util::GetStringUTF8( - IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY); - ShowSettingsSubPageForAppropriateBrowser( - sub_page, - ProfileManager::GetActiveUserProfile()); - } - - virtual void ShowPublicAccountInfo() OVERRIDE { - chrome::ScopedTabbedBrowserDisplayer displayer( - ProfileManager::GetActiveUserProfile(), - chrome::HOST_DESKTOP_TYPE_ASH); - chrome::ShowPolicy(displayer.browser()); - } - - virtual void ShowLocallyManagedUserInfo() OVERRIDE { - // TODO(antrim): find out what should we show in this case. - // http://crbug.com/229762 - } - - virtual void ShowEnterpriseInfo() OVERRIDE { - ash::user::LoginStatus status = GetUserLoginStatus(); - if (status == ash::user::LOGGED_IN_NONE || - status == ash::user::LOGGED_IN_LOCKED) { - scoped_refptr help_app( - new chromeos::HelpAppLauncher(GetNativeWindow())); - help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE); - } else { - GURL url(google_util::StringAppendGoogleLocaleParam( - chrome::kLearnMoreEnterpriseURL)); - chrome::ScopedTabbedBrowserDisplayer displayer( - ProfileManager::GetActiveUserProfile(), - chrome::HOST_DESKTOP_TYPE_ASH); - chrome::ShowSingletonTab(displayer.browser(), url); - } - } - - virtual void ShowUserLogin() OVERRIDE { - ash::Shell* shell = ash::Shell::GetInstance(); - if (!shell->delegate()->IsMultiProfilesEnabled()) - return; - - // Only regular users could add other users to current session. - if (UserManager::Get()->GetActiveUser()->GetType() != - User::USER_TYPE_REGULAR) { - return; - } - - if (static_cast(UserManager::Get()->GetLoggedInUsers().size()) >= - shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers()) - return; - - // Launch sign in screen to add another user to current session. - if (UserManager::Get()->GetUsersAdmittedForMultiProfile().size()) { - // Don't show dialog if any logged in user in multi-profiles session - // dismissed it. - bool show_intro = true; - const UserList logged_in_users = UserManager::Get()->GetLoggedInUsers(); - for (UserList::const_iterator it = logged_in_users.begin(); - it != logged_in_users.end(); ++it) { - show_intro &= !multi_user_util::GetProfileFromUserID( - multi_user_util::GetUserIDFromEmail((*it)->email()))->GetPrefs()-> - GetBoolean(prefs::kMultiProfileNeverShowIntro); - if (!show_intro) - break; - } - if (show_intro) { - base::Callback on_accept = - base::Bind(&OnAcceptMultiprofilesIntro); - ShowMultiprofilesIntroDialog(on_accept); - } else { - UserAddingScreen::Get()->Start(); - } - } - } - - virtual void ShowSpringChargerReplacementDialog() OVERRIDE { - if (!ChargerReplacementDialog::ShouldShowDialog()) - return; - - ChargerReplacementDialog* dialog = - new ChargerReplacementDialog(GetNativeWindow()); - dialog->Show(); - } - - virtual bool HasUserConfirmedSafeSpringCharger() OVERRIDE { - return ChargerReplacementHandler::GetChargerStatusPref() == - ChargerReplacementHandler::CONFIRM_SAFE_CHARGER; - } - - virtual void ShutDown() OVERRIDE { - ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown(); - } - - virtual void SignOut() OVERRIDE { - chrome::AttemptUserExit(); - } - - virtual void RequestLockScreen() OVERRIDE { - // TODO(antrim) : additional logging for crbug/173178 - LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate"; - DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen(); - } - - virtual void RequestRestartForUpdate() OVERRIDE { - // We expect that UpdateEngine is in "Reboot for update" state now. - chrome::NotifyAndTerminate(true /* fast path */); - } - - virtual void GetAvailableBluetoothDevices( - ash::BluetoothDeviceList* list) OVERRIDE { - device::BluetoothAdapter::DeviceList devices = - bluetooth_adapter_->GetDevices(); - for (size_t i = 0; i < devices.size(); ++i) { - device::BluetoothDevice* device = devices[i]; - ash::BluetoothDeviceInfo info; - info.address = device->GetAddress(); - info.display_name = device->GetName(); - info.connected = device->IsConnected(); - info.connecting = device->IsConnecting(); - info.paired = device->IsPaired(); - list->push_back(info); - } - } - - virtual void BluetoothStartDiscovering() OVERRIDE { - bluetooth_adapter_->StartDiscovering( - base::Bind(&base::DoNothing), - base::Bind(&BluetoothSetDiscoveringError)); - } - - virtual void BluetoothStopDiscovering() OVERRIDE { - bluetooth_adapter_->StopDiscovering( - base::Bind(&base::DoNothing), - base::Bind(&BluetoothSetDiscoveringError)); - } - - virtual void ConnectToBluetoothDevice(const std::string& address) OVERRIDE { - device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address); - if (!device || device->IsConnecting() || - (device->IsConnected() && device->IsPaired())) { - return; - } - if (device->IsPaired() && !device->IsConnectable()) - return; - if (device->IsPaired() || !device->IsPairable()) { - ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction( - ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE); - device->Connect( - NULL, - base::Bind(&base::DoNothing), - base::Bind(&BluetoothDeviceConnectError)); - } else { // Show paring dialog for the unpaired device. - ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction( - ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE); - BluetoothPairingDialog* dialog = - new BluetoothPairingDialog(GetNativeWindow(), device); - // The dialog deletes itself on close. - dialog->Show(); - } - } - - virtual bool IsBluetoothDiscovering() OVERRIDE { - return bluetooth_adapter_->IsDiscovering(); - } - - virtual void GetCurrentIME(ash::IMEInfo* info) OVERRIDE { - input_method::InputMethodManager* manager = - input_method::InputMethodManager::Get(); - input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); - input_method::InputMethodDescriptor ime = manager->GetCurrentInputMethod(); - ExtractIMEInfo(ime, *util, info); - info->selected = true; - } - - virtual void GetAvailableIMEList(ash::IMEInfoList* list) OVERRIDE { - input_method::InputMethodManager* manager = - input_method::InputMethodManager::Get(); - input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); - scoped_ptr ime_descriptors( - manager->GetActiveInputMethods()); - std::string current = manager->GetCurrentInputMethod().id(); - for (size_t i = 0; i < ime_descriptors->size(); i++) { - input_method::InputMethodDescriptor& ime = ime_descriptors->at(i); - ash::IMEInfo info; - ExtractIMEInfo(ime, *util, &info); - info.selected = ime.id() == current; - list->push_back(info); - } - } - - virtual void GetCurrentIMEProperties( - ash::IMEPropertyInfoList* list) OVERRIDE { - input_method::InputMethodManager* manager = - input_method::InputMethodManager::Get(); - input_method::InputMethodPropertyList properties = - manager->GetCurrentInputMethodProperties(); - for (size_t i = 0; i < properties.size(); ++i) { - ash::IMEPropertyInfo property; - property.key = properties[i].key; - property.name = base::UTF8ToUTF16(properties[i].label); - property.selected = properties[i].is_selection_item_checked; - list->push_back(property); - } - } - - virtual void SwitchIME(const std::string& ime_id) OVERRIDE { - input_method::InputMethodManager::Get()->ChangeInputMethod(ime_id); - } - - virtual void ActivateIMEProperty(const std::string& key) OVERRIDE { - input_method::InputMethodManager::Get()-> - ActivateInputMethodProperty(key); - } - - virtual void CancelDriveOperation(int32 operation_id) OVERRIDE { - DriveIntegrationService* integration_service = - FindDriveIntegrationService(); - if (!integration_service) - return; - - integration_service->job_list()->CancelJob(operation_id); - } - - virtual void GetDriveOperationStatusList( - ash::DriveOperationStatusList* list) OVERRIDE { - DriveIntegrationService* integration_service = - FindDriveIntegrationService(); - if (!integration_service) - return; - - *list = ConvertToDriveStatusList( - integration_service->job_list()->GetJobInfoList()); - } - - virtual void ShowNetworkConfigure(const std::string& network_id, - gfx::NativeWindow parent_window) OVERRIDE { - NetworkConfigView::Show(network_id, parent_window); - } - - virtual bool EnrollNetwork(const std::string& network_id, - gfx::NativeWindow parent_window) OVERRIDE { - return enrollment::CreateDialog(network_id, parent_window); - } - - virtual void ManageBluetoothDevices() OVERRIDE { - content::RecordAction( - base::UserMetricsAction("ShowBluetoothSettingsPage")); - std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + - l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH); - ShowSettingsSubPageForAppropriateBrowser( - sub_page, - ProfileManager::GetPrimaryUserProfile()); - } - - virtual void ToggleBluetooth() OVERRIDE { - bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(), - base::Bind(&base::DoNothing), - base::Bind(&BluetoothPowerFailure)); - } - - virtual void ShowMobileSimDialog() OVERRIDE { - SimDialogDelegate::ShowDialog(GetNativeWindow(), - SimDialogDelegate::SIM_DIALOG_UNLOCK); - } - - virtual void ShowMobileSetupDialog(const std::string& service_path) OVERRIDE { - MobileSetupDialog::Show(service_path); - } - - virtual void ShowOtherNetworkDialog(const std::string& type) OVERRIDE { - if (type == shill::kTypeCellular) { - ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); - return; - } - NetworkConfigView::ShowForType(type, GetNativeWindow()); - } - - virtual bool GetBluetoothAvailable() OVERRIDE { - return bluetooth_adapter_->IsPresent(); - } - - virtual bool GetBluetoothEnabled() OVERRIDE { - return bluetooth_adapter_->IsPowered(); - } - - virtual void ChangeProxySettings() OVERRIDE { - CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE); - LoginDisplayHostImpl::default_host()->OpenProxySettings(); - } - - virtual ash::VolumeControlDelegate* - GetVolumeControlDelegate() const OVERRIDE { - return volume_control_delegate_.get(); - } - - virtual void SetVolumeControlDelegate( - scoped_ptr delegate) OVERRIDE { - volume_control_delegate_.swap(delegate); - } - - virtual bool GetSessionStartTime( - base::TimeTicks* session_start_time) OVERRIDE { - *session_start_time = session_start_time_; - return have_session_start_time_; - } - - virtual bool GetSessionLengthLimit( - base::TimeDelta* session_length_limit) OVERRIDE { - *session_length_limit = session_length_limit_; - return have_session_length_limit_; - } - - virtual int GetSystemTrayMenuWidth() OVERRIDE { - return l10n_util::GetLocalizedContentsWidthInPixels( - IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS); - } - - virtual void ActiveUserWasChanged() OVERRIDE { - GetSystemTrayNotifier()->NotifyUserUpdate(); - } - - private: - ash::SystemTray* GetPrimarySystemTray() { - return ash::Shell::GetInstance()->GetPrimarySystemTray(); - } - - ash::SystemTrayNotifier* GetSystemTrayNotifier() { - return ash::Shell::GetInstance()->system_tray_notifier(); - } - - void SetProfile(Profile* profile) { - // Stop observing the current |user_profile_| on Drive integration status. - UnobserveDriveUpdates(); - - user_profile_ = profile; - - // Restart observation, now for the newly set |profile|. - ObserveDriveUpdates(); - - PrefService* prefs = profile->GetPrefs(); - user_pref_registrar_.reset(new PrefChangeRegistrar); - user_pref_registrar_->Init(prefs); - user_pref_registrar_->Add( - prefs::kUse24HourClock, - base::Bind(&SystemTrayDelegate::UpdateClockType, - base::Unretained(this))); - user_pref_registrar_->Add( - prefs::kLanguageRemapSearchKeyTo, - base::Bind(&SystemTrayDelegate::OnLanguageRemapSearchKeyToChanged, - base::Unretained(this))); - user_pref_registrar_->Add( - prefs::kShowLogoutButtonInTray, - base::Bind(&SystemTrayDelegate::UpdateShowLogoutButtonInTray, - base::Unretained(this))); - user_pref_registrar_->Add( - prefs::kLogoutDialogDurationMs, - base::Bind(&SystemTrayDelegate::UpdateLogoutDialogDuration, - base::Unretained(this))); - user_pref_registrar_->Add( - prefs::kLargeCursorEnabled, - base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged, - base::Unretained(this), - ash::A11Y_NOTIFICATION_NONE)); - user_pref_registrar_->Add( - prefs::kAutoclickEnabled, - base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged, - base::Unretained(this), - ash::A11Y_NOTIFICATION_NONE)); - user_pref_registrar_->Add( - prefs::kShouldAlwaysShowAccessibilityMenu, - base::Bind(&SystemTrayDelegate::OnAccessibilityModeChanged, - base::Unretained(this), - ash::A11Y_NOTIFICATION_NONE)); - user_pref_registrar_->Add( - prefs::kPerformanceTracingEnabled, - base::Bind(&SystemTrayDelegate::UpdatePerformanceTracing, - base::Unretained(this))); - - UpdateClockType(); - UpdateShowLogoutButtonInTray(); - UpdateLogoutDialogDuration(); - UpdatePerformanceTracing(); - search_key_mapped_to_ = - profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo); - } - - bool UnsetProfile(Profile* profile) { - if (profile != user_profile_) - return false; - user_pref_registrar_.reset(); - return true; - } - - void ObserveDriveUpdates() { - DriveIntegrationService* integration_service = - FindDriveIntegrationService(); - if (integration_service) - integration_service->job_list()->AddObserver(this); - } - - void UnobserveDriveUpdates() { - DriveIntegrationService* integration_service = - FindDriveIntegrationService(); - if (integration_service) - integration_service->job_list()->RemoveObserver(this); - } - - bool ShouldUse24HourClock() const { - // On login screen and in guest mode owner default is used for - // kUse24HourClock preference. - const ash::user::LoginStatus status = GetUserLoginStatus(); - const CrosSettings* const cros_settings = CrosSettings::Get(); - bool system_use_24_hour_clock = true; - const bool system_value_found = cros_settings->GetBoolean( - kSystemUse24HourClock, &system_use_24_hour_clock); - - if (status == ash::user::LOGGED_IN_NONE) - return (system_value_found - ? system_use_24_hour_clock - : (base::GetHourClockType() == base::k24HourClock)); - - const PrefService::Preference* user_pref = - user_pref_registrar_->prefs()->FindPreference(prefs::kUse24HourClock); - if (status == ash::user::LOGGED_IN_GUEST && user_pref->IsDefaultValue()) - return (system_value_found - ? system_use_24_hour_clock - : (base::GetHourClockType() == base::k24HourClock)); - - bool use_24_hour_clock = true; - user_pref->GetValue()->GetAsBoolean(&use_24_hour_clock); - return use_24_hour_clock; - } - - void UpdateClockType() { - if (!user_pref_registrar_) - return; - - const bool use_24_hour_clock = ShouldUse24HourClock(); - clock_type_ = use_24_hour_clock ? base::k24HourClock : base::k12HourClock; - GetSystemTrayNotifier()->NotifyDateFormatChanged(); - // This also works for enterprise-managed devices because they never have - // local owner. - if (chromeos::UserManager::Get()->IsCurrentUserOwner()) - CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, use_24_hour_clock); - } - - void UpdateShowLogoutButtonInTray() { - GetSystemTrayNotifier()->NotifyShowLoginButtonChanged( - user_pref_registrar_->prefs()->GetBoolean( - prefs::kShowLogoutButtonInTray)); - } - - void UpdateLogoutDialogDuration() { - const int duration_ms = user_pref_registrar_->prefs()->GetInteger( - prefs::kLogoutDialogDurationMs); - GetSystemTrayNotifier()->NotifyLogoutDialogDurationChanged( - base::TimeDelta::FromMilliseconds(duration_ms)); - } - - void UpdateSessionStartTime() { - const PrefService* local_state = local_state_registrar_->prefs(); - if (local_state->HasPrefPath(prefs::kSessionStartTime)) { - have_session_start_time_ = true; - session_start_time_ = base::TimeTicks::FromInternalValue( - local_state->GetInt64(prefs::kSessionStartTime)); - } else { - have_session_start_time_ = false; - session_start_time_ = base::TimeTicks(); - } - GetSystemTrayNotifier()->NotifySessionStartTimeChanged(); - } - - void UpdateSessionLengthLimit() { - const PrefService* local_state = local_state_registrar_->prefs(); - if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) { - have_session_length_limit_ = true; - session_length_limit_ = base::TimeDelta::FromMilliseconds( - std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit), - kSessionLengthLimitMinMs), - kSessionLengthLimitMaxMs)); - } else { - have_session_length_limit_ = false; - session_length_limit_ = base::TimeDelta(); - } - GetSystemTrayNotifier()->NotifySessionLengthLimitChanged(); - } - - // LoginState::Observer overrides. - virtual void LoggedInStateChanged() OVERRIDE { - // It apparently sometimes takes a while after login before the current user - // is recognized as the owner. Make sure that the system-wide clock setting - // is updated when the recognition eventually happens - // (http://crbug.com/278601). - // - // Note that it isn't safe to blindly call UpdateClockType() from this - // method, as LoggedInStateChanged() is also called before the logged-in - // user's profile has actually been loaded (http://crbug.com/317745). The - // system tray's time format is updated at login via SetProfile(). - if (chromeos::UserManager::Get()->IsCurrentUserOwner()) { - CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, - ShouldUse24HourClock()); - } - } - - // Overridden from SessionManagerClient::Observer. - virtual void LockScreen() OVERRIDE { - screen_locked_ = true; - ash::Shell::GetInstance()->UpdateAfterLoginStatusChange( - GetUserLoginStatus()); - } - - virtual void ScreenIsUnlocked() OVERRIDE { - screen_locked_ = false; - ash::Shell::GetInstance()->UpdateAfterLoginStatusChange( - GetUserLoginStatus()); - } - - gfx::NativeWindow GetNativeWindow() const { - bool session_started = ash::Shell::GetInstance()->session_state_delegate() - ->IsActiveUserSessionStarted(); - return GetNativeWindowByStatus(GetUserLoginStatus(), session_started); - } - - // content::NotificationObserver implementation. - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) OVERRIDE { - switch (type) { - case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: { - UpgradeDetector* detector = - content::Source(source).ptr(); - ash::UpdateObserver::UpdateSeverity severity = - ash::UpdateObserver::UPDATE_NORMAL; - switch (detector->upgrade_notification_stage()) { - case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE: - severity = ash::UpdateObserver::UPDATE_SEVERE_RED; - break; - - case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH: - severity = ash::UpdateObserver::UPDATE_HIGH_ORANGE; - break; - - case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED: - severity = ash::UpdateObserver::UPDATE_LOW_GREEN; - break; - - case UpgradeDetector::UPGRADE_ANNOYANCE_LOW: - default: - severity = ash::UpdateObserver::UPDATE_NORMAL; - break; - } - GetSystemTrayNotifier()->NotifyUpdateRecommended(severity); - break; - } - case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: { - // This notification is also sent on login screen when user avatar - // is loaded from file. - if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) { - GetSystemTrayNotifier()->NotifyUserUpdate(); - } - break; - } - case chrome::NOTIFICATION_PROFILE_CREATED: { - SetProfile(content::Source(source).ptr()); - registrar_->Remove(this, - chrome::NOTIFICATION_PROFILE_CREATED, - content::NotificationService::AllSources()); - break; - } - case chrome::NOTIFICATION_PROFILE_DESTROYED: { - if (UnsetProfile(content::Source(source).ptr())) { - registrar_->Remove(this, - chrome::NOTIFICATION_PROFILE_DESTROYED, - content::NotificationService::AllSources()); - } - break; - } - case chrome::NOTIFICATION_SESSION_STARTED: { - ash::Shell::GetInstance()->UpdateAfterLoginStatusChange( - GetUserLoginStatus()); - SetProfile(ProfileManager::GetActiveUserProfile()); - break; - } - case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK: - case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE: - case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER: - case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD: { - AccessibilityStatusEventDetails* accessibility_status = - content::Details(details).ptr(); - OnAccessibilityModeChanged(accessibility_status->notify); - break; - } - default: - NOTREACHED(); - } - } - - void OnLanguageRemapSearchKeyToChanged() { - search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger( - prefs::kLanguageRemapSearchKeyTo); - } - - void OnAccessibilityModeChanged( - ash::AccessibilityNotificationVisibility notify) { - GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify); - } - - void UpdatePerformanceTracing() { - if (!user_pref_registrar_) - return; - bool value = - user_pref_registrar_->prefs()->GetBoolean( - prefs::kPerformanceTracingEnabled); - GetSystemTrayNotifier()->NotifyTracingModeChanged(value); - } - - // Overridden from InputMethodManager::Observer. - virtual void InputMethodChanged( - input_method::InputMethodManager* manager, bool show_message) OVERRIDE { - // |show_message| in ash means the message_center notifications - // which should not be shown unless kDisableIMEModeIndicator is - // on, since the mode indicator already notifies the user. - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableIMEModeIndicator)) { - show_message = false; - } - GetSystemTrayNotifier()->NotifyRefreshIME(show_message); - } - - virtual void InputMethodPropertyChanged( - input_method::InputMethodManager* manager) OVERRIDE { - GetSystemTrayNotifier()->NotifyRefreshIME(false); - } - - // drive::JobListObserver overrides. - virtual void OnJobAdded(const drive::JobInfo& job_info) OVERRIDE { - OnJobUpdated(job_info); - } - - virtual void OnJobDone(const drive::JobInfo& job_info, - drive::FileError error) OVERRIDE { - ash::DriveOperationStatus status; - if (ConvertToFinishedDriveOperationStatus(job_info, error, &status)) - GetSystemTrayNotifier()->NotifyDriveJobUpdated(status); - } - - virtual void OnJobUpdated(const drive::JobInfo& job_info) OVERRIDE { - ash::DriveOperationStatus status; - if (ConvertToDriveOperationStatus(job_info, &status)) - GetSystemTrayNotifier()->NotifyDriveJobUpdated(status); - } - - DriveIntegrationService* FindDriveIntegrationService() { - return user_profile_ ? - DriveIntegrationServiceFactory::FindForProfile(user_profile_) : NULL; - } - - // Overridden from BluetoothAdapter::Observer. - virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter, - bool present) OVERRIDE { - GetSystemTrayNotifier()->NotifyRefreshBluetooth(); - } - - virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter, - bool powered) OVERRIDE { - GetSystemTrayNotifier()->NotifyRefreshBluetooth(); - } - - virtual void AdapterDiscoveringChanged(device::BluetoothAdapter* adapter, - bool discovering) OVERRIDE { - GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged(); - } - - virtual void DeviceAdded(device::BluetoothAdapter* adapter, - device::BluetoothDevice* device) OVERRIDE { - GetSystemTrayNotifier()->NotifyRefreshBluetooth(); - } - - virtual void DeviceChanged(device::BluetoothAdapter* adapter, - device::BluetoothDevice* device) OVERRIDE { - GetSystemTrayNotifier()->NotifyRefreshBluetooth(); - } - - virtual void DeviceRemoved(device::BluetoothAdapter* adapter, - device::BluetoothDevice* device) OVERRIDE { - GetSystemTrayNotifier()->NotifyRefreshBluetooth(); - } - - // Overridden from SystemKeyEventListener::CapsLockObserver. - virtual void OnCapsLockChange(bool enabled) OVERRIDE { - bool search_mapped_to_caps_lock = false; - if (!base::SysInfo::IsRunningOnChromeOS() || - search_key_mapped_to_ == input_method::kCapsLockKey) - search_mapped_to_caps_lock = true; - GetSystemTrayNotifier()->NotifyCapsLockChanged( - enabled, search_mapped_to_caps_lock); - } - - void UpdateEnterpriseDomain() { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - std::string enterprise_domain = connector->GetEnterpriseDomain(); - if (enterprise_domain_ != enterprise_domain) { - enterprise_domain_ = enterprise_domain; - GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged(); - } - } - - // Overridden from CloudPolicyStore::Observer - virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE { - UpdateEnterpriseDomain(); - } - - virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE { - UpdateEnterpriseDomain(); - } - - // Overridden from ash::SessionStateObserver - virtual void UserAddedToSession(const std::string& user_id) OVERRIDE { - GetSystemTrayNotifier()->NotifyUserAddedToSession(); - } - - scoped_ptr > ui_weak_ptr_factory_; - scoped_ptr registrar_; - scoped_ptr local_state_registrar_; - scoped_ptr user_pref_registrar_; - Profile* user_profile_; - base::HourClockType clock_type_; - int search_key_mapped_to_; - bool screen_locked_; - bool have_session_start_time_; - base::TimeTicks session_start_time_; - bool have_session_length_limit_; - base::TimeDelta session_length_limit_; - std::string enterprise_domain_; - - scoped_refptr bluetooth_adapter_; - scoped_ptr volume_control_delegate_; - - DISALLOW_COPY_AND_ASSIGN(SystemTrayDelegate); -}; - -} // namespace - -ash::SystemTrayDelegate* CreateSystemTrayDelegate() { - return new chromeos::SystemTrayDelegate(); -} - -} // namespace chromeos +// Copyright 2013 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/ash/system_tray_delegate_chromeos.h" + +#include +#include +#include +#include + +#include "ash/ash_switches.h" +#include "ash/desktop_background/desktop_background_controller.h" +#include "ash/metrics/user_metrics_recorder.h" +#include "ash/session_state_delegate.h" +#include "ash/session_state_observer.h" +#include "ash/shell.h" +#include "ash/shell_delegate.h" +#include "ash/shell_window_ids.h" +#include "ash/system/bluetooth/bluetooth_observer.h" +#include "ash/system/date/clock_observer.h" +#include "ash/system/drive/drive_observer.h" +#include "ash/system/ime/ime_observer.h" +#include "ash/system/logout_button/logout_button_observer.h" +#include "ash/system/tray/system_tray.h" +#include "ash/system/tray/system_tray_delegate.h" +#include "ash/system/tray/system_tray_notifier.h" +#include "ash/system/tray_accessibility.h" +#include "ash/system/tray_caps_lock.h" +#include "ash/system/user/login_status.h" +#include "ash/system/user/update_observer.h" +#include "ash/system/user/user_observer.h" +#include "ash/volume_control_delegate.h" +#include "ash/wm/lock_state_controller.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "base/memory/weak_ptr.h" +#include "base/prefs/pref_service.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "base/sys_info.h" +#include "base/time/time.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" +#include "chrome/browser/chromeos/accessibility/magnification_manager.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h" +#include "chrome/browser/chromeos/charger_replace/charger_replacement_dialog.h" +#include "chrome/browser/chromeos/choose_mobile_network_dialog.h" +#include "chrome/browser/chromeos/drive/drive_integration_service.h" +#include "chrome/browser/chromeos/drive/job_list.h" +#include "chrome/browser/chromeos/enrollment_dialog_view.h" +#include "chrome/browser/chromeos/input_method/input_method_util.h" +#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" +#include "chrome/browser/chromeos/login/help_app_launcher.h" +#include "chrome/browser/chromeos/login/login_display_host.h" +#include "chrome/browser/chromeos/login/login_display_host_impl.h" +#include "chrome/browser/chromeos/login/login_wizard.h" +#include "chrome/browser/chromeos/login/startup_utils.h" +#include "chrome/browser/chromeos/login/supervised_user_manager.h" +#include "chrome/browser/chromeos/login/user.h" +#include "chrome/browser/chromeos/login/user_adding_screen.h" +#include "chrome/browser/chromeos/login/user_manager.h" +#include "chrome/browser/chromeos/options/network_config_view.h" +#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/settings/cros_settings.h" +#include "chrome/browser/chromeos/sim_dialog_delegate.h" +#include "chrome/browser/chromeos/system_key_event_listener.h" +#include "chrome/browser/drive/drive_service_interface.h" +#include "chrome/browser/feedback/tracing_manager.h" +#include "chrome/browser/google/google_util.h" +#include "chrome/browser/lifetime/application_lifetime.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" +#include "chrome/browser/ui/ash/volume_controller_chromeos.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/host_desktop.h" +#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" +#include "chrome/browser/ui/singleton_tabs.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/webui/chromeos/charger_replacement_handler.h" +#include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h" +#include "chrome/browser/upgrade_detector.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/url_constants.h" +#include "chromeos/chromeos_switches.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/session_manager_client.h" +#include "chromeos/ime/extension_ime_util.h" +#include "chromeos/ime/input_method_manager.h" +#include "chromeos/ime/xkeyboard.h" +#include "chromeos/login/login_state.h" +#include "components/policy/core/common/cloud/cloud_policy_store.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/user_metrics.h" +#include "content/public/browser/web_contents.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/bluetooth_device.h" +#include "grit/ash_strings.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" +#include "net/base/escape.h" +#include "third_party/cros_system_api/dbus/service_constants.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/l10n/time_format.h" + +using drive::DriveIntegrationService; +using drive::DriveIntegrationServiceFactory; + +namespace chromeos { + +namespace { + +// The minimum session length limit that can be set. +const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds. + +// The maximum session length limit that can be set. +const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours. + +const char kDisplaySettingsSubPageName[] = "display"; +const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan"; + +// The URL for the Google Drive settings page. +const char kDriveSettingsPageURL[] = "https://drive.google.com"; + +void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime, + const input_method::InputMethodUtil& util, + ash::IMEInfo* info) { + info->id = ime.id(); + info->name = util.GetInputMethodLongName(ime); + info->medium_name = util.GetInputMethodMediumName(ime); + info->short_name = util.GetInputMethodShortName(ime); + info->third_party = extension_ime_util::IsExtensionIME(ime.id()); +} + +gfx::NativeWindow GetNativeWindowByStatus(ash::user::LoginStatus login_status, + bool session_started) { + int container_id = + (!session_started || login_status == ash::user::LOGGED_IN_NONE || + login_status == ash::user::LOGGED_IN_LOCKED) ? + ash::internal::kShellWindowId_LockSystemModalContainer : + ash::internal::kShellWindowId_SystemModalContainer; + return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), + container_id); +} + +// Converts drive::JobInfo to ash::DriveOperationStatus. +// If the job is not of type that ash tray is interested, returns false. +bool ConvertToDriveOperationStatus(const drive::JobInfo& info, + ash::DriveOperationStatus* status) { + if (info.job_type == drive::TYPE_DOWNLOAD_FILE) { + status->type = ash::DriveOperationStatus::OPERATION_DOWNLOAD; + } else if (info.job_type == drive::TYPE_UPLOAD_NEW_FILE || + info.job_type == drive::TYPE_UPLOAD_EXISTING_FILE) { + status->type = ash::DriveOperationStatus::OPERATION_UPLOAD; + } else { + return false; + } + + if (info.state == drive::STATE_NONE) + status->state = ash::DriveOperationStatus::OPERATION_NOT_STARTED; + else + status->state = ash::DriveOperationStatus::OPERATION_IN_PROGRESS; + + status->id = info.job_id; + status->file_path = info.file_path; + status->progress = info.num_total_bytes == 0 ? 0.0 : + static_cast(info.num_completed_bytes) / + static_cast(info.num_total_bytes); + return true; +} + +// Converts drive::JobInfo that has finished in |error| state +// to ash::DriveOperationStatus. +// If the job is not of type that ash tray is interested, returns false. +bool ConvertToFinishedDriveOperationStatus(const drive::JobInfo& info, + drive::FileError error, + ash::DriveOperationStatus* status) { + if (!ConvertToDriveOperationStatus(info, status)) + return false; + status->state = (error == drive::FILE_ERROR_OK) + ? ash::DriveOperationStatus::OPERATION_COMPLETED + : ash::DriveOperationStatus::OPERATION_FAILED; + return true; +} + +// Converts a list of drive::JobInfo to a list of ash::DriveOperationStatusList. +ash::DriveOperationStatusList ConvertToDriveStatusList( + const std::vector& list) { + ash::DriveOperationStatusList results; + for (size_t i = 0; i < list.size(); ++i) { + ash::DriveOperationStatus status; + if (ConvertToDriveOperationStatus(list[i], &status)) + results.push_back(status); + } + return results; +} + +void BluetoothPowerFailure() { + // TODO(sad): Show an error bubble? +} + +void BluetoothSetDiscoveringError() { + LOG(ERROR) << "BluetoothSetDiscovering failed."; +} + +void BluetoothDeviceConnectError( + device::BluetoothDevice::ConnectErrorCode error_code) { + // TODO(sad): Do something? +} + +// Shows the settings sub page in the last active browser. If there is no such +// browser, creates a new browser with the settings sub page. +void ShowSettingsSubPageForAppropriateBrowser(const std::string& sub_page, + Profile* profile) { + chrome::ScopedTabbedBrowserDisplayer displayer(profile, + chrome::HOST_DESKTOP_TYPE_ASH); + chrome::ShowSettingsSubPage(displayer.browser(), sub_page); +} + +void ShowNetworkSettingsPage(const std::string& service_path) { + std::string page = chrome::kInternetOptionsSubPage; + page += "?servicePath=" + net::EscapeUrlEncodedData(service_path, true); + content::RecordAction(base::UserMetricsAction("OpenInternetOptionsDialog")); + ShowSettingsSubPageForAppropriateBrowser( + page, ProfileManager::GetPrimaryUserProfile()); +} + +void OnAcceptMultiprofilesIntro(bool no_show_again) { + PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); + prefs->SetBoolean(prefs::kMultiProfileNeverShowIntro, no_show_again); + UserAddingScreen::Get()->Start(); +} + +} // namespace + +SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS() + : weak_ptr_factory_(this), + user_profile_(NULL), + clock_type_(base::GetHourClockType()), + search_key_mapped_to_(input_method::kSearchKey), + screen_locked_(false), + have_session_start_time_(false), + have_session_length_limit_(false), + volume_control_delegate_(new VolumeController()), + device_settings_observer_(CrosSettings::Get()->AddSettingsObserver( + kSystemUse24HourClock, + base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType, + base::Unretained(this)))) { + // Register notifications on construction so that events such as + // PROFILE_CREATED do not get missed if they happen before Initialize(). + registrar_.reset(new content::NotificationRegistrar); + registrar_->Add(this, + chrome::NOTIFICATION_UPGRADE_RECOMMENDED, + content::NotificationService::AllSources()); + registrar_->Add(this, + chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, + content::NotificationService::AllSources()); + if (GetUserLoginStatus() == ash::user::LOGGED_IN_NONE) { + registrar_->Add(this, + chrome::NOTIFICATION_SESSION_STARTED, + content::NotificationService::AllSources()); + } + registrar_->Add(this, + chrome::NOTIFICATION_PROFILE_CREATED, + content::NotificationService::AllSources()); + registrar_->Add(this, + chrome::NOTIFICATION_PROFILE_DESTROYED, + content::NotificationService::AllSources()); + registrar_->Add( + this, + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER, + content::NotificationService::AllSources()); + registrar_->Add( + this, + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK, + content::NotificationService::AllSources()); + registrar_->Add( + this, + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE, + content::NotificationService::AllSources()); + registrar_->Add( + this, + chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD, + content::NotificationService::AllSources()); +} + +void SystemTrayDelegateChromeOS::Initialize() { + DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this); + + input_method::InputMethodManager::Get()->AddObserver(this); + UpdateClockType(); + + if (SystemKeyEventListener::GetInstance()) + SystemKeyEventListener::GetInstance()->AddCapsLockObserver(this); + + device::BluetoothAdapterFactory::GetAdapter( + base::Bind(&SystemTrayDelegateChromeOS::InitializeOnAdapterReady, + weak_ptr_factory_.GetWeakPtr())); + + ash::Shell::GetInstance()->session_state_delegate()->AddSessionStateObserver( + this); + + if (LoginState::IsInitialized()) + LoginState::Get()->AddObserver(this); +} + +void SystemTrayDelegateChromeOS::Shutdown() { + device_settings_observer_.reset(); +} + +void SystemTrayDelegateChromeOS::InitializeOnAdapterReady( + scoped_refptr adapter) { + bluetooth_adapter_ = adapter; + CHECK(bluetooth_adapter_.get()); + bluetooth_adapter_->AddObserver(this); + + local_state_registrar_.reset(new PrefChangeRegistrar); + local_state_registrar_->Init(g_browser_process->local_state()); + + UpdateSessionStartTime(); + UpdateSessionLengthLimit(); + + local_state_registrar_->Add( + prefs::kSessionStartTime, + base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionStartTime, + base::Unretained(this))); + local_state_registrar_->Add( + prefs::kSessionLengthLimit, + base::Bind(&SystemTrayDelegateChromeOS::UpdateSessionLengthLimit, + base::Unretained(this))); + + policy::BrowserPolicyConnectorChromeOS* policy_connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + policy::DeviceCloudPolicyManagerChromeOS* policy_manager = + policy_connector->GetDeviceCloudPolicyManager(); + if (policy_manager) + policy_manager->core()->store()->AddObserver(this); + UpdateEnterpriseDomain(); +} + +SystemTrayDelegateChromeOS::~SystemTrayDelegateChromeOS() { + // Unregister PrefChangeRegistrars. + local_state_registrar_.reset(); + user_pref_registrar_.reset(); + + // Unregister content notifications befure destroying any components. + registrar_.reset(); + + DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this); + input_method::InputMethodManager::Get()->RemoveObserver(this); + if (SystemKeyEventListener::GetInstance()) + SystemKeyEventListener::GetInstance()->RemoveCapsLockObserver(this); + bluetooth_adapter_->RemoveObserver(this); + ash::Shell::GetInstance() + ->session_state_delegate() + ->RemoveSessionStateObserver(this); + LoginState::Get()->RemoveObserver(this); + + // Stop observing Drive operations. + UnobserveDriveUpdates(); + + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + policy::DeviceCloudPolicyManagerChromeOS* policy_manager = + connector->GetDeviceCloudPolicyManager(); + if (policy_manager) + policy_manager->core()->store()->RemoveObserver(this); +} + +// Overridden from ash::SystemTrayDelegate: +bool SystemTrayDelegateChromeOS::GetTrayVisibilityOnStartup() { + // In case of OOBE / sign in screen tray will be shown later. + return LoginState::Get()->IsUserLoggedIn(); +} + +ash::user::LoginStatus SystemTrayDelegateChromeOS::GetUserLoginStatus() const { + // All non-logged in ChromeOS specific LOGGED_IN states map to the same + // Ash specific LOGGED_IN state. + if (!LoginState::Get()->IsUserLoggedIn()) + return ash::user::LOGGED_IN_NONE; + + if (screen_locked_) + return ash::user::LOGGED_IN_LOCKED; + + LoginState::LoggedInUserType user_type = + LoginState::Get()->GetLoggedInUserType(); + switch (user_type) { + case LoginState::LOGGED_IN_USER_NONE: + return ash::user::LOGGED_IN_NONE; + case LoginState::LOGGED_IN_USER_REGULAR: + return ash::user::LOGGED_IN_USER; + case LoginState::LOGGED_IN_USER_OWNER: + return ash::user::LOGGED_IN_OWNER; + case LoginState::LOGGED_IN_USER_GUEST: + return ash::user::LOGGED_IN_GUEST; + case LoginState::LOGGED_IN_USER_RETAIL_MODE: + return ash::user::LOGGED_IN_RETAIL_MODE; + case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT: + return ash::user::LOGGED_IN_PUBLIC; + case LoginState::LOGGED_IN_USER_LOCALLY_MANAGED: + return ash::user::LOGGED_IN_LOCALLY_MANAGED; + case LoginState::LOGGED_IN_USER_KIOSK_APP: + return ash::user::LOGGED_IN_KIOSK_APP; + } + NOTREACHED(); + return ash::user::LOGGED_IN_NONE; +} + +bool SystemTrayDelegateChromeOS::IsOobeCompleted() const { + if (!base::SysInfo::IsRunningOnChromeOS() && + LoginState::Get()->IsUserLoggedIn()) + return true; + return StartupUtils::IsOobeCompleted(); +} + +void SystemTrayDelegateChromeOS::ChangeProfilePicture() { + content::RecordAction( + base::UserMetricsAction("OpenChangeProfilePictureDialog")); + ShowSettingsSubPageForAppropriateBrowser( + chrome::kChangeProfilePictureSubPage, + ProfileManager::GetActiveUserProfile()); +} + +const std::string SystemTrayDelegateChromeOS::GetEnterpriseDomain() const { + return enterprise_domain_; +} + +const base::string16 SystemTrayDelegateChromeOS::GetEnterpriseMessage() const { + if (GetEnterpriseDomain().empty()) + return base::string16(); + return l10n_util::GetStringFUTF16(IDS_DEVICE_OWNED_BY_NOTICE, + base::UTF8ToUTF16(GetEnterpriseDomain())); +} + +const std::string SystemTrayDelegateChromeOS::GetLocallyManagedUserManager() + const { + if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) + return std::string(); + return UserManager::Get()->GetSupervisedUserManager()->GetManagerDisplayEmail( + chromeos::UserManager::Get()->GetActiveUser()->email()); +} + +const base::string16 +SystemTrayDelegateChromeOS::GetLocallyManagedUserManagerName() const { + if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) + return base::string16(); + return UserManager::Get()->GetSupervisedUserManager()->GetManagerDisplayName( + chromeos::UserManager::Get()->GetActiveUser()->email()); +} + +const base::string16 SystemTrayDelegateChromeOS::GetLocallyManagedUserMessage() + const { + if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED) + return base::string16(); + return l10n_util::GetStringFUTF16( + IDS_USER_IS_LOCALLY_MANAGED_BY_NOTICE, + base::UTF8ToUTF16(GetLocallyManagedUserManager())); +} + +bool SystemTrayDelegateChromeOS::SystemShouldUpgrade() const { + return UpgradeDetector::GetInstance()->notify_upgrade(); +} + +base::HourClockType SystemTrayDelegateChromeOS::GetHourClockType() const { + return clock_type_; +} + +void SystemTrayDelegateChromeOS::ShowSettings() { + chrome::ScopedTabbedBrowserDisplayer displayer( + ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); + chrome::ShowSettings(displayer.browser()); +} + +bool SystemTrayDelegateChromeOS::ShouldShowSettings() { + return UserManager::Get()->GetCurrentUserFlow()->ShouldShowSettings(); +} + +void SystemTrayDelegateChromeOS::ShowDateSettings() { + content::RecordAction(base::UserMetricsAction("ShowDateOptions")); + std::string sub_page = + std::string(chrome::kSearchSubPage) + "#" + + l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME); + // Everybody can change the time zone (even though it is a device setting). + ShowSettingsSubPageForAppropriateBrowser( + sub_page, ProfileManager::GetActiveUserProfile()); +} + +void SystemTrayDelegateChromeOS::ShowNetworkSettings( + const std::string& service_path) { + if (!LoginState::Get()->IsUserLoggedIn()) + return; + ShowNetworkSettingsPage(service_path); +} + +void SystemTrayDelegateChromeOS::ShowBluetoothSettings() { + // TODO(sad): Make this work. +} + +void SystemTrayDelegateChromeOS::ShowDisplaySettings() { + content::RecordAction(base::UserMetricsAction("ShowDisplayOptions")); + ShowSettingsSubPageForAppropriateBrowser( + kDisplaySettingsSubPageName, ProfileManager::GetActiveUserProfile()); +} + +void SystemTrayDelegateChromeOS::ShowChromeSlow() { + chrome::ScopedTabbedBrowserDisplayer displayer( + ProfileManager::GetPrimaryUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); + chrome::ShowSlow(displayer.browser()); +} + +bool SystemTrayDelegateChromeOS::ShouldShowDisplayNotification() { + // Packaged app is not counted as 'last active', so if a browser opening the + // display settings is in background of a packaged app, it will return true. + // TODO(mukai): fix this. + Browser* active_browser = + chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH); + if (!active_browser) + return true; + + content::WebContents* active_contents = + active_browser->tab_strip_model()->GetActiveWebContents(); + if (!active_contents) + return true; + + GURL visible_url = active_contents->GetLastCommittedURL(); + std::string display_settings_url = + std::string(chrome::kChromeUISettingsURL) + kDisplaySettingsSubPageName; + std::string display_overscan_url = std::string(chrome::kChromeUISettingsURL) + + kDisplayOverscanSettingsSubPageName; + return (visible_url.spec() != display_settings_url) && + (visible_url.spec() != display_overscan_url); +} + +void SystemTrayDelegateChromeOS::ShowDriveSettings() { + // TODO(tengs): Open the drive-specific settings page once we put it in. + // For now just show Google Drive main page. + chrome::ScopedTabbedBrowserDisplayer displayer( + ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); + chrome::ShowSingletonTabOverwritingNTP( + displayer.browser(), + chrome::GetSingletonTabNavigateParams(displayer.browser(), + GURL(kDriveSettingsPageURL))); +} + +void SystemTrayDelegateChromeOS::ShowIMESettings() { + content::RecordAction(base::UserMetricsAction("OpenLanguageOptionsDialog")); + ShowSettingsSubPageForAppropriateBrowser( + chrome::kLanguageOptionsSubPage, ProfileManager::GetActiveUserProfile()); +} + +void SystemTrayDelegateChromeOS::ShowHelp() { + chrome::ShowHelpForProfile(ProfileManager::GetActiveUserProfile(), + chrome::HOST_DESKTOP_TYPE_ASH, + chrome::HELP_SOURCE_MENU); +} + +void SystemTrayDelegateChromeOS::ShowAccessibilityHelp() { + chrome::ScopedTabbedBrowserDisplayer displayer( + ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); + accessibility::ShowAccessibilityHelp(displayer.browser()); +} + +void SystemTrayDelegateChromeOS::ShowAccessibilitySettings() { + content::RecordAction(base::UserMetricsAction("ShowAccessibilitySettings")); + std::string sub_page = std::string(chrome::kSearchSubPage) + "#" + + l10n_util::GetStringUTF8( + IDS_OPTIONS_SETTINGS_SECTION_TITLE_ACCESSIBILITY); + ShowSettingsSubPageForAppropriateBrowser( + sub_page, ProfileManager::GetActiveUserProfile()); +} + +void SystemTrayDelegateChromeOS::ShowPublicAccountInfo() { + chrome::ScopedTabbedBrowserDisplayer displayer( + ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); + chrome::ShowPolicy(displayer.browser()); +} + +void SystemTrayDelegateChromeOS::ShowLocallyManagedUserInfo() { + // TODO(antrim): find out what should we show in this case. + // http://crbug.com/229762 +} + +void SystemTrayDelegateChromeOS::ShowEnterpriseInfo() { + ash::user::LoginStatus status = GetUserLoginStatus(); + if (status == ash::user::LOGGED_IN_NONE || + status == ash::user::LOGGED_IN_LOCKED) { + scoped_refptr help_app( + new chromeos::HelpAppLauncher(GetNativeWindow())); + help_app->ShowHelpTopic(chromeos::HelpAppLauncher::HELP_ENTERPRISE); + } else { + GURL url(google_util::StringAppendGoogleLocaleParam( + chrome::kLearnMoreEnterpriseURL)); + chrome::ScopedTabbedBrowserDisplayer displayer( + ProfileManager::GetActiveUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH); + chrome::ShowSingletonTab(displayer.browser(), url); + } +} + +void SystemTrayDelegateChromeOS::ShowUserLogin() { + ash::Shell* shell = ash::Shell::GetInstance(); + if (!shell->delegate()->IsMultiProfilesEnabled()) + return; + + // Only regular users could add other users to current session. + if (UserManager::Get()->GetActiveUser()->GetType() != + User::USER_TYPE_REGULAR) { + return; + } + + if (static_cast(UserManager::Get()->GetLoggedInUsers().size()) >= + shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers()) + return; + + // Launch sign in screen to add another user to current session. + if (UserManager::Get()->GetUsersAdmittedForMultiProfile().size()) { + // Don't show dialog if any logged in user in multi-profiles session + // dismissed it. + bool show_intro = true; + const UserList logged_in_users = UserManager::Get()->GetLoggedInUsers(); + for (UserList::const_iterator it = logged_in_users.begin(); + it != logged_in_users.end(); + ++it) { + show_intro &= !multi_user_util::GetProfileFromUserID( + multi_user_util::GetUserIDFromEmail((*it)->email())) + ->GetPrefs() + ->GetBoolean(prefs::kMultiProfileNeverShowIntro); + if (!show_intro) + break; + } + if (show_intro) { + base::Callback on_accept = + base::Bind(&OnAcceptMultiprofilesIntro); + ShowMultiprofilesIntroDialog(on_accept); + } else { + UserAddingScreen::Get()->Start(); + } + } +} + +void SystemTrayDelegateChromeOS::ShowSpringChargerReplacementDialog() { + if (!ChargerReplacementDialog::ShouldShowDialog()) + return; + + ChargerReplacementDialog* dialog = + new ChargerReplacementDialog(GetNativeWindow()); + dialog->Show(); +} + +bool SystemTrayDelegateChromeOS::HasUserConfirmedSafeSpringCharger() { + return ChargerReplacementHandler::GetChargerStatusPref() == + ChargerReplacementHandler::CONFIRM_SAFE_CHARGER; +} + +void SystemTrayDelegateChromeOS::ShutDown() { + ash::Shell::GetInstance()->lock_state_controller()->RequestShutdown(); +} + +void SystemTrayDelegateChromeOS::SignOut() { + chrome::AttemptUserExit(); +} + +void SystemTrayDelegateChromeOS::RequestLockScreen() { + // TODO(antrim) : additional logging for crbug/173178 + LOG(WARNING) << "Requesting screen lock from AshSystemTrayDelegate"; + DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen(); +} + +void SystemTrayDelegateChromeOS::RequestRestartForUpdate() { + // We expect that UpdateEngine is in "Reboot for update" state now. + chrome::NotifyAndTerminate(true /* fast path */); +} + +void SystemTrayDelegateChromeOS::GetAvailableBluetoothDevices( + ash::BluetoothDeviceList* list) { + device::BluetoothAdapter::DeviceList devices = + bluetooth_adapter_->GetDevices(); + for (size_t i = 0; i < devices.size(); ++i) { + device::BluetoothDevice* device = devices[i]; + ash::BluetoothDeviceInfo info; + info.address = device->GetAddress(); + info.display_name = device->GetName(); + info.connected = device->IsConnected(); + info.connecting = device->IsConnecting(); + info.paired = device->IsPaired(); + list->push_back(info); + } +} + +void SystemTrayDelegateChromeOS::BluetoothStartDiscovering() { + bluetooth_adapter_->StartDiscovering( + base::Bind(&base::DoNothing), base::Bind(&BluetoothSetDiscoveringError)); +} + +void SystemTrayDelegateChromeOS::BluetoothStopDiscovering() { + bluetooth_adapter_->StopDiscovering( + base::Bind(&base::DoNothing), base::Bind(&BluetoothSetDiscoveringError)); +} + +void SystemTrayDelegateChromeOS::ConnectToBluetoothDevice( + const std::string& address) { + device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address); + if (!device || device->IsConnecting() || + (device->IsConnected() && device->IsPaired())) { + return; + } + if (device->IsPaired() && !device->IsConnectable()) + return; + if (device->IsPaired() || !device->IsPairable()) { + ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction( + ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE); + device->Connect(NULL, + base::Bind(&base::DoNothing), + base::Bind(&BluetoothDeviceConnectError)); + } else { // Show paring dialog for the unpaired device. + ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction( + ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE); + BluetoothPairingDialog* dialog = + new BluetoothPairingDialog(GetNativeWindow(), device); + // The dialog deletes itself on close. + dialog->Show(); + } +} + +bool SystemTrayDelegateChromeOS::IsBluetoothDiscovering() { + return bluetooth_adapter_->IsDiscovering(); +} + +void SystemTrayDelegateChromeOS::GetCurrentIME(ash::IMEInfo* info) { + input_method::InputMethodManager* manager = + input_method::InputMethodManager::Get(); + input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); + input_method::InputMethodDescriptor ime = manager->GetCurrentInputMethod(); + ExtractIMEInfo(ime, *util, info); + info->selected = true; +} + +void SystemTrayDelegateChromeOS::GetAvailableIMEList(ash::IMEInfoList* list) { + input_method::InputMethodManager* manager = + input_method::InputMethodManager::Get(); + input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); + scoped_ptr ime_descriptors( + manager->GetActiveInputMethods()); + std::string current = manager->GetCurrentInputMethod().id(); + for (size_t i = 0; i < ime_descriptors->size(); i++) { + input_method::InputMethodDescriptor& ime = ime_descriptors->at(i); + ash::IMEInfo info; + ExtractIMEInfo(ime, *util, &info); + info.selected = ime.id() == current; + list->push_back(info); + } +} + +void SystemTrayDelegateChromeOS::GetCurrentIMEProperties( + ash::IMEPropertyInfoList* list) { + input_method::InputMethodManager* manager = + input_method::InputMethodManager::Get(); + input_method::InputMethodPropertyList properties = + manager->GetCurrentInputMethodProperties(); + for (size_t i = 0; i < properties.size(); ++i) { + ash::IMEPropertyInfo property; + property.key = properties[i].key; + property.name = base::UTF8ToUTF16(properties[i].label); + property.selected = properties[i].is_selection_item_checked; + list->push_back(property); + } +} + +void SystemTrayDelegateChromeOS::SwitchIME(const std::string& ime_id) { + input_method::InputMethodManager::Get()->ChangeInputMethod(ime_id); +} + +void SystemTrayDelegateChromeOS::ActivateIMEProperty(const std::string& key) { + input_method::InputMethodManager::Get()->ActivateInputMethodProperty(key); +} + +void SystemTrayDelegateChromeOS::CancelDriveOperation(int32 operation_id) { + DriveIntegrationService* integration_service = FindDriveIntegrationService(); + if (!integration_service) + return; + + integration_service->job_list()->CancelJob(operation_id); +} + +void SystemTrayDelegateChromeOS::GetDriveOperationStatusList( + ash::DriveOperationStatusList* list) { + DriveIntegrationService* integration_service = FindDriveIntegrationService(); + if (!integration_service) + return; + + *list = ConvertToDriveStatusList( + integration_service->job_list()->GetJobInfoList()); +} + +void SystemTrayDelegateChromeOS::ShowNetworkConfigure( + const std::string& network_id, + gfx::NativeWindow parent_window) { + NetworkConfigView::Show(network_id, parent_window); +} + +bool SystemTrayDelegateChromeOS::EnrollNetwork( + const std::string& network_id, + gfx::NativeWindow parent_window) { + return enrollment::CreateDialog(network_id, parent_window); +} + +void SystemTrayDelegateChromeOS::ManageBluetoothDevices() { + content::RecordAction(base::UserMetricsAction("ShowBluetoothSettingsPage")); + std::string sub_page = + std::string(chrome::kSearchSubPage) + "#" + + l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_BLUETOOTH); + ShowSettingsSubPageForAppropriateBrowser( + sub_page, ProfileManager::GetPrimaryUserProfile()); +} + +void SystemTrayDelegateChromeOS::ToggleBluetooth() { + bluetooth_adapter_->SetPowered(!bluetooth_adapter_->IsPowered(), + base::Bind(&base::DoNothing), + base::Bind(&BluetoothPowerFailure)); +} + +void SystemTrayDelegateChromeOS::ShowMobileSimDialog() { + SimDialogDelegate::ShowDialog(GetNativeWindow(), + SimDialogDelegate::SIM_DIALOG_UNLOCK); +} + +void SystemTrayDelegateChromeOS::ShowMobileSetupDialog( + const std::string& service_path) { + MobileSetupDialog::Show(service_path); +} + +void SystemTrayDelegateChromeOS::ShowOtherNetworkDialog( + const std::string& type) { + if (type == shill::kTypeCellular) { + ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); + return; + } + NetworkConfigView::ShowForType(type, GetNativeWindow()); +} + +bool SystemTrayDelegateChromeOS::GetBluetoothAvailable() { + return bluetooth_adapter_->IsPresent(); +} + +bool SystemTrayDelegateChromeOS::GetBluetoothEnabled() { + return bluetooth_adapter_->IsPowered(); +} + +void SystemTrayDelegateChromeOS::ChangeProxySettings() { + CHECK(GetUserLoginStatus() == ash::user::LOGGED_IN_NONE); + LoginDisplayHostImpl::default_host()->OpenProxySettings(); +} + +ash::VolumeControlDelegate* +SystemTrayDelegateChromeOS::GetVolumeControlDelegate() const { + return volume_control_delegate_.get(); +} + +void SystemTrayDelegateChromeOS::SetVolumeControlDelegate( + scoped_ptr delegate) { + volume_control_delegate_.swap(delegate); +} + +bool SystemTrayDelegateChromeOS::GetSessionStartTime( + base::TimeTicks* session_start_time) { + *session_start_time = session_start_time_; + return have_session_start_time_; +} + +bool SystemTrayDelegateChromeOS::GetSessionLengthLimit( + base::TimeDelta* session_length_limit) { + *session_length_limit = session_length_limit_; + return have_session_length_limit_; +} + +int SystemTrayDelegateChromeOS::GetSystemTrayMenuWidth() { + return l10n_util::GetLocalizedContentsWidthInPixels( + IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS); +} + +void SystemTrayDelegateChromeOS::ActiveUserWasChanged() { + GetSystemTrayNotifier()->NotifyUserUpdate(); +} + +ash::SystemTray* SystemTrayDelegateChromeOS::GetPrimarySystemTray() { + return ash::Shell::GetInstance()->GetPrimarySystemTray(); +} + +ash::SystemTrayNotifier* SystemTrayDelegateChromeOS::GetSystemTrayNotifier() { + return ash::Shell::GetInstance()->system_tray_notifier(); +} + +void SystemTrayDelegateChromeOS::SetProfile(Profile* profile) { + // Stop observing the current |user_profile_| on Drive integration status. + UnobserveDriveUpdates(); + + user_profile_ = profile; + + // Restart observation, now for the newly set |profile|. + ObserveDriveUpdates(); + + PrefService* prefs = profile->GetPrefs(); + user_pref_registrar_.reset(new PrefChangeRegistrar); + user_pref_registrar_->Init(prefs); + user_pref_registrar_->Add( + prefs::kUse24HourClock, + base::Bind(&SystemTrayDelegateChromeOS::UpdateClockType, + base::Unretained(this))); + user_pref_registrar_->Add( + prefs::kLanguageRemapSearchKeyTo, + base::Bind(&SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged, + base::Unretained(this))); + user_pref_registrar_->Add( + prefs::kShowLogoutButtonInTray, + base::Bind(&SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray, + base::Unretained(this))); + user_pref_registrar_->Add( + prefs::kLogoutDialogDurationMs, + base::Bind(&SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration, + base::Unretained(this))); + user_pref_registrar_->Add( + prefs::kLargeCursorEnabled, + base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged, + base::Unretained(this), + ash::A11Y_NOTIFICATION_NONE)); + user_pref_registrar_->Add( + prefs::kAutoclickEnabled, + base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged, + base::Unretained(this), + ash::A11Y_NOTIFICATION_NONE)); + user_pref_registrar_->Add( + prefs::kShouldAlwaysShowAccessibilityMenu, + base::Bind(&SystemTrayDelegateChromeOS::OnAccessibilityModeChanged, + base::Unretained(this), + ash::A11Y_NOTIFICATION_NONE)); + user_pref_registrar_->Add( + prefs::kPerformanceTracingEnabled, + base::Bind(&SystemTrayDelegateChromeOS::UpdatePerformanceTracing, + base::Unretained(this))); + + UpdateClockType(); + UpdateShowLogoutButtonInTray(); + UpdateLogoutDialogDuration(); + UpdatePerformanceTracing(); + search_key_mapped_to_ = + profile->GetPrefs()->GetInteger(prefs::kLanguageRemapSearchKeyTo); +} + +bool SystemTrayDelegateChromeOS::UnsetProfile(Profile* profile) { + if (profile != user_profile_) + return false; + user_pref_registrar_.reset(); + return true; +} + +void SystemTrayDelegateChromeOS::ObserveDriveUpdates() { + DriveIntegrationService* integration_service = FindDriveIntegrationService(); + if (integration_service) + integration_service->job_list()->AddObserver(this); +} + +void SystemTrayDelegateChromeOS::UnobserveDriveUpdates() { + DriveIntegrationService* integration_service = FindDriveIntegrationService(); + if (integration_service) + integration_service->job_list()->RemoveObserver(this); +} + +bool SystemTrayDelegateChromeOS::GetShouldUse24HourClockForTesting() const { + return ShouldUse24HourClock(); +} + +bool SystemTrayDelegateChromeOS::ShouldUse24HourClock() const { + // On login screen and in guest mode owner default is used for + // kUse24HourClock preference. + const ash::user::LoginStatus status = GetUserLoginStatus(); + const CrosSettings* const cros_settings = CrosSettings::Get(); + bool system_use_24_hour_clock = true; + const bool system_value_found = cros_settings->GetBoolean( + kSystemUse24HourClock, &system_use_24_hour_clock); + + if ((status == ash::user::LOGGED_IN_NONE) || !user_pref_registrar_) + return (system_value_found + ? system_use_24_hour_clock + : (base::GetHourClockType() == base::k24HourClock)); + + const PrefService::Preference* user_pref = + user_pref_registrar_->prefs()->FindPreference(prefs::kUse24HourClock); + if (status == ash::user::LOGGED_IN_GUEST && user_pref->IsDefaultValue()) + return (system_value_found + ? system_use_24_hour_clock + : (base::GetHourClockType() == base::k24HourClock)); + + bool use_24_hour_clock = true; + user_pref->GetValue()->GetAsBoolean(&use_24_hour_clock); + return use_24_hour_clock; +} + +void SystemTrayDelegateChromeOS::UpdateClockType() { + const bool use_24_hour_clock = ShouldUse24HourClock(); + clock_type_ = use_24_hour_clock ? base::k24HourClock : base::k12HourClock; + GetSystemTrayNotifier()->NotifyDateFormatChanged(); + // This also works for enterprise-managed devices because they never have + // local owner. + if (chromeos::UserManager::Get()->IsCurrentUserOwner()) + CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, use_24_hour_clock); +} + +void SystemTrayDelegateChromeOS::UpdateShowLogoutButtonInTray() { + GetSystemTrayNotifier()->NotifyShowLoginButtonChanged( + user_pref_registrar_->prefs()->GetBoolean( + prefs::kShowLogoutButtonInTray)); +} + +void SystemTrayDelegateChromeOS::UpdateLogoutDialogDuration() { + const int duration_ms = + user_pref_registrar_->prefs()->GetInteger(prefs::kLogoutDialogDurationMs); + GetSystemTrayNotifier()->NotifyLogoutDialogDurationChanged( + base::TimeDelta::FromMilliseconds(duration_ms)); +} + +void SystemTrayDelegateChromeOS::UpdateSessionStartTime() { + const PrefService* local_state = local_state_registrar_->prefs(); + if (local_state->HasPrefPath(prefs::kSessionStartTime)) { + have_session_start_time_ = true; + session_start_time_ = base::TimeTicks::FromInternalValue( + local_state->GetInt64(prefs::kSessionStartTime)); + } else { + have_session_start_time_ = false; + session_start_time_ = base::TimeTicks(); + } + GetSystemTrayNotifier()->NotifySessionStartTimeChanged(); +} + +void SystemTrayDelegateChromeOS::UpdateSessionLengthLimit() { + const PrefService* local_state = local_state_registrar_->prefs(); + if (local_state->HasPrefPath(prefs::kSessionLengthLimit)) { + have_session_length_limit_ = true; + session_length_limit_ = base::TimeDelta::FromMilliseconds( + std::min(std::max(local_state->GetInteger(prefs::kSessionLengthLimit), + kSessionLengthLimitMinMs), + kSessionLengthLimitMaxMs)); + } else { + have_session_length_limit_ = false; + session_length_limit_ = base::TimeDelta(); + } + GetSystemTrayNotifier()->NotifySessionLengthLimitChanged(); +} + +// LoginState::Observer overrides. +void SystemTrayDelegateChromeOS::LoggedInStateChanged() { + // It apparently sometimes takes a while after login before the current user + // is recognized as the owner. Make sure that the system-wide clock setting + // is updated when the recognition eventually happens + // (http://crbug.com/278601). + // + // Note that it isn't safe to blindly call UpdateClockType() from this + // method, as LoggedInStateChanged() is also called before the logged-in + // user's profile has actually been loaded (http://crbug.com/317745). The + // system tray's time format is updated at login via SetProfile(). + if (chromeos::UserManager::Get()->IsCurrentUserOwner()) { + CrosSettings::Get()->SetBoolean(kSystemUse24HourClock, + ShouldUse24HourClock()); + } +} + +// Overridden from SessionManagerClient::Observer. +void SystemTrayDelegateChromeOS::LockScreen() { + screen_locked_ = true; + ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus()); +} + +void SystemTrayDelegateChromeOS::ScreenIsUnlocked() { + screen_locked_ = false; + ash::Shell::GetInstance()->UpdateAfterLoginStatusChange(GetUserLoginStatus()); +} + +gfx::NativeWindow SystemTrayDelegateChromeOS::GetNativeWindow() const { + bool session_started = ash::Shell::GetInstance() + ->session_state_delegate() + ->IsActiveUserSessionStarted(); + return GetNativeWindowByStatus(GetUserLoginStatus(), session_started); +} + +// content::NotificationObserver implementation. +void SystemTrayDelegateChromeOS::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + switch (type) { + case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: { + UpgradeDetector* detector = + content::Source(source).ptr(); + ash::UpdateObserver::UpdateSeverity severity = + ash::UpdateObserver::UPDATE_NORMAL; + switch (detector->upgrade_notification_stage()) { + case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE: + severity = ash::UpdateObserver::UPDATE_SEVERE_RED; + break; + + case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH: + severity = ash::UpdateObserver::UPDATE_HIGH_ORANGE; + break; + + case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED: + severity = ash::UpdateObserver::UPDATE_LOW_GREEN; + break; + + case UpgradeDetector::UPGRADE_ANNOYANCE_LOW: + default: + severity = ash::UpdateObserver::UPDATE_NORMAL; + break; + } + GetSystemTrayNotifier()->NotifyUpdateRecommended(severity); + break; + } + case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: { + // This notification is also sent on login screen when user avatar + // is loaded from file. + if (GetUserLoginStatus() != ash::user::LOGGED_IN_NONE) { + GetSystemTrayNotifier()->NotifyUserUpdate(); + } + break; + } + case chrome::NOTIFICATION_PROFILE_CREATED: { + SetProfile(content::Source(source).ptr()); + registrar_->Remove(this, + chrome::NOTIFICATION_PROFILE_CREATED, + content::NotificationService::AllSources()); + break; + } + case chrome::NOTIFICATION_PROFILE_DESTROYED: { + if (UnsetProfile(content::Source(source).ptr())) { + registrar_->Remove(this, + chrome::NOTIFICATION_PROFILE_DESTROYED, + content::NotificationService::AllSources()); + } + break; + } + case chrome::NOTIFICATION_SESSION_STARTED: { + ash::Shell::GetInstance()->UpdateAfterLoginStatusChange( + GetUserLoginStatus()); + SetProfile(ProfileManager::GetActiveUserProfile()); + break; + } + case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK: + case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE: + case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER: + case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_VIRTUAL_KEYBOARD: { + AccessibilityStatusEventDetails* accessibility_status = + content::Details(details).ptr(); + OnAccessibilityModeChanged(accessibility_status->notify); + break; + } + default: + NOTREACHED(); + } +} + +void SystemTrayDelegateChromeOS::OnLanguageRemapSearchKeyToChanged() { + search_key_mapped_to_ = user_pref_registrar_->prefs()->GetInteger( + prefs::kLanguageRemapSearchKeyTo); +} + +void SystemTrayDelegateChromeOS::OnAccessibilityModeChanged( + ash::AccessibilityNotificationVisibility notify) { + GetSystemTrayNotifier()->NotifyAccessibilityModeChanged(notify); +} + +void SystemTrayDelegateChromeOS::UpdatePerformanceTracing() { + if (!user_pref_registrar_) + return; + bool value = user_pref_registrar_->prefs()->GetBoolean( + prefs::kPerformanceTracingEnabled); + GetSystemTrayNotifier()->NotifyTracingModeChanged(value); +} + +// Overridden from InputMethodManager::Observer. +void SystemTrayDelegateChromeOS::InputMethodChanged( + input_method::InputMethodManager* manager, + bool show_message) { + // |show_message| in ash means the message_center notifications + // which should not be shown unless kDisableIMEModeIndicator is + // on, since the mode indicator already notifies the user. + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableIMEModeIndicator)) { + show_message = false; + } + GetSystemTrayNotifier()->NotifyRefreshIME(show_message); +} + +void SystemTrayDelegateChromeOS::InputMethodPropertyChanged( + input_method::InputMethodManager* manager) { + GetSystemTrayNotifier()->NotifyRefreshIME(false); +} + +// drive::JobListObserver overrides. +void SystemTrayDelegateChromeOS::OnJobAdded(const drive::JobInfo& job_info) { + OnJobUpdated(job_info); +} + +void SystemTrayDelegateChromeOS::OnJobDone(const drive::JobInfo& job_info, + drive::FileError error) { + ash::DriveOperationStatus status; + if (ConvertToFinishedDriveOperationStatus(job_info, error, &status)) + GetSystemTrayNotifier()->NotifyDriveJobUpdated(status); +} + +void SystemTrayDelegateChromeOS::OnJobUpdated(const drive::JobInfo& job_info) { + ash::DriveOperationStatus status; + if (ConvertToDriveOperationStatus(job_info, &status)) + GetSystemTrayNotifier()->NotifyDriveJobUpdated(status); +} + +DriveIntegrationService* +SystemTrayDelegateChromeOS::FindDriveIntegrationService() { + return user_profile_ + ? DriveIntegrationServiceFactory::FindForProfile(user_profile_) + : NULL; +} + +// Overridden from BluetoothAdapter::Observer. +void SystemTrayDelegateChromeOS::AdapterPresentChanged( + device::BluetoothAdapter* adapter, + bool present) { + GetSystemTrayNotifier()->NotifyRefreshBluetooth(); +} + +void SystemTrayDelegateChromeOS::AdapterPoweredChanged( + device::BluetoothAdapter* adapter, + bool powered) { + GetSystemTrayNotifier()->NotifyRefreshBluetooth(); +} + +void SystemTrayDelegateChromeOS::AdapterDiscoveringChanged( + device::BluetoothAdapter* adapter, + bool discovering) { + GetSystemTrayNotifier()->NotifyBluetoothDiscoveringChanged(); +} + +void SystemTrayDelegateChromeOS::DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) { + GetSystemTrayNotifier()->NotifyRefreshBluetooth(); +} + +void SystemTrayDelegateChromeOS::DeviceChanged( + device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) { + GetSystemTrayNotifier()->NotifyRefreshBluetooth(); +} + +void SystemTrayDelegateChromeOS::DeviceRemoved( + device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) { + GetSystemTrayNotifier()->NotifyRefreshBluetooth(); +} + +// Overridden from SystemKeyEventListener::CapsLockObserver. +void SystemTrayDelegateChromeOS::OnCapsLockChange(bool enabled) { + bool search_mapped_to_caps_lock = false; + if (!base::SysInfo::IsRunningOnChromeOS() || + search_key_mapped_to_ == input_method::kCapsLockKey) + search_mapped_to_caps_lock = true; + GetSystemTrayNotifier()->NotifyCapsLockChanged(enabled, + search_mapped_to_caps_lock); +} + +void SystemTrayDelegateChromeOS::UpdateEnterpriseDomain() { + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + std::string enterprise_domain = connector->GetEnterpriseDomain(); + if (enterprise_domain_ != enterprise_domain) { + enterprise_domain_ = enterprise_domain; + GetSystemTrayNotifier()->NotifyEnterpriseDomainChanged(); + } +} + +// Overridden from CloudPolicyStore::Observer +void SystemTrayDelegateChromeOS::OnStoreLoaded( + policy::CloudPolicyStore* store) { + UpdateEnterpriseDomain(); +} + +void SystemTrayDelegateChromeOS::OnStoreError(policy::CloudPolicyStore* store) { + UpdateEnterpriseDomain(); +} + +// Overridden from ash::SessionStateObserver +void SystemTrayDelegateChromeOS::UserAddedToSession( + const std::string& user_id) { + GetSystemTrayNotifier()->NotifyUserAddedToSession(); +} + +ash::SystemTrayDelegate* CreateSystemTrayDelegate() { + return new SystemTrayDelegateChromeOS(); +} + +} // namespace chromeos diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h index e0d834035abf..af578e63c4fe 100644 --- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h +++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h @@ -5,12 +5,240 @@ #ifndef CHROME_BROWSER_UI_ASH_SYSTEM_TRAY_DELEGATE_CHROMEOS_H_ #define CHROME_BROWSER_UI_ASH_SYSTEM_TRAY_DELEGATE_CHROMEOS_H_ -namespace ash { -class SystemTrayDelegate; -} +#include "ash/session_state_observer.h" +#include "ash/system/tray/system_tray.h" +#include "ash/system/tray/system_tray_delegate.h" +#include "ash/system/tray/system_tray_notifier.h" +#include "base/callback_list.h" +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/prefs/pref_change_registrar.h" +#include "chrome/browser/chromeos/drive/drive_integration_service.h" +#include "chrome/browser/chromeos/drive/job_list.h" +#include "chrome/browser/chromeos/system_key_event_listener.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/ash/system_tray_delegate_chromeos.h" +#include "chromeos/dbus/session_manager_client.h" +#include "chromeos/ime/input_method_manager.h" +#include "chromeos/login/login_state.h" +#include "components/policy/core/common/cloud/cloud_policy_store.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" +#include "device/bluetooth/bluetooth_adapter.h" namespace chromeos { + +class SystemTrayDelegateChromeOS + : public ash::SystemTrayDelegate, + public SessionManagerClient::Observer, + public drive::JobListObserver, + public content::NotificationObserver, + public input_method::InputMethodManager::Observer, + public chromeos::LoginState::Observer, + public device::BluetoothAdapter::Observer, + public SystemKeyEventListener::CapsLockObserver, + public policy::CloudPolicyStore::Observer, + public ash::SessionStateObserver { + public: + SystemTrayDelegateChromeOS(); + + virtual ~SystemTrayDelegateChromeOS(); + + void InitializeOnAdapterReady( + scoped_refptr adapter); + + // Overridden from ash::SystemTrayDelegate: + virtual void Initialize() OVERRIDE; + virtual void Shutdown() OVERRIDE; + virtual bool GetTrayVisibilityOnStartup() OVERRIDE; + virtual ash::user::LoginStatus GetUserLoginStatus() const OVERRIDE; + virtual bool IsOobeCompleted() const OVERRIDE; + virtual void ChangeProfilePicture() OVERRIDE; + virtual const std::string GetEnterpriseDomain() const OVERRIDE; + virtual const base::string16 GetEnterpriseMessage() const OVERRIDE; + virtual const std::string GetLocallyManagedUserManager() const OVERRIDE; + virtual const base::string16 GetLocallyManagedUserManagerName() + const OVERRIDE; + virtual const base::string16 GetLocallyManagedUserMessage() const OVERRIDE; + virtual bool SystemShouldUpgrade() const OVERRIDE; + virtual base::HourClockType GetHourClockType() const OVERRIDE; + virtual void ShowSettings() OVERRIDE; + virtual bool ShouldShowSettings() OVERRIDE; + virtual void ShowDateSettings() OVERRIDE; + virtual void ShowNetworkSettings(const std::string& service_path) OVERRIDE; + virtual void ShowBluetoothSettings() OVERRIDE; + virtual void ShowDisplaySettings() OVERRIDE; + virtual void ShowChromeSlow() OVERRIDE; + virtual bool ShouldShowDisplayNotification() OVERRIDE; + virtual void ShowDriveSettings() OVERRIDE; + virtual void ShowIMESettings() OVERRIDE; + virtual void ShowHelp() OVERRIDE; + virtual void ShowAccessibilityHelp() OVERRIDE; + virtual void ShowAccessibilitySettings() OVERRIDE; + virtual void ShowPublicAccountInfo() OVERRIDE; + virtual void ShowLocallyManagedUserInfo() OVERRIDE; + virtual void ShowEnterpriseInfo() OVERRIDE; + virtual void ShowUserLogin() OVERRIDE; + virtual void ShowSpringChargerReplacementDialog() OVERRIDE; + virtual bool HasUserConfirmedSafeSpringCharger() OVERRIDE; + virtual void ShutDown() OVERRIDE; + virtual void SignOut() OVERRIDE; + virtual void RequestLockScreen() OVERRIDE; + virtual void RequestRestartForUpdate() OVERRIDE; + virtual void GetAvailableBluetoothDevices(ash::BluetoothDeviceList* list) + OVERRIDE; + virtual void BluetoothStartDiscovering() OVERRIDE; + virtual void BluetoothStopDiscovering() OVERRIDE; + virtual void ConnectToBluetoothDevice(const std::string& address) OVERRIDE; + virtual bool IsBluetoothDiscovering() OVERRIDE; + virtual void GetCurrentIME(ash::IMEInfo* info) OVERRIDE; + virtual void GetAvailableIMEList(ash::IMEInfoList* list) OVERRIDE; + virtual void GetCurrentIMEProperties(ash::IMEPropertyInfoList* list) OVERRIDE; + virtual void SwitchIME(const std::string& ime_id) OVERRIDE; + virtual void ActivateIMEProperty(const std::string& key) OVERRIDE; + virtual void CancelDriveOperation(int32 operation_id) OVERRIDE; + virtual void GetDriveOperationStatusList(ash::DriveOperationStatusList* list) + OVERRIDE; + virtual void ShowNetworkConfigure(const std::string& network_id, + gfx::NativeWindow parent_window) OVERRIDE; + virtual bool EnrollNetwork(const std::string& network_id, + gfx::NativeWindow parent_window) OVERRIDE; + virtual void ManageBluetoothDevices() OVERRIDE; + virtual void ToggleBluetooth() OVERRIDE; + virtual void ShowMobileSimDialog() OVERRIDE; + virtual void ShowMobileSetupDialog(const std::string& service_path) OVERRIDE; + virtual void ShowOtherNetworkDialog(const std::string& type) OVERRIDE; + virtual bool GetBluetoothAvailable() OVERRIDE; + virtual bool GetBluetoothEnabled() OVERRIDE; + virtual void ChangeProxySettings() OVERRIDE; + virtual ash::VolumeControlDelegate* GetVolumeControlDelegate() const OVERRIDE; + virtual void SetVolumeControlDelegate( + scoped_ptr delegate) OVERRIDE; + virtual bool GetSessionStartTime(base::TimeTicks* session_start_time) + OVERRIDE; + virtual bool GetSessionLengthLimit(base::TimeDelta* session_length_limit) + OVERRIDE; + virtual int GetSystemTrayMenuWidth() OVERRIDE; + virtual void ActiveUserWasChanged() OVERRIDE; + + // browser tests need to call ShouldUse24HourClock(). + bool GetShouldUse24HourClockForTesting() const; + + private: + // Should be the same as CrosSettings::ObserverSubscription. + typedef base::CallbackList::Subscription + CrosSettingsObserverSubscription; + + ash::SystemTray* GetPrimarySystemTray(); + + ash::SystemTrayNotifier* GetSystemTrayNotifier(); + + void SetProfile(Profile* profile); + + bool UnsetProfile(Profile* profile); + + void ObserveDriveUpdates(); + + void UnobserveDriveUpdates(); + + bool ShouldUse24HourClock() const; + + void UpdateClockType(); + + void UpdateShowLogoutButtonInTray(); + + void UpdateLogoutDialogDuration(); + + void UpdateSessionStartTime(); + + void UpdateSessionLengthLimit(); + + // LoginState::Observer overrides. + virtual void LoggedInStateChanged() OVERRIDE; + + // Overridden from SessionManagerClient::Observer. + virtual void LockScreen() OVERRIDE; + virtual void ScreenIsUnlocked() OVERRIDE; + + gfx::NativeWindow GetNativeWindow() const; + + // content::NotificationObserver implementation. + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + void OnLanguageRemapSearchKeyToChanged(); + + void OnAccessibilityModeChanged( + ash::AccessibilityNotificationVisibility notify); + + void UpdatePerformanceTracing(); + + // Overridden from InputMethodManager::Observer. + virtual void InputMethodChanged(input_method::InputMethodManager* manager, + bool show_message) OVERRIDE; + + virtual void InputMethodPropertyChanged( + input_method::InputMethodManager* manager) OVERRIDE; + + // drive::JobListObserver overrides. + virtual void OnJobAdded(const drive::JobInfo& job_info) OVERRIDE; + + virtual void OnJobDone(const drive::JobInfo& job_info, + drive::FileError error) OVERRIDE; + + virtual void OnJobUpdated(const drive::JobInfo& job_info) OVERRIDE; + + drive::DriveIntegrationService* FindDriveIntegrationService(); + + // Overridden from BluetoothAdapter::Observer. + virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter, + bool present) OVERRIDE; + virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter, + bool powered) OVERRIDE; + virtual void AdapterDiscoveringChanged(device::BluetoothAdapter* adapter, + bool discovering) OVERRIDE; + virtual void DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE; + virtual void DeviceChanged(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE; + virtual void DeviceRemoved(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE; + + // Overridden from SystemKeyEventListener::CapsLockObserver. + virtual void OnCapsLockChange(bool enabled) OVERRIDE; + + void UpdateEnterpriseDomain(); + + // Overridden from CloudPolicyStore::Observer + virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE; + virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE; + // Overridden from ash::SessionStateObserver + virtual void UserAddedToSession(const std::string& user_id) OVERRIDE; + + base::WeakPtrFactory weak_ptr_factory_; + scoped_ptr registrar_; + scoped_ptr local_state_registrar_; + scoped_ptr user_pref_registrar_; + Profile* user_profile_; + base::HourClockType clock_type_; + int search_key_mapped_to_; + bool screen_locked_; + bool have_session_start_time_; + base::TimeTicks session_start_time_; + bool have_session_length_limit_; + base::TimeDelta session_length_limit_; + std::string enterprise_domain_; + + scoped_refptr bluetooth_adapter_; + scoped_ptr volume_control_delegate_; + scoped_ptr device_settings_observer_; + + DISALLOW_COPY_AND_ASSIGN(SystemTrayDelegateChromeOS); +}; + ash::SystemTrayDelegate* CreateSystemTrayDelegate(); -} +} // namespace chromeos #endif // CHROME_BROWSER_UI_ASH_SYSTEM_TRAY_DELEGATE_CHROMEOS_H_ diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index b64a06a42312..daa681d4db62 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1083,6 +1083,7 @@ 'browser/chromeos/policy/device_policy_cros_browser_test.cc', 'browser/chromeos/policy/device_policy_cros_browser_test.h', 'browser/chromeos/policy/device_status_collector_browsertest.cc', + 'browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc', 'browser/chromeos/policy/login_screen_default_policy_browsertest.cc', 'browser/chromeos/policy/policy_cert_verifier_browsertest.cc', 'browser/chromeos/policy/power_policy_browsertest.cc', -- 2.11.4.GIT