1 // Copyright (c) 2012 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 "chromeos/dbus/root_power_manager_client.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/observer_list.h"
10 #include "base/time.h"
11 #include "chromeos/dbus/power_manager/input_event.pb.h"
12 #include "chromeos/dbus/power_manager/suspend.pb.h"
13 #include "chromeos/dbus/root_power_manager_observer.h"
15 #include "dbus/message.h"
16 #include "dbus/object_path.h"
17 #include "dbus/object_proxy.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
22 // The RootPowerManagerClient implementation used in production.
23 class RootPowerManagerClientImpl
: public RootPowerManagerClient
{
25 explicit RootPowerManagerClientImpl(dbus::Bus
* bus
)
27 weak_ptr_factory_(this) {
28 proxy_
= bus
->GetObjectProxy(
29 power_manager::kRootPowerManagerServiceName
,
30 dbus::ObjectPath(power_manager::kRootPowerManagerServicePath
));
32 proxy_
->ConnectToSignal(
33 power_manager::kRootPowerManagerInterface
,
34 power_manager::kInputEventSignal
,
35 base::Bind(&RootPowerManagerClientImpl::InputEventReceived
,
36 weak_ptr_factory_
.GetWeakPtr()),
37 base::Bind(&RootPowerManagerClientImpl::SignalConnected
,
38 weak_ptr_factory_
.GetWeakPtr()));
39 proxy_
->ConnectToSignal(
40 power_manager::kRootPowerManagerInterface
,
41 power_manager::kSuspendStateChangedSignal
,
42 base::Bind(&RootPowerManagerClientImpl::SuspendStateChangedReceived
,
43 weak_ptr_factory_
.GetWeakPtr()),
44 base::Bind(&RootPowerManagerClientImpl::SignalConnected
,
45 weak_ptr_factory_
.GetWeakPtr()));
48 virtual ~RootPowerManagerClientImpl() {
51 // RootPowerManagerClient overrides:
52 virtual void AddObserver(RootPowerManagerObserver
* observer
) OVERRIDE
{
53 observers_
.AddObserver(observer
);
56 virtual void RemoveObserver(RootPowerManagerObserver
* observer
) OVERRIDE
{
57 observers_
.RemoveObserver(observer
);
60 virtual bool HasObserver(RootPowerManagerObserver
* observer
) OVERRIDE
{
61 return observers_
.HasObserver(observer
);
65 // Called when a D-Bus signal is initially connected.
66 void SignalConnected(const std::string
& interface_name
,
67 const std::string
& signal_name
,
70 LOG(WARNING
) << "Failed to connect to signal " << signal_name
;
73 void InputEventReceived(dbus::Signal
* signal
) {
74 dbus::MessageReader
reader(signal
);
75 power_manager::InputEvent proto
;
76 if (!reader
.PopArrayOfBytesAsProto(&proto
)) {
77 LOG(ERROR
) << "Unable to decode protocol buffer from "
78 << power_manager::kInputEventSignal
<< " signal";
82 base::TimeTicks timestamp
=
83 base::TimeTicks::FromInternalValue(proto
.timestamp());
84 VLOG(1) << "Got " << power_manager::kInputEventSignal
<< " signal:"
85 << " type=" << proto
.type() << " timestamp=" << proto
.timestamp();
86 switch (proto
.type()) {
87 case power_manager::InputEvent_Type_POWER_BUTTON_DOWN
:
88 case power_manager::InputEvent_Type_POWER_BUTTON_UP
: {
90 (proto
.type() == power_manager::InputEvent_Type_POWER_BUTTON_DOWN
);
91 FOR_EACH_OBSERVER(RootPowerManagerObserver
, observers_
,
92 OnPowerButtonEvent(down
, timestamp
));
95 case power_manager::InputEvent_Type_LID_OPEN
:
96 case power_manager::InputEvent_Type_LID_CLOSED
: {
98 (proto
.type() == power_manager::InputEvent_Type_LID_OPEN
);
99 FOR_EACH_OBSERVER(RootPowerManagerObserver
, observers_
,
100 OnLidEvent(open
, timestamp
));
106 void SuspendStateChangedReceived(dbus::Signal
* signal
) {
107 dbus::MessageReader
reader(signal
);
108 power_manager::SuspendState proto
;
109 if (!reader
.PopArrayOfBytesAsProto(&proto
)) {
110 LOG(ERROR
) << "Unable to decode protocol buffer from "
111 << power_manager::kSuspendStateChangedSignal
<< " signal";
115 VLOG(1) << "Got " << power_manager::kSuspendStateChangedSignal
<< " signal:"
116 << " type=" << proto
.type() << " wall_time=" << proto
.wall_time();
117 base::Time wall_time
=
118 base::Time::FromInternalValue(proto
.wall_time());
119 switch (proto
.type()) {
120 case power_manager::SuspendState_Type_SUSPEND_TO_MEMORY
:
121 last_suspend_wall_time_
= wall_time
;
123 case power_manager::SuspendState_Type_RESUME
:
125 RootPowerManagerObserver
, observers_
,
126 OnResume(wall_time
- last_suspend_wall_time_
));
131 dbus::ObjectProxy
* proxy_
;
133 ObserverList
<RootPowerManagerObserver
> observers_
;
135 // Wall time from the latest signal telling us that the system was about to
136 // suspend to memory.
137 base::Time last_suspend_wall_time_
;
139 // Note: This should remain the last member so it'll be destroyed and
140 // invalidate its weak pointers before any other members are destroyed.
141 base::WeakPtrFactory
<RootPowerManagerClientImpl
> weak_ptr_factory_
;
143 DISALLOW_COPY_AND_ASSIGN(RootPowerManagerClientImpl
);
146 // A no-op RootPowerManagerClient implementation used on Linux desktops.
147 class RootPowerManagerClientStubImpl
: public RootPowerManagerClient
{
149 RootPowerManagerClientStubImpl() {}
150 virtual ~RootPowerManagerClientStubImpl() {}
152 // RootPowerManagerClient overrides:
153 virtual void AddObserver(RootPowerManagerObserver
* observer
) OVERRIDE
{
154 observers_
.AddObserver(observer
);
157 virtual void RemoveObserver(RootPowerManagerObserver
* observer
) OVERRIDE
{
158 observers_
.RemoveObserver(observer
);
161 virtual bool HasObserver(RootPowerManagerObserver
* observer
) OVERRIDE
{
162 return observers_
.HasObserver(observer
);
166 ObserverList
<RootPowerManagerObserver
> observers_
;
168 DISALLOW_COPY_AND_ASSIGN(RootPowerManagerClientStubImpl
);
171 RootPowerManagerClient::RootPowerManagerClient() {
174 RootPowerManagerClient::~RootPowerManagerClient() {
177 RootPowerManagerClient
* RootPowerManagerClient::Create(
178 DBusClientImplementationType type
,
180 if (type
== REAL_DBUS_CLIENT_IMPLEMENTATION
)
181 return new RootPowerManagerClientImpl(bus
);
182 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION
, type
);
183 return new RootPowerManagerClientStubImpl();
186 } // namespace chromeos