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 "ash/common/system/chromeos/network/network_list.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include "ash/common/system/chromeos/network/network_icon.h" | |
10 #include "ash/common/system/chromeos/network/network_icon_animation.h" | |
11 #include "ash/common/system/chromeos/network/network_info.h" | |
12 #include "ash/common/system/chromeos/network/network_list_delegate.h" | |
13 #include "ash/strings/grit/ash_strings.h" | |
14 #include "base/memory/ptr_util.h" | |
15 #include "chromeos/dbus/dbus_thread_manager.h" | |
16 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h" | |
17 #include "chromeos/dbus/power_manager_client.h" | |
18 #include "chromeos/login/login_state.h" | |
19 #include "chromeos/network/managed_network_configuration_handler.h" | |
20 #include "chromeos/network/network_state.h" | |
21 #include "chromeos/network/network_state_handler.h" | |
22 #include "chromeos/network/network_state_handler_observer.h" | |
23 #include "components/device_event_log/device_event_log.h" | |
24 #include "ui/base/l10n/l10n_util.h" | |
25 #include "ui/base/resource/resource_bundle.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 ash { | |
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* guid) 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 *guid = 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(); ++iter) { | |
105 const chromeos::NetworkState* network = *iter; | |
106 if (!pattern.MatchesType(network->type())) | |
107 continue; | |
108 network_list_.push_back(base::MakeUnique<NetworkInfo>(network->guid())); | |
109 } | |
110 } | |
111 | |
112 void NetworkListView::UpdateNetworkIcons() { | |
113 SCOPED_NET_LOG_IF_SLOW(); | |
114 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); | |
115 | |
116 // First, update state for all networks | |
117 bool animating = false; | |
118 | |
119 for (auto& info : network_list_) { | |
120 const chromeos::NetworkState* network = | |
121 handler->GetNetworkStateFromGuid(info->guid); | |
122 if (!network) | |
123 continue; | |
124 bool prohibited_by_policy = IsProhibitedByPolicy(network); | |
125 info->image = | |
126 network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST); | |
127 info->label = | |
128 network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST); | |
129 info->highlight = | |
130 network->IsConnectedState() || network->IsConnectingState(); | |
131 info->disable = | |
132 (network->activation_state() == shill::kActivationStateActivating) || | |
133 prohibited_by_policy; | |
134 if (network->Matches(NetworkTypePattern::WiFi())) | |
135 info->type = NetworkInfo::Type::WIFI; | |
136 else if (network->Matches(NetworkTypePattern::Cellular())) | |
137 info->type = NetworkInfo::Type::CELLULAR; | |
138 if (prohibited_by_policy) { | |
139 info->tooltip = | |
140 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_PROHIBITED); | |
141 } | |
142 if (!animating && network->IsConnectingState()) | |
143 animating = true; | |
144 } | |
145 if (animating) | |
146 network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this); | |
147 else | |
148 network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); | |
149 } | |
150 | |
151 void NetworkListView::UpdateNetworkListInternal() { | |
152 SCOPED_NET_LOG_IF_SLOW(); | |
153 // Get the updated list entries | |
154 network_map_.clear(); | |
155 std::set<std::string> new_guids; | |
156 bool needs_relayout = UpdateNetworkListEntries(&new_guids); | |
157 | |
158 // Remove old children | |
159 std::set<std::string> remove_guids; | |
160 for (NetworkGuidMap::const_iterator it = network_guid_map_.begin(); | |
161 it != network_guid_map_.end(); ++it) { | |
162 if (new_guids.find(it->first) == new_guids.end()) { | |
163 remove_guids.insert(it->first); | |
164 network_map_.erase(it->second); | |
165 delete it->second; | |
166 needs_relayout = true; | |
167 } | |
168 } | |
169 | |
170 for (std::set<std::string>::const_iterator remove_it = remove_guids.begin(); | |
171 remove_it != remove_guids.end(); ++remove_it) { | |
172 network_guid_map_.erase(*remove_it); | |
173 } | |
174 | |
175 if (needs_relayout) | |
176 HandleRelayout(); | |
177 } | |
178 | |
179 void NetworkListView::HandleRelayout() { | |
180 views::View* selected_view = nullptr; | |
181 for (auto& iter : network_guid_map_) { | |
182 if (delegate_->IsViewHovered(iter.second)) { | |
183 selected_view = iter.second; | |
184 break; | |
185 } | |
186 } | |
187 container()->SizeToPreferredSize(); | |
188 delegate_->RelayoutScrollList(); | |
189 if (selected_view) | |
190 container()->ScrollRectToVisible(selected_view->bounds()); | |
191 } | |
192 | |
193 bool NetworkListView::UpdateNetworkListEntries( | |
194 std::set<std::string>* new_guids) { | |
195 bool needs_relayout = false; | |
196 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); | |
197 | |
198 // Insert child views | |
199 int index = 0; | |
200 | |
201 // Highlighted networks | |
202 needs_relayout |= | |
203 UpdateNetworkChildren(new_guids, &index, true /* highlighted */); | |
204 | |
205 const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern(); | |
206 if (pattern.MatchesPattern(NetworkTypePattern::Cellular())) { | |
207 // Cellular initializing | |
208 int message_id = network_icon::GetCellularUninitializedMsg(); | |
209 if (!message_id && | |
210 handler->IsTechnologyEnabled(NetworkTypePattern::Mobile()) && | |
211 !handler->FirstNetworkByType(NetworkTypePattern::Mobile())) { | |
212 message_id = IDS_ASH_STATUS_TRAY_NO_MOBILE_NETWORKS; | |
213 } | |
214 needs_relayout |= | |
215 UpdateInfoLabel(message_id, index, &no_cellular_networks_view_); | |
216 | |
217 if (message_id) | |
218 ++index; | |
219 } | |
220 | |
221 if (pattern.MatchesPattern(NetworkTypePattern::WiFi())) { | |
222 // "Wifi Enabled / Disabled" | |
223 int message_id = 0; | |
224 if (network_list_.empty()) { | |
225 message_id = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()) | |
226 ? IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED | |
227 : IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED; | |
228 } | |
229 needs_relayout |= | |
230 UpdateInfoLabel(message_id, index, &no_wifi_networks_view_); | |
231 if (message_id) | |
232 ++index; | |
233 } | |
234 | |
235 // Un-highlighted networks | |
236 needs_relayout |= | |
237 UpdateNetworkChildren(new_guids, &index, false /* not highlighted */); | |
238 | |
239 // No networks or other messages (fallback) | |
240 if (index == 0) { | |
241 needs_relayout |= UpdateInfoLabel(IDS_ASH_STATUS_TRAY_NO_NETWORKS, index, | |
242 &no_wifi_networks_view_); | |
243 } | |
244 | |
245 return needs_relayout; | |
246 } | |
247 | |
248 bool NetworkListView::UpdateNetworkChildren(std::set<std::string>* new_guids, | |
249 int* child_index, | |
250 bool highlighted) { | |
251 bool needs_relayout = false; | |
252 int index = *child_index; | |
253 for (auto& info : network_list_) { | |
254 if (info->highlight != highlighted) | |
255 continue; | |
256 needs_relayout |= UpdateNetworkChild(index++, info.get()); | |
257 new_guids->insert(info->guid); | |
258 } | |
259 *child_index = index; | |
260 return needs_relayout; | |
261 } | |
262 | |
263 bool NetworkListView::UpdateNetworkChild(int index, const NetworkInfo* info) { | |
264 bool needs_relayout = false; | |
265 views::View* network_view = nullptr; | |
266 NetworkGuidMap::const_iterator found = network_guid_map_.find(info->guid); | |
267 if (found == network_guid_map_.end()) { | |
268 network_view = delegate_->CreateViewForNetwork(*info); | |
269 container()->AddChildViewAt(network_view, index); | |
270 needs_relayout = true; | |
271 } else { | |
272 network_view = found->second; | |
273 network_view->RemoveAllChildViews(true); | |
274 delegate_->UpdateViewForNetwork(network_view, *info); | |
275 network_view->Layout(); | |
276 network_view->SchedulePaint(); | |
277 needs_relayout = PlaceViewAtIndex(network_view, index); | |
278 } | |
279 if (info->disable) | |
280 network_view->SetEnabled(false); | |
281 network_map_[network_view] = info->guid; | |
282 network_guid_map_[info->guid] = network_view; | |
283 return needs_relayout; | |
284 } | |
285 | |
286 bool NetworkListView::PlaceViewAtIndex(views::View* view, int index) { | |
287 if (container()->child_at(index) == view) | |
288 return false; | |
289 container()->ReorderChildView(view, index); | |
290 return true; | |
291 } | |
292 | |
293 bool NetworkListView::UpdateInfoLabel(int message_id, | |
294 int index, | |
295 views::Label** label) { | |
296 CHECK(label); | |
297 bool needs_relayout = false; | |
298 if (message_id) { | |
299 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
300 base::string16 text = rb.GetLocalizedString(message_id); | |
301 if (!*label) { | |
302 *label = delegate_->CreateInfoLabel(); | |
303 (*label)->SetText(text); | |
304 container()->AddChildViewAt(*label, index); | |
305 needs_relayout = true; | |
306 } else { | |
307 (*label)->SetText(text); | |
308 needs_relayout = PlaceViewAtIndex(*label, index); | |
309 } | |
310 } else if (*label) { | |
311 delete *label; | |
312 *label = nullptr; | |
313 needs_relayout = true; | |
314 } | |
315 return needs_relayout; | |
316 } | |
317 | |
318 void NetworkListView::NetworkIconChanged() { | |
319 Update(); | |
320 } | |
321 | |
322 } // namespace ash | |
OLD | NEW |