15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/chromeos/network/tray_network.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/ash_switches.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/metrics/user_metrics_recorder.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/chromeos/network/network_icon_animation.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/chromeos/network/network_state_list_detailed_view.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/system/chromeos/network/tray_network_state_observer.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_item_more.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_item_view.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/system/tray/tray_utils.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_state.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_state_handler.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/image_view.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link_listener.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using chromeos::NetworkHandler;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using chromeos::NetworkState;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using chromeos::NetworkStateHandler;
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using chromeos::NetworkTypePattern;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace ash {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tray {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NetworkTrayView : public TrayItemView,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        public network_icon::AnimationObserver {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit NetworkTrayView(TrayNetwork* network_tray)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayItemView(network_tray),
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        network_tray_(network_tray) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLayoutManager(
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_view_ = new views::ImageView;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(image_view_);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    UpdateNetworkStateHandlerIcon();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~NetworkTrayView() {
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual const char* GetClassName() const OVERRIDE {
64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return "NetworkTrayView";
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateNetworkStateHandlerIcon() {
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    NetworkStateHandler* handler =
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NetworkHandler::Get()->network_state_handler();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia image;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 name;
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool animating = false;
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    network_icon::GetDefaultNetworkImageAndLabel(
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        network_icon::ICON_TYPE_TRAY, &image, &name, &animating);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool show_in_tray = !image.isNull();
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateIcon(show_in_tray, image);
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (animating)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Update accessibility.
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkState* connected_network =
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (connected_network) {
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      UpdateConnectionStatus(
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF8ToUTF16(connected_network->name()), true);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UpdateConnectionStatus(base::string16(), false);
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void UpdateAlignment(ShelfAlignment alignment) {
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SetLayoutManager(new views::BoxLayout(
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        alignment == SHELF_ALIGNMENT_BOTTOM ?
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            views::BoxLayout::kHorizontal : views::BoxLayout::kVertical,
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            0, 0, 0));
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Layout();
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // views::View override.
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    state->name = connection_status_string_;
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state->role = ui::AX_ROLE_BUTTON;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // network_icon::AnimationObserver
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkIconChanged() OVERRIDE {
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    UpdateNetworkStateHandlerIcon();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates connection status and notifies accessibility event when necessary.
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void UpdateConnectionStatus(const base::string16& network_name,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool connected) {
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 new_connection_status_string;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (connected) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_connection_status_string = l10n_util::GetStringFUTF16(
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED, network_name);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (new_connection_status_string != connection_status_string_) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      connection_status_string_ = new_connection_status_string;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if(!connection_status_string_.empty())
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateIcon(bool tray_icon_visible, const gfx::ImageSkia& image) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_view_->SetImage(image);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetVisible(tray_icon_visible);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SchedulePaint();
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrayNetwork* network_tray_;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::ImageView* image_view_;
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 connection_status_string_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkTrayView);
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NetworkDefaultView : public TrayItemMore,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           public network_icon::AnimationObserver {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NetworkDefaultView(TrayNetwork* network_tray, bool show_more)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayItemMore(network_tray, show_more),
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        network_tray_(network_tray) {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Update();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~NetworkDefaultView() {
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Update() {
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gfx::ImageSkia image;
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::string16 label;
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool animating = false;
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    network_icon::GetDefaultNetworkImageAndLabel(
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        network_icon::ICON_TYPE_DEFAULT_VIEW, &image, &label, &animating);
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (animating)
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    else
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetImage(&image);
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetLabel(label);
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetAccessibleName(label);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // network_icon::AnimationObserver
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkIconChanged() OVERRIDE {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Update();
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrayNetwork* network_tray_;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NetworkWifiDetailedView : public NetworkDetailedView {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  explicit NetworkWifiDetailedView(SystemTrayItem* owner)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : NetworkDetailedView(owner) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          kTrayPopupPaddingHorizontal,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          10,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          kTrayPopupPaddingBetweenItems));
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    image_view_ = new views::ImageView;
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddChildView(image_view_);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_ = new views::Label();
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetMultiLine(true);
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddChildView(label_view_);
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~NetworkWifiDetailedView() {
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from NetworkDetailedView:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Init() OVERRIDE {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual NetworkDetailedView::DetailedViewType GetViewType() const OVERRIDE {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NetworkDetailedView::WIFI_VIEW;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ManagerChanged() OVERRIDE {
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkListChanged() OVERRIDE {
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkServiceChanged(
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const chromeos::NetworkState* network) OVERRIDE {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
223c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  virtual void Layout() OVERRIDE {
224c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    // Center both views vertically.
225c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    views::View::Layout();
226c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    image_view_->SetY(
227c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        (height() - image_view_->GetPreferredSize().height()) / 2);
228c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    label_view_->SetY(
229c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        (height() - label_view_->GetPreferredSize().height()) / 2);
230c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  }
231c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void Update() {
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool wifi_enabled =
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        NetworkHandler::Get()->network_state_handler()->IsTechnologyEnabled(
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            NetworkTypePattern::WiFi());
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const int image_id = wifi_enabled ?
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDR_AURA_UBER_TRAY_WIFI_ENABLED : IDR_AURA_UBER_TRAY_WIFI_DISABLED;
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    image_view_->SetImage(bundle.GetImageNamed(image_id).ToImageSkia());
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const int string_id = wifi_enabled ?
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED :
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED;
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetText(bundle.GetLocalizedString(string_id));
245c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    label_view_->SizeToFit(kTrayPopupMinWidth -
246c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        kTrayPopupPaddingHorizontal * 2 - kTrayPopupPaddingBetweenItems -
247c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        kTrayPopupDetailsIconWidth);
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  views::ImageView* image_view_;
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  views::Label* label_view_;
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkWifiDetailedView);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace tray
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TrayNetwork::TrayNetwork(SystemTray* system_tray)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SystemTrayItem(system_tray),
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tray_(NULL),
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_(NULL),
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_(NULL),
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_wifi_view_(false) {
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  network_state_observer_.reset(new TrayNetworkStateObserver(this));
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SystemTrayNotifier* notifier = Shell::GetInstance()->system_tray_notifier();
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->AddNetworkObserver(this);
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->AddNetworkPortalDetectorObserver(this);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrayNetwork::~TrayNetwork() {
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SystemTrayNotifier* notifier = Shell::GetInstance()->system_tray_notifier();
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->RemoveNetworkObserver(this);
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->RemoveNetworkPortalDetectorObserver(this);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(tray_ == NULL);
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tray_ = new tray::NetworkTrayView(this);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return tray_;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(default_ == NULL);
28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(tray_ != NULL);
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  default_ = new tray::NetworkDefaultView(
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this, status != user::LOGGED_IN_LOCKED);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(detailed_ == NULL);
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::UMA_STATUS_AREA_DETAILED_NETWORK_VIEW);
29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_wifi_view_) {
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    detailed_ = new tray::NetworkWifiDetailedView(this);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_wifi_view_ = false;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    detailed_ = new tray::NetworkStateListDetailedView(
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        this, tray::NetworkStateListDetailedView::LIST_TYPE_NETWORK, status);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    detailed_->Init();
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return detailed_;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyTrayView() {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tray_ = NULL;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyDefaultView() {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_ = NULL;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyDetailedView() {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  detailed_ = NULL;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
32768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (tray_) {
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetTrayImageItemBorder(tray_, alignment);
32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    tray_->UpdateAlignment(alignment);
33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TrayNetwork::RequestToggleWifi() {
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // This will always be triggered by a user action (e.g. keyboard shortcut)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!detailed_ ||
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_->GetViewType() == tray::NetworkDetailedView::WIFI_VIEW) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_wifi_view_ = true;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool enabled = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi());
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      enabled ?
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ash::UMA_STATUS_AREA_DISABLE_WIFI :
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ash::UMA_STATUS_AREA_ENABLE_WIFI);
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handler->SetTechnologyEnabled(NetworkTypePattern::WiFi(),
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                !enabled,
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                chromeos::network_handler::ErrorCallback());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayNetwork::OnCaptivePortalDetected(
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& /* service_path */) {
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NetworkStateChanged(false);
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TrayNetwork::NetworkStateChanged(bool list_changed) {
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (tray_)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tray_->UpdateNetworkStateHandlerIcon();
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (default_)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default_->Update();
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (detailed_) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (list_changed)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      detailed_->NetworkListChanged();
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      detailed_->ManagerChanged();
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TrayNetwork::NetworkServiceChanged(const chromeos::NetworkState* network) {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (detailed_)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    detailed_->NetworkServiceChanged(network);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
375