blob: ae53dc1732420e116b565ce3662e984412b05713 [file] [log] [blame]
// 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 "power_manager/proto_bindings/suspend.pb.h"
#include "shill/logging.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,
const string &description,
int *delay_id_out) {
return RegisterSuspendDelayInternal(false,
timeout,
description,
delay_id_out);
}
bool PowerManagerProxy::UnregisterSuspendDelay(int delay_id) {
return UnregisterSuspendDelayInternal(false, delay_id);
}
bool PowerManagerProxy::ReportSuspendReadiness(int delay_id, int suspend_id) {
return ReportSuspendReadinessInternal(false, delay_id, suspend_id);
}
bool PowerManagerProxy::RegisterDarkSuspendDelay(
base::TimeDelta timeout,
const string &description,
int *delay_id_out) {
return RegisterSuspendDelayInternal(true,
timeout,
description,
delay_id_out);
}
bool PowerManagerProxy::UnregisterDarkSuspendDelay(int delay_id) {
return UnregisterSuspendDelayInternal(true, delay_id);
}
bool PowerManagerProxy::ReportDarkSuspendReadiness(int delay_id,
int suspend_id ) {
return ReportSuspendReadinessInternal(true, delay_id, suspend_id);
}
bool PowerManagerProxy::RegisterSuspendDelayInternal(
bool is_dark,
base::TimeDelta timeout,
const string &description,
int *delay_id_out) {
const string is_dark_arg = (is_dark ? "dark=true" : "dark=false");
LOG(INFO) << __func__ << "(" << timeout.InMilliseconds()
<< ", " << is_dark_arg <<")";
power_manager::RegisterSuspendDelayRequest request_proto;
request_proto.set_timeout(timeout.ToInternalValue());
request_proto.set_description(description);
vector<uint8_t> serialized_request;
CHECK(SerializeProtocolBuffer(request_proto, &serialized_request));
vector<uint8_t> serialized_reply;
try {
if (is_dark)
serialized_reply = proxy_.RegisterDarkSuspendDelay(serialized_request);
else
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 "
<< (is_dark ? "dark " : "")
<< "suspend delay. Couldn't parse response.";
return false;
}
*delay_id_out = reply_proto.delay_id();
return true;
}
bool PowerManagerProxy::UnregisterSuspendDelayInternal(bool is_dark,
int delay_id) {
const string is_dark_arg = (is_dark ? "dark=true" : "dark=false");
LOG(INFO) << __func__ << "(" << delay_id << ", " << is_dark_arg << ")";
power_manager::UnregisterSuspendDelayRequest request_proto;
request_proto.set_delay_id(delay_id);
vector<uint8_t> serialized_request;
CHECK(SerializeProtocolBuffer(request_proto, &serialized_request));
try {
if (is_dark)
proxy_.UnregisterDarkSuspendDelay(serialized_request);
else
proxy_.UnregisterSuspendDelay(serialized_request);
} catch (const DBus::Error &e) {
LOG(ERROR) << "DBus exception: " << e.name() << ": " << e.what();
return false;
}
return true;
}
bool PowerManagerProxy::ReportSuspendReadinessInternal(bool is_dark,
int delay_id,
int suspend_id) {
const string is_dark_arg = (is_dark ? "dark=true" : "dark=false");
LOG(INFO) << __func__
<< "(" << delay_id
<< ", " << suspend_id
<< ", " << is_dark_arg << ")";
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 {
if (is_dark)
proxy_.HandleDarkSuspendReadiness(serialized_proto);
else
proxy_.HandleSuspendReadiness(serialized_proto);
} catch (const DBus::Error &e) {
LOG(ERROR) << "DBus exception: " << e.name() << ": " << e.what();
return false;
}
return true;
}
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::SuspendDone(
const vector<uint8_t> &serialized_proto) {
LOG(INFO) << __func__;
power_manager::SuspendDone proto;
if (!DeserializeProtocolBuffer(serialized_proto, &proto)) {
LOG(ERROR) << "Failed to parse SuspendDone signal.";
return;
}
delegate_->OnSuspendDone(proto.suspend_id());
}
void PowerManagerProxy::Proxy::DarkSuspendImminent(
const vector<uint8_t> &serialized_proto) {
LOG(INFO) << __func__;
power_manager::SuspendImminent proto;
if (!DeserializeProtocolBuffer(serialized_proto, &proto)) {
LOG(ERROR) << "Failed to parse DarkSuspendImminent signal.";
return;
}
delegate_->OnDarkSuspendImminent(proto.suspend_id());
}
} // namespace shill