| // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "shill/power_manager_proxy.h" |
| |
| #include <chromeos/dbus/service_constants.h> |
| #include <google/protobuf/message_lite.h> |
| |
| #include "shill/logging.h" |
| #include "shill/proto_bindings/power_manager/suspend.pb.h" |
| |
| using std::string; |
| using std::vector; |
| |
| namespace shill { |
| |
| namespace { |
| |
| // Serializes |protobuf| to |out| and returns true on success. |
| bool SerializeProtocolBuffer(const google::protobuf::MessageLite &protobuf, |
| vector<uint8_t> *out) { |
| CHECK(out); |
| out->clear(); |
| string serialized_protobuf; |
| if (!protobuf.SerializeToString(&serialized_protobuf)) |
| return false; |
| out->assign(serialized_protobuf.begin(), serialized_protobuf.end()); |
| return true; |
| } |
| |
| // Deserializes |serialized_protobuf| to |protobuf_out| and returns true on |
| // success. |
| bool DeserializeProtocolBuffer(const vector<uint8_t> &serialized_protobuf, |
| google::protobuf::MessageLite *protobuf_out) { |
| CHECK(protobuf_out); |
| if (serialized_protobuf.empty()) |
| return false; |
| return protobuf_out->ParseFromArray(&serialized_protobuf.front(), |
| serialized_protobuf.size()); |
| } |
| |
| } // namespace |
| |
| PowerManagerProxy::PowerManagerProxy(PowerManagerProxyDelegate *delegate, |
| DBus::Connection *connection) |
| : proxy_(delegate, connection) {} |
| |
| PowerManagerProxy::~PowerManagerProxy() {} |
| |
| bool PowerManagerProxy::RegisterSuspendDelay(base::TimeDelta timeout, |
| int *delay_id_out) { |
| LOG(INFO) << __func__ << "(" << timeout.InMilliseconds() << ")"; |
| |
| power_manager::RegisterSuspendDelayRequest request_proto; |
| request_proto.set_timeout(timeout.ToInternalValue()); |
| vector<uint8_t> serialized_request; |
| CHECK(SerializeProtocolBuffer(request_proto, &serialized_request)); |
| |
| vector<uint8_t> serialized_reply; |
| try { |
| serialized_reply = proxy_.RegisterSuspendDelay(serialized_request); |
| } catch (const DBus::Error &e) { |
| LOG(ERROR) << "DBus exception: " << e.name() << ": " << e.what(); |
| return false; |
| } |
| |
| power_manager::RegisterSuspendDelayReply reply_proto; |
| if (!DeserializeProtocolBuffer(serialized_reply, &reply_proto)) { |
| LOG(ERROR) << "Failed to register suspend delay. Couldn't parse response."; |
| return false; |
| } |
| *delay_id_out = reply_proto.delay_id(); |
| return true; |
| } |
| |
| bool PowerManagerProxy::UnregisterSuspendDelay(int delay_id) { |
| LOG(INFO) << __func__ << "(" << delay_id << ")"; |
| |
| power_manager::UnregisterSuspendDelayRequest request_proto; |
| request_proto.set_delay_id(delay_id); |
| vector<uint8_t> serialized_request; |
| CHECK(SerializeProtocolBuffer(request_proto, &serialized_request)); |
| |
| try { |
| proxy_.UnregisterSuspendDelay(serialized_request); |
| return true; |
| } catch (const DBus::Error &e) { |
| LOG(ERROR) << "DBus exception: " << e.name() << ": " << e.what(); |
| return false; |
| } |
| } |
| |
| bool PowerManagerProxy::ReportSuspendReadiness(int delay_id, int suspend_id) { |
| LOG(INFO) << __func__ << "(" << delay_id << ", " << suspend_id << ")"; |
| |
| power_manager::SuspendReadinessInfo proto; |
| proto.set_delay_id(delay_id); |
| proto.set_suspend_id(suspend_id); |
| vector<uint8_t> serialized_proto; |
| CHECK(SerializeProtocolBuffer(proto, &serialized_proto)); |
| |
| try { |
| proxy_.HandleSuspendReadiness(serialized_proto); |
| return true; |
| } catch (const DBus::Error &e) { |
| LOG(ERROR) << "DBus exception: " << e.name() << ": " << e.what(); |
| return false; |
| } |
| } |
| |
| PowerManagerProxy::Proxy::Proxy(PowerManagerProxyDelegate *delegate, |
| DBus::Connection *connection) |
| : DBus::ObjectProxy(*connection, |
| power_manager::kPowerManagerServicePath, |
| power_manager::kPowerManagerServiceName), |
| delegate_(delegate) {} |
| |
| PowerManagerProxy::Proxy::~Proxy() {} |
| |
| void PowerManagerProxy::Proxy::SuspendImminent( |
| const vector<uint8_t> &serialized_proto) { |
| LOG(INFO) << __func__; |
| |
| power_manager::SuspendImminent proto; |
| if (!DeserializeProtocolBuffer(serialized_proto, &proto)) { |
| LOG(ERROR) << "Failed to parse SuspendImminent signal."; |
| return; |
| } |
| delegate_->OnSuspendImminent(proto.suspend_id()); |
| } |
| |
| void PowerManagerProxy::Proxy::PowerStateChanged( |
| const string &new_power_state) { |
| LOG(INFO) << __func__ << "(" << new_power_state << ")"; |
| |
| PowerManagerProxyDelegate::SuspendState suspend_state; |
| if (new_power_state == "on") { |
| suspend_state = PowerManagerProxyDelegate::kOn; |
| } else if (new_power_state == "standby") { |
| suspend_state = PowerManagerProxyDelegate::kStandby; |
| } else if (new_power_state == "mem") { |
| suspend_state = PowerManagerProxyDelegate::kMem; |
| } else if (new_power_state == "disk") { |
| suspend_state = PowerManagerProxyDelegate::kDisk; |
| } else { |
| suspend_state = PowerManagerProxyDelegate::kUnknown; |
| } |
| delegate_->OnPowerStateChanged(suspend_state); |
| } |
| |
| } // namespace shill |