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