blob: ba6b9c77e9b15fdf80bba6a297a8e7a1cd30c744 [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_loop.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
// power_manager::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 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(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::MessageLoopForIO message_loop;
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);
if (FLAGS_use_audio_activity >= 0)
policy.set_use_audio_activity(FLAGS_use_audio_activity != 0);
if (FLAGS_use_video_activity >= 0)
policy.set_use_video_activity(FLAGS_use_video_activity != 0);
if (FLAGS_ac_brightness_percent >= 0.0)
policy.set_ac_brightness_percent(FLAGS_ac_brightness_percent);
if (FLAGS_battery_brightness_percent >= 0.0)
policy.set_battery_brightness_percent(FLAGS_battery_brightness_percent);
if (FLAGS_presentation_screen_dim_delay_factor >= 1.0) {
policy.set_presentation_screen_dim_delay_factor(
FLAGS_presentation_screen_dim_delay_factor);
}
if (FLAGS_user_activity_screen_dim_delay_factor >= 1.0) {
policy.set_user_activity_screen_dim_delay_factor(
FLAGS_user_activity_screen_dim_delay_factor);
}
if (FLAGS_wait_for_initial_user_activity >= 0) {
policy.set_wait_for_initial_user_activity(
FLAGS_wait_for_initial_user_activity != 0);
}
if (FLAGS_force_nonzero_brightness_for_user_activity >= 0) {
policy.set_force_nonzero_brightness_for_user_activity(
FLAGS_force_nonzero_brightness_for_user_activity != 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;
}