Chromium Code Reviews| Index: ash/system/chromeos/network/tray_network.cc |
| diff --git a/ash/system/chromeos/network/tray_network.cc b/ash/system/chromeos/network/tray_network.cc |
| index 0f10da1a7075d0bada5605c7764da3beaca61262..7d9761acdb2cbc7146d5c16b9961748289c72ac9 100644 |
| --- a/ash/system/chromeos/network/tray_network.cc |
| +++ b/ash/system/chromeos/network/tray_network.cc |
| @@ -6,6 +6,7 @@ |
| #include "ash/ash_switches.h" |
| #include "ash/shell.h" |
| +#include "ash/system/chromeos/network/network_icon_animation.h" |
| #include "ash/system/chromeos/network/network_list_detailed_view.h" |
| #include "ash/system/chromeos/network/network_list_detailed_view_base.h" |
| #include "ash/system/chromeos/network/network_state_list_detailed_view.h" |
| @@ -18,6 +19,9 @@ |
| #include "ash/system/tray/tray_item_view.h" |
| #include "ash/system/tray/tray_notification_view.h" |
| #include "base/command_line.h" |
| +#include "base/utf_string_conversions.h" |
| +#include "chromeos/network/network_configuration_handler.h" |
| +#include "chromeos/network/network_state.h" |
| #include "chromeos/network/network_state_handler.h" |
| #include "grit/ash_resources.h" |
| #include "grit/ash_strings.h" |
| @@ -60,16 +64,14 @@ bool UseNewNetworkHandlers() { |
| } // namespace |
| +using chromeos::NetworkState; |
| +using chromeos::NetworkStateHandler; |
| + |
| namespace ash { |
| namespace internal { |
| namespace tray { |
| -enum ColorTheme { |
| - LIGHT, |
| - DARK, |
| -}; |
| - |
| class NetworkMessages { |
| public: |
| struct Message { |
| @@ -99,39 +101,70 @@ class NetworkMessages { |
| MessageMap messages_; |
| }; |
| -class NetworkTrayView : public TrayItemView { |
| +class NetworkTrayView : public TrayItemView, |
| + public network_icon::AnimationObserver { |
| public: |
| - NetworkTrayView(SystemTrayItem* owner, ColorTheme size) |
| - : TrayItemView(owner), color_theme_(size) { |
| + explicit NetworkTrayView(TrayNetwork* network_tray) |
| + : TrayItemView(network_tray), |
| + network_tray_(network_tray) { |
| SetLayoutManager( |
| new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); |
| - image_view_ = color_theme_ == DARK ? |
| - new FixedSizedImageView(0, kTrayPopupItemHeight) : |
| - new views::ImageView; |
| + image_view_ = new views::ImageView; |
| AddChildView(image_view_); |
| NetworkIconInfo info; |
| - Shell::GetInstance()->system_tray_delegate()-> |
| - GetMostRelevantNetworkIcon(&info, false); |
| - Update(info); |
| + if (UseNewNetworkHandlers()) { |
| + UpdateNetworkStateHandlerIcon(); |
| + network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this); |
| + } else { |
| + Shell::GetInstance()->system_tray_delegate()-> |
| + GetMostRelevantNetworkIcon(&info, false); |
| + UpdateIcon(info.tray_icon_visible, info.image); |
| + } |
| } |
| - virtual ~NetworkTrayView() {} |
| + virtual ~NetworkTrayView() { |
| + if (UseNewNetworkHandlers()) |
| + network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); |
| + } |
| void Update(const NetworkIconInfo& info) { |
| - image_view_->SetImage(info.image); |
| - SetVisible(info.tray_icon_visible); |
| - SchedulePaint(); |
| + if (UseNewNetworkHandlers()) |
| + return; |
| + UpdateIcon(info.tray_icon_visible, info.image); |
| UpdateConnectionStatus(info.name, info.connected); |
| } |
| + void UpdateNetworkStateHandlerIcon() { |
| + DCHECK(UseNewNetworkHandlers()); |
| + NetworkStateHandler* handler = NetworkStateHandler::Get(); |
| + gfx::ImageSkia image; |
| + string16 name; |
| + network_tray_->GetNetworkStateHandlerImageAndLabel( |
| + network_icon::ICON_TYPE_TRAY, &image, &name); |
| + bool show_in_tray = !image.isNull(); |
| + UpdateIcon(show_in_tray, image); |
| + const NetworkState* connected_network = handler->ConnectedNetworkByType( |
| + NetworkStateHandler::kMatchTypeNonVirtual); |
| + if (connected_network) |
| + UpdateConnectionStatus(UTF8ToUTF16(connected_network->name()), true); |
| + else |
| + UpdateConnectionStatus(string16(), false); |
| + } |
| + |
| // views::View override. |
| virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE { |
| state->name = connection_status_string_; |
| state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; |
| } |
| + // network_icon::AnimationObserver |
| + virtual void NetworkIconChanged() { |
|
jennyz
2013/02/11 20:23:16
Is this a virtual OVERRIDE?
stevenjb
2013/02/11 22:34:45
Done.
|
| + if (UseNewNetworkHandlers()) |
| + UpdateNetworkStateHandlerIcon(); |
| + } |
| + |
| private: |
| // Updates connection status and notifies accessibility event when necessary. |
| void UpdateConnectionStatus(const string16& network_name, bool connected) { |
| @@ -149,32 +182,62 @@ class NetworkTrayView : public TrayItemView { |
| } |
| } |
| + void UpdateIcon(bool tray_icon_visible, const gfx::ImageSkia& image) { |
| + image_view_->SetImage(image); |
| + SetVisible(tray_icon_visible); |
| + SchedulePaint(); |
| + } |
| + |
| + TrayNetwork* network_tray_; |
| views::ImageView* image_view_; |
| - ColorTheme color_theme_; |
| string16 connection_status_string_; |
| DISALLOW_COPY_AND_ASSIGN(NetworkTrayView); |
| }; |
| -class NetworkDefaultView : public TrayItemMore { |
| +class NetworkDefaultView : public TrayItemMore, |
| + public network_icon::AnimationObserver { |
| public: |
| - NetworkDefaultView(SystemTrayItem* owner, bool show_more) |
| - : TrayItemMore(owner, show_more) { |
| + NetworkDefaultView(TrayNetwork* network_tray, bool show_more) |
| + : TrayItemMore(network_tray, show_more), |
| + network_tray_(network_tray) { |
| Update(); |
| + if (UseNewNetworkHandlers()) |
| + network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this); |
| } |
| - virtual ~NetworkDefaultView() {} |
| + virtual ~NetworkDefaultView() { |
| + if (UseNewNetworkHandlers()) |
| + network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); |
| + } |
| void Update() { |
| - NetworkIconInfo info; |
| - Shell::GetInstance()->system_tray_delegate()-> |
| - GetMostRelevantNetworkIcon(&info, true); |
| - SetImage(&info.image); |
| - SetLabel(info.description); |
| - SetAccessibleName(info.description); |
| + if (UseNewNetworkHandlers()) { |
| + gfx::ImageSkia image; |
| + string16 label; |
| + network_tray_->GetNetworkStateHandlerImageAndLabel( |
| + network_icon::ICON_TYPE_DEFAULT_VIEW, &image, &label); |
| + SetImage(&image); |
| + SetLabel(label); |
| + SetAccessibleName(label); |
| + } else { |
| + NetworkIconInfo info; |
| + Shell::GetInstance()->system_tray_delegate()-> |
| + GetMostRelevantNetworkIcon(&info, true); |
| + SetImage(&info.image); |
| + SetLabel(info.description); |
| + SetAccessibleName(info.description); |
| + } |
| + } |
| + |
| + // network_icon::AnimationObserver |
| + virtual void NetworkIconChanged() { |
|
jennyz
2013/02/11 20:23:16
OVERRIDE?
stevenjb
2013/02/11 22:34:45
Done.
|
| + Update(); |
| } |
| private: |
| + TrayNetwork* network_tray_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView); |
| }; |
| @@ -231,10 +294,10 @@ class NetworkWifiDetailedView : public NetworkDetailedView { |
| class NetworkMessageView : public views::View, |
| public views::LinkListener { |
| public: |
| - NetworkMessageView(TrayNetwork* owner, |
| + NetworkMessageView(TrayNetwork* tray_network, |
| TrayNetwork::MessageType message_type, |
| const NetworkMessages::Message& network_msg) |
| - : owner_(owner), |
| + : tray_network_(tray_network), |
| message_type_(message_type), |
| network_type_(network_msg.network_type_) { |
| SetLayoutManager( |
| @@ -273,14 +336,14 @@ class NetworkMessageView : public views::View, |
| // Overridden from views::LinkListener. |
| virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE { |
| - owner_->LinkClicked(message_type_, source->id()); |
| + tray_network_->LinkClicked(message_type_, source->id()); |
| } |
| TrayNetwork::MessageType message_type() const { return message_type_; } |
| TrayNetwork::NetworkType network_type() const { return network_type_; } |
| private: |
| - TrayNetwork* owner_; |
| + TrayNetwork* tray_network_; |
| TrayNetwork::MessageType message_type_; |
| TrayNetwork::NetworkType network_type_; |
| @@ -289,8 +352,9 @@ class NetworkMessageView : public views::View, |
| class NetworkNotificationView : public TrayNotificationView { |
| public: |
| - explicit NetworkNotificationView(TrayNetwork* owner) |
| - : TrayNotificationView(owner, 0) { |
| + explicit NetworkNotificationView(TrayNetwork* tray_network) |
| + : TrayNotificationView(tray_network, 0), |
| + tray_network_(tray_network) { |
| CreateMessageView(); |
| InitView(network_message_view_); |
| SetIconImage(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| @@ -300,13 +364,13 @@ class NetworkNotificationView : public TrayNotificationView { |
| // Overridden from TrayNotificationView. |
| virtual void OnClose() OVERRIDE { |
| - tray_network()->ClearNetworkMessage(network_message_view_->message_type()); |
| + tray_network_->ClearNetworkMessage(network_message_view_->message_type()); |
| } |
| virtual void OnClickAction() OVERRIDE { |
| if (network_message_view_->message_type() != |
| TrayNetwork::MESSAGE_DATA_PROMO) |
| - owner()->PopupDetailedView(0, true); |
| + tray_network_->PopupDetailedView(0, true); |
| } |
| void Update() { |
| @@ -318,19 +382,16 @@ class NetworkNotificationView : public TrayNotificationView { |
| } |
| private: |
| - TrayNetwork* tray_network() { |
| - return static_cast<TrayNetwork*>(owner()); |
| - } |
| - |
| void CreateMessageView() { |
| // Display the first (highest priority) message. |
| - CHECK(!tray_network()->messages()->messages().empty()); |
| + CHECK(!tray_network_->messages()->messages().empty()); |
| NetworkMessages::MessageMap::const_iterator iter = |
| - tray_network()->messages()->messages().begin(); |
| + tray_network_->messages()->messages().begin(); |
| network_message_view_ = |
| - new NetworkMessageView(tray_network(), iter->first, iter->second); |
| + new NetworkMessageView(tray_network_, iter->first, iter->second); |
| } |
| + TrayNetwork* tray_network_; |
| tray::NetworkMessageView* network_message_view_; |
| DISALLOW_COPY_AND_ASSIGN(NetworkNotificationView); |
| @@ -345,7 +406,8 @@ TrayNetwork::TrayNetwork(SystemTray* system_tray) |
| detailed_(NULL), |
| notification_(NULL), |
| messages_(new tray::NetworkMessages()), |
| - request_wifi_view_(false) { |
| + request_wifi_view_(false), |
| + uninitialized_msg_(0) { |
| if (UseNewNetworkHandlers()) |
| network_state_observer_.reset(new TrayNetworkStateObserver(this)); |
| Shell::GetInstance()->system_tray_notifier()->AddNetworkObserver(this); |
| @@ -357,14 +419,15 @@ TrayNetwork::~TrayNetwork() { |
| views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) { |
| CHECK(tray_ == NULL); |
| - tray_ = new tray::NetworkTrayView(this, tray::LIGHT); |
| + tray_ = new tray::NetworkTrayView(this); |
| return tray_; |
| } |
| views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) { |
| CHECK(default_ == NULL); |
| - default_ = |
| - new tray::NetworkDefaultView(this, status != user::LOGGED_IN_LOCKED); |
| + CHECK(tray_ != NULL); |
| + default_ = new tray::NetworkDefaultView( |
| + this, status != user::LOGGED_IN_LOCKED); |
| return default_; |
| } |
| @@ -467,6 +530,112 @@ void TrayNetwork::OnWillToggleWifi() { |
| } |
| } |
| +void TrayNetwork::TrayNetworkUpdated() { |
| + if (tray_ && UseNewNetworkHandlers()) |
| + tray_->UpdateNetworkStateHandlerIcon(); |
| + if (default_) |
| + default_->Update(); |
| +} |
| + |
| +void TrayNetwork::NetworkServiceChanged(const chromeos::NetworkState* network) { |
| + if (!network->IsConnectingState()) |
| + connecting_networks_.erase(network->path()); |
| +} |
| + |
| +void TrayNetwork::ConnectToNetwork(const std::string& service_path) { |
| + DCHECK(UseNewNetworkHandlers()); |
| + const NetworkState* network = |
| + NetworkStateHandler::Get()->GetNetworkState(service_path); |
| + if (!network) |
| + return; |
| + if (!network->IsConnectedState()) { |
| + chromeos::NetworkConfigurationHandler::Get()->Connect( |
| + service_path, |
| + base::Bind(&base::DoNothing), |
| + chromeos::network_handler::ErrorCallback()); |
| + connecting_networks_.insert(service_path); |
| + } else { |
| + // This will show the settings UI for a connected network. |
| + // TODO(stevenjb): Change the API to explicitly show network settings. |
| + Shell::GetInstance()->system_tray_delegate()->ConnectToNetwork( |
| + service_path); |
| + } |
| +} |
| + |
| +bool TrayNetwork::HasConnectingNetwork(const std::string& service_path) { |
| + return connecting_networks_.count(service_path) > 0; |
| +} |
| + |
| +void TrayNetwork::GetNetworkStateHandlerImageAndLabel( |
| + network_icon::IconType icon_type, |
| + gfx::ImageSkia* image, |
| + string16* label) { |
| + NetworkStateHandler* handler = NetworkStateHandler::Get(); |
| + const NetworkState* network = handler->ConnectedNetworkByType( |
| + NetworkStateHandler::kMatchTypeNonVirtual); |
| + if (network && network->type() == flimflam::kTypeEthernet && |
| + icon_type == network_icon::ICON_TYPE_TRAY) { |
| + *image = gfx::ImageSkia(); // Don't show ethernet in the tray. |
| + return; |
| + } |
| + const NetworkState* connecting_network = handler->ConnectingNetworkByType( |
| + NetworkStateHandler::kMatchTypeWireless); |
| + // If we are connecting to a network, and there is either no connected |
| + // network, or the connection was user requested, use the connecting |
| + // network. |
| + if (connecting_network && |
| + (!network || |
| + HasConnectingNetwork(connecting_network->path()))) { |
| + network = connecting_network; |
| + } |
| + if (!network) { |
| + // If no connecting network, check for cellular initializing. |
| + int uninitialized_msg = GetUninitializedMsg(); |
| + if (uninitialized_msg != 0) { |
| + *image = network_icon::GetImageForConnectingNetwork( |
| + icon_type, flimflam::kTypeCellular); |
| + if (label) |
| + *label = l10n_util::GetStringUTF16(uninitialized_msg); |
| + } else { |
| + // Otherwise show the disconnected wifi icon. |
| + *image = network_icon::GetImageForDisconnectedNetwork( |
| + icon_type, flimflam::kTypeWifi); |
| + if (label) { |
| + *label = l10n_util::GetStringUTF16( |
| + IDS_ASH_STATUS_TRAY_NETWORK_NOT_CONNECTED); |
| + } |
| + } |
| + return; |
| + } |
| + // Get icon and label for connected or connecting network. |
| + *image = network_icon::GetImageForNetwork(network, icon_type); |
| + if (label) |
| + *label = network_icon::GetLabelForNetwork(network, icon_type); |
| +} |
| + |
| +int TrayNetwork::GetUninitializedMsg() { |
| + NetworkStateHandler* handler = NetworkStateHandler::Get(); |
| + if (handler->TechnologyUninitialized( |
| + NetworkStateHandler::kMatchTypeMobile)) { |
| + uninitialized_msg_ = IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR; |
| + uninitialized_state_time_ = base::Time::Now(); |
| + return uninitialized_msg_; |
| + } else if (handler->GetScanningByType( |
| + NetworkStateHandler::kMatchTypeMobile)) { |
| + uninitialized_msg_ = IDS_ASH_STATUS_TRAY_CELLULAR_SCANNING; |
| + uninitialized_state_time_ = base::Time::Now(); |
| + return uninitialized_msg_; |
| + } |
| + // There can be a delay between leaving the Initializing state and when |
| + // a Cellular device shows up, so keep showing the initializing |
| + // animation for a bit to avoid flashing the disconnect icon. |
| + const int kInitializingDelaySeconds = 1; |
| + base::TimeDelta dtime = base::Time::Now() - uninitialized_state_time_; |
| + if (dtime.InSeconds() < kInitializingDelaySeconds) |
| + return uninitialized_msg_; |
| + return 0; |
| +} |
| + |
| void TrayNetwork::LinkClicked(MessageType message_type, int link_id) { |
| tray::NetworkMessages::MessageMap::const_iterator iter = |
| messages()->messages().find(message_type); |