tray_network.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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_state_list_detailed_view.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/system/chromeos/network/tray_network_state_observer.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_item_more.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_item_view.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/system/tray/tray_utils.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_state.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_state_handler.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "grit/ui_chromeos_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"
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/chromeos/network/network_icon.h"
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/chromeos/network/network_icon_animation.h"
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/image_view.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link_listener.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using chromeos::NetworkHandler;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using chromeos::NetworkState;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using chromeos::NetworkStateHandler;
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using chromeos::NetworkTypePattern;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace ash {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tray {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NetworkTrayView : public TrayItemView,
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        public ui::network_icon::AnimationObserver {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit NetworkTrayView(TrayNetwork* network_tray)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : TrayItemView(network_tray),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        network_tray_(network_tray) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLayoutManager(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_view_ = new views::ImageView;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(image_view_);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    UpdateNetworkStateHandlerIcon();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~NetworkTrayView() {
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual const char* GetClassName() const OVERRIDE {
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return "NetworkTrayView";
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateNetworkStateHandlerIcon() {
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    NetworkStateHandler* handler =
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NetworkHandler::Get()->network_state_handler();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia image;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 name;
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool animating = false;
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ui::network_icon::GetDefaultNetworkImageAndLabel(
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ui::network_icon::ICON_TYPE_TRAY, &image, &name, &animating);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool show_in_tray = !image.isNull();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateIcon(show_in_tray, image);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (animating)
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ui::network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          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)
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // ui::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,
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           public ui::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() {
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ui::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;
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ui::network_icon::GetDefaultNetworkImageAndLabel(
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ui::network_icon::ICON_TYPE_DEFAULT_VIEW, &image, &label, &animating);
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (animating)
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ui::network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    else
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          this);
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetImage(&image);
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetLabel(label);
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetAccessibleName(label);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // ui::network_icon::AnimationObserver
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkIconChanged() OVERRIDE {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Update();
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrayNetwork* network_tray_;
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NetworkWifiDetailedView : public NetworkDetailedView {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  explicit NetworkWifiDetailedView(SystemTrayItem* owner)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : NetworkDetailedView(owner) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          kTrayPopupPaddingHorizontal,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          10,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          kTrayPopupPaddingBetweenItems));
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    image_view_ = new views::ImageView;
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddChildView(image_view_);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_ = new views::Label();
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetMultiLine(true);
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddChildView(label_view_);
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~NetworkWifiDetailedView() {
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from NetworkDetailedView:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Init() OVERRIDE {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual NetworkDetailedView::DetailedViewType GetViewType() const OVERRIDE {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NetworkDetailedView::WIFI_VIEW;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ManagerChanged() OVERRIDE {
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkListChanged() OVERRIDE {
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Update();
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void NetworkServiceChanged(
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const chromeos::NetworkState* network) OVERRIDE {
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
227c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  virtual void Layout() OVERRIDE {
228c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    // Center both views vertically.
229c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    views::View::Layout();
230c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    image_view_->SetY(
231c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        (height() - image_view_->GetPreferredSize().height()) / 2);
232c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    label_view_->SetY(
233c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        (height() - label_view_->GetPreferredSize().height()) / 2);
234c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  }
235c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void Update() {
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool wifi_enabled =
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        NetworkHandler::Get()->network_state_handler()->IsTechnologyEnabled(
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            NetworkTypePattern::WiFi());
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const int image_id = wifi_enabled ?
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDR_AURA_UBER_TRAY_WIFI_ENABLED : IDR_AURA_UBER_TRAY_WIFI_DISABLED;
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    image_view_->SetImage(bundle.GetImageNamed(image_id).ToImageSkia());
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const int string_id = wifi_enabled ?
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED :
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED;
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    label_view_->SetText(bundle.GetLocalizedString(string_id));
249c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    label_view_->SizeToFit(kTrayPopupMinWidth -
250c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        kTrayPopupPaddingHorizontal * 2 - kTrayPopupPaddingBetweenItems -
251c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        kTrayPopupDetailsIconWidth);
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  views::ImageView* image_view_;
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  views::Label* label_view_;
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkWifiDetailedView);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace tray
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TrayNetwork::TrayNetwork(SystemTray* system_tray)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SystemTrayItem(system_tray),
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tray_(NULL),
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_(NULL),
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_(NULL),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_wifi_view_(false) {
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  network_state_observer_.reset(new TrayNetworkStateObserver(this));
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SystemTrayNotifier* notifier = Shell::GetInstance()->system_tray_notifier();
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->AddNetworkObserver(this);
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->AddNetworkPortalDetectorObserver(this);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrayNetwork::~TrayNetwork() {
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SystemTrayNotifier* notifier = Shell::GetInstance()->system_tray_notifier();
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->RemoveNetworkObserver(this);
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  notifier->RemoveNetworkPortalDetectorObserver(this);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(tray_ == NULL);
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tray_ = new tray::NetworkTrayView(this);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return tray_;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(default_ == NULL);
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(tray_ != NULL);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  default_ = new tray::NetworkDefaultView(
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this, status != user::LOGGED_IN_LOCKED);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(detailed_ == NULL);
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::UMA_STATUS_AREA_DETAILED_NETWORK_VIEW);
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!chromeos::NetworkHandler::IsInitialized())
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_wifi_view_) {
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    detailed_ = new tray::NetworkWifiDetailedView(this);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_wifi_view_ = false;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    detailed_ = new tray::NetworkStateListDetailedView(
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        this, tray::NetworkStateListDetailedView::LIST_TYPE_NETWORK, status);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    detailed_->Init();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return detailed_;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyTrayView() {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tray_ = NULL;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyDefaultView() {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_ = NULL;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::DestroyDetailedView() {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  detailed_ = NULL;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayNetwork::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
33168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (tray_) {
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetTrayImageItemBorder(tray_, alignment);
33368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    tray_->UpdateAlignment(alignment);
33468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TrayNetwork::RequestToggleWifi() {
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // This will always be triggered by a user action (e.g. keyboard shortcut)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!detailed_ ||
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detailed_->GetViewType() == tray::NetworkDetailedView::WIFI_VIEW) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_wifi_view_ = true;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool enabled = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi());
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      enabled ?
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ash::UMA_STATUS_AREA_DISABLE_WIFI :
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ash::UMA_STATUS_AREA_ENABLE_WIFI);
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handler->SetTechnologyEnabled(NetworkTypePattern::WiFi(),
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                !enabled,
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                chromeos::network_handler::ErrorCallback());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayNetwork::OnCaptivePortalDetected(
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& /* service_path */) {
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NetworkStateChanged(false);
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TrayNetwork::NetworkStateChanged(bool list_changed) {
36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (tray_)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tray_->UpdateNetworkStateHandlerIcon();
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (default_)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default_->Update();
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (detailed_) {
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (list_changed)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      detailed_->NetworkListChanged();
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      detailed_->ManagerChanged();
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TrayNetwork::NetworkServiceChanged(const chromeos::NetworkState* network) {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (detailed_)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    detailed_->NetworkServiceChanged(network);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
379