From 9abeee5f9efffd8d76762858d2c662f99c9d63f1 Mon Sep 17 00:00:00 2001 From: "tommi@chromium.org" Date: Wed, 17 Oct 2012 14:31:40 +0000 Subject: Revert 162377 - Move Ash system network trays to ash/system/chromeos ### Reason: 52>system\chromeos\tray_display.cc(56): error C2039: 'output_configurator' : is not a member of 'ash::Shell' 52> ..\ash/shell.h(116) : see declaration of 'ash::Shell' 52>system\chromeos\tray_display.cc(56): error C2227: left of '->output_state' must point to class/struct/union/generic type 52>system\chromeos\tray_display.cc(122): error C2039: 'output_configurator' : is not a member of 'ash::Shell' 52> ..\ash/shell.h(116) : see declaration of 'ash::Shell' 52>system\chromeos\tray_display.cc(122): error C2227: left of '->AddObserver' must point to class/struct/union/generic type 52>system\chromeos\tray_display.cc(127): error C2039: 'output_configurator' : is not a member of 'ash::Shell' 52> ..\ash/shell.h(116) : see declaration of 'ash::Shell' 52>system\chromeos\tray_display.cc(127): error C2227: left of '->RemoveObserver' must point to class/struct/union/generic type ### Also adds DEPS to keep chromeos dependencies out of ash/system This is part of an effort to move chromeos network management code from src/chrome/ to src/chromeos. BUG=154856 Review URL: https://chromiumcodereview.appspot.com/11039034 TBR=stevenjb@chromium.org git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162406 0039d316-1c4b-4281-b951-d872f2087c98 --- ash/ash.gyp | 14 +- ash/system/DEPS | 3 - ash/system/chromeos/DEPS | 3 - ash/system/chromeos/network/network_observer.h | 58 -- ash/system/chromeos/network/sms_observer.h | 26 - ash/system/chromeos/network/tray_network.cc | 959 ------------------------- ash/system/chromeos/network/tray_network.h | 80 --- ash/system/chromeos/network/tray_sms.cc | 378 ---------- ash/system/chromeos/network/tray_sms.h | 65 -- ash/system/chromeos/tray_display.cc | 160 ----- ash/system/chromeos/tray_display.h | 51 -- ash/system/network/network_observer.h | 58 ++ ash/system/network/sms_observer.h | 28 + ash/system/network/tray_network.cc | 959 +++++++++++++++++++++++++ ash/system/network/tray_network.h | 80 +++ ash/system/network/tray_sms.cc | 378 ++++++++++ ash/system/network/tray_sms.h | 65 ++ ash/system/power/DEPS | 4 - ash/system/status_area_widget.cc | 17 + ash/system/tray/system_tray.cc | 31 +- ash/system/tray/system_tray.h | 18 +- ash/system/tray_display.cc | 171 +++++ ash/system/tray_display.h | 57 ++ 23 files changed, 1835 insertions(+), 1828 deletions(-) delete mode 100644 ash/system/DEPS delete mode 100644 ash/system/chromeos/DEPS delete mode 100644 ash/system/chromeos/network/network_observer.h delete mode 100644 ash/system/chromeos/network/sms_observer.h delete mode 100644 ash/system/chromeos/network/tray_network.cc delete mode 100644 ash/system/chromeos/network/tray_network.h delete mode 100644 ash/system/chromeos/network/tray_sms.cc delete mode 100644 ash/system/chromeos/network/tray_sms.h delete mode 100644 ash/system/chromeos/tray_display.cc delete mode 100644 ash/system/chromeos/tray_display.h create mode 100644 ash/system/network/network_observer.h create mode 100644 ash/system/network/sms_observer.h create mode 100644 ash/system/network/tray_network.cc create mode 100644 ash/system/network/tray_network.h create mode 100644 ash/system/network/tray_sms.cc create mode 100644 ash/system/network/tray_sms.h delete mode 100644 ash/system/power/DEPS create mode 100644 ash/system/tray_display.cc create mode 100644 ash/system/tray_display.h (limited to 'ash') diff --git a/ash/ash.gyp b/ash/ash.gyp index bbaad34..837402bf 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -160,13 +160,6 @@ 'system/brightness/brightness_control_delegate.h', 'system/brightness/tray_brightness.cc', 'system/brightness/tray_brightness.h', - 'system/chromeos/network/network_observer.h', - 'system/chromeos/network/tray_network.cc', - 'system/chromeos/network/tray_network.h', - 'system/chromeos/network/tray_sms.cc', - 'system/chromeos/network/tray_sms.h', - 'system/chromeos/tray_display.cc', - 'system/chromeos/tray_display.h', 'system/date/clock_observer.h', 'system/date/date_view.cc', 'system/date/date_view.h', @@ -181,6 +174,11 @@ 'system/keyboard_brightness/keyboard_brightness_control_delegate.h', 'system/locale/tray_locale.cc', 'system/locale/tray_locale.h', + 'system/network/network_observer.h', + 'system/network/tray_network.cc', + 'system/network/tray_network.h', + 'system/network/tray_sms.cc', + 'system/network/tray_sms.h', 'system/power/power_status_observer.h', 'system/power/power_status_view.cc', 'system/power/power_status_view.h', @@ -230,6 +228,8 @@ 'system/tray_accessibility.h', 'system/tray_caps_lock.cc', 'system/tray_caps_lock.h', + 'system/tray_display.cc', + 'system/tray_display.h', 'system/tray_update.cc', 'system/tray_update.h', 'system/user/login_status.h', diff --git a/ash/system/DEPS b/ash/system/DEPS deleted file mode 100644 index abf5b5f..0000000 --- a/ash/system/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "-chromeos", -] diff --git a/ash/system/chromeos/DEPS b/ash/system/chromeos/DEPS deleted file mode 100644 index 79b8e8b..0000000 --- a/ash/system/chromeos/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+chromeos", -] diff --git a/ash/system/chromeos/network/network_observer.h b/ash/system/chromeos/network/network_observer.h deleted file mode 100644 index 6ecc242..0000000 --- a/ash/system/chromeos/network/network_observer.h +++ /dev/null @@ -1,58 +0,0 @@ -// 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. - -#ifndef ASH_SYSTEM_CHROMEOS_NETWORK_NETWORK_OBSERVER_H -#define ASH_SYSTEM_CHROMEOS_NETWORK_NETWORK_OBSERVER_H - -#include - -#include "base/string16.h" - -namespace ash { - -struct NetworkIconInfo; - -class NetworkTrayDelegate { - public: - virtual ~NetworkTrayDelegate() {} - - // Notifies that the |index|-th link on the notification is clicked. - virtual void NotificationLinkClicked(size_t index) = 0; -}; - -class NetworkObserver { - public: - enum MessageType { - // Priority order, highest to lowest. - ERROR_CONNECT_FAILED, - - MESSAGE_DATA_NONE, - MESSAGE_DATA_LOW, - MESSAGE_DATA_PROMO, - }; - - virtual ~NetworkObserver() {} - - virtual void OnNetworkRefresh(const NetworkIconInfo& info) = 0; - - // Sets a network message notification. |message_type| identifies the type of - // message. |delegate|->NotificationLinkClicked() will be called if any of the - // |links| are clicked (if supplied, |links| may be empty). - virtual void SetNetworkMessage(NetworkTrayDelegate* delegate, - MessageType message_type, - const string16& title, - const string16& message, - const std::vector& links) = 0; - // Clears the message notification for |message_type|. - virtual void ClearNetworkMessage(MessageType message_type) = 0; - - // Called when the user attempted to toggle Wi-Fi enable/disable. - // NOTE: Toggling is asynchronous and subsequent calls to query the current - // state may return the old value. - virtual void OnWillToggleWifi() = 0; -}; - -} // namespace ash - -#endif // ASH_SYSTEM_CHROMEOS_NETWORK_NETWORK_OBSERVER_H diff --git a/ash/system/chromeos/network/sms_observer.h b/ash/system/chromeos/network/sms_observer.h deleted file mode 100644 index bc54967..0000000 --- a/ash/system/chromeos/network/sms_observer.h +++ /dev/null @@ -1,26 +0,0 @@ -// 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. - -#ifndef ASH_SYSTEM_CHROMEOS_NETWORK_SMS_OBSERVER_H -#define ASH_SYSTEM_CHROMEOS_NETWORK_SMS_OBSERVER_H - -namespace base { -class DictionaryValue; -} - -namespace ash { - -const char kSmsNumberKey[] = "number"; -const char kSmsTextKey[] = "text"; - -class SmsObserver { - public: - virtual ~SmsObserver() {} - - virtual void AddMessage(const base::DictionaryValue& message) = 0; -}; - -} // namespace ash - -#endif // ASH_SYSTEM_CHROMEOS_NETWORK_SMS_OBSERVER_H diff --git a/ash/system/chromeos/network/tray_network.cc b/ash/system/chromeos/network/tray_network.cc deleted file mode 100644 index 8f2a9cf..0000000 --- a/ash/system/chromeos/network/tray_network.cc +++ /dev/null @@ -1,959 +0,0 @@ -// 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/chromeos/network/tray_network.h" - -#include "ash/shell.h" -#include "ash/shell_window_ids.h" -#include "ash/system/tray/system_tray.h" -#include "ash/system/tray/system_tray_delegate.h" -#include "ash/system/tray/tray_constants.h" -#include "ash/system/tray/tray_details_view.h" -#include "ash/system/tray/tray_item_more.h" -#include "ash/system/tray/tray_item_view.h" -#include "ash/system/tray/tray_notification_view.h" -#include "ash/system/tray/tray_views.h" -#include "base/utf_string_conversions.h" -#include "grit/ash_resources.h" -#include "grit/ash_strings.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/aura/window.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/font.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/skia_util.h" -#include "ui/views/bubble/bubble_border.h" -#include "ui/views/bubble/bubble_delegate.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/button/image_button.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/controls/link.h" -#include "ui/views/controls/link_listener.h" -#include "ui/views/controls/scroll_view.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/fill_layout.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" - -namespace { - -// Height of the list of networks in the popup. -const int kNetworkListHeight = 203; - -// Create a label with the font size and color used in the network info bubble. -views::Label* CreateInfoBubbleLabel(const string16& text) { - const SkColor text_color = SkColorSetARGB(127, 0, 0, 0); - views::Label* label = new views::Label(text); - label->SetFont(label->font().DeriveFont(-1)); - label->SetEnabledColor(text_color); - return label; -} - -// Create a row of labels for the network info bubble. -views::View* CreateInfoBubbleLine(const string16& text_label, - const std::string& text_string) { - views::View* view = new views::View; - view->SetLayoutManager( - new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 1)); - view->AddChildView(CreateInfoBubbleLabel(text_label)); - view->AddChildView(CreateInfoBubbleLabel(UTF8ToUTF16(": "))); - view->AddChildView(CreateInfoBubbleLabel(UTF8ToUTF16(text_string))); - return view; -} - -// A bubble that cannot be activated. -class NonActivatableSettingsBubble : public views::BubbleDelegateView { - public: - NonActivatableSettingsBubble(views::View* anchor, views::View* content) - : views::BubbleDelegateView(anchor, views::BubbleBorder::TOP_RIGHT) { - set_use_focusless(true); - set_parent_window(ash::Shell::GetContainer( - anchor->GetWidget()->GetNativeWindow()->GetRootWindow(), - ash::internal::kShellWindowId_SettingBubbleContainer)); - SetLayoutManager(new views::FillLayout()); - AddChildView(content); - } - - virtual ~NonActivatableSettingsBubble() {} - - virtual bool CanActivate() const OVERRIDE { - return false; - } - - private: - DISALLOW_COPY_AND_ASSIGN(NonActivatableSettingsBubble); -}; - -using ash::internal::TrayNetwork; - -int GetMessageIcon(TrayNetwork::MessageType message_type) { - switch(message_type) { - case TrayNetwork::ERROR_CONNECT_FAILED: - return IDR_AURA_UBER_TRAY_NETWORK_FAILED; - case TrayNetwork::MESSAGE_DATA_LOW: - return IDR_AURA_UBER_TRAY_NETWORK_DATA_LOW; - case TrayNetwork::MESSAGE_DATA_NONE: - return IDR_AURA_UBER_TRAY_NETWORK_DATA_NONE; - case TrayNetwork::MESSAGE_DATA_PROMO: - return IDR_AURA_UBER_TRAY_NOTIFICATION_3G; - } - NOTREACHED(); - return 0; -} - -} // namespace - -namespace ash { -namespace internal { - -namespace tray { - -enum ColorTheme { - LIGHT, - DARK, -}; - -class NetworkMessages { - public: - struct Message { - Message() : delegate(NULL) {} - Message(NetworkTrayDelegate* in_delegate, - const string16& in_title, - const string16& in_message, - const std::vector& in_links) : - delegate(in_delegate), - title(in_title), - message(in_message), - links(in_links) {} - NetworkTrayDelegate* delegate; - string16 title; - string16 message; - std::vector links; - }; - typedef std::map MessageMap; - - MessageMap& messages() { return messages_; } - const MessageMap& messages() const { return messages_; } - - private: - MessageMap messages_; -}; - -class NetworkTrayView : public TrayItemView { - public: - NetworkTrayView(ColorTheme size, bool tray_icon) - : color_theme_(size), tray_icon_(tray_icon) { - SetLayoutManager( - new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); - - image_view_ = color_theme_ == DARK ? - new FixedSizedImageView(0, kTrayPopupItemHeight) : - new views::ImageView; - AddChildView(image_view_); - - NetworkIconInfo info; - Shell::GetInstance()->tray_delegate()-> - GetMostRelevantNetworkIcon(&info, false); - Update(info); - } - - virtual ~NetworkTrayView() {} - - void Update(const NetworkIconInfo& info) { - image_view_->SetImage(info.image); - if (tray_icon_) - SetVisible(info.tray_icon_visible); - SchedulePaint(); - } - - private: - views::ImageView* image_view_; - ColorTheme color_theme_; - bool tray_icon_; - - DISALLOW_COPY_AND_ASSIGN(NetworkTrayView); -}; - -class NetworkDefaultView : public TrayItemMore { - public: - explicit NetworkDefaultView(SystemTrayItem* owner) - : TrayItemMore(owner) { - Update(); - } - - virtual ~NetworkDefaultView() {} - - void Update() { - NetworkIconInfo info; - Shell::GetInstance()->tray_delegate()-> - GetMostRelevantNetworkIcon(&info, true); - SetImage(&info.image); - SetLabel(info.description); - SetAccessibleName(info.description); - } - - private: - DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView); -}; - -class NetworkDetailedView : public TrayDetailsView { - public: - NetworkDetailedView() {} - - virtual ~NetworkDetailedView() {} - - virtual TrayNetwork::DetailedViewType GetViewType() const = 0; - - virtual void Update() = 0; -}; - -class NetworkListDetailedView : public NetworkDetailedView, - public views::ButtonListener, - public ViewClickListener { - public: - NetworkListDetailedView(user::LoginStatus login) - : login_(login), - airplane_(NULL), - info_icon_(NULL), - button_wifi_(NULL), - button_mobile_(NULL), - view_mobile_account_(NULL), - setup_mobile_account_(NULL), - other_wifi_(NULL), - turn_on_wifi_(NULL), - other_mobile_(NULL), - settings_(NULL), - proxy_settings_(NULL), - info_bubble_(NULL) { - SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); - delegate->RequestNetworkScan(); - CreateItems(); - Update(); - } - - virtual ~NetworkListDetailedView() { - if (info_bubble_) - info_bubble_->GetWidget()->CloseNow(); - } - - void CreateItems() { - RemoveAllChildViews(true); - - airplane_ = NULL; - info_icon_ = NULL; - button_wifi_ = NULL; - button_mobile_ = NULL; - view_mobile_account_ = NULL; - setup_mobile_account_ = NULL; - other_wifi_ = NULL; - turn_on_wifi_ = NULL; - other_mobile_ = NULL; - settings_ = NULL; - proxy_settings_ = NULL; - - AppendNetworkEntries(); - AppendNetworkExtra(); - AppendHeaderEntry(); - AppendHeaderButtons(); - - Update(); - } - - // Overridden from NetworkDetailedView: - virtual TrayNetwork::DetailedViewType GetViewType() const OVERRIDE { - return TrayNetwork::LIST_VIEW; - } - - virtual void Update() OVERRIDE { - UpdateAvailableNetworkList(); - UpdateHeaderButtons(); - UpdateNetworkEntries(); - UpdateNetworkExtra(); - - Layout(); - } - - private: - void AppendHeaderEntry() { - CreateSpecialRow(IDS_ASH_STATUS_TRAY_NETWORK, this); - } - - void AppendHeaderButtons() { - button_wifi_ = new TrayPopupHeaderButton(this, - IDR_AURA_UBER_TRAY_WIFI_ENABLED, - IDR_AURA_UBER_TRAY_WIFI_DISABLED, - IDR_AURA_UBER_TRAY_WIFI_ENABLED_HOVER, - IDR_AURA_UBER_TRAY_WIFI_DISABLED_HOVER, - IDS_ASH_STATUS_TRAY_WIFI); - button_wifi_->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISABLE_WIFI)); - button_wifi_->SetToggledTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_WIFI)); - footer()->AddButton(button_wifi_); - - button_mobile_ = new TrayPopupHeaderButton(this, - IDR_AURA_UBER_TRAY_CELLULAR_ENABLED, - IDR_AURA_UBER_TRAY_CELLULAR_DISABLED, - IDR_AURA_UBER_TRAY_CELLULAR_ENABLED_HOVER, - IDR_AURA_UBER_TRAY_CELLULAR_DISABLED_HOVER, - IDS_ASH_STATUS_TRAY_CELLULAR); - button_mobile_->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISABLE_MOBILE)); - button_mobile_->SetToggledTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_MOBILE)); - footer()->AddButton(button_mobile_); - - info_icon_ = new TrayPopupHeaderButton(this, - IDR_AURA_UBER_TRAY_NETWORK_INFO, - IDR_AURA_UBER_TRAY_NETWORK_INFO, - IDR_AURA_UBER_TRAY_NETWORK_INFO_HOVER, - IDR_AURA_UBER_TRAY_NETWORK_INFO_HOVER, - IDS_ASH_STATUS_TRAY_NETWORK_INFO); - info_icon_->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_INFO)); - footer()->AddButton(info_icon_); - } - - void UpdateHeaderButtons() { - SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); - button_wifi_->SetToggled(!delegate->GetWifiEnabled()); - button_mobile_->SetToggled(!delegate->GetMobileEnabled()); - button_mobile_->SetVisible(delegate->GetMobileAvailable()); - if (proxy_settings_) - proxy_settings_->SetEnabled(delegate->IsNetworkConnected()); - } - - void AppendNetworkEntries() { - CreateScrollableList(); - - HoverHighlightView* container = new HoverHighlightView(this); - container->set_fixed_height(kTrayPopupItemHeight); - container->AddLabel(ui::ResourceBundle::GetSharedInstance(). - GetLocalizedString(IDS_ASH_STATUS_TRAY_MOBILE_VIEW_ACCOUNT), - gfx::Font::NORMAL); - AddChildView(container); - view_mobile_account_ = container; - - container = new HoverHighlightView(this); - container->set_fixed_height(kTrayPopupItemHeight); - container->AddLabel(ui::ResourceBundle::GetSharedInstance(). - GetLocalizedString(IDS_ASH_STATUS_TRAY_SETUP_MOBILE), - gfx::Font::NORMAL); - AddChildView(container); - setup_mobile_account_ = container; - } - - void UpdateAvailableNetworkList() { - network_list_.clear(); - Shell::GetInstance()->tray_delegate()->GetAvailableNetworks(&network_list_); - } - - void RefreshNetworkScrollWithUpdatedNetworkList() { - network_map_.clear(); - std::set new_service_paths; - - bool needs_relayout = false; - views::View* highlighted_view = NULL; - - if (service_path_map_.empty()) - scroll_content()->RemoveAllChildViews(true); - - for (size_t i = 0; i < network_list_.size(); ++i) { - std::map::const_iterator it = - service_path_map_.find(network_list_[i].service_path); - HoverHighlightView* container = NULL; - if (it == service_path_map_.end()) { - // Create a new view. - container = new HoverHighlightView(this); - container->set_fixed_height(kTrayPopupItemHeight); - container->AddIconAndLabel(network_list_[i].image, - network_list_[i].description.empty() ? - network_list_[i].name : network_list_[i].description, - network_list_[i].highlight ? - gfx::Font::BOLD : gfx::Font::NORMAL); - scroll_content()->AddChildViewAt(container, i); - container->set_border(views::Border::CreateEmptyBorder(0, - kTrayPopupPaddingHorizontal, 0, 0)); - needs_relayout = true; - } else { - container = it->second; - container->RemoveAllChildViews(true); - container->AddIconAndLabel(network_list_[i].image, - network_list_[i].description.empty() ? - network_list_[i].name : network_list_[i].description, - network_list_[i].highlight ? gfx::Font::BOLD : gfx::Font::NORMAL); - container->Layout(); - container->SchedulePaint(); - - // Reordering the view if necessary. - views::View* child = scroll_content()->child_at(i); - if (child != container) { - scroll_content()->ReorderChildView(container, i); - needs_relayout = true; - } - } - - if (network_list_[i].highlight) - highlighted_view = container; - network_map_[container] = network_list_[i].service_path; - service_path_map_[network_list_[i].service_path] = container; - new_service_paths.insert(network_list_[i].service_path); - } - - std::set remove_service_paths; - for (std::map::const_iterator it = - service_path_map_.begin(); it != service_path_map_.end(); ++it) { - if (new_service_paths.find(it->first) == new_service_paths.end()) { - remove_service_paths.insert(it->first); - scroll_content()->RemoveChildView(it->second); - needs_relayout = true; - } - } - - for (std::set::const_iterator remove_it = - remove_service_paths.begin(); - remove_it != remove_service_paths.end(); ++remove_it) { - service_path_map_.erase(*remove_it); - } - - if (needs_relayout) { - scroll_content()->SizeToPreferredSize(); - static_cast(scroller())->Layout(); - if (highlighted_view) - scroll_content()->ScrollRectToVisible(highlighted_view->bounds()); - } - } - - void RefreshNetworkScrollWithEmptyNetworkList() { - service_path_map_.clear(); - network_map_.clear(); - scroll_content()->RemoveAllChildViews(true); - HoverHighlightView* container = new HoverHighlightView(this); - container->set_fixed_height(kTrayPopupItemHeight); - - if (Shell::GetInstance()->tray_delegate()->GetWifiEnabled()) { - NetworkIconInfo info; - Shell::GetInstance()->tray_delegate()-> - GetMostRelevantNetworkIcon(&info, true); - container->AddIconAndLabel(info.image, - info.description, - gfx::Font::NORMAL); - container->set_border(views::Border::CreateEmptyBorder(0, - kTrayPopupPaddingHorizontal, 0, 0)); - - } else { - container->AddLabel(ui::ResourceBundle::GetSharedInstance(). - GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED), - gfx::Font::NORMAL); - } - - scroll_content()->AddChildViewAt(container, 0); - scroll_content()->SizeToPreferredSize(); - static_cast(scroller())->Layout(); - } - - void UpdateNetworkEntries() { - if (network_list_.size() > 0 ) - RefreshNetworkScrollWithUpdatedNetworkList(); - else - RefreshNetworkScrollWithEmptyNetworkList(); - - view_mobile_account_->SetVisible(false); - setup_mobile_account_->SetVisible(false); - - if (login_ == user::LOGGED_IN_NONE) - return; - - std::string carrier_id, topup_url, setup_url; - if (Shell::GetInstance()->tray_delegate()-> - GetCellularCarrierInfo(&carrier_id, - &topup_url, - &setup_url)) { - if (carrier_id != carrier_id_) { - carrier_id_ = carrier_id; - if (!topup_url.empty()) - topup_url_ = topup_url; - } - - if (!setup_url.empty()) - setup_url_ = setup_url; - - if (!topup_url_.empty()) - view_mobile_account_->SetVisible(true); - if (!setup_url_.empty()) - setup_mobile_account_->SetVisible(true); - } - } - - void AppendNetworkExtra() { - if (login_ == user::LOGGED_IN_LOCKED) - return; - - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - - TrayPopupTextButtonContainer* bottom_row = - new TrayPopupTextButtonContainer; - - other_wifi_ = new TrayPopupTextButton(this, - rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_OTHER_WIFI)); - bottom_row->AddTextButton(other_wifi_); - - turn_on_wifi_ = new TrayPopupTextButton(this, - rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_TURN_ON_WIFI)); - bottom_row->AddTextButton(turn_on_wifi_); - - other_mobile_ = new TrayPopupTextButton(this, - rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_OTHER_MOBILE)); - bottom_row->AddTextButton(other_mobile_); - - CreateSettingsEntry(); - DCHECK(settings_ || proxy_settings_); - bottom_row->AddTextButton(settings_ ? settings_ : proxy_settings_); - - AddChildView(bottom_row); - } - - void UpdateNetworkExtra() { - if (login_ == user::LOGGED_IN_LOCKED) - return; - - SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); - if (network_list_.size() == 0 && !delegate->GetWifiEnabled()) { - turn_on_wifi_->SetVisible(true); - other_wifi_->SetVisible(false); - } else { - turn_on_wifi_->SetVisible(false); - other_wifi_->SetVisible(true); - other_wifi_->SetEnabled(delegate->GetWifiEnabled()); - } - other_mobile_->SetVisible(delegate->GetMobileAvailable() && - delegate->GetMobileScanSupported()); - if (other_mobile_->visible()) - other_mobile_->SetEnabled(delegate->GetMobileEnabled()); - - turn_on_wifi_->parent()->Layout(); - } - - // Adds a settings entry when logged in, and an entry for changing proxy - // settings otherwise. - void CreateSettingsEntry() { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - if (login_ != user::LOGGED_IN_NONE) { - // Settings, only if logged in. - settings_ = new TrayPopupTextButton(this, - rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_SETTINGS)); - } else { - proxy_settings_ = new TrayPopupTextButton(this, - rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_PROXY_SETTINGS)); - } - } - - views::View* CreateNetworkInfoView() { - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - std::string ip_address, ethernet_address, wifi_address; - Shell::GetInstance()->tray_delegate()->GetNetworkAddresses(&ip_address, - ðernet_address, &wifi_address); - - views::View* container = new views::View; - container->SetLayoutManager(new - views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); - container->set_border(views::Border::CreateEmptyBorder(0, 5, 0, 5)); - - // GetNetworkAddresses returns empty strings if no information is available. - if (!ip_address.empty()) { - container->AddChildView(CreateInfoBubbleLine(bundle.GetLocalizedString( - IDS_ASH_STATUS_TRAY_IP), ip_address)); - } - if (!ethernet_address.empty()) { - container->AddChildView(CreateInfoBubbleLine(bundle.GetLocalizedString( - IDS_ASH_STATUS_TRAY_ETHERNET), ethernet_address)); - } - if (!wifi_address.empty()) { - container->AddChildView(CreateInfoBubbleLine(bundle.GetLocalizedString( - IDS_ASH_STATUS_TRAY_WIFI), wifi_address)); - } - - // Avoid an empty bubble in the unlikely event that there is no network - // information at all. - if (!container->has_children()) { - container->AddChildView(CreateInfoBubbleLabel(bundle.GetLocalizedString( - IDS_ASH_STATUS_TRAY_NO_NETWORKS))); - } - - return container; - } - - void ToggleInfoBubble() { - if (ResetInfoBubble()) - return; - - info_bubble_ = new NonActivatableSettingsBubble( - info_icon_, CreateNetworkInfoView()); - views::BubbleDelegateView::CreateBubble(info_bubble_); - info_bubble_->Show(); - } - - // Returns whether an existing info-bubble was closed. - bool ResetInfoBubble() { - if (!info_bubble_) - return false; - info_bubble_->GetWidget()->Close(); - info_bubble_ = NULL; - return true; - } - - // Overridden from ButtonListener. - virtual void ButtonPressed(views::Button* sender, - const ui::Event& event) OVERRIDE { - ash::SystemTrayDelegate* delegate = - ash::Shell::GetInstance()->tray_delegate(); - if (sender == info_icon_) { - ToggleInfoBubble(); - return; - } - - // If the info bubble was visible, close it when some other item is clicked - // on. - ResetInfoBubble(); - if (sender == button_wifi_) - delegate->ToggleWifi(); - else if (sender == button_mobile_) - delegate->ToggleMobile(); - else if (sender == settings_) - delegate->ShowNetworkSettings(); - else if (sender == proxy_settings_) - delegate->ChangeProxySettings(); - else if (sender == other_mobile_) - delegate->ShowOtherCellular(); - else if (sender == other_wifi_) - delegate->ShowOtherWifi(); - else if (sender == turn_on_wifi_) - delegate->ToggleWifi(); - else - NOTREACHED(); - } - - // Overridden from ViewClickListener. - virtual void ClickedOn(views::View* sender) OVERRIDE { - ash::SystemTrayDelegate* delegate = - ash::Shell::GetInstance()->tray_delegate(); - // If the info bubble was visible, close it when some other item is clicked - // on. - ResetInfoBubble(); - - if (sender == footer()->content()) { - Shell::GetInstance()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING); - return; - } - - if (login_ == user::LOGGED_IN_LOCKED) - return; - - if (sender == view_mobile_account_) { - delegate->ShowCellularURL(topup_url_); - } else if (sender == setup_mobile_account_) { - delegate->ShowCellularURL(setup_url_); - } else if (sender == airplane_) { - delegate->ToggleAirplaneMode(); - } else { - std::map::iterator find; - find = network_map_.find(sender); - if (find != network_map_.end()) { - std::string network_id = find->second; - delegate->ConnectToNetwork(network_id); - } - } - } - - std::string carrier_id_; - std::string topup_url_; - std::string setup_url_; - - user::LoginStatus login_; - std::map network_map_; - std::map service_path_map_; - std::vector network_list_; - views::View* airplane_; - TrayPopupHeaderButton* info_icon_; - TrayPopupHeaderButton* button_wifi_; - TrayPopupHeaderButton* button_mobile_; - views::View* view_mobile_account_; - views::View* setup_mobile_account_; - TrayPopupTextButton* other_wifi_; - TrayPopupTextButton* turn_on_wifi_; - TrayPopupTextButton* other_mobile_; - TrayPopupTextButton* settings_; - TrayPopupTextButton* proxy_settings_; - - views::BubbleDelegateView* info_bubble_; - - DISALLOW_COPY_AND_ASSIGN(NetworkListDetailedView); -}; - -class NetworkWifiDetailedView : public NetworkDetailedView { - public: - explicit NetworkWifiDetailedView(bool wifi_enabled) { - SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, - kTrayPopupPaddingHorizontal, - 10, - kTrayPopupPaddingBetweenItems)); - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - views::ImageView* image = new views::ImageView; - const int image_id = wifi_enabled ? - IDR_AURA_UBER_TRAY_WIFI_ENABLED : IDR_AURA_UBER_TRAY_WIFI_DISABLED; - image->SetImage(bundle.GetImageNamed(image_id).ToImageSkia()); - AddChildView(image); - - const int string_id = wifi_enabled ? - IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED: - IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED; - views::Label* label = - new views::Label(bundle.GetLocalizedString(string_id)); - label->SetMultiLine(true); - label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(label); - } - - virtual ~NetworkWifiDetailedView() {} - - // Overridden from NetworkDetailedView: - virtual TrayNetwork::DetailedViewType GetViewType() const OVERRIDE { - return TrayNetwork::WIFI_VIEW; - } - - virtual void Update() OVERRIDE {} - - private: - DISALLOW_COPY_AND_ASSIGN(NetworkWifiDetailedView); -}; - -class NetworkMessageView : public views::View, - public views::LinkListener { - public: - NetworkMessageView(TrayNetwork* tray, - TrayNetwork::MessageType message_type, - const NetworkMessages::Message& network_msg) - : tray_(tray), - message_type_(message_type) { - SetLayoutManager( - new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); - - if (!network_msg.title.empty()) { - views::Label* title = new views::Label(network_msg.title); - title->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - title->SetFont(title->font().DeriveFont(0, gfx::Font::BOLD)); - AddChildView(title); - } - - if (!network_msg.message.empty()) { - views::Label* message = new views::Label(network_msg.message); - message->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - message->SetMultiLine(true); - message->SizeToFit(kTrayNotificationContentsWidth); - AddChildView(message); - } - - if (!network_msg.links.empty()) { - for (size_t i = 0; i < network_msg.links.size(); ++i) { - views::Link* link = new views::Link(network_msg.links[i]); - link->set_id(i); - link->set_listener(this); - link->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - link->SetMultiLine(true); - link->SizeToFit(kTrayNotificationContentsWidth); - AddChildView(link); - } - } - } - - virtual ~NetworkMessageView() { - } - - // Overridden from views::LinkListener. - virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE { - tray_->LinkClicked(message_type_, source->id()); - } - - TrayNetwork::MessageType message_type() const { return message_type_; } - - private: - TrayNetwork* tray_; - TrayNetwork::MessageType message_type_; - - DISALLOW_COPY_AND_ASSIGN(NetworkMessageView); -}; - -class NetworkNotificationView : public TrayNotificationView { - public: - explicit NetworkNotificationView(TrayNetwork* tray) - : TrayNotificationView(tray, 0) { - CreateMessageView(); - InitView(network_message_view_); - SetIconImage(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - GetMessageIcon(network_message_view_->message_type()))); - } - - // Overridden from TrayNotificationView. - virtual void OnClose() OVERRIDE { - tray_network()->ClearNetworkMessage(network_message_view_->message_type()); - } - - virtual void OnClickAction() OVERRIDE { - if (network_message_view_->message_type() != - TrayNetwork::MESSAGE_DATA_PROMO) - tray()->PopupDetailedView(0, true); - } - - void Update() { - CreateMessageView(); - UpdateViewAndImage(network_message_view_, - *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - GetMessageIcon(network_message_view_->message_type()))); - } - - private: - TrayNetwork* tray_network() { - return static_cast(tray()); - } - - void CreateMessageView() { - // Display the first (highest priority) message. - CHECK(!tray_network()->messages()->messages().empty()); - NetworkMessages::MessageMap::const_iterator iter = - tray_network()->messages()->messages().begin(); - network_message_view_ = - new NetworkMessageView(tray_network(), iter->first, iter->second); - } - - tray::NetworkMessageView* network_message_view_; - - DISALLOW_COPY_AND_ASSIGN(NetworkNotificationView); -}; - -} // namespace tray - -TrayNetwork::TrayNetwork() - : tray_(NULL), - default_(NULL), - detailed_(NULL), - notification_(NULL), - messages_(new tray::NetworkMessages()), - request_wifi_view_(false) { -} - -TrayNetwork::~TrayNetwork() { -} - -views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) { - CHECK(tray_ == NULL); - tray_ = new tray::NetworkTrayView(tray::LIGHT, true /*tray_icon*/); - return tray_; -} - -views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) { - CHECK(default_ == NULL); - default_ = new tray::NetworkDefaultView(this); - return default_; -} - -views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) { - CHECK(detailed_ == NULL); - // Clear any notifications when showing the detailed view. - messages_->messages().clear(); - HideNotificationView(); - if (request_wifi_view_) { - SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); - // The Wi-Fi state is not toggled yet at this point. - detailed_ = new tray::NetworkWifiDetailedView(!delegate->GetWifiEnabled()); - request_wifi_view_ = false; - } else { - detailed_ = new tray::NetworkListDetailedView(status); - } - return detailed_; -} - -views::View* TrayNetwork::CreateNotificationView(user::LoginStatus status) { - CHECK(notification_ == NULL); - if (messages_->messages().empty()) - return NULL; // Message has already been cleared. - notification_ = new tray::NetworkNotificationView(this); - return notification_; -} - -void TrayNetwork::DestroyTrayView() { - tray_ = NULL; -} - -void TrayNetwork::DestroyDefaultView() { - default_ = NULL; -} - -void TrayNetwork::DestroyDetailedView() { - detailed_ = NULL; -} - -void TrayNetwork::DestroyNotificationView() { - notification_ = NULL; -} - -void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) { -} - -void TrayNetwork::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { - SetTrayImageItemBorder(tray_, alignment); -} - -void TrayNetwork::OnNetworkRefresh(const NetworkIconInfo& info) { - if (tray_) - tray_->Update(info); - if (default_) - default_->Update(); - if (detailed_) - detailed_->Update(); -} - -void TrayNetwork::SetNetworkMessage(NetworkTrayDelegate* delegate, - MessageType message_type, - const string16& title, - const string16& message, - const std::vector& links) { - messages_->messages()[message_type] = - tray::NetworkMessages::Message(delegate, title, message, links); - if (notification_) - notification_->Update(); - else - ShowNotificationView(); -} - -void TrayNetwork::ClearNetworkMessage(MessageType message_type) { - messages_->messages().erase(message_type); - if (messages_->messages().empty()) { - HideNotificationView(); - return; - } - if (notification_) - notification_->Update(); - else - ShowNotificationView(); -} - -void TrayNetwork::OnWillToggleWifi() { - if (!detailed_ || detailed_->GetViewType() == WIFI_VIEW) { - request_wifi_view_ = true; - PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false); - } -} - -void TrayNetwork::LinkClicked(MessageType message_type, int link_id) { - tray::NetworkMessages::MessageMap::const_iterator iter = - messages()->messages().find(message_type); - if (iter != messages()->messages().end() && iter->second.delegate) - iter->second.delegate->NotificationLinkClicked(link_id); -} - -} // namespace internal -} // namespace ash diff --git a/ash/system/chromeos/network/tray_network.h b/ash/system/chromeos/network/tray_network.h deleted file mode 100644 index 271c87c..0000000 --- a/ash/system/chromeos/network/tray_network.h +++ /dev/null @@ -1,80 +0,0 @@ -// 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. - -#ifndef ASH_SYSTEM_CHROMEOS_NETWORK_TRAY_NETWORK_H -#define ASH_SYSTEM_CHROMEOS_NETWORK_TRAY_NETWORK_H - -#include "ash/system/chromeos/network/network_observer.h" -#include "ash/system/tray/system_tray_item.h" -#include "base/memory/scoped_ptr.h" - -namespace ash { -namespace internal { - -namespace tray { -class NetworkDefaultView; -class NetworkDetailedView; -class NetworkMessages; -class NetworkMessageView; -class NetworkNotificationView; -class NetworkTrayView; -} - -class TrayNetwork : public SystemTrayItem, - public NetworkObserver { - public: - enum DetailedViewType { - LIST_VIEW, - WIFI_VIEW, - }; - - TrayNetwork(); - virtual ~TrayNetwork(); - - // Overridden from SystemTrayItem. - virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE; - virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE; - virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE; - virtual views::View* CreateNotificationView( - user::LoginStatus status) OVERRIDE; - virtual void DestroyTrayView() OVERRIDE; - virtual void DestroyDefaultView() OVERRIDE; - virtual void DestroyDetailedView() OVERRIDE; - virtual void DestroyNotificationView() OVERRIDE; - virtual void UpdateAfterLoginStatusChange(user::LoginStatus status) OVERRIDE; - virtual void UpdateAfterShelfAlignmentChange( - ShelfAlignment alignment) OVERRIDE; - - // Overridden from NetworkObserver. - virtual void OnNetworkRefresh(const NetworkIconInfo& info) OVERRIDE; - virtual void SetNetworkMessage(NetworkTrayDelegate* delegate, - MessageType message_type, - const string16& title, - const string16& message, - const std::vector& links) OVERRIDE; - virtual void ClearNetworkMessage(MessageType message_type) OVERRIDE; - virtual void OnWillToggleWifi() OVERRIDE; - - private: - friend class tray::NetworkMessageView; - friend class tray::NetworkNotificationView; - - void LinkClicked(MessageType message_type, int link_id); - - const tray::NetworkMessages* messages() const { return messages_.get(); } - - tray::NetworkTrayView* tray_; - tray::NetworkDefaultView* default_; - tray::NetworkDetailedView* detailed_; - tray::NetworkNotificationView* notification_; - scoped_ptr messages_; - bool request_wifi_view_; - - DISALLOW_COPY_AND_ASSIGN(TrayNetwork); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_SYSTEM_CHROMEOS_NETWORK_TRAY_NETWORK_H diff --git a/ash/system/chromeos/network/tray_sms.cc b/ash/system/chromeos/network/tray_sms.cc deleted file mode 100644 index 65ff9c6..0000000 --- a/ash/system/chromeos/network/tray_sms.cc +++ /dev/null @@ -1,378 +0,0 @@ -// 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/chromeos/network/tray_sms.h" - -#include "ash/ash_switches.h" -#include "ash/shell.h" -#include "ash/system/tray/system_tray.h" -#include "ash/system/tray/tray_constants.h" -#include "ash/system/tray/tray_details_view.h" -#include "ash/system/tray/tray_item_more.h" -#include "ash/system/tray/tray_item_view.h" -#include "ash/system/tray/tray_notification_view.h" -#include "ash/system/tray/tray_views.h" -#include "base/command_line.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "grit/ash_resources.h" -#include "grit/ash_strings.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.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/layout/grid_layout.h" -#include "ui/views/view.h" - -namespace { - -// Min height of the list of messages in the popup. -const int kMessageListMinHeight = 200; -// Top/bottom padding of the text items. -const int kPaddingVertical = 10; - -bool GetMessageFromDictionary(const base::DictionaryValue* message, - std::string* number, - std::string* text) { - if (!message->GetStringWithoutPathExpansion(ash::kSmsNumberKey, number)) - return false; - if (!message->GetStringWithoutPathExpansion(ash::kSmsTextKey, text)) - return false; - return true; -} - -} // namespace - -namespace ash { -namespace internal { - -class TraySms::SmsDefaultView : public TrayItemMore { - public: - explicit SmsDefaultView(TraySms* tray) - : TrayItemMore(tray), - tray_(tray) { - SetImage(ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_AURA_UBER_TRAY_SMS)); - Update(); - } - - virtual ~SmsDefaultView() {} - - void Update() { - int message_count = tray_->messages().GetSize(); - string16 label = l10n_util::GetStringFUTF16( - IDS_ASH_STATUS_TRAY_SMS_MESSAGES, base::IntToString16(message_count)); - SetLabel(label); - SetAccessibleName(label); - } - - private: - TraySms* tray_; - - DISALLOW_COPY_AND_ASSIGN(SmsDefaultView); -}; - -// An entry (row) in SmsDetailedView or NotificationView. -class TraySms::SmsMessageView : public views::View, - public views::ButtonListener { - public: - enum ViewType { - VIEW_DETAILED, - VIEW_NOTIFICATION - }; - - SmsMessageView(TraySms* tray, - ViewType view_type, - size_t index, - const std::string& number, - const std::string& message) - : tray_(tray), - index_(index) { - number_label_ = new views::Label( - l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_SMS_NUMBER, - UTF8ToUTF16(number))); - number_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - number_label_->SetFont( - number_label_->font().DeriveFont(0, gfx::Font::BOLD)); - - message_label_ = new views::Label(UTF8ToUTF16(message)); - message_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - message_label_->SetMultiLine(true); - - if (view_type == VIEW_DETAILED) - LayoutDetailedView(); - else - LayoutNotificationView(); - } - - virtual ~SmsMessageView() { - } - - // Overridden from ButtonListener. - virtual void ButtonPressed(views::Button* sender, - const ui::Event& event) OVERRIDE { - tray_->RemoveMessage(index_); - tray_->Update(false); - } - - private: - void LayoutDetailedView() { - views::ImageButton* close_button = new views::ImageButton(this); - close_button->SetImage(views::CustomButton::BS_NORMAL, - ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_AURA_WINDOW_CLOSE)); - - int msg_width = kTrayPopupWidth - kNotificationIconWidth - - kTrayPopupPaddingHorizontal * 2; - message_label_->SizeToFit(msg_width); - - views::GridLayout* layout = new views::GridLayout(this); - SetLayoutManager(layout); - - views::ColumnSet* columns = layout->AddColumnSet(0); - - // Message - columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal); - columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, - 0 /* resize percent */, - views::GridLayout::FIXED, msg_width, msg_width); - - // Close button - columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, - 0, /* resize percent */ - views::GridLayout::FIXED, - kNotificationIconWidth, kNotificationIconWidth); - - - layout->AddPaddingRow(0, kPaddingVertical); - layout->StartRow(0, 0); - layout->AddView(number_label_); - layout->AddView(close_button, 1, 2); // 2 rows for icon - layout->StartRow(0, 0); - layout->AddView(message_label_); - - layout->AddPaddingRow(0, kPaddingVertical); - } - - void LayoutNotificationView() { - SetLayoutManager( - new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); - AddChildView(number_label_); - message_label_->SizeToFit(kTrayNotificationContentsWidth); - AddChildView(message_label_); - } - - TraySms* tray_; - size_t index_; - views::Label* number_label_; - views::Label* message_label_; - - DISALLOW_COPY_AND_ASSIGN(SmsMessageView); -}; - -class TraySms::SmsDetailedView : public TrayDetailsView, - public ViewClickListener { - public: - explicit SmsDetailedView(TraySms* tray) - : tray_(tray) { - Init(); - Update(); - } - - virtual ~SmsDetailedView() { - } - - void Init() { - CreateScrollableList(); - CreateSpecialRow(IDS_ASH_STATUS_TRAY_SMS, this); - } - - void Update() { - UpdateMessageList(); - Layout(); - SchedulePaint(); - } - - // Overridden from views::View. - gfx::Size GetPreferredSize() { - gfx::Size preferred_size = TrayDetailsView::GetPreferredSize(); - if (preferred_size.height() < kMessageListMinHeight) - preferred_size.set_height(kMessageListMinHeight); - return preferred_size; - } - - private: - void UpdateMessageList() { - const base::ListValue& messages = tray_->messages(); - scroll_content()->RemoveAllChildViews(true); - for (size_t index = 0; index < messages.GetSize(); ++index) { - const base::DictionaryValue* message = NULL; - if (!messages.GetDictionary(index, &message)) { - LOG(ERROR) << "SMS message not a dictionary at: " << index; - continue; - } - std::string number, text; - if (!GetMessageFromDictionary(message, &number, &text)) { - LOG(ERROR) << "Error parsing SMS message"; - continue; - } - SmsMessageView* msgview = new SmsMessageView( - tray_, SmsMessageView::VIEW_DETAILED, index, number, text); - scroll_content()->AddChildView(msgview); - } - scroller()->Layout(); - } - - // Overridden from ViewClickListener. - virtual void ClickedOn(views::View* sender) OVERRIDE { - if (sender == footer()->content()) - Shell::GetInstance()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING); - } - - TraySms* tray_; - - DISALLOW_COPY_AND_ASSIGN(SmsDetailedView); -}; - -class TraySms::SmsNotificationView : public TrayNotificationView { - public: - SmsNotificationView(TraySms* tray, - size_t message_index, - const std::string& number, - const std::string& text) - : TrayNotificationView(tray, IDR_AURA_UBER_TRAY_SMS), - message_index_(message_index) { - SmsMessageView* message_view = new SmsMessageView( - tray, SmsMessageView::VIEW_NOTIFICATION, message_index_, number, text); - InitView(message_view); - } - - void Update(size_t message_index, - const std::string& number, - const std::string& text) { - SmsMessageView* message_view = new SmsMessageView( - tray_sms(), SmsMessageView::VIEW_NOTIFICATION, - message_index_, number, text); - UpdateView(message_view); - } - - // Overridden from TrayNotificationView: - virtual void OnClose() OVERRIDE { - tray_sms()->RemoveMessage(message_index_); - } - - virtual void OnClickAction() OVERRIDE { - tray()->PopupDetailedView(0, true); - } - - private: - TraySms* tray_sms() { - return static_cast(tray()); - } - - size_t message_index_; - - DISALLOW_COPY_AND_ASSIGN(SmsNotificationView); -}; - -TraySms::TraySms() - : default_(NULL), - detailed_(NULL), - notification_(NULL) { -} - -TraySms::~TraySms() { -} - -views::View* TraySms::CreateDefaultView(user::LoginStatus status) { - CHECK(default_ == NULL); - default_ = new SmsDefaultView(this); - default_->SetVisible(!messages_.empty()); - return default_; -} - -views::View* TraySms::CreateDetailedView(user::LoginStatus status) { - CHECK(detailed_ == NULL); - HideNotificationView(); - if (messages_.empty()) - return NULL; - detailed_ = new SmsDetailedView(this); - return detailed_; -} - -views::View* TraySms::CreateNotificationView(user::LoginStatus status) { - CHECK(notification_ == NULL); - size_t index; - std::string number, text; - if (GetLatestMessage(&index, &number, &text)) - notification_ = new SmsNotificationView(this, index, number, text); - return notification_; -} - -void TraySms::DestroyDefaultView() { - default_ = NULL; -} - -void TraySms::DestroyDetailedView() { - detailed_ = NULL; -} - -void TraySms::DestroyNotificationView() { - notification_ = NULL; -} - -void TraySms::AddMessage(const base::DictionaryValue& message) { - messages_.Append(message.DeepCopy()); - Update(true); -} - -bool TraySms::GetLatestMessage(size_t* index, - std::string* number, - std::string* text) { - if (messages_.empty()) - return false; - DictionaryValue* message; - size_t message_index = messages_.GetSize() - 1; - if (!messages_.GetDictionary(message_index, &message)) - return false; - if (!GetMessageFromDictionary(message, number, text)) - return false; - *index = message_index; - return true; -} - -void TraySms::RemoveMessage(size_t index) { - if (index < messages_.GetSize()) - messages_.Remove(index, NULL); -} - -void TraySms::Update(bool notify) { - if (messages_.empty()) { - if (default_) - default_->SetVisible(false); - if (detailed_) - HideDetailedView(); - HideNotificationView(); - } else { - if (default_) { - default_->SetVisible(true); - default_->Update(); - } - if (detailed_) - detailed_->Update(); - if (notification_) { - size_t index; - std::string number, text; - if (GetLatestMessage(&index, &number, &text)) - notification_->Update(index, number, text); - } else if (notify) { - ShowNotificationView(); - } - } -} - -} // namespace internal -} // namespace ash diff --git a/ash/system/chromeos/network/tray_sms.h b/ash/system/chromeos/network/tray_sms.h deleted file mode 100644 index 41501a3..0000000 --- a/ash/system/chromeos/network/tray_sms.h +++ /dev/null @@ -1,65 +0,0 @@ -// 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. - -#ifndef ASH_SYSTEM_CHROMEOS_NETWORK_TRAY_SMS_H -#define ASH_SYSTEM_CHROMEOS_NETWORK_TRAY_SMS_H - -#include - -#include "ash/system/chromeos/network/sms_observer.h" -#include "ash/system/tray/system_tray_item.h" -#include "base/values.h" - -namespace ash { -namespace internal { - -class TraySms : public SystemTrayItem, - public SmsObserver { - public: - TraySms(); - virtual ~TraySms(); - - // Overridden from SystemTrayItem. - virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE; - virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE; - virtual views::View* CreateNotificationView( - user::LoginStatus status) OVERRIDE; - virtual void DestroyDefaultView() OVERRIDE; - virtual void DestroyDetailedView() OVERRIDE; - virtual void DestroyNotificationView() OVERRIDE; - - // Overridden from SmsObserver. - virtual void AddMessage(const base::DictionaryValue& message) OVERRIDE; - - protected: - class SmsDefaultView; - class SmsDetailedView; - class SmsMessageView; - class SmsNotificationView; - - // Gets the most recent message. Returns false if no messages or unable to - // retrieve the numebr and text from the message. - bool GetLatestMessage(size_t* index, std::string* number, std::string* text); - - // Removes message at |index| from message list. - void RemoveMessage(size_t index); - - // Called when sms messages have changed (by tray::SmsObserver). - void Update(bool notify); - - base::ListValue& messages() { return messages_; } - - private: - SmsDefaultView* default_; - SmsDetailedView* detailed_; - SmsNotificationView* notification_; - base::ListValue messages_; - - DISALLOW_COPY_AND_ASSIGN(TraySms); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_SYSTEM_CHROMEOS_NETWORK_TRAY_SMS_H diff --git a/ash/system/chromeos/tray_display.cc b/ash/system/chromeos/tray_display.cc deleted file mode 100644 index 0e672d1..0000000 --- a/ash/system/chromeos/tray_display.cc +++ /dev/null @@ -1,160 +0,0 @@ -// 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/chromeos/tray_display.h" - -#include "ash/display/display_controller.h" -#include "ash/screen_ash.h" -#include "ash/shell.h" -#include "ash/system/tray/system_tray.h" -#include "ash/system/tray/system_tray_delegate.h" -#include "ash/system/tray/tray_constants.h" -#include "ash/system/tray/tray_views.h" -#include "base/utf_string_conversions.h" -#include "grit/ash_resources.h" -#include "grit/ash_strings.h" -#include "ui/aura/display_manager.h" -#include "ui/aura/env.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/layout/box_layout.h" - -#if defined(USE_X11) -#include "ui/base/x/x11_util.h" -#endif - -namespace ash { -namespace internal { - -class DisplayView : public ash::internal::ActionableView { - public: - explicit DisplayView(user::LoginStatus login_status) - : login_status_(login_status) { - SetLayoutManager(new - views::BoxLayout(views::BoxLayout::kHorizontal, - ash::kTrayPopupPaddingHorizontal, 0, - ash::kTrayPopupPaddingBetweenItems)); - - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - views::ImageView* image = - new ash::internal::FixedSizedImageView(0, ash::kTrayPopupItemHeight); - image->SetImage( - bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia()); - AddChildView(image); - label_ = new views::Label(); - AddChildView(label_); - Update(); - } - - virtual ~DisplayView() {} - - void Update() { - switch (Shell::GetInstance()->output_configurator()->output_state()) { - case chromeos::STATE_INVALID: - case chromeos::STATE_HEADLESS: - case chromeos::STATE_SINGLE: - SetVisible(false); - return; - case chromeos::STATE_DUAL_MIRROR: { - // Simply assumes that the primary display appears first and the - // secondary display appears next in the list. - std::vector display_names; -#if defined(USE_X11) - std::vector output_ids; - ui::GetOutputDeviceHandles(&output_ids); - display_names = ui::GetDisplayNames(output_ids); -#endif - if (display_names.size() > 1) { - label_->SetText(l10n_util::GetStringFUTF16( - IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, - UTF8ToUTF16(display_names[1]))); - SetVisible(true); - } else { - SetVisible(false); - } - return; - } - case chromeos::STATE_DUAL_PRIMARY_ONLY: - case chromeos::STATE_DUAL_SECONDARY_ONLY: { - aura::DisplayManager* display_manager = - aura::Env::GetInstance()->display_manager(); - if (display_manager->GetNumDisplays() > 1) { - label_->SetText(l10n_util::GetStringFUTF16( - IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, - UTF8ToUTF16(display_manager->GetDisplayNameFor( - ScreenAsh::GetSecondaryDisplay())))); - SetVisible(true); - } else { - SetVisible(false); - } - return; - } - default: - NOTREACHED(); - } - } - - private: - // Overridden from ActionableView. - virtual bool PerformAction(const ui::Event& event) OVERRIDE { - if (login_status_ == ash::user::LOGGED_IN_USER || - login_status_ == ash::user::LOGGED_IN_OWNER || - login_status_ == ash::user::LOGGED_IN_GUEST) { - ash::Shell::GetInstance()->tray_delegate()->ShowDisplaySettings(); - } - - return true; - } - - user::LoginStatus login_status_; - views::Label* label_; - - DISALLOW_COPY_AND_ASSIGN(DisplayView); -}; - -TrayDisplay::TrayDisplay() - : default_(NULL) { - aura::Env::GetInstance()->display_manager()->AddObserver(this); - ash::Shell::GetInstance()->output_configurator()->AddObserver(this); -} - -TrayDisplay::~TrayDisplay() { - aura::Env::GetInstance()->display_manager()->RemoveObserver(this); - ash::Shell::GetInstance()->output_configurator()->RemoveObserver(this); -} - -views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) { - default_ = new DisplayView(status); - return default_; -} - -void TrayDisplay::DestroyDefaultView() { - default_ = NULL; -} - -void TrayDisplay::OnDisplayBoundsChanged(const gfx::Display& display) { - if (default_) - default_->Update(); -} - -void TrayDisplay::OnDisplayAdded(const gfx::Display& new_display) { - if (default_) - default_->Update(); -} - -void TrayDisplay::OnDisplayRemoved(const gfx::Display& old_display) { - if (default_) - default_->Update(); -} - -void TrayDisplay::OnDisplayModeChanged() { - if (default_) - default_->Update(); -} - -} // namespace internal -} // namespace ash diff --git a/ash/system/chromeos/tray_display.h b/ash/system/chromeos/tray_display.h deleted file mode 100644 index 77994b6..0000000 --- a/ash/system/chromeos/tray_display.h +++ /dev/null @@ -1,51 +0,0 @@ -// 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. - -#ifndef ASH_SYSTEM_CHROMEOS_TRAY_DISPLAY_H_ -#define ASH_SYSTEM_CHROMEOS_TRAY_DISPLAY_H_ - -#include "ash/system/tray/system_tray_item.h" -#include "base/memory/scoped_ptr.h" -#include "ui/aura/display_observer.h" - -#include "chromeos/display/output_configurator.h" - -namespace views { -class View; -} - -namespace ash { - -namespace internal { -class DisplayView; - -class TrayDisplay : public SystemTrayItem, - public chromeos::OutputConfigurator::Observer, - public aura::DisplayObserver { - public: - TrayDisplay(); - virtual ~TrayDisplay(); - - private: - // Overridden from SystemTrayItem. - virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE; - virtual void DestroyDefaultView() OVERRIDE; - - // Overridden from aura::DisplayObserver - virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE; - virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE; - virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE; - - // Overridden from chromeos::OutputConfigurator::Observer - virtual void OnDisplayModeChanged() OVERRIDE; - - DisplayView* default_; - - DISALLOW_COPY_AND_ASSIGN(TrayDisplay); -}; - -} // namespace internal -} // namespace ash - -#endif // ASH_SYSTEM_CHROMEOS_TRAY_DISPLAY_H_ diff --git a/ash/system/network/network_observer.h b/ash/system/network/network_observer.h new file mode 100644 index 0000000..2a27b6d --- /dev/null +++ b/ash/system/network/network_observer.h @@ -0,0 +1,58 @@ +// 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. + +#ifndef ASH_SYSTEM_NETWORK_NETWORK_OBSERVER_H +#define ASH_SYSTEM_NETWORK_NETWORK_OBSERVER_H + +#include + +#include "base/string16.h" + +namespace ash { + +struct NetworkIconInfo; + +class NetworkTrayDelegate { + public: + virtual ~NetworkTrayDelegate() {} + + // Notifies that the |index|-th link on the notification is clicked. + virtual void NotificationLinkClicked(size_t index) = 0; +}; + +class NetworkObserver { + public: + enum MessageType { + // Priority order, highest to lowest. + ERROR_CONNECT_FAILED, + + MESSAGE_DATA_NONE, + MESSAGE_DATA_LOW, + MESSAGE_DATA_PROMO, + }; + + virtual ~NetworkObserver() {} + + virtual void OnNetworkRefresh(const NetworkIconInfo& info) = 0; + + // Sets a network message notification. |message_type| identifies the type of + // message. |delegate|->NotificationLinkClicked() will be called if any of the + // |links| are clicked (if supplied, |links| may be empty). + virtual void SetNetworkMessage(NetworkTrayDelegate* delegate, + MessageType message_type, + const string16& title, + const string16& message, + const std::vector& links) = 0; + // Clears the message notification for |message_type|. + virtual void ClearNetworkMessage(MessageType message_type) = 0; + + // Called when the user attempted to toggle Wi-Fi enable/disable. + // NOTE: Toggling is asynchronous and subsequent calls to query the current + // state may return the old value. + virtual void OnWillToggleWifi() = 0; +}; + +} // namespace ash + +#endif // ASH_SYSTEM_NETWORK_NETWORK_OBSERVER_H diff --git a/ash/system/network/sms_observer.h b/ash/system/network/sms_observer.h new file mode 100644 index 0000000..d9b317f --- /dev/null +++ b/ash/system/network/sms_observer.h @@ -0,0 +1,28 @@ +// 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. + +#ifndef ASH_SYSTEM_NETWORK_SMS_OBSERVER_H +#define ASH_SYSTEM_NETWORK_SMS_OBSERVER_H + +#include "base/string16.h" + +namespace base { +class DictionaryValue; +} + +namespace ash { + +const char kSmsNumberKey[] = "number"; +const char kSmsTextKey[] = "text"; + +class SmsObserver { + public: + virtual ~SmsObserver() {} + + virtual void AddMessage(const base::DictionaryValue& message) = 0; +}; + +} // namespace ash + +#endif // ASH_SYSTEM_NETWORK_SMS_OBSERVER_H diff --git a/ash/system/network/tray_network.cc b/ash/system/network/tray_network.cc new file mode 100644 index 0000000..7769e54 --- /dev/null +++ b/ash/system/network/tray_network.cc @@ -0,0 +1,959 @@ +// 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/network/tray_network.h" + +#include "ash/shell.h" +#include "ash/shell_window_ids.h" +#include "ash/system/tray/system_tray.h" +#include "ash/system/tray/system_tray_delegate.h" +#include "ash/system/tray/tray_constants.h" +#include "ash/system/tray/tray_details_view.h" +#include "ash/system/tray/tray_item_more.h" +#include "ash/system/tray/tray_item_view.h" +#include "ash/system/tray/tray_notification_view.h" +#include "ash/system/tray/tray_views.h" +#include "base/utf_string_conversions.h" +#include "grit/ash_resources.h" +#include "grit/ash_strings.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/aura/window.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/font.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/skia_util.h" +#include "ui/views/bubble/bubble_border.h" +#include "ui/views/bubble/bubble_delegate.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/link.h" +#include "ui/views/controls/link_listener.h" +#include "ui/views/controls/scroll_view.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" + +namespace { + +// Height of the list of networks in the popup. +const int kNetworkListHeight = 203; + +// Create a label with the font size and color used in the network info bubble. +views::Label* CreateInfoBubbleLabel(const string16& text) { + const SkColor text_color = SkColorSetARGB(127, 0, 0, 0); + views::Label* label = new views::Label(text); + label->SetFont(label->font().DeriveFont(-1)); + label->SetEnabledColor(text_color); + return label; +} + +// Create a row of labels for the network info bubble. +views::View* CreateInfoBubbleLine(const string16& text_label, + const std::string& text_string) { + views::View* view = new views::View; + view->SetLayoutManager( + new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 1)); + view->AddChildView(CreateInfoBubbleLabel(text_label)); + view->AddChildView(CreateInfoBubbleLabel(UTF8ToUTF16(": "))); + view->AddChildView(CreateInfoBubbleLabel(UTF8ToUTF16(text_string))); + return view; +} + +// A bubble that cannot be activated. +class NonActivatableSettingsBubble : public views::BubbleDelegateView { + public: + NonActivatableSettingsBubble(views::View* anchor, views::View* content) + : views::BubbleDelegateView(anchor, views::BubbleBorder::TOP_RIGHT) { + set_use_focusless(true); + set_parent_window(ash::Shell::GetContainer( + anchor->GetWidget()->GetNativeWindow()->GetRootWindow(), + ash::internal::kShellWindowId_SettingBubbleContainer)); + SetLayoutManager(new views::FillLayout()); + AddChildView(content); + } + + virtual ~NonActivatableSettingsBubble() {} + + virtual bool CanActivate() const OVERRIDE { + return false; + } + + private: + DISALLOW_COPY_AND_ASSIGN(NonActivatableSettingsBubble); +}; + +using ash::internal::TrayNetwork; + +int GetMessageIcon(TrayNetwork::MessageType message_type) { + switch(message_type) { + case TrayNetwork::ERROR_CONNECT_FAILED: + return IDR_AURA_UBER_TRAY_NETWORK_FAILED; + case TrayNetwork::MESSAGE_DATA_LOW: + return IDR_AURA_UBER_TRAY_NETWORK_DATA_LOW; + case TrayNetwork::MESSAGE_DATA_NONE: + return IDR_AURA_UBER_TRAY_NETWORK_DATA_NONE; + case TrayNetwork::MESSAGE_DATA_PROMO: + return IDR_AURA_UBER_TRAY_NOTIFICATION_3G; + } + NOTREACHED(); + return 0; +} + +} // namespace + +namespace ash { +namespace internal { + +namespace tray { + +enum ColorTheme { + LIGHT, + DARK, +}; + +class NetworkMessages { + public: + struct Message { + Message() : delegate(NULL) {} + Message(NetworkTrayDelegate* in_delegate, + const string16& in_title, + const string16& in_message, + const std::vector& in_links) : + delegate(in_delegate), + title(in_title), + message(in_message), + links(in_links) {} + NetworkTrayDelegate* delegate; + string16 title; + string16 message; + std::vector links; + }; + typedef std::map MessageMap; + + MessageMap& messages() { return messages_; } + const MessageMap& messages() const { return messages_; } + + private: + MessageMap messages_; +}; + +class NetworkTrayView : public TrayItemView { + public: + NetworkTrayView(ColorTheme size, bool tray_icon) + : color_theme_(size), tray_icon_(tray_icon) { + SetLayoutManager( + new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); + + image_view_ = color_theme_ == DARK ? + new FixedSizedImageView(0, kTrayPopupItemHeight) : + new views::ImageView; + AddChildView(image_view_); + + NetworkIconInfo info; + Shell::GetInstance()->tray_delegate()-> + GetMostRelevantNetworkIcon(&info, false); + Update(info); + } + + virtual ~NetworkTrayView() {} + + void Update(const NetworkIconInfo& info) { + image_view_->SetImage(info.image); + if (tray_icon_) + SetVisible(info.tray_icon_visible); + SchedulePaint(); + } + + private: + views::ImageView* image_view_; + ColorTheme color_theme_; + bool tray_icon_; + + DISALLOW_COPY_AND_ASSIGN(NetworkTrayView); +}; + +class NetworkDefaultView : public TrayItemMore { + public: + explicit NetworkDefaultView(SystemTrayItem* owner) + : TrayItemMore(owner) { + Update(); + } + + virtual ~NetworkDefaultView() {} + + void Update() { + NetworkIconInfo info; + Shell::GetInstance()->tray_delegate()-> + GetMostRelevantNetworkIcon(&info, true); + SetImage(&info.image); + SetLabel(info.description); + SetAccessibleName(info.description); + } + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView); +}; + +class NetworkDetailedView : public TrayDetailsView { + public: + NetworkDetailedView() {} + + virtual ~NetworkDetailedView() {} + + virtual TrayNetwork::DetailedViewType GetViewType() const = 0; + + virtual void Update() = 0; +}; + +class NetworkListDetailedView : public NetworkDetailedView, + public views::ButtonListener, + public ViewClickListener { + public: + NetworkListDetailedView(user::LoginStatus login) + : login_(login), + airplane_(NULL), + info_icon_(NULL), + button_wifi_(NULL), + button_mobile_(NULL), + view_mobile_account_(NULL), + setup_mobile_account_(NULL), + other_wifi_(NULL), + turn_on_wifi_(NULL), + other_mobile_(NULL), + settings_(NULL), + proxy_settings_(NULL), + info_bubble_(NULL) { + SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); + delegate->RequestNetworkScan(); + CreateItems(); + Update(); + } + + virtual ~NetworkListDetailedView() { + if (info_bubble_) + info_bubble_->GetWidget()->CloseNow(); + } + + void CreateItems() { + RemoveAllChildViews(true); + + airplane_ = NULL; + info_icon_ = NULL; + button_wifi_ = NULL; + button_mobile_ = NULL; + view_mobile_account_ = NULL; + setup_mobile_account_ = NULL; + other_wifi_ = NULL; + turn_on_wifi_ = NULL; + other_mobile_ = NULL; + settings_ = NULL; + proxy_settings_ = NULL; + + AppendNetworkEntries(); + AppendNetworkExtra(); + AppendHeaderEntry(); + AppendHeaderButtons(); + + Update(); + } + + // Overridden from NetworkDetailedView: + virtual TrayNetwork::DetailedViewType GetViewType() const OVERRIDE { + return TrayNetwork::LIST_VIEW; + } + + virtual void Update() OVERRIDE { + UpdateAvailableNetworkList(); + UpdateHeaderButtons(); + UpdateNetworkEntries(); + UpdateNetworkExtra(); + + Layout(); + } + + private: + void AppendHeaderEntry() { + CreateSpecialRow(IDS_ASH_STATUS_TRAY_NETWORK, this); + } + + void AppendHeaderButtons() { + button_wifi_ = new TrayPopupHeaderButton(this, + IDR_AURA_UBER_TRAY_WIFI_ENABLED, + IDR_AURA_UBER_TRAY_WIFI_DISABLED, + IDR_AURA_UBER_TRAY_WIFI_ENABLED_HOVER, + IDR_AURA_UBER_TRAY_WIFI_DISABLED_HOVER, + IDS_ASH_STATUS_TRAY_WIFI); + button_wifi_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISABLE_WIFI)); + button_wifi_->SetToggledTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_WIFI)); + footer()->AddButton(button_wifi_); + + button_mobile_ = new TrayPopupHeaderButton(this, + IDR_AURA_UBER_TRAY_CELLULAR_ENABLED, + IDR_AURA_UBER_TRAY_CELLULAR_DISABLED, + IDR_AURA_UBER_TRAY_CELLULAR_ENABLED_HOVER, + IDR_AURA_UBER_TRAY_CELLULAR_DISABLED_HOVER, + IDS_ASH_STATUS_TRAY_CELLULAR); + button_mobile_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISABLE_MOBILE)); + button_mobile_->SetToggledTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_MOBILE)); + footer()->AddButton(button_mobile_); + + info_icon_ = new TrayPopupHeaderButton(this, + IDR_AURA_UBER_TRAY_NETWORK_INFO, + IDR_AURA_UBER_TRAY_NETWORK_INFO, + IDR_AURA_UBER_TRAY_NETWORK_INFO_HOVER, + IDR_AURA_UBER_TRAY_NETWORK_INFO_HOVER, + IDS_ASH_STATUS_TRAY_NETWORK_INFO); + info_icon_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_INFO)); + footer()->AddButton(info_icon_); + } + + void UpdateHeaderButtons() { + SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); + button_wifi_->SetToggled(!delegate->GetWifiEnabled()); + button_mobile_->SetToggled(!delegate->GetMobileEnabled()); + button_mobile_->SetVisible(delegate->GetMobileAvailable()); + if (proxy_settings_) + proxy_settings_->SetEnabled(delegate->IsNetworkConnected()); + } + + void AppendNetworkEntries() { + CreateScrollableList(); + + HoverHighlightView* container = new HoverHighlightView(this); + container->set_fixed_height(kTrayPopupItemHeight); + container->AddLabel(ui::ResourceBundle::GetSharedInstance(). + GetLocalizedString(IDS_ASH_STATUS_TRAY_MOBILE_VIEW_ACCOUNT), + gfx::Font::NORMAL); + AddChildView(container); + view_mobile_account_ = container; + + container = new HoverHighlightView(this); + container->set_fixed_height(kTrayPopupItemHeight); + container->AddLabel(ui::ResourceBundle::GetSharedInstance(). + GetLocalizedString(IDS_ASH_STATUS_TRAY_SETUP_MOBILE), + gfx::Font::NORMAL); + AddChildView(container); + setup_mobile_account_ = container; + } + + void UpdateAvailableNetworkList() { + network_list_.clear(); + Shell::GetInstance()->tray_delegate()->GetAvailableNetworks(&network_list_); + } + + void RefreshNetworkScrollWithUpdatedNetworkList() { + network_map_.clear(); + std::set new_service_paths; + + bool needs_relayout = false; + views::View* highlighted_view = NULL; + + if (service_path_map_.empty()) + scroll_content()->RemoveAllChildViews(true); + + for (size_t i = 0; i < network_list_.size(); ++i) { + std::map::const_iterator it = + service_path_map_.find(network_list_[i].service_path); + HoverHighlightView* container = NULL; + if (it == service_path_map_.end()) { + // Create a new view. + container = new HoverHighlightView(this); + container->set_fixed_height(kTrayPopupItemHeight); + container->AddIconAndLabel(network_list_[i].image, + network_list_[i].description.empty() ? + network_list_[i].name : network_list_[i].description, + network_list_[i].highlight ? + gfx::Font::BOLD : gfx::Font::NORMAL); + scroll_content()->AddChildViewAt(container, i); + container->set_border(views::Border::CreateEmptyBorder(0, + kTrayPopupPaddingHorizontal, 0, 0)); + needs_relayout = true; + } else { + container = it->second; + container->RemoveAllChildViews(true); + container->AddIconAndLabel(network_list_[i].image, + network_list_[i].description.empty() ? + network_list_[i].name : network_list_[i].description, + network_list_[i].highlight ? gfx::Font::BOLD : gfx::Font::NORMAL); + container->Layout(); + container->SchedulePaint(); + + // Reordering the view if necessary. + views::View* child = scroll_content()->child_at(i); + if (child != container) { + scroll_content()->ReorderChildView(container, i); + needs_relayout = true; + } + } + + if (network_list_[i].highlight) + highlighted_view = container; + network_map_[container] = network_list_[i].service_path; + service_path_map_[network_list_[i].service_path] = container; + new_service_paths.insert(network_list_[i].service_path); + } + + std::set remove_service_paths; + for (std::map::const_iterator it = + service_path_map_.begin(); it != service_path_map_.end(); ++it) { + if (new_service_paths.find(it->first) == new_service_paths.end()) { + remove_service_paths.insert(it->first); + scroll_content()->RemoveChildView(it->second); + needs_relayout = true; + } + } + + for (std::set::const_iterator remove_it = + remove_service_paths.begin(); + remove_it != remove_service_paths.end(); ++remove_it) { + service_path_map_.erase(*remove_it); + } + + if (needs_relayout) { + scroll_content()->SizeToPreferredSize(); + static_cast(scroller())->Layout(); + if (highlighted_view) + scroll_content()->ScrollRectToVisible(highlighted_view->bounds()); + } + } + + void RefreshNetworkScrollWithEmptyNetworkList() { + service_path_map_.clear(); + network_map_.clear(); + scroll_content()->RemoveAllChildViews(true); + HoverHighlightView* container = new HoverHighlightView(this); + container->set_fixed_height(kTrayPopupItemHeight); + + if (Shell::GetInstance()->tray_delegate()->GetWifiEnabled()) { + NetworkIconInfo info; + Shell::GetInstance()->tray_delegate()-> + GetMostRelevantNetworkIcon(&info, true); + container->AddIconAndLabel(info.image, + info.description, + gfx::Font::NORMAL); + container->set_border(views::Border::CreateEmptyBorder(0, + kTrayPopupPaddingHorizontal, 0, 0)); + + } else { + container->AddLabel(ui::ResourceBundle::GetSharedInstance(). + GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED), + gfx::Font::NORMAL); + } + + scroll_content()->AddChildViewAt(container, 0); + scroll_content()->SizeToPreferredSize(); + static_cast(scroller())->Layout(); + } + + void UpdateNetworkEntries() { + if (network_list_.size() > 0 ) + RefreshNetworkScrollWithUpdatedNetworkList(); + else + RefreshNetworkScrollWithEmptyNetworkList(); + + view_mobile_account_->SetVisible(false); + setup_mobile_account_->SetVisible(false); + + if (login_ == user::LOGGED_IN_NONE) + return; + + std::string carrier_id, topup_url, setup_url; + if (Shell::GetInstance()->tray_delegate()-> + GetCellularCarrierInfo(&carrier_id, + &topup_url, + &setup_url)) { + if (carrier_id != carrier_id_) { + carrier_id_ = carrier_id; + if (!topup_url.empty()) + topup_url_ = topup_url; + } + + if (!setup_url.empty()) + setup_url_ = setup_url; + + if (!topup_url_.empty()) + view_mobile_account_->SetVisible(true); + if (!setup_url_.empty()) + setup_mobile_account_->SetVisible(true); + } + } + + void AppendNetworkExtra() { + if (login_ == user::LOGGED_IN_LOCKED) + return; + + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + + TrayPopupTextButtonContainer* bottom_row = + new TrayPopupTextButtonContainer; + + other_wifi_ = new TrayPopupTextButton(this, + rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_OTHER_WIFI)); + bottom_row->AddTextButton(other_wifi_); + + turn_on_wifi_ = new TrayPopupTextButton(this, + rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_TURN_ON_WIFI)); + bottom_row->AddTextButton(turn_on_wifi_); + + other_mobile_ = new TrayPopupTextButton(this, + rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_OTHER_MOBILE)); + bottom_row->AddTextButton(other_mobile_); + + CreateSettingsEntry(); + DCHECK(settings_ || proxy_settings_); + bottom_row->AddTextButton(settings_ ? settings_ : proxy_settings_); + + AddChildView(bottom_row); + } + + void UpdateNetworkExtra() { + if (login_ == user::LOGGED_IN_LOCKED) + return; + + SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); + if (network_list_.size() == 0 && !delegate->GetWifiEnabled()) { + turn_on_wifi_->SetVisible(true); + other_wifi_->SetVisible(false); + } else { + turn_on_wifi_->SetVisible(false); + other_wifi_->SetVisible(true); + other_wifi_->SetEnabled(delegate->GetWifiEnabled()); + } + other_mobile_->SetVisible(delegate->GetMobileAvailable() && + delegate->GetMobileScanSupported()); + if (other_mobile_->visible()) + other_mobile_->SetEnabled(delegate->GetMobileEnabled()); + + turn_on_wifi_->parent()->Layout(); + } + + // Adds a settings entry when logged in, and an entry for changing proxy + // settings otherwise. + void CreateSettingsEntry() { + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + if (login_ != user::LOGGED_IN_NONE) { + // Settings, only if logged in. + settings_ = new TrayPopupTextButton(this, + rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_SETTINGS)); + } else { + proxy_settings_ = new TrayPopupTextButton(this, + rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_PROXY_SETTINGS)); + } + } + + views::View* CreateNetworkInfoView() { + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + std::string ip_address, ethernet_address, wifi_address; + Shell::GetInstance()->tray_delegate()->GetNetworkAddresses(&ip_address, + ðernet_address, &wifi_address); + + views::View* container = new views::View; + container->SetLayoutManager(new + views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); + container->set_border(views::Border::CreateEmptyBorder(0, 5, 0, 5)); + + // GetNetworkAddresses returns empty strings if no information is available. + if (!ip_address.empty()) { + container->AddChildView(CreateInfoBubbleLine(bundle.GetLocalizedString( + IDS_ASH_STATUS_TRAY_IP), ip_address)); + } + if (!ethernet_address.empty()) { + container->AddChildView(CreateInfoBubbleLine(bundle.GetLocalizedString( + IDS_ASH_STATUS_TRAY_ETHERNET), ethernet_address)); + } + if (!wifi_address.empty()) { + container->AddChildView(CreateInfoBubbleLine(bundle.GetLocalizedString( + IDS_ASH_STATUS_TRAY_WIFI), wifi_address)); + } + + // Avoid an empty bubble in the unlikely event that there is no network + // information at all. + if (!container->has_children()) { + container->AddChildView(CreateInfoBubbleLabel(bundle.GetLocalizedString( + IDS_ASH_STATUS_TRAY_NO_NETWORKS))); + } + + return container; + } + + void ToggleInfoBubble() { + if (ResetInfoBubble()) + return; + + info_bubble_ = new NonActivatableSettingsBubble( + info_icon_, CreateNetworkInfoView()); + views::BubbleDelegateView::CreateBubble(info_bubble_); + info_bubble_->Show(); + } + + // Returns whether an existing info-bubble was closed. + bool ResetInfoBubble() { + if (!info_bubble_) + return false; + info_bubble_->GetWidget()->Close(); + info_bubble_ = NULL; + return true; + } + + // Overridden from ButtonListener. + virtual void ButtonPressed(views::Button* sender, + const ui::Event& event) OVERRIDE { + ash::SystemTrayDelegate* delegate = + ash::Shell::GetInstance()->tray_delegate(); + if (sender == info_icon_) { + ToggleInfoBubble(); + return; + } + + // If the info bubble was visible, close it when some other item is clicked + // on. + ResetInfoBubble(); + if (sender == button_wifi_) + delegate->ToggleWifi(); + else if (sender == button_mobile_) + delegate->ToggleMobile(); + else if (sender == settings_) + delegate->ShowNetworkSettings(); + else if (sender == proxy_settings_) + delegate->ChangeProxySettings(); + else if (sender == other_mobile_) + delegate->ShowOtherCellular(); + else if (sender == other_wifi_) + delegate->ShowOtherWifi(); + else if (sender == turn_on_wifi_) + delegate->ToggleWifi(); + else + NOTREACHED(); + } + + // Overridden from ViewClickListener. + virtual void ClickedOn(views::View* sender) OVERRIDE { + ash::SystemTrayDelegate* delegate = + ash::Shell::GetInstance()->tray_delegate(); + // If the info bubble was visible, close it when some other item is clicked + // on. + ResetInfoBubble(); + + if (sender == footer()->content()) { + Shell::GetInstance()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING); + return; + } + + if (login_ == user::LOGGED_IN_LOCKED) + return; + + if (sender == view_mobile_account_) { + delegate->ShowCellularURL(topup_url_); + } else if (sender == setup_mobile_account_) { + delegate->ShowCellularURL(setup_url_); + } else if (sender == airplane_) { + delegate->ToggleAirplaneMode(); + } else { + std::map::iterator find; + find = network_map_.find(sender); + if (find != network_map_.end()) { + std::string network_id = find->second; + delegate->ConnectToNetwork(network_id); + } + } + } + + std::string carrier_id_; + std::string topup_url_; + std::string setup_url_; + + user::LoginStatus login_; + std::map network_map_; + std::map service_path_map_; + std::vector network_list_; + views::View* airplane_; + TrayPopupHeaderButton* info_icon_; + TrayPopupHeaderButton* button_wifi_; + TrayPopupHeaderButton* button_mobile_; + views::View* view_mobile_account_; + views::View* setup_mobile_account_; + TrayPopupTextButton* other_wifi_; + TrayPopupTextButton* turn_on_wifi_; + TrayPopupTextButton* other_mobile_; + TrayPopupTextButton* settings_; + TrayPopupTextButton* proxy_settings_; + + views::BubbleDelegateView* info_bubble_; + + DISALLOW_COPY_AND_ASSIGN(NetworkListDetailedView); +}; + +class NetworkWifiDetailedView : public NetworkDetailedView { + public: + explicit NetworkWifiDetailedView(bool wifi_enabled) { + SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, + kTrayPopupPaddingHorizontal, + 10, + kTrayPopupPaddingBetweenItems)); + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + views::ImageView* image = new views::ImageView; + const int image_id = wifi_enabled ? + IDR_AURA_UBER_TRAY_WIFI_ENABLED : IDR_AURA_UBER_TRAY_WIFI_DISABLED; + image->SetImage(bundle.GetImageNamed(image_id).ToImageSkia()); + AddChildView(image); + + const int string_id = wifi_enabled ? + IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED: + IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED; + views::Label* label = + new views::Label(bundle.GetLocalizedString(string_id)); + label->SetMultiLine(true); + label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + AddChildView(label); + } + + virtual ~NetworkWifiDetailedView() {} + + // Overridden from NetworkDetailedView: + virtual TrayNetwork::DetailedViewType GetViewType() const OVERRIDE { + return TrayNetwork::WIFI_VIEW; + } + + virtual void Update() OVERRIDE {} + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkWifiDetailedView); +}; + +class NetworkMessageView : public views::View, + public views::LinkListener { + public: + NetworkMessageView(TrayNetwork* tray, + TrayNetwork::MessageType message_type, + const NetworkMessages::Message& network_msg) + : tray_(tray), + message_type_(message_type) { + SetLayoutManager( + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); + + if (!network_msg.title.empty()) { + views::Label* title = new views::Label(network_msg.title); + title->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + title->SetFont(title->font().DeriveFont(0, gfx::Font::BOLD)); + AddChildView(title); + } + + if (!network_msg.message.empty()) { + views::Label* message = new views::Label(network_msg.message); + message->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + message->SetMultiLine(true); + message->SizeToFit(kTrayNotificationContentsWidth); + AddChildView(message); + } + + if (!network_msg.links.empty()) { + for (size_t i = 0; i < network_msg.links.size(); ++i) { + views::Link* link = new views::Link(network_msg.links[i]); + link->set_id(i); + link->set_listener(this); + link->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + link->SetMultiLine(true); + link->SizeToFit(kTrayNotificationContentsWidth); + AddChildView(link); + } + } + } + + virtual ~NetworkMessageView() { + } + + // Overridden from views::LinkListener. + virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE { + tray_->LinkClicked(message_type_, source->id()); + } + + TrayNetwork::MessageType message_type() const { return message_type_; } + + private: + TrayNetwork* tray_; + TrayNetwork::MessageType message_type_; + + DISALLOW_COPY_AND_ASSIGN(NetworkMessageView); +}; + +class NetworkNotificationView : public TrayNotificationView { + public: + explicit NetworkNotificationView(TrayNetwork* tray) + : TrayNotificationView(tray, 0) { + CreateMessageView(); + InitView(network_message_view_); + SetIconImage(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + GetMessageIcon(network_message_view_->message_type()))); + } + + // Overridden from TrayNotificationView. + virtual void OnClose() OVERRIDE { + tray_network()->ClearNetworkMessage(network_message_view_->message_type()); + } + + virtual void OnClickAction() OVERRIDE { + if (network_message_view_->message_type() != + TrayNetwork::MESSAGE_DATA_PROMO) + tray()->PopupDetailedView(0, true); + } + + void Update() { + CreateMessageView(); + UpdateViewAndImage(network_message_view_, + *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + GetMessageIcon(network_message_view_->message_type()))); + } + + private: + TrayNetwork* tray_network() { + return static_cast(tray()); + } + + void CreateMessageView() { + // Display the first (highest priority) message. + CHECK(!tray_network()->messages()->messages().empty()); + NetworkMessages::MessageMap::const_iterator iter = + tray_network()->messages()->messages().begin(); + network_message_view_ = + new NetworkMessageView(tray_network(), iter->first, iter->second); + } + + tray::NetworkMessageView* network_message_view_; + + DISALLOW_COPY_AND_ASSIGN(NetworkNotificationView); +}; + +} // namespace tray + +TrayNetwork::TrayNetwork() + : tray_(NULL), + default_(NULL), + detailed_(NULL), + notification_(NULL), + messages_(new tray::NetworkMessages()), + request_wifi_view_(false) { +} + +TrayNetwork::~TrayNetwork() { +} + +views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) { + CHECK(tray_ == NULL); + tray_ = new tray::NetworkTrayView(tray::LIGHT, true /*tray_icon*/); + return tray_; +} + +views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) { + CHECK(default_ == NULL); + default_ = new tray::NetworkDefaultView(this); + return default_; +} + +views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) { + CHECK(detailed_ == NULL); + // Clear any notifications when showing the detailed view. + messages_->messages().clear(); + HideNotificationView(); + if (request_wifi_view_) { + SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); + // The Wi-Fi state is not toggled yet at this point. + detailed_ = new tray::NetworkWifiDetailedView(!delegate->GetWifiEnabled()); + request_wifi_view_ = false; + } else { + detailed_ = new tray::NetworkListDetailedView(status); + } + return detailed_; +} + +views::View* TrayNetwork::CreateNotificationView(user::LoginStatus status) { + CHECK(notification_ == NULL); + if (messages_->messages().empty()) + return NULL; // Message has already been cleared. + notification_ = new tray::NetworkNotificationView(this); + return notification_; +} + +void TrayNetwork::DestroyTrayView() { + tray_ = NULL; +} + +void TrayNetwork::DestroyDefaultView() { + default_ = NULL; +} + +void TrayNetwork::DestroyDetailedView() { + detailed_ = NULL; +} + +void TrayNetwork::DestroyNotificationView() { + notification_ = NULL; +} + +void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) { +} + +void TrayNetwork::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { + SetTrayImageItemBorder(tray_, alignment); +} + +void TrayNetwork::OnNetworkRefresh(const NetworkIconInfo& info) { + if (tray_) + tray_->Update(info); + if (default_) + default_->Update(); + if (detailed_) + detailed_->Update(); +} + +void TrayNetwork::SetNetworkMessage(NetworkTrayDelegate* delegate, + MessageType message_type, + const string16& title, + const string16& message, + const std::vector& links) { + messages_->messages()[message_type] = + tray::NetworkMessages::Message(delegate, title, message, links); + if (notification_) + notification_->Update(); + else + ShowNotificationView(); +} + +void TrayNetwork::ClearNetworkMessage(MessageType message_type) { + messages_->messages().erase(message_type); + if (messages_->messages().empty()) { + HideNotificationView(); + return; + } + if (notification_) + notification_->Update(); + else + ShowNotificationView(); +} + +void TrayNetwork::OnWillToggleWifi() { + if (!detailed_ || detailed_->GetViewType() == WIFI_VIEW) { + request_wifi_view_ = true; + PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false); + } +} + +void TrayNetwork::LinkClicked(MessageType message_type, int link_id) { + tray::NetworkMessages::MessageMap::const_iterator iter = + messages()->messages().find(message_type); + if (iter != messages()->messages().end() && iter->second.delegate) + iter->second.delegate->NotificationLinkClicked(link_id); +} + +} // namespace internal +} // namespace ash diff --git a/ash/system/network/tray_network.h b/ash/system/network/tray_network.h new file mode 100644 index 0000000..b4d7e08 --- /dev/null +++ b/ash/system/network/tray_network.h @@ -0,0 +1,80 @@ +// 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. + +#ifndef ASH_SYSTEM_NETWORK_TRAY_NETWORK_H +#define ASH_SYSTEM_NETWORK_TRAY_NETWORK_H + +#include "ash/system/network/network_observer.h" +#include "ash/system/tray/system_tray_item.h" +#include "base/memory/scoped_ptr.h" + +namespace ash { +namespace internal { + +namespace tray { +class NetworkDefaultView; +class NetworkDetailedView; +class NetworkMessages; +class NetworkMessageView; +class NetworkNotificationView; +class NetworkTrayView; +} + +class TrayNetwork : public SystemTrayItem, + public NetworkObserver { + public: + enum DetailedViewType { + LIST_VIEW, + WIFI_VIEW, + }; + + TrayNetwork(); + virtual ~TrayNetwork(); + + // Overridden from SystemTrayItem. + virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE; + virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE; + virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE; + virtual views::View* CreateNotificationView( + user::LoginStatus status) OVERRIDE; + virtual void DestroyTrayView() OVERRIDE; + virtual void DestroyDefaultView() OVERRIDE; + virtual void DestroyDetailedView() OVERRIDE; + virtual void DestroyNotificationView() OVERRIDE; + virtual void UpdateAfterLoginStatusChange(user::LoginStatus status) OVERRIDE; + virtual void UpdateAfterShelfAlignmentChange( + ShelfAlignment alignment) OVERRIDE; + + // Overridden from NetworkObserver. + virtual void OnNetworkRefresh(const NetworkIconInfo& info) OVERRIDE; + virtual void SetNetworkMessage(NetworkTrayDelegate* delegate, + MessageType message_type, + const string16& title, + const string16& message, + const std::vector& links) OVERRIDE; + virtual void ClearNetworkMessage(MessageType message_type) OVERRIDE; + virtual void OnWillToggleWifi() OVERRIDE; + + private: + friend class tray::NetworkMessageView; + friend class tray::NetworkNotificationView; + + void LinkClicked(MessageType message_type, int link_id); + + const tray::NetworkMessages* messages() const { return messages_.get(); } + + tray::NetworkTrayView* tray_; + tray::NetworkDefaultView* default_; + tray::NetworkDetailedView* detailed_; + tray::NetworkNotificationView* notification_; + scoped_ptr messages_; + bool request_wifi_view_; + + DISALLOW_COPY_AND_ASSIGN(TrayNetwork); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_SYSTEM_NETWORK_TRAY_NETWORK_H diff --git a/ash/system/network/tray_sms.cc b/ash/system/network/tray_sms.cc new file mode 100644 index 0000000..7aca24f --- /dev/null +++ b/ash/system/network/tray_sms.cc @@ -0,0 +1,378 @@ +// 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/network/tray_sms.h" + +#include "ash/ash_switches.h" +#include "ash/shell.h" +#include "ash/system/tray/system_tray.h" +#include "ash/system/tray/tray_constants.h" +#include "ash/system/tray/tray_details_view.h" +#include "ash/system/tray/tray_item_more.h" +#include "ash/system/tray/tray_item_view.h" +#include "ash/system/tray/tray_notification_view.h" +#include "ash/system/tray/tray_views.h" +#include "base/command_line.h" +#include "base/string_number_conversions.h" +#include "base/utf_string_conversions.h" +#include "grit/ash_resources.h" +#include "grit/ash_strings.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.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/layout/grid_layout.h" +#include "ui/views/view.h" + +namespace { + +// Min height of the list of messages in the popup. +const int kMessageListMinHeight = 200; +// Top/bottom padding of the text items. +const int kPaddingVertical = 10; + +bool GetMessageFromDictionary(const base::DictionaryValue* message, + std::string* number, + std::string* text) { + if (!message->GetStringWithoutPathExpansion(ash::kSmsNumberKey, number)) + return false; + if (!message->GetStringWithoutPathExpansion(ash::kSmsTextKey, text)) + return false; + return true; +} + +} // namespace + +namespace ash { +namespace internal { + +class TraySms::SmsDefaultView : public TrayItemMore { + public: + explicit SmsDefaultView(TraySms* tray) + : TrayItemMore(tray), + tray_(tray) { + SetImage(ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + IDR_AURA_UBER_TRAY_SMS)); + Update(); + } + + virtual ~SmsDefaultView() {} + + void Update() { + int message_count = tray_->messages().GetSize(); + string16 label = l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_SMS_MESSAGES, base::IntToString16(message_count)); + SetLabel(label); + SetAccessibleName(label); + } + + private: + TraySms* tray_; + + DISALLOW_COPY_AND_ASSIGN(SmsDefaultView); +}; + +// An entry (row) in SmsDetailedView or NotificationView. +class TraySms::SmsMessageView : public views::View, + public views::ButtonListener { + public: + enum ViewType { + VIEW_DETAILED, + VIEW_NOTIFICATION + }; + + SmsMessageView(TraySms* tray, + ViewType view_type, + size_t index, + const std::string& number, + const std::string& message) + : tray_(tray), + index_(index) { + number_label_ = new views::Label( + l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_SMS_NUMBER, + UTF8ToUTF16(number))); + number_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + number_label_->SetFont( + number_label_->font().DeriveFont(0, gfx::Font::BOLD)); + + message_label_ = new views::Label(UTF8ToUTF16(message)); + message_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + message_label_->SetMultiLine(true); + + if (view_type == VIEW_DETAILED) + LayoutDetailedView(); + else + LayoutNotificationView(); + } + + virtual ~SmsMessageView() { + } + + // Overridden from ButtonListener. + virtual void ButtonPressed(views::Button* sender, + const ui::Event& event) OVERRIDE { + tray_->RemoveMessage(index_); + tray_->Update(false); + } + + private: + void LayoutDetailedView() { + views::ImageButton* close_button = new views::ImageButton(this); + close_button->SetImage(views::CustomButton::BS_NORMAL, + ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + IDR_AURA_WINDOW_CLOSE)); + + int msg_width = kTrayPopupWidth - kNotificationIconWidth - + kTrayPopupPaddingHorizontal * 2; + message_label_->SizeToFit(msg_width); + + views::GridLayout* layout = new views::GridLayout(this); + SetLayoutManager(layout); + + views::ColumnSet* columns = layout->AddColumnSet(0); + + // Message + columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal); + columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, + 0 /* resize percent */, + views::GridLayout::FIXED, msg_width, msg_width); + + // Close button + columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, + 0, /* resize percent */ + views::GridLayout::FIXED, + kNotificationIconWidth, kNotificationIconWidth); + + + layout->AddPaddingRow(0, kPaddingVertical); + layout->StartRow(0, 0); + layout->AddView(number_label_); + layout->AddView(close_button, 1, 2); // 2 rows for icon + layout->StartRow(0, 0); + layout->AddView(message_label_); + + layout->AddPaddingRow(0, kPaddingVertical); + } + + void LayoutNotificationView() { + SetLayoutManager( + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); + AddChildView(number_label_); + message_label_->SizeToFit(kTrayNotificationContentsWidth); + AddChildView(message_label_); + } + + TraySms* tray_; + size_t index_; + views::Label* number_label_; + views::Label* message_label_; + + DISALLOW_COPY_AND_ASSIGN(SmsMessageView); +}; + +class TraySms::SmsDetailedView : public TrayDetailsView, + public ViewClickListener { + public: + explicit SmsDetailedView(TraySms* tray) + : tray_(tray) { + Init(); + Update(); + } + + virtual ~SmsDetailedView() { + } + + void Init() { + CreateScrollableList(); + CreateSpecialRow(IDS_ASH_STATUS_TRAY_SMS, this); + } + + void Update() { + UpdateMessageList(); + Layout(); + SchedulePaint(); + } + + // Overridden from views::View. + gfx::Size GetPreferredSize() { + gfx::Size preferred_size = TrayDetailsView::GetPreferredSize(); + if (preferred_size.height() < kMessageListMinHeight) + preferred_size.set_height(kMessageListMinHeight); + return preferred_size; + } + + private: + void UpdateMessageList() { + const base::ListValue& messages = tray_->messages(); + scroll_content()->RemoveAllChildViews(true); + for (size_t index = 0; index < messages.GetSize(); ++index) { + const base::DictionaryValue* message = NULL; + if (!messages.GetDictionary(index, &message)) { + LOG(ERROR) << "SMS message not a dictionary at: " << index; + continue; + } + std::string number, text; + if (!GetMessageFromDictionary(message, &number, &text)) { + LOG(ERROR) << "Error parsing SMS message"; + continue; + } + SmsMessageView* msgview = new SmsMessageView( + tray_, SmsMessageView::VIEW_DETAILED, index, number, text); + scroll_content()->AddChildView(msgview); + } + scroller()->Layout(); + } + + // Overridden from ViewClickListener. + virtual void ClickedOn(views::View* sender) OVERRIDE { + if (sender == footer()->content()) + Shell::GetInstance()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING); + } + + TraySms* tray_; + + DISALLOW_COPY_AND_ASSIGN(SmsDetailedView); +}; + +class TraySms::SmsNotificationView : public TrayNotificationView { + public: + SmsNotificationView(TraySms* tray, + size_t message_index, + const std::string& number, + const std::string& text) + : TrayNotificationView(tray, IDR_AURA_UBER_TRAY_SMS), + message_index_(message_index) { + SmsMessageView* message_view = new SmsMessageView( + tray, SmsMessageView::VIEW_NOTIFICATION, message_index_, number, text); + InitView(message_view); + } + + void Update(size_t message_index, + const std::string& number, + const std::string& text) { + SmsMessageView* message_view = new SmsMessageView( + tray_sms(), SmsMessageView::VIEW_NOTIFICATION, + message_index_, number, text); + UpdateView(message_view); + } + + // Overridden from TrayNotificationView: + virtual void OnClose() OVERRIDE { + tray_sms()->RemoveMessage(message_index_); + } + + virtual void OnClickAction() OVERRIDE { + tray()->PopupDetailedView(0, true); + } + + private: + TraySms* tray_sms() { + return static_cast(tray()); + } + + size_t message_index_; + + DISALLOW_COPY_AND_ASSIGN(SmsNotificationView); +}; + +TraySms::TraySms() + : default_(NULL), + detailed_(NULL), + notification_(NULL) { +} + +TraySms::~TraySms() { +} + +views::View* TraySms::CreateDefaultView(user::LoginStatus status) { + CHECK(default_ == NULL); + default_ = new SmsDefaultView(this); + default_->SetVisible(!messages_.empty()); + return default_; +} + +views::View* TraySms::CreateDetailedView(user::LoginStatus status) { + CHECK(detailed_ == NULL); + HideNotificationView(); + if (messages_.empty()) + return NULL; + detailed_ = new SmsDetailedView(this); + return detailed_; +} + +views::View* TraySms::CreateNotificationView(user::LoginStatus status) { + CHECK(notification_ == NULL); + size_t index; + std::string number, text; + if (GetLatestMessage(&index, &number, &text)) + notification_ = new SmsNotificationView(this, index, number, text); + return notification_; +} + +void TraySms::DestroyDefaultView() { + default_ = NULL; +} + +void TraySms::DestroyDetailedView() { + detailed_ = NULL; +} + +void TraySms::DestroyNotificationView() { + notification_ = NULL; +} + +void TraySms::AddMessage(const base::DictionaryValue& message) { + messages_.Append(message.DeepCopy()); + Update(true); +} + +bool TraySms::GetLatestMessage(size_t* index, + std::string* number, + std::string* text) { + if (messages_.empty()) + return false; + DictionaryValue* message; + size_t message_index = messages_.GetSize() - 1; + if (!messages_.GetDictionary(message_index, &message)) + return false; + if (!GetMessageFromDictionary(message, number, text)) + return false; + *index = message_index; + return true; +} + +void TraySms::RemoveMessage(size_t index) { + if (index < messages_.GetSize()) + messages_.Remove(index, NULL); +} + +void TraySms::Update(bool notify) { + if (messages_.empty()) { + if (default_) + default_->SetVisible(false); + if (detailed_) + HideDetailedView(); + HideNotificationView(); + } else { + if (default_) { + default_->SetVisible(true); + default_->Update(); + } + if (detailed_) + detailed_->Update(); + if (notification_) { + size_t index; + std::string number, text; + if (GetLatestMessage(&index, &number, &text)) + notification_->Update(index, number, text); + } else if (notify) { + ShowNotificationView(); + } + } +} + +} // namespace internal +} // namespace ash diff --git a/ash/system/network/tray_sms.h b/ash/system/network/tray_sms.h new file mode 100644 index 0000000..198557e --- /dev/null +++ b/ash/system/network/tray_sms.h @@ -0,0 +1,65 @@ +// 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. + +#ifndef ASH_SYSTEM_NETWORK_TRAY_SMS_H +#define ASH_SYSTEM_NETWORK_TRAY_SMS_H + +#include + +#include "ash/system/network/sms_observer.h" +#include "ash/system/tray/system_tray_item.h" +#include "base/values.h" + +namespace ash { +namespace internal { + +class TraySms : public SystemTrayItem, + public SmsObserver { + public: + TraySms(); + virtual ~TraySms(); + + // Overridden from SystemTrayItem. + virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE; + virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE; + virtual views::View* CreateNotificationView( + user::LoginStatus status) OVERRIDE; + virtual void DestroyDefaultView() OVERRIDE; + virtual void DestroyDetailedView() OVERRIDE; + virtual void DestroyNotificationView() OVERRIDE; + + // Overridden from SmsObserver. + virtual void AddMessage(const base::DictionaryValue& message) OVERRIDE; + + protected: + class SmsDefaultView; + class SmsDetailedView; + class SmsMessageView; + class SmsNotificationView; + + // Gets the most recent message. Returns false if no messages or unable to + // retrieve the numebr and text from the message. + bool GetLatestMessage(size_t* index, std::string* number, std::string* text); + + // Removes message at |index| from message list. + void RemoveMessage(size_t index); + + // Called when sms messages have changed (by tray::SmsObserver). + void Update(bool notify); + + base::ListValue& messages() { return messages_; } + + private: + SmsDefaultView* default_; + SmsDetailedView* detailed_; + SmsNotificationView* notification_; + base::ListValue messages_; + + DISALLOW_COPY_AND_ASSIGN(TraySms); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_SYSTEM_NETWORK_TRAY_SMS_H diff --git a/ash/system/power/DEPS b/ash/system/power/DEPS deleted file mode 100644 index 69b8167..0000000 --- a/ash/system/power/DEPS +++ /dev/null @@ -1,4 +0,0 @@ -include_rules = [ - # TODO(stevenjb): Move this code to src/ash/system/chromeos, crbug.com/154842 - "+chromeos/dbus/power_supply_status.h", -] diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc index 769ec6c..59f91a7 100644 --- a/ash/system/status_area_widget.cc +++ b/ash/system/status_area_widget.cc @@ -9,6 +9,7 @@ #include "ash/shell_delegate.h" #include "ash/shell_window_ids.h" #include "ash/system/bluetooth/bluetooth_observer.h" +#include "ash/system/network/network_observer.h" #include "ash/system/status_area_widget_delegate.h" #include "ash/system/tray/system_tray.h" #include "ash/system/tray/system_tray_delegate.h" @@ -200,14 +201,30 @@ class DummySystemTrayDelegate : public SystemTrayDelegate { virtual void ToggleWifi() OVERRIDE { wifi_enabled_ = !wifi_enabled_; + ash::NetworkObserver* observer = + ash::Shell::GetInstance()->system_tray()->network_observer(); + if (observer) { + ash::NetworkIconInfo info; + observer->OnNetworkRefresh(info); + } } virtual void ToggleMobile() OVERRIDE { cellular_enabled_ = !cellular_enabled_; + ash::NetworkObserver* observer = + ash::Shell::GetInstance()->system_tray()->network_observer(); + if (observer) { + ash::NetworkIconInfo info; + observer->OnNetworkRefresh(info); + } } virtual void ToggleBluetooth() OVERRIDE { bluetooth_enabled_ = !bluetooth_enabled_; + ash::BluetoothObserver* observer = + ash::Shell::GetInstance()->system_tray()->bluetooth_observer(); + if (observer) + observer->OnBluetoothRefresh(); } virtual void ShowOtherWifi() OVERRIDE { diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index 4411e23..56b7e9c 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc @@ -10,11 +10,12 @@ #include "ash/system/audio/tray_volume.h" #include "ash/system/bluetooth/tray_bluetooth.h" #include "ash/system/brightness/tray_brightness.h" -#include "ash/system/chromeos/tray_display.h" #include "ash/system/date/tray_date.h" #include "ash/system/drive/tray_drive.h" #include "ash/system/ime/tray_ime.h" #include "ash/system/locale/tray_locale.h" +#include "ash/system/network/tray_network.h" +#include "ash/system/network/tray_sms.h" #include "ash/system/power/power_status_observer.h" #include "ash/system/power/power_supply_status.h" #include "ash/system/power/tray_power.h" @@ -26,6 +27,7 @@ #include "ash/system/tray/tray_constants.h" #include "ash/system/tray_accessibility.h" #include "ash/system/tray_caps_lock.h" +#include "ash/system/tray_display.h" #include "ash/system/tray_update.h" #include "ash/system/user/login_status.h" #include "ash/system/user/tray_user.h" @@ -47,11 +49,6 @@ #include "ui/views/layout/fill_layout.h" #include "ui/views/view.h" -#if defined(OS_CHROMEOS) -#include "ash/system/chromeos/network/tray_network.h" -#include "ash/system/chromeos/network/tray_sms.h" -#endif - namespace ash { // SystemTray @@ -70,10 +67,7 @@ SystemTray::SystemTray(internal::StatusAreaWidget* status_area_widget) drive_observer_(NULL), ime_observer_(NULL), locale_observer_(NULL), -#if defined(OS_CHROMEOS) network_observer_(NULL), - sms_observer_(NULL), -#endif update_observer_(NULL), user_observer_(NULL), default_bubble_height_(0), @@ -96,6 +90,8 @@ void SystemTray::CreateItems() { internal::TrayBrightness* tray_brightness = new internal::TrayBrightness(); internal::TrayDate* tray_date = new internal::TrayDate(); internal::TrayPower* tray_power = new internal::TrayPower(); + internal::TrayNetwork* tray_network = new internal::TrayNetwork; + internal::TraySms* tray_sms = new internal::TraySms(); internal::TrayUser* tray_user = new internal::TrayUser; internal::TrayAccessibility* tray_accessibility = new internal::TrayAccessibility; @@ -105,6 +101,7 @@ void SystemTray::CreateItems() { internal::TrayLocale* tray_locale = new internal::TrayLocale; internal::TrayUpdate* tray_update = new internal::TrayUpdate; internal::TraySettings* tray_settings = new internal::TraySettings(); + internal::TrayDisplay* tray_display = new internal::TrayDisplay; accessibility_observer_ = tray_accessibility; audio_observer_ = tray_volume; @@ -115,32 +112,22 @@ void SystemTray::CreateItems() { drive_observer_ = tray_drive; ime_observer_ = tray_ime; locale_observer_ = tray_locale; + network_observer_ = tray_network; power_status_observers_.AddObserver(tray_power); power_status_observers_.AddObserver(tray_settings); + sms_observer_ = tray_sms; update_observer_ = tray_update; user_observer_ = tray_user; -#if defined(OS_CHROMEOS) - internal::TrayDisplay* tray_display = new internal::TrayDisplay; - internal::TrayNetwork* tray_network = new internal::TrayNetwork; - internal::TraySms* tray_sms = new internal::TraySms(); - network_observer_ = tray_network; - sms_observer_ = tray_sms; -#endif - AddTrayItem(tray_user); AddTrayItem(tray_power); -#if defined(OS_CHROMEOS) AddTrayItem(tray_network); - AddTrayItem(tray_sms); -#endif AddTrayItem(tray_bluetooth); + AddTrayItem(tray_sms); AddTrayItem(tray_drive); AddTrayItem(tray_ime); AddTrayItem(tray_locale); -#if defined(OS_CHROMEOS) AddTrayItem(tray_display); -#endif AddTrayItem(tray_volume); AddTrayItem(tray_brightness); AddTrayItem(tray_update); diff --git a/ash/system/tray/system_tray.h b/ash/system/tray/system_tray.h index aa03885..760c527 100644 --- a/ash/system/tray/system_tray.h +++ b/ash/system/tray/system_tray.h @@ -30,13 +30,11 @@ class ClockObserver; class DriveObserver; class IMEObserver; class LocaleObserver; +class NetworkObserver; +class SmsObserver; class PowerStatusObserver; class UpdateObserver; class UserObserver; -#if defined(OS_CHROMEOS) -class NetworkObserver; -class SmsObserver; -#endif class SystemTrayItem; @@ -135,17 +133,15 @@ class ASH_EXPORT SystemTray : public internal::TrayBackgroundView { LocaleObserver* locale_observer() const { return locale_observer_; } -#if defined(OS_CHROMEOS) NetworkObserver* network_observer() const { return network_observer_; } - SmsObserver* sms_observer() const { - return sms_observer_; - } -#endif ObserverList& power_status_observers() { return power_status_observers_; } + SmsObserver* sms_observer() const { + return sms_observer_; + } UpdateObserver* update_observer() const { return update_observer_; } @@ -220,11 +216,9 @@ class ASH_EXPORT SystemTray : public internal::TrayBackgroundView { DriveObserver* drive_observer_; IMEObserver* ime_observer_; LocaleObserver* locale_observer_; -#if defined(OS_CHROMEOS) NetworkObserver* network_observer_; - SmsObserver* sms_observer_; -#endif ObserverList power_status_observers_; + SmsObserver* sms_observer_; UpdateObserver* update_observer_; UserObserver* user_observer_; diff --git a/ash/system/tray_display.cc b/ash/system/tray_display.cc new file mode 100644 index 0000000..66c9952 --- /dev/null +++ b/ash/system/tray_display.cc @@ -0,0 +1,171 @@ +// 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/tray_display.h" + +#include "ash/display/display_controller.h" +#include "ash/screen_ash.h" +#include "ash/shell.h" +#include "ash/system/tray/system_tray.h" +#include "ash/system/tray/system_tray_delegate.h" +#include "ash/system/tray/tray_constants.h" +#include "ash/system/tray/tray_views.h" +#include "base/utf_string_conversions.h" +#include "grit/ash_resources.h" +#include "grit/ash_strings.h" +#include "ui/aura/display_manager.h" +#include "ui/aura/env.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/image.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" + +#if defined(USE_X11) +#include "ui/base/x/x11_util.h" +#endif + +namespace ash { +namespace internal { + +class DisplayView : public ash::internal::ActionableView { + public: + explicit DisplayView(user::LoginStatus login_status) + : login_status_(login_status) { + SetLayoutManager(new + views::BoxLayout(views::BoxLayout::kHorizontal, + ash::kTrayPopupPaddingHorizontal, 0, + ash::kTrayPopupPaddingBetweenItems)); + + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + views::ImageView* image = + new ash::internal::FixedSizedImageView(0, ash::kTrayPopupItemHeight); + image->SetImage( + bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia()); + AddChildView(image); + label_ = new views::Label(); + AddChildView(label_); + Update(); + } + + virtual ~DisplayView() {} + + void Update() { +#if defined(OS_CHROMEOS) + switch (Shell::GetInstance()->output_configurator()->output_state()) { + case chromeos::STATE_INVALID: + case chromeos::STATE_HEADLESS: + case chromeos::STATE_SINGLE: + SetVisible(false); + return; + case chromeos::STATE_DUAL_MIRROR: { + // Simply assumes that the primary display appears first and the + // secondary display appears next in the list. + std::vector display_names; +#if defined(USE_X11) + std::vector output_ids; + ui::GetOutputDeviceHandles(&output_ids); + display_names = ui::GetDisplayNames(output_ids); +#endif + if (display_names.size() > 1) { + label_->SetText(l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, + UTF8ToUTF16(display_names[1]))); + SetVisible(true); + } else { + SetVisible(false); + } + return; + } + case chromeos::STATE_DUAL_PRIMARY_ONLY: + case chromeos::STATE_DUAL_SECONDARY_ONLY: { + aura::DisplayManager* display_manager = + aura::Env::GetInstance()->display_manager(); + if (display_manager->GetNumDisplays() > 1) { + label_->SetText(l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, + UTF8ToUTF16(display_manager->GetDisplayNameFor( + ScreenAsh::GetSecondaryDisplay())))); + SetVisible(true); + } else { + SetVisible(false); + } + return; + } + default: + NOTREACHED(); + } +#endif // OS_CHROMEOS + } + + private: + // Overridden from ActionableView. + virtual bool PerformAction(const ui::Event& event) OVERRIDE { + if (login_status_ == ash::user::LOGGED_IN_USER || + login_status_ == ash::user::LOGGED_IN_OWNER || + login_status_ == ash::user::LOGGED_IN_GUEST) { + ash::Shell::GetInstance()->tray_delegate()->ShowDisplaySettings(); + } + + return true; + } + + user::LoginStatus login_status_; + views::Label* label_; + + DISALLOW_COPY_AND_ASSIGN(DisplayView); +}; + +TrayDisplay::TrayDisplay() + : default_(NULL) { + aura::Env::GetInstance()->display_manager()->AddObserver(this); +#if defined(OS_CHROMEOS) + ash::Shell::GetInstance()->output_configurator()->AddObserver(this); +#endif +} + +TrayDisplay::~TrayDisplay() { + aura::Env::GetInstance()->display_manager()->RemoveObserver(this); +#if defined(OS_CHROMEOS) + ash::Shell::GetInstance()->output_configurator()->RemoveObserver(this); +#endif +} + +views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) { +#if defined(OS_CHROMEOS) + default_ = new DisplayView(status); +#endif + return default_; +} + +void TrayDisplay::DestroyDefaultView() { + default_ = NULL; +} + +void TrayDisplay::OnDisplayBoundsChanged(const gfx::Display& display) { + if (default_) + default_->Update(); +} + +void TrayDisplay::OnDisplayAdded(const gfx::Display& new_display) { + if (default_) + default_->Update(); +} + +void TrayDisplay::OnDisplayRemoved(const gfx::Display& old_display) { + if (default_) + default_->Update(); +} + +#if defined(OS_CHROMEOS) +void TrayDisplay::OnDisplayModeChanged() { + if (default_) + default_->Update(); +} +#endif + + +} // namespace internal +} // namespace ash diff --git a/ash/system/tray_display.h b/ash/system/tray_display.h new file mode 100644 index 0000000..e969e76 --- /dev/null +++ b/ash/system/tray_display.h @@ -0,0 +1,57 @@ +// 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. + +#ifndef ASH_SYSTEM_TRAY_DISPLAY_H_ +#define ASH_SYSTEM_TRAY_DISPLAY_H_ + +#include "ash/system/tray/system_tray_item.h" +#include "base/memory/scoped_ptr.h" +#include "ui/aura/display_observer.h" + +#if defined(OS_CHROMEOS) +#include "chromeos/display/output_configurator.h" +#endif + +namespace views { +class View; +} + +namespace ash { + +namespace internal { +class DisplayView; + +class TrayDisplay : public SystemTrayItem, +#if defined(OS_CHROMEOS) + public chromeos::OutputConfigurator::Observer, +#endif + public aura::DisplayObserver { + public: + TrayDisplay(); + virtual ~TrayDisplay(); + + private: + // Overridden from SystemTrayItem. + virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE; + virtual void DestroyDefaultView() OVERRIDE; + + // Overridden from aura::DisplayObserver + virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE; + virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE; + virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE; + +#if defined(OS_CHROMEOS) + // Overridden from chromeos::OutputConfigurator::Observer + virtual void OnDisplayModeChanged() OVERRIDE; +#endif + + DisplayView* default_; + + DISALLOW_COPY_AND_ASSIGN(TrayDisplay); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_SYSTEM_TRAY_DISPLAY_H_ -- cgit v1.1