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 "content/browser/devtools/devtools_power_handler.h"
6
7#include "base/bind.h"
8#include "base/values.h"
9#include "content/browser/devtools/devtools_protocol_constants.h"
10#include "content/browser/power_profiler/power_profiler_service.h"
11
12namespace content {
13
14DevToolsPowerHandler::DevToolsPowerHandler()
15    : is_profiling_(false) {
16  RegisterCommandHandler(devtools::Power::start::kName,
17                         base::Bind(&DevToolsPowerHandler::OnStart,
18                                    base::Unretained(this)));
19  RegisterCommandHandler(devtools::Power::end::kName,
20                         base::Bind(&DevToolsPowerHandler::OnEnd,
21                                    base::Unretained(this)));
22  RegisterCommandHandler(devtools::Power::canProfilePower::kName,
23                         base::Bind(&DevToolsPowerHandler::OnCanProfilePower,
24                                    base::Unretained(this)));
25  RegisterCommandHandler(devtools::Power::getAccuracyLevel::kName,
26                         base::Bind(&DevToolsPowerHandler::OnGetAccuracyLevel,
27                                    base::Unretained(this)));
28}
29
30DevToolsPowerHandler::~DevToolsPowerHandler() {
31  if (is_profiling_)
32    PowerProfilerService::GetInstance()->RemoveObserver(this);
33}
34
35void DevToolsPowerHandler::OnPowerEvent(const PowerEventVector& events) {
36  base::DictionaryValue* params = new base::DictionaryValue();
37  base::ListValue* event_list = new base::ListValue();
38
39  std::vector<PowerEvent>::const_iterator iter;
40  for (iter = events.begin(); iter != events.end(); ++iter) {
41    base::DictionaryValue* event_body = new base::DictionaryValue();
42
43    DCHECK(iter->type < PowerEvent::ID_COUNT);
44    event_body->SetString("type", kPowerTypeNames[iter->type]);
45    // Use internal value to be consistent with Blink's
46    // monotonicallyIncreasingTime.
47    event_body->SetDouble("timestamp", iter->time.ToInternalValue() /
48        static_cast<double>(base::Time::kMicrosecondsPerMillisecond));
49    event_body->SetDouble("value", iter->value);
50    event_list->Append(event_body);
51  }
52
53  params->Set(devtools::Power::dataAvailable::kParamValue, event_list);
54  SendNotification(devtools::Power::dataAvailable::kName, params);
55}
56
57scoped_refptr<DevToolsProtocol::Response>
58DevToolsPowerHandler::OnStart(
59    scoped_refptr<DevToolsProtocol::Command> command) {
60  if (PowerProfilerService::GetInstance()->IsAvailable()) {
61    PowerProfilerService::GetInstance()->AddObserver(this);
62    is_profiling_ = true;
63    return command->SuccessResponse(NULL);
64  }
65
66  return command->InternalErrorResponse("Power profiler service unavailable");
67}
68
69scoped_refptr<DevToolsProtocol::Response>
70DevToolsPowerHandler::OnEnd(scoped_refptr<DevToolsProtocol::Command> command) {
71  if (PowerProfilerService::GetInstance()->IsAvailable()) {
72    PowerProfilerService::GetInstance()->RemoveObserver(this);
73    is_profiling_ = false;
74    return command->SuccessResponse(NULL);
75  }
76
77  return command->InternalErrorResponse("Power profiler service unavailable");
78}
79
80scoped_refptr<DevToolsProtocol::Response>
81DevToolsPowerHandler::OnCanProfilePower(
82    scoped_refptr<DevToolsProtocol::Command> command) {
83  base::DictionaryValue* result = new base::DictionaryValue();
84  result->SetBoolean(devtools::kResult,
85                     PowerProfilerService::GetInstance()->IsAvailable());
86
87  return command->SuccessResponse(result);
88}
89
90scoped_refptr<DevToolsProtocol::Response>
91DevToolsPowerHandler::OnGetAccuracyLevel(
92    scoped_refptr<DevToolsProtocol::Command> command) {
93  if (PowerProfilerService::GetInstance()->IsAvailable()) {
94    base::DictionaryValue* result = new base::DictionaryValue();
95    result->SetString(
96        devtools::kResult,
97        PowerProfilerService::GetInstance()->GetAccuracyLevel());
98    return command->SuccessResponse(result);
99  }
100  return command->InternalErrorResponse("Power profiler service unavailable");
101}
102
103void DevToolsPowerHandler::OnClientDetached() {
104  if (is_profiling_)
105    PowerProfilerService::GetInstance()->RemoveObserver(this);
106}
107
108}  // namespace content
109