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