OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "ui/chromeos/network/network_list.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include "base/memory/ptr_util.h" | |
10 #include "chromeos/dbus/dbus_thread_manager.h" | |
11 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h" | |
12 #include "chromeos/dbus/power_manager_client.h" | |
13 #include "chromeos/login/login_state.h" | |
14 #include "chromeos/network/managed_network_configuration_handler.h" | |
15 #include "chromeos/network/network_state.h" | |
16 #include "chromeos/network/network_state_handler.h" | |
17 #include "chromeos/network/network_state_handler_observer.h" | |
18 #include "components/device_event_log/device_event_log.h" | |
19 #include "grit/ui_chromeos_strings.h" | |
20 #include "ui/base/l10n/l10n_util.h" | |
21 #include "ui/base/resource/resource_bundle.h" | |
22 #include "ui/chromeos/network/network_icon.h" | |
23 #include "ui/chromeos/network/network_icon_animation.h" | |
24 #include "ui/chromeos/network/network_info.h" | |
25 #include "ui/chromeos/network/network_list_delegate.h" | |
26 #include "ui/gfx/font.h" | |
27 #include "ui/views/controls/label.h" | |
28 #include "ui/views/view.h" | |
29 | |
30 using chromeos::LoginState; | |
31 using chromeos::NetworkHandler; | |
32 using chromeos::NetworkStateHandler; | |
33 using chromeos::ManagedNetworkConfigurationHandler; | |
34 using chromeos::NetworkTypePattern; | |
35 | |
36 namespace ui { | |
37 | |
38 namespace { | |
39 | |
40 bool IsProhibitedByPolicy(const chromeos::NetworkState* network) { | |
41 if (!NetworkTypePattern::WiFi().MatchesType(network->type())) | |
42 return false; | |
43 if (!LoginState::IsInitialized() || !LoginState::Get()->IsUserLoggedIn()) | |
44 return false; | |
45 ManagedNetworkConfigurationHandler* managed_configuration_handler = | |
46 NetworkHandler::Get()->managed_network_configuration_handler(); | |
47 const base::DictionaryValue* global_network_config = | |
48 managed_configuration_handler->GetGlobalConfigFromPolicy( | |
49 std::string() /* no username hash, device policy */); | |
50 bool policy_prohibites_unmanaged = false; | |
51 if (global_network_config) { | |
52 global_network_config->GetBooleanWithoutPathExpansion( | |
53 ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, | |
54 &policy_prohibites_unmanaged); | |
55 } | |
56 if (!policy_prohibites_unmanaged) | |
57 return false; | |
58 return !managed_configuration_handler->FindPolicyByGuidAndProfile( | |
59 network->guid(), network->profile_path()); | |
60 } | |
61 | |
62 } // namespace | |
63 | |
64 // NetworkListView: | |
65 | |
66 NetworkListView::NetworkListView(NetworkListDelegate* delegate) | |
67 : delegate_(delegate), | |
68 no_wifi_networks_view_(nullptr), | |
69 no_cellular_networks_view_(nullptr) { | |
70 CHECK(delegate_); | |
71 } | |
72 | |
73 NetworkListView::~NetworkListView() { | |
74 network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); | |
75 } | |
76 | |
77 void NetworkListView::Update() { | |
78 CHECK(container()); | |
79 NetworkStateHandler::NetworkStateList network_list; | |
80 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); | |
81 handler->GetVisibleNetworkList(&network_list); | |
82 UpdateNetworks(network_list); | |
83 UpdateNetworkIcons(); | |
84 UpdateNetworkListInternal(); | |
85 } | |
86 | |
87 bool NetworkListView::IsNetworkEntry(views::View* view, | |
88 std::string* service_path) const { | |
89 std::map<views::View*, std::string>::const_iterator found = | |
90 network_map_.find(view); | |
91 if (found == network_map_.end()) | |
92 return false; | |
93 *service_path = found->second; | |
94 return true; | |
95 } | |
96 | |
97 void NetworkListView::UpdateNetworks( | |
98 const NetworkStateHandler::NetworkStateList& networks) { | |
99 SCOPED_NET_LOG_IF_SLOW(); | |
100 network_list_.clear(); | |
101 const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern(); | |
102 for (NetworkStateHandler::NetworkStateList::const_iterator iter = | |
103 networks.begin(); | |
104 iter != networks.end(); | |
105 ++iter) { | |
106 const chromeos::NetworkState* network = *iter; | |
107 if (!pattern.MatchesType(network->type())) | |
108 continue; | |
109 network_list_.push_back(base::MakeUnique<NetworkInfo>(network->path())); | |
110 } | |
111 } | |
112 | |
113 void NetworkListView::UpdateNetworkIcons() { | |
114 SCOPED_NET_LOG_IF_SLOW(); | |
115 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); | |
116 | |
117 // First, update state for all networks | |
118 bool animating = false; | |
119 | |
120 for (auto& info : network_list_) { | |
121 const chromeos::NetworkState* network = | |
122 handler->GetNetworkState(info->service_path); | |
123 if (!network) | |
124 continue; | |
125 bool prohibited_by_policy = IsProhibitedByPolicy(network); | |
126 info->image = | |
127 network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST); | |
128 info->label = | |
129 network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST); | |
130 info->highlight = | |
131 network->IsConnectedState() || network->IsConnectingState(); | |
132 info->disable = | |
133 (network->activation_state() == shill::kActivationStateActivating) || | |
134 prohibited_by_policy; | |
135 info->is_wifi = network->Matches(NetworkTypePattern::WiFi()); | |
136 if (prohibited_by_policy) { | |
137 info->tooltip = | |
138 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_PROHIBITED); | |
139 } | |
140 if (!animating && network->IsConnectingState()) | |
141 animating = true; | |
142 } | |
143 if (animating) | |
144 network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this); | |
145 else | |
146 network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); | |
147 } | |
148 | |
149 void NetworkListView::UpdateNetworkListInternal() { | |
150 SCOPED_NET_LOG_IF_SLOW(); | |
151 // Get the updated list entries | |
152 network_map_.clear(); | |
153 std::set<std::string> new_service_paths; | |
154 bool needs_relayout = UpdateNetworkListEntries(&new_service_paths); | |
155 | |
156 // Remove old children | |
157 std::set<std::string> remove_service_paths; | |
158 for (ServicePathMap::const_iterator it = service_path_map_.begin(); | |
159 it != service_path_map_.end(); | |
160 ++it) { | |
161 if (new_service_paths.find(it->first) == new_service_paths.end()) { | |
162 remove_service_paths.insert(it->first); | |
163 network_map_.erase(it->second); | |
164 delete it->second; | |
165 needs_relayout = true; | |
166 } | |
167 } | |
168 | |
169 for (std::set<std::string>::const_iterator remove_it = | |
170 remove_service_paths.begin(); | |
171 remove_it != remove_service_paths.end(); | |
172 ++remove_it) { | |
173 service_path_map_.erase(*remove_it); | |
174 } | |
175 | |
176 if (needs_relayout) | |
177 HandleRelayout(); | |
178 } | |
179 | |
180 void NetworkListView::HandleRelayout() { | |
181 views::View* selected_view = nullptr; | |
182 for (auto& iter : service_path_map_) { | |
183 if (delegate_->IsViewHovered(iter.second)) { | |
184 selected_view = iter.second; | |
185 break; | |
186 } | |
187 } | |
188 container()->SizeToPreferredSize(); | |
189 delegate_->RelayoutScrollList(); | |
190 if (selected_view) | |
191 container()->ScrollRectToVisible(selected_view->bounds()); | |
192 } | |
193 | |
194 bool NetworkListView::UpdateNetworkListEntries( | |
195 std::set<std::string>* new_service_paths) { | |
196 bool needs_relayout = false; | |
197 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); | |
198 | |
199 // Insert child views | |
200 int index = 0; | |
201 | |
202 // Highlighted networks | |
203 needs_relayout |= | |
204 UpdateNetworkChildren(new_service_paths, &index, true /* highlighted */); | |
205 | |
206 const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern(); | |
207 if (pattern.MatchesPattern(NetworkTypePattern::Cellular())) { | |
208 // Cellular initializing | |
209 int message_id = network_icon::GetCellularUninitializedMsg(); | |
210 if (!message_id && | |
211 handler->IsTechnologyEnabled(NetworkTypePattern::Mobile()) && | |
212 !handler->FirstNetworkByType(NetworkTypePattern::Mobile())) { | |
213 message_id = IDS_ASH_STATUS_TRAY_NO_CELLULAR_NETWORKS; | |
214 } | |
215 needs_relayout |= | |
216 UpdateInfoLabel(message_id, index, &no_cellular_networks_view_); | |
217 | |
218 if (message_id) | |
219 ++index; | |
220 } | |
221 | |
222 if (pattern.MatchesPattern(NetworkTypePattern::WiFi())) { | |
223 // "Wifi Enabled / Disabled" | |
224 int message_id = 0; | |
225 if (network_list_.empty()) { | |
226 message_id = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()) | |
227 ? IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED | |
228 : IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED; | |
229 } | |
230 needs_relayout |= | |
231 UpdateInfoLabel(message_id, index, &no_wifi_networks_view_); | |
232 if (message_id) | |
233 ++index; | |
234 } | |
235 | |
236 // Un-highlighted networks | |
237 needs_relayout |= UpdateNetworkChildren(new_service_paths, &index, | |
238 false /* not highlighted */); | |
239 | |
240 // No networks or other messages (fallback) | |
241 if (index == 0) { | |
242 needs_relayout |= UpdateInfoLabel(IDS_ASH_STATUS_TRAY_NO_NETWORKS, index, | |
243 &no_wifi_networks_view_); | |
244 } | |
245 | |
246 return needs_relayout; | |
247 } | |
248 | |
249 bool NetworkListView::UpdateNetworkChildren( | |
250 std::set<std::string>* new_service_paths, | |
251 int* child_index, | |
252 bool highlighted) { | |
253 bool needs_relayout = false; | |
254 int index = *child_index; | |
255 for (auto& info : network_list_) { | |
256 if (info->highlight != highlighted) | |
257 continue; | |
258 needs_relayout |= UpdateNetworkChild(index++, info.get()); | |
259 new_service_paths->insert(info->service_path); | |
260 } | |
261 *child_index = index; | |
262 return needs_relayout; | |
263 } | |
264 | |
265 bool NetworkListView::UpdateNetworkChild(int index, const NetworkInfo* info) { | |
266 bool needs_relayout = false; | |
267 views::View* network_view = nullptr; | |
268 ServicePathMap::const_iterator found = | |
269 service_path_map_.find(info->service_path); | |
270 if (found == service_path_map_.end()) { | |
271 network_view = delegate_->CreateViewForNetwork(*info); | |
272 container()->AddChildViewAt(network_view, index); | |
273 needs_relayout = true; | |
274 } else { | |
275 network_view = found->second; | |
276 network_view->RemoveAllChildViews(true); | |
277 delegate_->UpdateViewForNetwork(network_view, *info); | |
278 network_view->Layout(); | |
279 network_view->SchedulePaint(); | |
280 needs_relayout = PlaceViewAtIndex(network_view, index); | |
281 } | |
282 if (info->disable) | |
283 network_view->SetEnabled(false); | |
284 network_map_[network_view] = info->service_path; | |
285 service_path_map_[info->service_path] = network_view; | |
286 return needs_relayout; | |
287 } | |
288 | |
289 bool NetworkListView::PlaceViewAtIndex(views::View* view, int index) { | |
290 if (container()->child_at(index) == view) | |
291 return false; | |
292 container()->ReorderChildView(view, index); | |
293 return true; | |
294 } | |
295 | |
296 bool NetworkListView::UpdateInfoLabel(int message_id, | |
297 int index, | |
298 views::Label** label) { | |
299 CHECK(label); | |
300 bool needs_relayout = false; | |
301 if (message_id) { | |
302 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
303 base::string16 text = rb.GetLocalizedString(message_id); | |
304 if (!*label) { | |
305 *label = delegate_->CreateInfoLabel(); | |
306 (*label)->SetText(text); | |
307 container()->AddChildViewAt(*label, index); | |
308 needs_relayout = true; | |
309 } else { | |
310 (*label)->SetText(text); | |
311 needs_relayout = PlaceViewAtIndex(*label, index); | |
312 } | |
313 } else if (*label) { | |
314 delete *label; | |
315 *label = nullptr; | |
316 needs_relayout = true; | |
317 } | |
318 return needs_relayout; | |
319 } | |
320 | |
321 void NetworkListView::NetworkIconChanged() { | |
322 Update(); | |
323 } | |
324 | |
325 } // namespace ui | |
OLD | NEW |