power: Support max-level-dependent initial brightness.
To make it possible to use a single image in conjunction
with different backlight hardware, extend the format of
powerd's internal_backlight_no_als_ac_brightness and
internal_backlight_no_als_battery_brightness prefs to
support defining multiple initial brightness percentages.
For example, using:
60.0 250
50.0 500
indicates that 60% should be used when the backlight's
maximum brightness level is reported as 250, while 50%
should be used for 500.
Note that the former single-percentage format is still
allowed (and should be used in almost all cases).
Also note that when defining multiple percentages, all
possible maximum levels must be supplied.
BUG=chrome-os-partner:28715
TEST=added unit tests; manually checked that powerd starts
up happily on lumpy
Change-Id: Icfb901c91ca7b25ee36a1c5d1f2d6aa5875fcae0
Reviewed-on: https://chromium-review.googlesource.com/199159
Commit-Queue: Daniel Erat <derat@chromium.org>
Tested-by: Daniel Erat <derat@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/common/power_constants.h b/common/power_constants.h
index 17b38e6..f0667ee 100644
--- a/common/power_constants.h
+++ b/common/power_constants.h
@@ -66,7 +66,8 @@
extern const char kInternalBacklightAlsStepsPref[];
// Starting internal backlight brightness while on line and battery power for
-// systems lacking an ambient light sensor.
+// systems lacking an ambient light sensor. See
+// powerd/policy/internal_backlight_controller.cc for details.
extern const char kInternalBacklightNoAlsAcBrightnessPref[];
extern const char kInternalBacklightNoAlsBatteryBrightnessPref[];
diff --git a/powerd/policy/internal_backlight_controller.cc b/powerd/policy/internal_backlight_controller.cc
index 8e53f13..ece4ab8 100644
--- a/powerd/policy/internal_backlight_controller.cc
+++ b/powerd/policy/internal_backlight_controller.cc
@@ -11,6 +11,8 @@
#include <string>
#include <base/logging.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
@@ -74,6 +76,62 @@
std::max(InternalBacklightController::kMinVisiblePercent, percent));
}
+// Reads |pref_name| from |prefs| and returns the desired initial brightness
+// percent corresponding to |max_brightness_level|, the backlight's actual
+// maximum brightness. Crashes on failure.
+//
+// The pref's value should consist of one or more lines, each containing either
+// a single double brightness percentage or a space-separated "<double-percent>
+// <int64-max-level>" pair. The percentage from the first line either using the
+// single-value format or matching |max_brightness_level| will be returned.
+//
+// For example,
+//
+// 60.0 300
+// 50.0 400
+//
+// indicates that 60% should be used if the maximum brightness level is 300,
+// while 50% should be used if it's 400.
+//
+// Note that when using the two-value format, all possible maximum levels for
+// the current system must be covered by the pref.
+double GetInitialBrightnessPercent(PrefsInterface* prefs,
+ const std::string& pref_name,
+ int64 max_brightness_level) {
+ DCHECK(prefs);
+ std::string pref_value;
+ CHECK(prefs->GetString(pref_name, &pref_value))
+ << "Unable to read pref " << pref_name;
+
+ std::vector<std::string> lines;
+ base::SplitString(pref_value, '\n', &lines);
+ for (size_t i = 0; i < lines.size(); ++i) {
+ std::vector<std::string> parts;
+ base::SplitStringAlongWhitespace(lines[i], &parts);
+ CHECK(parts.size() == 1U || parts.size() == 2U)
+ << "Unable to parse \"" << lines[i] << "\" from pref " << pref_name;
+
+ double percent = 0.0;
+ CHECK(base::StringToDouble(parts[0], &percent) &&
+ percent >= 0.0 && percent <= 100.0)
+ << "Unable to parse \"" << parts[0] << "\" from pref " << pref_name
+ << " as double in [0.0, 100.0]";
+
+ int64 max_level = -1;
+ CHECK(parts.size() == 1U ||
+ (base::StringToInt64(parts[1], &max_level) && max_level > 0))
+ << "Unable to parse \"" << parts[1] << "\" from pref " << pref_name;
+
+ if (max_level < 0 || max_level == max_brightness_level)
+ return percent;
+ }
+
+ LOG(FATAL) << "Unable to find initial brightness level in pref "
+ << pref_name << " for max brightness level "
+ << max_brightness_level;
+ return kMaxPercent;
+}
+
} // namespace
const int64 InternalBacklightController::kMaxBrightnessSteps = 16;
@@ -138,12 +196,10 @@
const double initial_percent = LevelToPercent(current_level_);
ambient_light_brightness_percent_ = initial_percent;
- plugged_explicit_brightness_percent_ = initial_percent;
- unplugged_explicit_brightness_percent_ = initial_percent;
- prefs_->GetDouble(kInternalBacklightNoAlsAcBrightnessPref,
- &plugged_explicit_brightness_percent_);
- prefs_->GetDouble(kInternalBacklightNoAlsBatteryBrightnessPref,
- &unplugged_explicit_brightness_percent_);
+ plugged_explicit_brightness_percent_ = GetInitialBrightnessPercent(
+ prefs_, kInternalBacklightNoAlsAcBrightnessPref, max_level_);
+ unplugged_explicit_brightness_percent_ = GetInitialBrightnessPercent(
+ prefs_, kInternalBacklightNoAlsBatteryBrightnessPref, max_level_);
prefs_->GetBool(kInstantTransitionsBelowMinLevelPref,
&instant_transitions_below_min_level_);
diff --git a/powerd/policy/internal_backlight_controller_unittest.cc b/powerd/policy/internal_backlight_controller_unittest.cc
index 1e21714..ef167e7 100644
--- a/powerd/policy/internal_backlight_controller_unittest.cc
+++ b/powerd/policy/internal_backlight_controller_unittest.cc
@@ -40,8 +40,8 @@
report_initial_power_source_(true),
default_min_visible_level_(1),
default_als_steps_("50.0 -1 400\n90.0 100 -1"),
- default_no_als_ac_brightness_(80.0),
- default_no_als_battery_brightness_(60.0),
+ default_no_als_ac_brightness_("80.0"),
+ default_no_als_battery_brightness_("60.0"),
backlight_(max_backlight_level_, initial_backlight_level_),
light_sensor_(initial_als_lux_) {
}
@@ -52,9 +52,9 @@
virtual void Init(PowerSource power_source) {
prefs_.SetInt64(kMinVisibleBacklightLevelPref, default_min_visible_level_);
prefs_.SetString(kInternalBacklightAlsStepsPref, default_als_steps_);
- prefs_.SetDouble(kInternalBacklightNoAlsAcBrightnessPref,
+ prefs_.SetString(kInternalBacklightNoAlsAcBrightnessPref,
default_no_als_ac_brightness_);
- prefs_.SetDouble(kInternalBacklightNoAlsBatteryBrightnessPref,
+ prefs_.SetString(kInternalBacklightNoAlsBatteryBrightnessPref,
default_no_als_battery_brightness_);
backlight_.set_max_level(max_backlight_level_);
backlight_.set_current_level(initial_backlight_level_);
@@ -102,8 +102,8 @@
// Default values for prefs. Applied when Init() is called.
int64 default_min_visible_level_;
std::string default_als_steps_;
- double default_no_als_ac_brightness_;
- double default_no_als_battery_brightness_;
+ std::string default_no_als_ac_brightness_;
+ std::string default_no_als_battery_brightness_;
FakePrefs prefs_;
system::BacklightStub backlight_;
@@ -547,20 +547,40 @@
pass_light_sensor_ = false;
report_initial_power_source_ = false;
report_initial_als_reading_ = false;
- default_no_als_ac_brightness_ = 95.0;
- default_no_als_battery_brightness_ = 75.0;
+ default_no_als_ac_brightness_ = "95.0";
+ default_no_als_battery_brightness_ = "75.0";
Init(POWER_AC);
EXPECT_EQ(initial_backlight_level_, backlight_.current_level());
// The brightness percentages from the "no ALS" prefs should be used as
// starting points when there's no ALS.
controller_->HandlePowerSourceChange(POWER_AC);
- EXPECT_EQ(PercentToLevel(default_no_als_ac_brightness_),
- backlight_.current_level());
+ EXPECT_EQ(PercentToLevel(95.0), backlight_.current_level());
controller_->HandlePowerSourceChange(POWER_BATTERY);
- EXPECT_EQ(PercentToLevel(default_no_als_battery_brightness_),
- backlight_.current_level());
+ EXPECT_EQ(PercentToLevel(75.0), backlight_.current_level());
+}
+
+TEST_F(InternalBacklightControllerTest, NoAmbientLightSensorMultipleDefaults) {
+ // Test that different default brightness percentages can be specified for
+ // different maximum brightness levels (http://crosbug.com/p/28715).
+ pass_light_sensor_ = false;
+ report_initial_power_source_ = false;
+ report_initial_als_reading_ = false;
+ max_backlight_level_ = 400;
+ default_no_als_ac_brightness_ = "40.0 300\n50.0 400";
+ default_no_als_battery_brightness_ = "20.0 400\n30.0 300";
+ Init(POWER_AC);
+ EXPECT_EQ(initial_backlight_level_, backlight_.current_level());
+
+ // The default percentages corresponding to a maximum level of 400 should be
+ // used on both AC and battery.
+ controller_->HandlePowerSourceChange(POWER_AC);
+ EXPECT_EQ(PercentToLevel(50.0), backlight_.current_level());
+
+ controller_->HandlePowerSourceChange(POWER_BATTERY);
+ EXPECT_EQ(PercentToLevel(20.0), backlight_.current_level());
+
}
TEST_F(InternalBacklightControllerTest, ForceBacklightOn) {