blob: 8c712f3316b1653205db2f04a508d3dde156d0b6 [file] [log] [blame]
// Copyright (c) 2013 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.
// This program can be used to send a message to powerd to configure the
// power management policy. This is the same mechanism used by Chrome; in
// fact, it will overwrite any policy set by Chrome. To revert to powerd's
// default policy, run it without any arguments.
#include <memory>
#include <base/at_exit.h>
#include <base/command_line.h>
#include <base/logging.h>
#include <base/message_loop/message_pump_type.h>
#include <base/task/single_thread_task_executor.h>
#include <brillo/flag_helper.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>
#include "power_manager/proto_bindings/policy.pb.h"
namespace {
const int kMsInSec = 1000;
// Given a command-line flag containing a duration in seconds, a
// PowerManagementPolicy::Delays* |submessage|, and the name of a milliseconds
// field in |submessage|, sets the field if the flag is greater than or equal to
// 0.
#define SET_DELAY_FIELD(flag, submessage, field) \
if (flag >= 0) { \
submessage->set_##field(flag* kMsInSec); \
}
// Given |name| (a string) and |proto| (a PowerManagementPolicy), sets |proto|'s
// |name| bool field to true if |FLAGS_<name>| is positive or to false if it's
// zero, leaving it unset if it's negative.
#define SET_BOOL_FIELD(name, proto) \
if (FLAGS_##name >= 0) { \
proto.set_##name(FLAGS_##name != 0); \
}
// Given |name| (a string), |proto| (a PowerManagementPolicy), and |min| (a
// double), sets |proto|'s |name| double field to |FLAGS_<name>| if
// |FLAGS_<name>| is >= |min|, leaving it unset otherwise.
#define SET_DOUBLE_FIELD(name, proto, min) \
if (FLAGS_##name >= min) { \
proto.set_##name(FLAGS_##name); \
}
// Given a string from a flag describing an action, returns the
// corresponding value from power_manager::PowerManagementPolicy_Action.
power_manager::PowerManagementPolicy_Action GetAction(
const std::string& action) {
if (action == "suspend")
return power_manager::PowerManagementPolicy_Action_SUSPEND;
else if (action == "stop_session")
return power_manager::PowerManagementPolicy_Action_STOP_SESSION;
else if (action == "shut_down")
return power_manager::PowerManagementPolicy_Action_SHUT_DOWN;
else if (action == "do_nothing")
return power_manager::PowerManagementPolicy_Action_DO_NOTHING;
else
LOG(FATAL) << "Invalid action \"" << action << "\"";
return power_manager::PowerManagementPolicy_Action_DO_NOTHING;
}
} // namespace
int main(int argc, char* argv[]) {
// These mirror the fields from the PowerManagementPolicy protocol buffer.
DEFINE_string(ac_idle_action, "",
"Action to perform when idle on AC power (one of "
"suspend, stop_session, shut_down, do_nothing)");
DEFINE_string(battery_idle_action, "",
"Action to perform when idle on battery power (one of "
"suspend, stop_session, shut_down, do_nothing)");
DEFINE_string(lid_closed_action, "",
"Action to perform when lid is closed (one of "
"suspend, stop_session, shut_down, do_nothing)");
DEFINE_int32(ac_screen_dim_delay, -1,
"Delay before dimming screen on AC power, in seconds");
DEFINE_int32(ac_screen_off_delay, -1,
"Delay before turning screen off on AC power, in seconds");
DEFINE_int32(ac_screen_lock_delay, -1,
"Delay before locking screen on AC power, in seconds");
DEFINE_int32(ac_idle_warning_delay, -1,
"Delay before idle action warning on AC power, in seconds");
DEFINE_int32(ac_idle_delay, -1,
"Delay before idle action on AC power, in seconds");
DEFINE_int32(battery_screen_dim_delay, -1,
"Delay before dimming screen on battery power, in seconds");
DEFINE_int32(battery_screen_off_delay, -1,
"Delay before turning screen off on battery power, in seconds");
DEFINE_int32(battery_screen_lock_delay, -1,
"Delay before locking screen on battery power, in seconds");
DEFINE_int32(battery_idle_warning_delay, -1,
"Delay before idle action warning on battery power, in seconds");
DEFINE_int32(battery_idle_delay, -1,
"Delay before idle action on battery power, in seconds");
DEFINE_int32(dim_wake_lock, -1,
"Report dim wake lock (1 is true, 0 is false, -1 is unset");
DEFINE_int32(screen_wake_lock, -1,
"Report screen wake lock (1 is true, 0 is false, -1 is unset");
DEFINE_int32(system_wake_lock, -1,
"Report system wake lock (1 is true, 0 is false, -1 is unset");
DEFINE_int32(use_audio_activity, -1,
"Honor audio activity (1 is true, 0 is false, -1 is unset");
DEFINE_int32(use_video_activity, -1,
"Honor video activity (1 is true, 0 is false, -1 is unset");
DEFINE_int32(wait_for_initial_user_activity, -1,
"Wait for initial user activity before enforcing delays "
"(1 is true, 0 is false, -1 is unset");
DEFINE_int32(force_nonzero_brightness_for_user_activity, -1,
"Force panel backlight to non-zero brightness for user activity "
"(1 is true, 0 is false, -1 is unset");
DEFINE_double(ac_brightness_percent, -1.0,
"Brightness percent to use while on AC power (less than 0.0 "
"means unset)");
DEFINE_double(battery_brightness_percent, -1.0,
"Brightness percent to use while on battery power (less than "
"0.0 means unset)");
DEFINE_double(presentation_screen_dim_delay_factor, 0.0,
"Factor by which the screen-dim delay is scaled while "
"presenting (less than 1.0 means unset)");
DEFINE_double(user_activity_screen_dim_delay_factor, 0.0,
"Factor by which the screen-dim delay is scaled if user "
"activity is observed while the screen is dimmed or soon after "
"it's been turned off (less than 1.0 means unset)");
brillo::FlagHelper::Init(
argc, argv,
"Configures powerd's power management policy.\n\n"
"When called without any arguments, uses default settings.");
base::AtExitManager at_exit_manager;
base::SingleThreadTaskExecutor task_executor(base::MessagePumpType::IO);
power_manager::PowerManagementPolicy policy;
if (!FLAGS_ac_idle_action.empty())
policy.set_ac_idle_action(GetAction(FLAGS_ac_idle_action));
if (!FLAGS_battery_idle_action.empty())
policy.set_battery_idle_action(GetAction(FLAGS_battery_idle_action));
if (!FLAGS_lid_closed_action.empty())
policy.set_lid_closed_action(GetAction(FLAGS_lid_closed_action));
power_manager::PowerManagementPolicy::Delays* delays =
policy.mutable_ac_delays();
SET_DELAY_FIELD(FLAGS_ac_screen_dim_delay, delays, screen_dim_ms);
SET_DELAY_FIELD(FLAGS_ac_screen_off_delay, delays, screen_off_ms);
SET_DELAY_FIELD(FLAGS_ac_screen_lock_delay, delays, screen_lock_ms);
SET_DELAY_FIELD(FLAGS_ac_idle_warning_delay, delays, idle_warning_ms);
SET_DELAY_FIELD(FLAGS_ac_idle_delay, delays, idle_ms);
delays = policy.mutable_battery_delays();
SET_DELAY_FIELD(FLAGS_battery_screen_dim_delay, delays, screen_dim_ms);
SET_DELAY_FIELD(FLAGS_battery_screen_off_delay, delays, screen_off_ms);
SET_DELAY_FIELD(FLAGS_battery_screen_lock_delay, delays, screen_lock_ms);
SET_DELAY_FIELD(FLAGS_battery_idle_warning_delay, delays, idle_warning_ms);
SET_DELAY_FIELD(FLAGS_battery_idle_delay, delays, idle_ms);
SET_BOOL_FIELD(use_audio_activity, policy);
SET_BOOL_FIELD(use_video_activity, policy);
SET_BOOL_FIELD(wait_for_initial_user_activity, policy);
SET_BOOL_FIELD(force_nonzero_brightness_for_user_activity, policy);
SET_BOOL_FIELD(dim_wake_lock, policy);
SET_BOOL_FIELD(screen_wake_lock, policy);
SET_BOOL_FIELD(system_wake_lock, policy);
SET_DOUBLE_FIELD(ac_brightness_percent, policy, 0.0);
SET_DOUBLE_FIELD(battery_brightness_percent, policy, 0.0);
SET_DOUBLE_FIELD(presentation_screen_dim_delay_factor, policy, 1.0);
SET_DOUBLE_FIELD(user_activity_screen_dim_delay_factor, policy, 1.0);
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
CHECK(bus->Connect());
dbus::ObjectProxy* proxy = bus->GetObjectProxy(
power_manager::kPowerManagerServiceName,
dbus::ObjectPath(power_manager::kPowerManagerServicePath));
dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
power_manager::kSetPolicyMethod);
dbus::MessageWriter writer(&method_call);
writer.AppendProtoAsArrayOfBytes(policy);
std::unique_ptr<dbus::Response> response(proxy->CallMethodAndBlock(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
CHECK(response.get());
return 0;
}