Move action_runner.py out of actions folder prior to moving actions to internal.
[chromium-blink-merge.git] / ui / chromeos / network / network_list.cc
blob5dad5b79913778ca2f6c67dc61d8ebebded0bd87
1 // Copyright 2014 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 "ui/chromeos/network/network_list.h"
7 #include "chromeos/dbus/dbus_thread_manager.h"
8 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
9 #include "chromeos/dbus/power_manager_client.h"
10 #include "chromeos/network/network_state.h"
11 #include "chromeos/network/network_state_handler.h"
12 #include "chromeos/network/network_state_handler_observer.h"
13 #include "components/device_event_log/device_event_log.h"
14 #include "grit/ui_chromeos_strings.h"
15 #include "ui/base/resource/resource_bundle.h"
16 #include "ui/chromeos/network/network_icon.h"
17 #include "ui/chromeos/network/network_icon_animation.h"
18 #include "ui/chromeos/network/network_info.h"
19 #include "ui/chromeos/network/network_list_delegate.h"
20 #include "ui/gfx/font.h"
21 #include "ui/views/controls/label.h"
22 #include "ui/views/view.h"
24 using chromeos::NetworkHandler;
25 using chromeos::NetworkStateHandler;
26 using chromeos::NetworkTypePattern;
28 namespace ui {
30 // NetworkListView:
32 NetworkListView::NetworkListView(NetworkListDelegate* delegate)
33 : delegate_(delegate),
34 scanning_view_(NULL),
35 no_wifi_networks_view_(NULL),
36 no_cellular_networks_view_(NULL) {
37 CHECK(delegate_);
40 NetworkListView::~NetworkListView() {
41 network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
44 void NetworkListView::Update() {
45 CHECK(container_);
46 NetworkStateHandler::NetworkStateList network_list;
47 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
48 handler->GetVisibleNetworkList(&network_list);
49 UpdateNetworks(network_list);
50 UpdateNetworkIcons();
51 UpdateNetworkListInternal();
54 bool NetworkListView::IsNetworkEntry(views::View* view,
55 std::string* service_path) const {
56 std::map<views::View*, std::string>::const_iterator found =
57 network_map_.find(view);
58 if (found == network_map_.end())
59 return false;
60 *service_path = found->second;
61 return true;
64 void NetworkListView::UpdateNetworks(
65 const NetworkStateHandler::NetworkStateList& networks) {
66 SCOPED_NET_LOG_IF_SLOW();
67 network_list_.clear();
68 const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern();
69 for (NetworkStateHandler::NetworkStateList::const_iterator iter =
70 networks.begin();
71 iter != networks.end();
72 ++iter) {
73 const chromeos::NetworkState* network = *iter;
74 if (!pattern.MatchesType(network->type()))
75 continue;
76 NetworkInfo* info = new NetworkInfo(network->path());
77 network_list_.push_back(info);
81 void NetworkListView::UpdateNetworkIcons() {
82 SCOPED_NET_LOG_IF_SLOW();
83 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
85 // First, update state for all networks
86 bool animating = false;
87 for (size_t i = 0; i < network_list_.size(); ++i) {
88 NetworkInfo* info = network_list_[i];
89 const chromeos::NetworkState* network =
90 handler->GetNetworkState(info->service_path);
91 if (!network)
92 continue;
93 info->image =
94 network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST);
95 info->label =
96 network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST);
97 info->highlight =
98 network->IsConnectedState() || network->IsConnectingState();
99 info->disable =
100 network->activation_state() == shill::kActivationStateActivating;
101 if (!animating && network->IsConnectingState())
102 animating = true;
104 if (animating)
105 network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
106 else
107 network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
110 void NetworkListView::UpdateNetworkListInternal() {
111 SCOPED_NET_LOG_IF_SLOW();
112 // Get the updated list entries
113 network_map_.clear();
114 std::set<std::string> new_service_paths;
115 bool needs_relayout = UpdateNetworkListEntries(&new_service_paths);
117 // Remove old children
118 std::set<std::string> remove_service_paths;
119 for (ServicePathMap::const_iterator it = service_path_map_.begin();
120 it != service_path_map_.end();
121 ++it) {
122 if (new_service_paths.find(it->first) == new_service_paths.end()) {
123 remove_service_paths.insert(it->first);
124 network_map_.erase(it->second);
125 container_->RemoveChildView(it->second);
126 needs_relayout = true;
130 for (std::set<std::string>::const_iterator remove_it =
131 remove_service_paths.begin();
132 remove_it != remove_service_paths.end();
133 ++remove_it) {
134 service_path_map_.erase(*remove_it);
137 if (needs_relayout)
138 HandleRelayout();
141 void NetworkListView::HandleRelayout() {
142 views::View* selected_view = NULL;
143 for (auto& iter : service_path_map_) {
144 if (delegate_->IsViewHovered(iter.second)) {
145 selected_view = iter.second;
146 break;
149 container_->SizeToPreferredSize();
150 delegate_->RelayoutScrollList();
151 if (selected_view)
152 container_->ScrollRectToVisible(selected_view->bounds());
155 bool NetworkListView::UpdateNetworkListEntries(
156 std::set<std::string>* new_service_paths) {
157 bool needs_relayout = false;
158 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
160 // Insert child views
161 int index = 0;
163 // Highlighted networks
164 needs_relayout |=
165 UpdateNetworkChildren(new_service_paths, &index, true /* highlighted */);
167 const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern();
168 if (pattern.MatchesPattern(NetworkTypePattern::Cellular())) {
169 // Cellular initializing
170 int message_id = network_icon::GetCellularUninitializedMsg();
171 if (!message_id &&
172 handler->IsTechnologyEnabled(NetworkTypePattern::Mobile()) &&
173 !handler->FirstNetworkByType(NetworkTypePattern::Mobile())) {
174 message_id = IDS_ASH_STATUS_TRAY_NO_CELLULAR_NETWORKS;
176 needs_relayout |=
177 UpdateInfoLabel(message_id, index, &no_cellular_networks_view_);
179 if (message_id)
180 ++index;
183 if (pattern.MatchesPattern(NetworkTypePattern::WiFi())) {
184 // "Wifi Enabled / Disabled"
185 int message_id = 0;
186 if (network_list_.empty()) {
187 message_id = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi())
188 ? IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED
189 : IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED;
191 needs_relayout |=
192 UpdateInfoLabel(message_id, index, &no_wifi_networks_view_);
193 if (message_id)
194 ++index;
196 // "Wifi Scanning"
197 message_id = 0;
198 if (handler->GetScanningByType(NetworkTypePattern::WiFi()))
199 message_id = IDS_ASH_STATUS_TRAY_WIFI_SCANNING_MESSAGE;
200 needs_relayout |= UpdateInfoLabel(message_id, index, &scanning_view_);
201 if (message_id)
202 ++index;
205 // Un-highlighted networks
206 needs_relayout |= UpdateNetworkChildren(new_service_paths, &index,
207 false /* not highlighted */);
209 // No networks or other messages (fallback)
210 if (index == 0) {
211 needs_relayout |= UpdateInfoLabel(IDS_ASH_STATUS_TRAY_NO_NETWORKS, index,
212 &scanning_view_);
215 return needs_relayout;
218 bool NetworkListView::UpdateNetworkChildren(
219 std::set<std::string>* new_service_paths,
220 int* child_index,
221 bool highlighted) {
222 bool needs_relayout = false;
223 int index = *child_index;
224 for (auto& info : network_list_) {
225 if (info->highlight != highlighted)
226 continue;
227 needs_relayout |= UpdateNetworkChild(index++, info);
228 new_service_paths->insert(info->service_path);
230 *child_index = index;
231 return needs_relayout;
234 bool NetworkListView::UpdateNetworkChild(int index, const NetworkInfo* info) {
235 bool needs_relayout = false;
236 views::View* container = NULL;
237 ServicePathMap::const_iterator found =
238 service_path_map_.find(info->service_path);
239 if (found == service_path_map_.end()) {
240 container = delegate_->CreateViewForNetwork(*info);
241 container_->AddChildViewAt(container, index);
242 needs_relayout = true;
243 } else {
244 container = found->second;
245 container->RemoveAllChildViews(true);
246 delegate_->UpdateViewForNetwork(container, *info);
247 container->Layout();
248 container->SchedulePaint();
249 needs_relayout = PlaceViewAtIndex(container, index);
251 if (info->disable)
252 container->SetEnabled(false);
253 network_map_[container] = info->service_path;
254 service_path_map_[info->service_path] = container;
255 return needs_relayout;
258 bool NetworkListView::PlaceViewAtIndex(views::View* view, int index) {
259 if (container_->child_at(index) == view)
260 return false;
261 container_->ReorderChildView(view, index);
262 return true;
265 bool NetworkListView::UpdateInfoLabel(int message_id,
266 int index,
267 views::Label** label) {
268 CHECK(label);
269 bool needs_relayout = false;
270 if (message_id) {
271 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
272 base::string16 text = rb.GetLocalizedString(message_id);
273 if (!*label) {
274 *label = delegate_->CreateInfoLabel();
275 (*label)->SetText(text);
276 container_->AddChildViewAt(*label, index);
277 needs_relayout = true;
278 } else {
279 (*label)->SetText(text);
280 needs_relayout = PlaceViewAtIndex(*label, index);
282 } else if (*label) {
283 container_->RemoveChildView(*label);
284 delete *label;
285 *label = NULL;
286 needs_relayout = true;
288 return needs_relayout;
291 void NetworkListView::NetworkIconChanged() {
292 Update();
295 } // namespace ui