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 "chrome/browser/ui/webui/chromeos/power_ui.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/time/time.h"
12 #include "base/values.h"
13 #include "chrome/browser/chromeos/power/power_data_collector.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/url_constants.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "content/public/browser/web_ui.h"
18 #include "content/public/browser/web_ui_data_source.h"
19 #include "content/public/browser/web_ui_message_handler.h"
20 #include "grit/browser_resources.h"
26 const char kStringsJsFile
[] = "strings.js";
28 const char kRequestBatteryChargeDataCallback
[] = "requestBatteryChargeData";
29 const char kOnRequestBatteryChargeDataFunction
[] =
30 "powerUI.showBatteryChargeData";
32 const char kRequestCpuIdleDataCallback
[] = "requestCpuIdleData";
33 const char kOnRequestCpuIdleDataFunction
[] =
34 "powerUI.showCpuIdleData";
36 const char kRequestCpuFreqDataCallback
[] = "requestCpuFreqData";
37 const char kOnRequestCpuFreqDataFunction
[] =
38 "powerUI.showCpuFreqData";
40 class PowerMessageHandler
: public content::WebUIMessageHandler
{
42 PowerMessageHandler();
43 ~PowerMessageHandler() override
;
45 // WebUIMessageHandler implementation.
46 void RegisterMessages() override
;
49 void OnGetBatteryChargeData(const base::ListValue
* value
);
50 void OnGetCpuIdleData(const base::ListValue
* value
);
51 void OnGetCpuFreqData(const base::ListValue
* value
);
52 void GetJsStateOccupancyData(
53 const std::vector
<CpuDataCollector::StateOccupancySampleDeque
>& data
,
54 const std::vector
<std::string
>& state_names
,
55 base::ListValue
* js_data
);
56 void GetJsSystemResumedData(base::ListValue
* value
);
59 PowerMessageHandler::PowerMessageHandler() {
62 PowerMessageHandler::~PowerMessageHandler() {
65 void PowerMessageHandler::RegisterMessages() {
66 web_ui()->RegisterMessageCallback(
67 kRequestBatteryChargeDataCallback
,
68 base::Bind(&PowerMessageHandler::OnGetBatteryChargeData
,
69 base::Unretained(this)));
70 web_ui()->RegisterMessageCallback(
71 kRequestCpuIdleDataCallback
,
72 base::Bind(&PowerMessageHandler::OnGetCpuIdleData
,
73 base::Unretained(this)));
74 web_ui()->RegisterMessageCallback(
75 kRequestCpuFreqDataCallback
,
76 base::Bind(&PowerMessageHandler::OnGetCpuFreqData
,
77 base::Unretained(this)));
80 void PowerMessageHandler::OnGetBatteryChargeData(const base::ListValue
* value
) {
81 const std::deque
<PowerDataCollector::PowerSupplySample
>& power_supply
=
82 PowerDataCollector::Get()->power_supply_data();
83 base::ListValue js_power_supply_data
;
84 for (size_t i
= 0; i
< power_supply
.size(); ++i
) {
85 const PowerDataCollector::PowerSupplySample
& sample
= power_supply
[i
];
86 scoped_ptr
<base::DictionaryValue
> element(new base::DictionaryValue
);
87 element
->SetDouble("batteryPercent", sample
.battery_percent
);
88 element
->SetDouble("batteryDischargeRate", sample
.battery_discharge_rate
);
89 element
->SetBoolean("externalPower", sample
.external_power
);
90 element
->SetDouble("time", sample
.time
.ToJsTime());
92 js_power_supply_data
.Append(element
.release());
95 base::ListValue js_system_resumed_data
;
96 GetJsSystemResumedData(&js_system_resumed_data
);
98 web_ui()->CallJavascriptFunction(kOnRequestBatteryChargeDataFunction
,
100 js_system_resumed_data
);
103 void PowerMessageHandler::OnGetCpuIdleData(const base::ListValue
* value
) {
104 const CpuDataCollector
& cpu_data_collector
=
105 PowerDataCollector::Get()->cpu_data_collector();
107 const std::vector
<CpuDataCollector::StateOccupancySampleDeque
>& idle_data
=
108 cpu_data_collector
.cpu_idle_state_data();
109 const std::vector
<std::string
>& idle_state_names
=
110 cpu_data_collector
.cpu_idle_state_names();
111 base::ListValue js_idle_data
;
112 GetJsStateOccupancyData(idle_data
, idle_state_names
, &js_idle_data
);
114 base::ListValue js_system_resumed_data
;
115 GetJsSystemResumedData(&js_system_resumed_data
);
117 web_ui()->CallJavascriptFunction(kOnRequestCpuIdleDataFunction
,
119 js_system_resumed_data
);
122 void PowerMessageHandler::OnGetCpuFreqData(const base::ListValue
* value
) {
123 const CpuDataCollector
& cpu_data_collector
=
124 PowerDataCollector::Get()->cpu_data_collector();
126 const std::vector
<CpuDataCollector::StateOccupancySampleDeque
>& freq_data
=
127 cpu_data_collector
.cpu_freq_state_data();
128 const std::vector
<std::string
>& freq_state_names
=
129 cpu_data_collector
.cpu_freq_state_names();
130 base::ListValue js_freq_data
;
131 GetJsStateOccupancyData(freq_data
, freq_state_names
, &js_freq_data
);
133 base::ListValue js_system_resumed_data
;
134 GetJsSystemResumedData(&js_system_resumed_data
);
136 web_ui()->CallJavascriptFunction(kOnRequestCpuFreqDataFunction
,
138 js_system_resumed_data
);
141 void PowerMessageHandler::GetJsSystemResumedData(base::ListValue
*data
) {
144 const std::deque
<PowerDataCollector::SystemResumedSample
>& system_resumed
=
145 PowerDataCollector::Get()->system_resumed_data();
146 for (size_t i
= 0; i
< system_resumed
.size(); ++i
) {
147 const PowerDataCollector::SystemResumedSample
& sample
= system_resumed
[i
];
148 scoped_ptr
<base::DictionaryValue
> element(new base::DictionaryValue
);
149 element
->SetDouble("sleepDuration",
150 sample
.sleep_duration
.InMillisecondsF());
151 element
->SetDouble("time", sample
.time
.ToJsTime());
153 data
->Append(element
.release());
157 void PowerMessageHandler::GetJsStateOccupancyData(
158 const std::vector
<CpuDataCollector::StateOccupancySampleDeque
>& data
,
159 const std::vector
<std::string
>& state_names
,
160 base::ListValue
*js_data
) {
161 for (unsigned int cpu
= 0; cpu
< data
.size(); ++cpu
) {
162 const CpuDataCollector::StateOccupancySampleDeque
& sample_deque
= data
[cpu
];
163 scoped_ptr
<base::ListValue
> js_sample_list(new base::ListValue
);
164 for (unsigned int i
= 0; i
< sample_deque
.size(); ++i
) {
165 const CpuDataCollector::StateOccupancySample
& sample
= sample_deque
[i
];
166 scoped_ptr
<base::DictionaryValue
> js_sample(new base::DictionaryValue
);
167 js_sample
->SetDouble("time", sample
.time
.ToJsTime());
168 js_sample
->SetBoolean("cpuOnline", sample
.cpu_online
);
170 scoped_ptr
<base::DictionaryValue
> state_dict(new base::DictionaryValue
);
171 for (size_t index
= 0; index
< sample
.time_in_state
.size(); ++index
) {
172 state_dict
->SetDouble(state_names
[index
],
173 static_cast<double>(sample
.time_in_state
[index
]));
175 js_sample
->Set("timeInState", state_dict
.release());
177 js_sample_list
->Append(js_sample
.release());
179 js_data
->Append(js_sample_list
.release());
185 PowerUI::PowerUI(content::WebUI
* web_ui
) : content::WebUIController(web_ui
) {
186 web_ui
->AddMessageHandler(new PowerMessageHandler());
188 content::WebUIDataSource
* html
=
189 content::WebUIDataSource::Create(chrome::kChromeUIPowerHost
);
191 html
->AddLocalizedString("titleText", IDS_ABOUT_POWER_TITLE
);
192 html
->AddLocalizedString("showButton", IDS_ABOUT_POWER_SHOW_BUTTON
);
193 html
->AddLocalizedString("hideButton", IDS_ABOUT_POWER_HIDE_BUTTON
);
194 html
->AddLocalizedString("reloadButton", IDS_ABOUT_POWER_RELOAD_BUTTON
);
195 html
->AddLocalizedString("notEnoughDataAvailableYet",
196 IDS_ABOUT_POWER_NOT_ENOUGH_DATA
);
197 html
->AddLocalizedString("systemSuspended",
198 IDS_ABOUT_POWER_SYSTEM_SUSPENDED
);
199 html
->AddLocalizedString("invalidData", IDS_ABOUT_POWER_INVALID
);
200 html
->AddLocalizedString("offlineText", IDS_ABOUT_POWER_OFFLINE
);
202 html
->AddLocalizedString("batteryChargeSectionTitle",
203 IDS_ABOUT_POWER_BATTERY_CHARGE_SECTION_TITLE
);
204 html
->AddLocalizedString("batteryChargePercentageHeader",
205 IDS_ABOUT_POWER_BATTERY_CHARGE_PERCENTAGE_HEADER
);
206 html
->AddLocalizedString("batteryDischargeRateHeader",
207 IDS_ABOUT_POWER_BATTERY_DISCHARGE_RATE_HEADER
);
208 html
->AddLocalizedString("dischargeRateLegendText",
209 IDS_ABOUT_POWER_DISCHARGE_RATE_LEGEND_TEXT
);
210 html
->AddLocalizedString("movingAverageLegendText",
211 IDS_ABOUT_POWER_MOVING_AVERAGE_LEGEND_TEXT
);
212 html
->AddLocalizedString("binnedAverageLegendText",
213 IDS_ABOUT_POWER_BINNED_AVERAGE_LEGEND_TEXT
);
214 html
->AddLocalizedString("averageOverText",
215 IDS_ABOUT_POWER_AVERAGE_OVER_TEXT
);
216 html
->AddLocalizedString("samplesText",
217 IDS_ABOUT_POWER_AVERAGE_SAMPLES_TEXT
);
219 html
->AddLocalizedString("cpuIdleSectionTitle",
220 IDS_ABOUT_POWER_CPU_IDLE_SECTION_TITLE
);
221 html
->AddLocalizedString("idleStateOccupancyPercentageHeader",
222 IDS_ABOUT_POWER_CPU_IDLE_STATE_OCCUPANCY_PERCENTAGE
);
224 html
->AddLocalizedString("cpuFreqSectionTitle",
225 IDS_ABOUT_POWER_CPU_FREQ_SECTION_TITLE
);
226 html
->AddLocalizedString("frequencyStateOccupancyPercentageHeader",
227 IDS_ABOUT_POWER_CPU_FREQ_STATE_OCCUPANCY_PERCENTAGE
);
229 html
->SetJsonPath(kStringsJsFile
);
231 html
->AddResourcePath("power.css", IDR_ABOUT_POWER_CSS
);
232 html
->AddResourcePath("power.js", IDR_ABOUT_POWER_JS
);
233 html
->SetDefaultResource(IDR_ABOUT_POWER_HTML
);
235 Profile
* profile
= Profile::FromWebUI(web_ui
);
236 content::WebUIDataSource::Add(profile
, html
);
239 PowerUI::~PowerUI() {
242 } // namespace chromeos