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 "athena/main/debug/debug_window.h" | |
6 | |
7 #include "athena/common/container_priorities.h" | |
8 #include "athena/main/debug/network_selector.h" | |
9 #include "athena/resources/athena_resources.h" | |
10 #include "athena/screen/public/screen_manager.h" | |
11 #include "base/bind.h" | |
12 #include "base/macros.h" | |
13 #include "base/strings/stringprintf.h" | |
14 #include "base/strings/utf_string_conversions.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/dbus/update_engine_client.h" | |
19 #include "chromeos/network/network_state.h" | |
20 #include "chromeos/network/network_state_handler.h" | |
21 #include "chromeos/network/network_state_handler_observer.h" | |
22 #include "chromeos/network/network_type_pattern.h" | |
23 #include "ui/aura/window.h" | |
24 #include "ui/base/resource/resource_bundle.h" | |
25 #include "ui/gfx/image/image.h" | |
26 #include "ui/gfx/image/image_skia.h" | |
27 #include "ui/gfx/image/image_skia_operations.h" | |
28 #include "ui/views/background.h" | |
29 #include "ui/views/border.h" | |
30 #include "ui/views/controls/image_view.h" | |
31 #include "ui/views/controls/label.h" | |
32 #include "ui/views/layout/box_layout.h" | |
33 #include "ui/views/view.h" | |
34 #include "ui/views/widget/widget.h" | |
35 | |
36 namespace { | |
37 | |
38 views::Label* CreateDebugLabel(const std::string& text) { | |
39 views::Label* label = new views::Label(base::UTF8ToUTF16(text)); | |
40 label->SetEnabledColor(SK_ColorWHITE); | |
41 label->SetBackgroundColor(SK_ColorTRANSPARENT); | |
42 label->SetFontList(gfx::FontList().Derive(-2, gfx::Font::BOLD)); | |
43 return label; | |
44 } | |
45 | |
46 class PowerStatus : public chromeos::PowerManagerClient::Observer { | |
47 public: | |
48 PowerStatus(views::ImageView* icon, const base::Closure& closure) | |
49 : icon_(icon), closure_(closure) { | |
50 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( | |
51 this); | |
52 chromeos::DBusThreadManager::Get() | |
53 ->GetPowerManagerClient() | |
54 ->RequestStatusUpdate(); | |
55 } | |
56 | |
57 virtual ~PowerStatus() { | |
58 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( | |
59 this); | |
60 } | |
61 | |
62 private: | |
63 const gfx::ImageSkia GetPowerIcon( | |
64 const power_manager::PowerSupplyProperties& proto) const { | |
65 // Width and height of battery images. | |
66 const int kBatteryImageHeight = 25; | |
67 const int kBatteryImageWidth = 25; | |
68 | |
69 // Number of different power states. | |
70 const int kNumPowerImages = 15; | |
71 | |
72 gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
73 IDR_AURA_UBER_TRAY_POWER_SMALL); | |
74 int horiz_offset = IsCharging(proto) ? 1 : 0; | |
75 int vert_offset = -1; | |
76 if (proto.battery_percent() >= 100) { | |
77 vert_offset = kNumPowerImages - 1; | |
78 } else { | |
79 vert_offset = static_cast<int>((kNumPowerImages - 1) * | |
80 proto.battery_percent() / 100); | |
81 vert_offset = std::max(std::min(vert_offset, kNumPowerImages - 2), 0); | |
82 } | |
83 gfx::Rect region(horiz_offset * kBatteryImageWidth, | |
84 vert_offset * kBatteryImageHeight, | |
85 kBatteryImageWidth, | |
86 kBatteryImageHeight); | |
87 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region); | |
88 } | |
89 | |
90 bool IsCharging(const power_manager::PowerSupplyProperties& proto) const { | |
91 return proto.external_power() != | |
92 power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED; | |
93 } | |
94 | |
95 // chromeos::PowerManagerClient::Observer: | |
96 virtual void PowerChanged( | |
97 const power_manager::PowerSupplyProperties& proto) OVERRIDE { | |
98 icon_->SetImage(GetPowerIcon(proto)); | |
99 if (!closure_.is_null()) | |
100 closure_.Run(); | |
101 } | |
102 | |
103 views::ImageView* icon_; | |
104 base::Closure closure_; | |
105 | |
106 DISALLOW_COPY_AND_ASSIGN(PowerStatus); | |
107 }; | |
108 | |
109 class NetworkStatus : public chromeos::NetworkStateHandlerObserver { | |
110 public: | |
111 NetworkStatus(views::Label* label, const base::Closure& closure) | |
112 : label_(label), closure_(closure) { | |
113 chromeos::NetworkStateHandler* handler = | |
114 chromeos::NetworkHandler::Get()->network_state_handler(); | |
115 handler->AddObserver(this, FROM_HERE); | |
116 } | |
117 | |
118 virtual ~NetworkStatus() { | |
119 chromeos::NetworkStateHandler* handler = | |
120 chromeos::NetworkHandler::Get()->network_state_handler(); | |
121 handler->RemoveObserver(this, FROM_HERE); | |
122 } | |
123 | |
124 private: | |
125 void Update() { | |
126 std::string status = "<unknown>"; | |
127 chromeos::NetworkStateHandler* handler = | |
128 chromeos::NetworkHandler::Get()->network_state_handler(); | |
129 const chromeos::NetworkState* network = handler->DefaultNetwork(); | |
130 if (!network) { | |
131 network = handler->ConnectedNetworkByType( | |
132 chromeos::NetworkTypePattern::NonVirtual()); | |
133 } | |
134 if (network) { | |
135 status = base::StringPrintf( | |
136 "%s (%s)", network->ip_address().c_str(), network->name().c_str()); | |
137 } | |
138 label_->SetText(base::UTF8ToUTF16(status)); | |
139 if (!closure_.is_null()) | |
140 closure_.Run(); | |
141 } | |
142 | |
143 // chromeos::NetworkStateHandlerObserver: | |
144 virtual void DefaultNetworkChanged( | |
145 const chromeos::NetworkState* network) OVERRIDE { | |
146 Update(); | |
147 } | |
148 | |
149 virtual void NetworkConnectionStateChanged( | |
150 const chromeos::NetworkState* network) OVERRIDE { | |
151 Update(); | |
152 } | |
153 | |
154 virtual void NetworkPropertiesUpdated( | |
155 const chromeos::NetworkState* network) OVERRIDE { | |
156 Update(); | |
157 } | |
158 | |
159 views::Label* label_; | |
160 base::Closure closure_; | |
161 }; | |
162 | |
163 void StartUpdateCallback( | |
164 chromeos::UpdateEngineClient::UpdateCheckResult result) { | |
165 VLOG(1) << "Callback from RequestUpdateCheck, result " << result; | |
166 } | |
167 | |
168 class UpdateStatus : public chromeos::UpdateEngineClient::Observer { | |
169 public: | |
170 UpdateStatus(views::ImageView* icon, const base::Closure& closure) | |
171 : icon_(icon), closure_(closure) { | |
172 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver( | |
173 this); | |
174 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()-> | |
175 RequestUpdateCheck(base::Bind(StartUpdateCallback)); | |
176 } | |
177 | |
178 virtual ~UpdateStatus() { | |
179 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver( | |
180 this); | |
181 } | |
182 | |
183 // chromeos::UpdateEngineClient::Observer: | |
184 virtual void UpdateStatusChanged( | |
185 const chromeos::UpdateEngineClient::Status& status) OVERRIDE { | |
186 if (status.status != | |
187 chromeos::UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) { | |
188 return; | |
189 } | |
190 icon_->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
191 IDR_AURA_UBER_TRAY_UPDATE)); | |
192 if (!closure_.is_null()) | |
193 closure_.Run(); | |
194 } | |
195 | |
196 private: | |
197 views::ImageView* icon_; | |
198 base::Closure closure_; | |
199 | |
200 DISALLOW_COPY_AND_ASSIGN(UpdateStatus); | |
201 }; | |
202 | |
203 // Processes user input to show the detailed network-list. | |
204 class DetailViewHandler : public ui::EventHandler { | |
205 public: | |
206 explicit DetailViewHandler(aura::Window* container) : container_(container) {} | |
207 virtual ~DetailViewHandler() {} | |
208 | |
209 private: | |
210 // ui::EventHandler: | |
211 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { | |
212 if (event->type() == ui::ET_MOUSE_PRESSED) { | |
213 debug::CreateNetworkSelector(container_); | |
214 event->SetHandled(); | |
215 } | |
216 } | |
217 | |
218 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { | |
219 if (event->type() == ui::ET_GESTURE_TAP) { | |
220 debug::CreateNetworkSelector(container_); | |
221 event->SetHandled(); | |
222 } | |
223 } | |
224 | |
225 aura::Window* container_; | |
226 | |
227 DISALLOW_COPY_AND_ASSIGN(DetailViewHandler); | |
228 }; | |
229 | |
230 class DebugWidget { | |
231 public: | |
232 DebugWidget() : container_(NULL), widget_(NULL) { | |
233 CreateContainer(); | |
234 CreateWidget(); | |
235 | |
236 CreateBatteryView(); | |
237 CreateUpdateView(); | |
238 CreateNetworkView(); | |
239 | |
240 UpdateSize(); | |
241 } | |
242 | |
243 virtual ~DebugWidget() {} | |
244 | |
245 private: | |
246 void CreateContainer() { | |
247 athena::ScreenManager::ContainerParams params("DebugContainer", | |
248 athena::CP_DEBUG); | |
249 params.can_activate_children = true; | |
250 container_ = athena::ScreenManager::Get()->CreateContainer(params); | |
251 } | |
252 | |
253 void CreateWidget() { | |
254 views::Widget::InitParams params; | |
255 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; | |
256 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | |
257 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; | |
258 params.accept_events = true; | |
259 params.bounds = gfx::Rect(200, 0, 100, 105); | |
260 params.parent = container_; | |
261 widget_ = new views::Widget(); | |
262 widget_->Init(params); | |
263 | |
264 event_handler_.reset(new DetailViewHandler(container_)); | |
265 | |
266 const int kHorizontalSpacing = 10; | |
267 const int kBorderVerticalSpacing = 3; | |
268 const int kBetweenChildSpacing = 10; | |
269 const int kBackgroundColor = SkColorSetARGB(0x7f, 0, 0, 0); | |
270 views::View* container = new views::View; | |
271 container->SetLayoutManager( | |
272 new views::BoxLayout(views::BoxLayout::kHorizontal, | |
273 kHorizontalSpacing, | |
274 kBorderVerticalSpacing, | |
275 kBetweenChildSpacing)); | |
276 container->set_background( | |
277 views::Background::CreateSolidBackground(kBackgroundColor)); | |
278 container->SetBorder(views::Border::CreateSolidBorder(1, kBackgroundColor)); | |
279 container->set_target_handler(event_handler_.get()); | |
280 widget_->SetContentsView(container); | |
281 widget_->StackAtTop(); | |
282 widget_->Show(); | |
283 | |
284 widget_->SetBounds(gfx::Rect(600, 0, 300, 25)); | |
285 } | |
286 | |
287 void CreateBatteryView() { | |
288 views::View* container = widget_->GetContentsView(); | |
289 views::ImageView* icon = new views::ImageView(); | |
290 container->AddChildView(icon); | |
291 container->Layout(); | |
292 | |
293 power_status_.reset(new PowerStatus( | |
294 icon, base::Bind(&DebugWidget::UpdateSize, base::Unretained(this)))); | |
295 } | |
296 | |
297 void CreateNetworkView() { | |
298 views::View* container = widget_->GetContentsView(); | |
299 container->AddChildView(CreateDebugLabel("Network:")); | |
300 | |
301 views::Label* label = CreateDebugLabel(std::string()); | |
302 container->AddChildView(label); | |
303 container->Layout(); | |
304 | |
305 network_status_.reset(new NetworkStatus( | |
306 label, base::Bind(&DebugWidget::UpdateSize, base::Unretained(this)))); | |
307 } | |
308 | |
309 void CreateUpdateView() { | |
310 views::View* container = widget_->GetContentsView(); | |
311 views::ImageView* icon = new views::ImageView(); | |
312 container->AddChildView(icon); | |
313 container->Layout(); | |
314 | |
315 update_status_.reset(new UpdateStatus( | |
316 icon, base::Bind(&DebugWidget::UpdateSize, base::Unretained(this)))); | |
317 } | |
318 | |
319 const gfx::Rect GetPositionForSize(const gfx::Size& size) { | |
320 int right = container_->bounds().right(); | |
321 int x = right - size.width(); | |
322 return gfx::Rect(x, 0, size.width(), size.height()); | |
323 } | |
324 | |
325 void UpdateSize() { | |
326 views::View* container = widget_->GetContentsView(); | |
327 container->Layout(); | |
328 gfx::Size size = container->GetPreferredSize(); | |
329 widget_->SetBounds(GetPositionForSize(size)); | |
330 } | |
331 | |
332 aura::Window* container_; | |
333 views::Widget* widget_; | |
334 scoped_ptr<PowerStatus> power_status_; | |
335 scoped_ptr<NetworkStatus> network_status_; | |
336 scoped_ptr<UpdateStatus> update_status_; | |
337 scoped_ptr<ui::EventHandler> event_handler_; | |
338 | |
339 DISALLOW_COPY_AND_ASSIGN(DebugWidget); | |
340 }; | |
341 | |
342 } // namespace | |
343 | |
344 void CreateDebugWindow() { | |
345 new DebugWidget(); | |
346 } | |
OLD | NEW |