Elim cr-checkbox
[chromium-blink-merge.git] / ash / system / chromeos / network / tray_network.cc
blob4bdb4284bf839c14b9769da81dbab5e9bd36c78b
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.
5 #include "ash/system/chromeos/network/tray_network.h"
7 #include "ash/ash_switches.h"
8 #include "ash/metrics/user_metrics_recorder.h"
9 #include "ash/shell.h"
10 #include "ash/system/chromeos/network/network_state_list_detailed_view.h"
11 #include "ash/system/chromeos/network/tray_network_state_observer.h"
12 #include "ash/system/tray/system_tray.h"
13 #include "ash/system/tray/system_tray_delegate.h"
14 #include "ash/system/tray/system_tray_notifier.h"
15 #include "ash/system/tray/tray_constants.h"
16 #include "ash/system/tray/tray_item_more.h"
17 #include "ash/system/tray/tray_item_view.h"
18 #include "ash/system/tray/tray_utils.h"
19 #include "base/command_line.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "chromeos/network/network_state.h"
22 #include "chromeos/network/network_state_handler.h"
23 #include "grit/ash_resources.h"
24 #include "grit/ash_strings.h"
25 #include "grit/ui_chromeos_strings.h"
26 #include "third_party/cros_system_api/dbus/service_constants.h"
27 #include "ui/accessibility/ax_view_state.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/resource/resource_bundle.h"
30 #include "ui/chromeos/network/network_icon.h"
31 #include "ui/chromeos/network/network_icon_animation.h"
32 #include "ui/chromeos/network/network_icon_animation_observer.h"
33 #include "ui/views/controls/image_view.h"
34 #include "ui/views/controls/link.h"
35 #include "ui/views/controls/link_listener.h"
36 #include "ui/views/layout/box_layout.h"
37 #include "ui/views/widget/widget.h"
39 using chromeos::NetworkHandler;
40 using chromeos::NetworkState;
41 using chromeos::NetworkStateHandler;
42 using chromeos::NetworkTypePattern;
44 namespace ash {
45 namespace tray {
47 class NetworkTrayView : public TrayItemView,
48 public ui::network_icon::AnimationObserver {
49 public:
50 explicit NetworkTrayView(TrayNetwork* network_tray)
51 : TrayItemView(network_tray) {
52 SetLayoutManager(
53 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
55 image_view_ = new views::ImageView;
56 AddChildView(image_view_);
58 UpdateNetworkStateHandlerIcon();
61 ~NetworkTrayView() override {
62 ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
65 const char* GetClassName() const override { return "NetworkTrayView"; }
67 void UpdateNetworkStateHandlerIcon() {
68 NetworkStateHandler* handler =
69 NetworkHandler::Get()->network_state_handler();
70 gfx::ImageSkia image;
71 base::string16 name;
72 bool animating = false;
73 ui::network_icon::GetDefaultNetworkImageAndLabel(
74 ui::network_icon::ICON_TYPE_TRAY, &image, &name, &animating);
75 bool show_in_tray = !image.isNull();
76 UpdateIcon(show_in_tray, image);
77 if (animating)
78 ui::network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
79 else
80 ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(
81 this);
82 // Update accessibility.
83 const NetworkState* connected_network =
84 handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
85 if (connected_network) {
86 UpdateConnectionStatus(base::UTF8ToUTF16(connected_network->name()),
87 true);
88 } else {
89 UpdateConnectionStatus(base::string16(), false);
93 void UpdateAlignment(ShelfAlignment alignment) {
94 SetLayoutManager(new views::BoxLayout(alignment == SHELF_ALIGNMENT_BOTTOM
95 ? views::BoxLayout::kHorizontal
96 : views::BoxLayout::kVertical,
97 0, 0, 0));
98 Layout();
101 // views::View override.
102 void GetAccessibleState(ui::AXViewState* state) override {
103 state->name = connection_status_string_;
104 state->role = ui::AX_ROLE_BUTTON;
107 // ui::network_icon::AnimationObserver
108 void NetworkIconChanged() override { UpdateNetworkStateHandlerIcon(); }
110 private:
111 // Updates connection status and notifies accessibility event when necessary.
112 void UpdateConnectionStatus(const base::string16& network_name,
113 bool connected) {
114 base::string16 new_connection_status_string;
115 if (connected) {
116 new_connection_status_string = l10n_util::GetStringFUTF16(
117 IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED, network_name);
119 if (new_connection_status_string != connection_status_string_) {
120 connection_status_string_ = new_connection_status_string;
121 if (!connection_status_string_.empty())
122 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
126 void UpdateIcon(bool tray_icon_visible, const gfx::ImageSkia& image) {
127 image_view_->SetImage(image);
128 SetVisible(tray_icon_visible);
129 SchedulePaint();
132 views::ImageView* image_view_;
133 base::string16 connection_status_string_;
135 DISALLOW_COPY_AND_ASSIGN(NetworkTrayView);
138 class NetworkDefaultView : public TrayItemMore,
139 public ui::network_icon::AnimationObserver {
140 public:
141 NetworkDefaultView(TrayNetwork* network_tray, bool show_more)
142 : TrayItemMore(network_tray, show_more) {
143 Update();
146 ~NetworkDefaultView() override {
147 ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
150 void Update() {
151 gfx::ImageSkia image;
152 base::string16 label;
153 bool animating = false;
154 ui::network_icon::GetDefaultNetworkImageAndLabel(
155 ui::network_icon::ICON_TYPE_DEFAULT_VIEW, &image, &label, &animating);
156 if (animating)
157 ui::network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
158 else
159 ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(
160 this);
161 SetImage(&image);
162 SetLabel(label);
163 SetAccessibleName(label);
166 // ui::network_icon::AnimationObserver
167 void NetworkIconChanged() override { Update(); }
169 private:
170 DISALLOW_COPY_AND_ASSIGN(NetworkDefaultView);
173 class NetworkWifiDetailedView : public NetworkDetailedView {
174 public:
175 explicit NetworkWifiDetailedView(SystemTrayItem* owner)
176 : NetworkDetailedView(owner) {
177 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
178 kTrayPopupPaddingHorizontal, 10,
179 kTrayPopupPaddingBetweenItems));
180 image_view_ = new views::ImageView;
181 AddChildView(image_view_);
183 label_view_ = new views::Label();
184 label_view_->SetMultiLine(true);
185 label_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
186 AddChildView(label_view_);
188 Update();
191 ~NetworkWifiDetailedView() override {}
193 // Overridden from NetworkDetailedView:
195 void Init() override {}
197 NetworkDetailedView::DetailedViewType GetViewType() const override {
198 return NetworkDetailedView::WIFI_VIEW;
201 void Layout() override {
202 // Center both views vertically.
203 views::View::Layout();
204 image_view_->SetY((height() - image_view_->GetPreferredSize().height()) /
206 label_view_->SetY((height() - label_view_->GetPreferredSize().height()) /
210 void Update() override {
211 bool wifi_enabled =
212 NetworkHandler::Get()->network_state_handler()->IsTechnologyEnabled(
213 NetworkTypePattern::WiFi());
214 const int image_id = wifi_enabled ? IDR_AURA_UBER_TRAY_WIFI_ENABLED
215 : IDR_AURA_UBER_TRAY_WIFI_DISABLED;
216 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
217 image_view_->SetImage(bundle.GetImageNamed(image_id).ToImageSkia());
219 const int string_id = wifi_enabled
220 ? IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED
221 : IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED;
222 label_view_->SetText(bundle.GetLocalizedString(string_id));
223 label_view_->SizeToFit(
224 kTrayPopupMinWidth - kTrayPopupPaddingHorizontal * 2 -
225 kTrayPopupPaddingBetweenItems - kTrayPopupDetailsIconWidth);
228 private:
229 views::ImageView* image_view_;
230 views::Label* label_view_;
232 DISALLOW_COPY_AND_ASSIGN(NetworkWifiDetailedView);
235 } // namespace tray
237 TrayNetwork::TrayNetwork(SystemTray* system_tray)
238 : SystemTrayItem(system_tray),
239 tray_(NULL),
240 default_(NULL),
241 detailed_(NULL),
242 request_wifi_view_(false) {
243 network_state_observer_.reset(new TrayNetworkStateObserver(this));
244 SystemTrayNotifier* notifier = Shell::GetInstance()->system_tray_notifier();
245 notifier->AddNetworkObserver(this);
246 notifier->AddNetworkPortalDetectorObserver(this);
249 TrayNetwork::~TrayNetwork() {
250 SystemTrayNotifier* notifier = Shell::GetInstance()->system_tray_notifier();
251 notifier->RemoveNetworkObserver(this);
252 notifier->RemoveNetworkPortalDetectorObserver(this);
255 views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) {
256 CHECK(tray_ == NULL);
257 if (!chromeos::NetworkHandler::IsInitialized())
258 return NULL;
259 tray_ = new tray::NetworkTrayView(this);
260 return tray_;
263 views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) {
264 CHECK(default_ == NULL);
265 if (!chromeos::NetworkHandler::IsInitialized())
266 return NULL;
267 CHECK(tray_ != NULL);
268 default_ =
269 new tray::NetworkDefaultView(this, status != user::LOGGED_IN_LOCKED);
270 return default_;
273 views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) {
274 CHECK(detailed_ == NULL);
275 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
276 ash::UMA_STATUS_AREA_DETAILED_NETWORK_VIEW);
277 if (!chromeos::NetworkHandler::IsInitialized())
278 return NULL;
279 if (request_wifi_view_) {
280 detailed_ = new tray::NetworkWifiDetailedView(this);
281 request_wifi_view_ = false;
282 } else {
283 detailed_ = new tray::NetworkStateListDetailedView(
284 this, tray::NetworkStateListDetailedView::LIST_TYPE_NETWORK, status);
285 detailed_->Init();
287 return detailed_;
290 void TrayNetwork::DestroyTrayView() {
291 tray_ = NULL;
294 void TrayNetwork::DestroyDefaultView() {
295 default_ = NULL;
298 void TrayNetwork::DestroyDetailedView() {
299 detailed_ = NULL;
302 void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) {
305 void TrayNetwork::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
306 if (tray_) {
307 SetTrayImageItemBorder(tray_, alignment);
308 tray_->UpdateAlignment(alignment);
312 void TrayNetwork::RequestToggleWifi() {
313 // This will always be triggered by a user action (e.g. keyboard shortcut)
314 if (!detailed_ ||
315 detailed_->GetViewType() == tray::NetworkDetailedView::WIFI_VIEW) {
316 request_wifi_view_ = true;
317 PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false);
319 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
320 bool enabled = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi());
321 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
322 enabled ? ash::UMA_STATUS_AREA_DISABLE_WIFI
323 : ash::UMA_STATUS_AREA_ENABLE_WIFI);
324 handler->SetTechnologyEnabled(NetworkTypePattern::WiFi(), !enabled,
325 chromeos::network_handler::ErrorCallback());
328 void TrayNetwork::OnCaptivePortalDetected(
329 const std::string& /* service_path */) {
330 NetworkStateChanged();
333 void TrayNetwork::NetworkStateChanged() {
334 if (tray_)
335 tray_->UpdateNetworkStateHandlerIcon();
336 if (default_)
337 default_->Update();
338 if (detailed_)
339 detailed_->Update();
342 } // namespace ash