tray_network.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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"
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/network/shill_property_util.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/image_view.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link_listener.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using chromeos::NetworkHandler;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using chromeos::NetworkState;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using chromeos::NetworkStateHandler;
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using chromeos::NetworkTypePattern;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace ash {
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace internal {
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tray {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NetworkTrayView : public TrayItemView,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        public network_icon::AnimationObserver {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit NetworkTrayView(TrayNetwork* network_tray)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayItemView(network_tray),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        network_tray_(network_tray) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLayoutManager(
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_view_ = new views::ImageView;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(image_view_);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    UpdateNetworkStateHandlerIcon();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~NetworkTrayView() {
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual const char* GetClassName() const OVERRIDE {
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return "NetworkTrayView";
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateNetworkStateHandlerIcon() {
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    NetworkStateHandler* handler =
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NetworkHandler::Get()->network_state_handler();
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia image;
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 name;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool animating = false;
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    network_icon::GetDefaultNetworkImageAndLabel(
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        network_icon::ICON_TYPE_TRAY, &image, &name, &animating);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool show_in_tray = !image.isNull();
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateIcon(show_in_tray, image);
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (animating)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Update accessibility.
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkState* connected_network =
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (connected_network) {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      UpdateConnectionStatus(
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF8ToUTF16(connected_network->name()), true);
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UpdateConnectionStatus(base::string16(), false);
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void UpdateAlignment(ShelfAlignment alignment) {
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SetLayoutManager(new views::BoxLayout(
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        alignment == SHELF_ALIGNMENT_BOTTOM ?
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            views::BoxLayout::kHorizontal : views::BoxLayout::kVertical,
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            0, 0, 0));
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Layout();
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // views::View override.
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    state->name = connection_status_string_;
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state->role = ui::AX_ROLE_BUTTON;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // network_icon::AnimationObserver
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkIconChanged() OVERRIDE {
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    UpdateNetworkStateHandlerIcon();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates connection status and notifies accessibility event when necessary.
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void UpdateConnectionStatus(const base::string16& network_name,
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool connected) {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 new_connection_status_string;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (connected) {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_connection_status_string = l10n_util::GetStringFUTF16(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED, network_name);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (new_connection_status_string != connection_status_string_) {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      connection_status_string_ = new_connection_status_string;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if(!connection_status_string_.empty())
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateIcon(bool tray_icon_visible, const gfx::ImageSkia& image) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_view_->SetImage(image);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetVisible(tray_icon_visible);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SchedulePaint();
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrayNetwork* network_tray_;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::ImageView* image_view_;
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 connection_status_string_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkTrayView);
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NetworkDefaultView : public TrayItemMore,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           public network_icon::AnimationObserver {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NetworkDefaultView(TrayNetwork* network_tray, bool show_more)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayItemMore(network_tray, show_more),
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        network_tray_(network_tray) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Update();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~NetworkDefaultView() {
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Update() {
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gfx::ImageSkia image;
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::string16 label;
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool animating = false;
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    network_icon::GetDefaultNetworkImageAndLabel(
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        network_icon::ICON_TYPE_DEFAULT_VIEW, &image, &label, &animating);
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (animating)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    else
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetImage(&image);
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetLabel(label);
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetAccessibleName(label);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // network_icon::AnimationObserver
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkIconChanged() OVERRIDE {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Update();
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrayNetwork* network_tray_;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NetworkWifiDetailedView : public NetworkDetailedView {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  explicit NetworkWifiDetailedView(SystemTrayItem* owner)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : NetworkDetailedView(owner) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          kTrayPopupPaddingHorizontal,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          10,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          kTrayPopupPaddingBetweenItems));
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    image_view_ = new views::ImageView;
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddChildView(image_view_);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_ = new views::Label();
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetMultiLine(true);
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddChildView(label_view_);
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~NetworkWifiDetailedView() {
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from NetworkDetailedView:
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Init() OVERRIDE {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual NetworkDetailedView::DetailedViewType GetViewType() const OVERRIDE {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NetworkDetailedView::WIFI_VIEW;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ManagerChanged() OVERRIDE {
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkListChanged() OVERRIDE {
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkServiceChanged(
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const chromeos::NetworkState* network) OVERRIDE {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
226c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  virtual void Layout() OVERRIDE {
227c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    // Center both views vertically.
228c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    views::View::Layout();
229c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    image_view_->SetY(
230c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        (height() - image_view_->GetPreferredSize().height()) / 2);
231c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    label_view_->SetY(
232c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        (height() - label_view_->GetPreferredSize().height()) / 2);
233c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  }
234c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void Update() {
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool wifi_enabled =
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        NetworkHandler::Get()->network_state_handler()->IsTechnologyEnabled(
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            NetworkTypePattern::WiFi());
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const int image_id = wifi_enabled ?
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDR_AURA_UBER_TRAY_WIFI_ENABLED : IDR_AURA_UBER_TRAY_WIFI_DISABLED;
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    image_view_->SetImage(bundle.GetImageNamed(image_id).ToImageSkia());
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const int string_id = wifi_enabled ?
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED :
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED;
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetText(bundle.GetLocalizedString(string_id));
248c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    label_view_->SizeToFit(kTrayPopupMinWidth -
249c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        kTrayPopupPaddingHorizontal * 2 - kTrayPopupPaddingBetweenItems -
250c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        kTrayPopupDetailsIconWidth);
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  views::ImageView* image_view_;
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  views::Label* label_view_;
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkWifiDetailedView);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace tray
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TrayNetwork::TrayNetwork(SystemTray* system_tray)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SystemTrayItem(system_tray),
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tray_(NULL),
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_(NULL),
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_(NULL),
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_wifi_view_(false) {
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  network_state_observer_.reset(new TrayNetworkStateObserver(this));
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SystemTrayNotifier* notifier = Shell::GetInstance()->system_tray_notifier();
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->AddNetworkObserver(this);
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->AddNetworkPortalDetectorObserver(this);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrayNetwork::~TrayNetwork() {
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SystemTrayNotifier* notifier = Shell::GetInstance()->system_tray_notifier();
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->RemoveNetworkObserver(this);
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->RemoveNetworkPortalDetectorObserver(this);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(tray_ == NULL);
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tray_ = new tray::NetworkTrayView(this);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return tray_;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(default_ == NULL);
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(tray_ != NULL);
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  default_ = new tray::NetworkDefaultView(
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this, status != user::LOGGED_IN_LOCKED);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(detailed_ == NULL);
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::UMA_STATUS_AREA_DETAILED_NETWORK_VIEW);
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_wifi_view_) {
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    detailed_ = new tray::NetworkWifiDetailedView(this);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_wifi_view_ = false;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    detailed_ = new tray::NetworkStateListDetailedView(
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        this, tray::NetworkStateListDetailedView::LIST_TYPE_NETWORK, status);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    detailed_->Init();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return detailed_;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyTrayView() {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tray_ = NULL;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyDefaultView() {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_ = NULL;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyDetailedView() {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  detailed_ = NULL;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (tray_) {
33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetTrayImageItemBorder(tray_, alignment);
33268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    tray_->UpdateAlignment(alignment);
33368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TrayNetwork::RequestToggleWifi() {
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // This will always be triggered by a user action (e.g. keyboard shortcut)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!detailed_ ||
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_->GetViewType() == tray::NetworkDetailedView::WIFI_VIEW) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_wifi_view_ = true;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool enabled = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi());
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      enabled ?
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ash::UMA_STATUS_AREA_DISABLE_WIFI :
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ash::UMA_STATUS_AREA_ENABLE_WIFI);
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handler->SetTechnologyEnabled(NetworkTypePattern::WiFi(),
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                !enabled,
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                chromeos::network_handler::ErrorCallback());
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayNetwork::OnCaptivePortalDetected(
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& /* service_path */) {
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NetworkStateChanged(false);
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TrayNetwork::NetworkStateChanged(bool list_changed) {
36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (tray_)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tray_->UpdateNetworkStateHandlerIcon();
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (default_)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default_->Update();
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (detailed_) {
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (list_changed)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      detailed_->NetworkListChanged();
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      detailed_->ManagerChanged();
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TrayNetwork::NetworkServiceChanged(const chromeos::NetworkState* network) {
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (detailed_)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    detailed_->NetworkServiceChanged(network);
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
379