tray_vpn.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ash/system/chromeos/network/tray_vpn.h"
6
7#include "ash/metrics/user_metrics_recorder.h"
8#include "ash/shell.h"
9#include "ash/system/chromeos/network/network_state_list_detailed_view.h"
10#include "ash/system/tray/system_tray.h"
11#include "ash/system/tray/system_tray_delegate.h"
12#include "ash/system/tray/tray_constants.h"
13#include "ash/system/tray/tray_item_more.h"
14#include "ash/system/tray/tray_popup_label_button.h"
15#include "chromeos/network/network_state.h"
16#include "chromeos/network/network_state_handler.h"
17#include "grit/ash_strings.h"
18#include "third_party/cros_system_api/dbus/service_constants.h"
19#include "ui/base/l10n/l10n_util.h"
20#include "ui/base/resource/resource_bundle.h"
21#include "ui/chromeos/network/network_icon_animation.h"
22
23using chromeos::NetworkHandler;
24using chromeos::NetworkState;
25using chromeos::NetworkStateHandler;
26using chromeos::NetworkTypePattern;
27
28namespace ash {
29namespace tray {
30
31class VpnDefaultView : public TrayItemMore,
32                       public ui::network_icon::AnimationObserver {
33 public:
34  VpnDefaultView(SystemTrayItem* owner, bool show_more)
35      : TrayItemMore(owner, show_more) {
36    Update();
37  }
38
39  virtual ~VpnDefaultView() {
40    ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
41  }
42
43  static bool ShouldShow() {
44    // Do not show VPN line in uber tray bubble if VPN is not configured.
45    NetworkStateHandler* handler =
46        NetworkHandler::Get()->network_state_handler();
47    const NetworkState* vpn =
48        handler->FirstNetworkByType(NetworkTypePattern::VPN());
49    return vpn != NULL;
50  }
51
52  void Update() {
53    gfx::ImageSkia image;
54    base::string16 label;
55    bool animating = false;
56    GetNetworkStateHandlerImageAndLabel(&image, &label, &animating);
57    if (animating)
58      ui::network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
59    else
60      ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(
61          this);
62    SetImage(&image);
63    SetLabel(label);
64    SetAccessibleName(label);
65  }
66
67  // ui::network_icon::AnimationObserver
68  virtual void NetworkIconChanged() OVERRIDE {
69    Update();
70  }
71
72 private:
73  void GetNetworkStateHandlerImageAndLabel(gfx::ImageSkia* image,
74                                           base::string16* label,
75                                           bool* animating) {
76    NetworkStateHandler* handler =
77        NetworkHandler::Get()->network_state_handler();
78    const NetworkState* vpn =
79        handler->FirstNetworkByType(NetworkTypePattern::VPN());
80    if (!vpn || (vpn->connection_state() == shill::kStateIdle)) {
81      *image = ui::network_icon::GetImageForDisconnectedNetwork(
82          ui::network_icon::ICON_TYPE_DEFAULT_VIEW, shill::kTypeVPN);
83      if (label) {
84        *label = l10n_util::GetStringUTF16(
85            IDS_ASH_STATUS_TRAY_VPN_DISCONNECTED);
86      }
87      *animating = false;
88      return;
89    }
90    *animating = vpn->IsConnectingState();
91    *image = ui::network_icon::GetImageForNetwork(
92        vpn, ui::network_icon::ICON_TYPE_DEFAULT_VIEW);
93    if (label) {
94      *label = ui::network_icon::GetLabelForNetwork(
95          vpn, ui::network_icon::ICON_TYPE_DEFAULT_VIEW);
96    }
97  }
98
99  DISALLOW_COPY_AND_ASSIGN(VpnDefaultView);
100};
101
102}  // namespace tray
103
104TrayVPN::TrayVPN(SystemTray* system_tray)
105    : SystemTrayItem(system_tray),
106      default_(NULL),
107      detailed_(NULL) {
108  network_state_observer_.reset(new TrayNetworkStateObserver(this));
109}
110
111TrayVPN::~TrayVPN() {
112}
113
114views::View* TrayVPN::CreateTrayView(user::LoginStatus status) {
115  return NULL;
116}
117
118views::View* TrayVPN::CreateDefaultView(user::LoginStatus status) {
119  CHECK(default_ == NULL);
120  if (!chromeos::NetworkHandler::IsInitialized())
121    return NULL;
122  if (status == user::LOGGED_IN_NONE)
123    return NULL;
124  if (!tray::VpnDefaultView::ShouldShow())
125    return NULL;
126
127  default_ = new tray::VpnDefaultView(this, status != user::LOGGED_IN_LOCKED);
128  return default_;
129}
130
131views::View* TrayVPN::CreateDetailedView(user::LoginStatus status) {
132  CHECK(detailed_ == NULL);
133  if (!chromeos::NetworkHandler::IsInitialized())
134    return NULL;
135
136  Shell::GetInstance()->metrics()->RecordUserMetricsAction(
137      ash::UMA_STATUS_AREA_DETAILED_VPN_VIEW);
138  detailed_ = new tray::NetworkStateListDetailedView(
139      this, tray::NetworkStateListDetailedView::LIST_TYPE_VPN, status);
140  detailed_->Init();
141  return detailed_;
142}
143
144void TrayVPN::DestroyTrayView() {
145}
146
147void TrayVPN::DestroyDefaultView() {
148  default_ = NULL;
149}
150
151void TrayVPN::DestroyDetailedView() {
152  detailed_ = NULL;
153}
154
155void TrayVPN::UpdateAfterLoginStatusChange(user::LoginStatus status) {
156}
157
158void TrayVPN::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
159}
160
161void TrayVPN::NetworkStateChanged(bool list_changed) {
162  if (default_)
163    default_->Update();
164  if (detailed_) {
165    if (list_changed)
166      detailed_->NetworkListChanged();
167    else
168      detailed_->ManagerChanged();
169  }
170}
171
172void TrayVPN::NetworkServiceChanged(const chromeos::NetworkState* network) {
173  if (detailed_)
174    detailed_->NetworkServiceChanged(network);
175}
176
177}  // namespace ash
178