#define LOG_TAG "BootParameters"
+#include <errno.h>
#include <fcntl.h>
#include <android-base/file.h>
-#include <base/json/json_parser.h>
-#include <base/json/json_reader.h>
-#include <base/json/json_value_converter.h>
#include <utils/Log.h>
using android::base::RemoveFileIfExists;
using android::base::ReadFileToString;
-using base::JSONReader;
-using base::JSONValueConverter;
-using base::Value;
+using Json::Reader;
+using Json::Value;
namespace android {
namespace {
-// Brightness and volume are stored as integer strings in next_boot.json.
-// They are divided by this constant to produce the actual float values in
-// range [0.0, 1.0]. This constant must match its counterpart in
-// DeviceManager.
-constexpr const float kFloatScaleFactor = 1000.0f;
+// Keys for volume, brightness, and user-defined parameters.
+constexpr const char* kKeyVolume = "volume";
+constexpr const char* kKeyBrightness = "brightness";
+constexpr const char* kKeyParams = "params";
constexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json";
constexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json";
} // namespace
-BootParameters::SavedBootParameters::SavedBootParameters()
- : brightness(-kFloatScaleFactor), volume(-kFloatScaleFactor) {}
-
-void BootParameters::SavedBootParameters::RegisterJSONConverter(
- JSONValueConverter<SavedBootParameters>* converter) {
- converter->RegisterIntField("brightness", &SavedBootParameters::brightness);
- converter->RegisterIntField("volume", &SavedBootParameters::volume);
- converter->RegisterRepeatedString("param_names",
- &SavedBootParameters::param_names);
- converter->RegisterRepeatedString("param_values",
- &SavedBootParameters::param_values);
-}
-
BootParameters::BootParameters() {
swapBootConfigs();
loadParameters();
}
void BootParameters::loadParameters(const std::string& raw_json) {
- std::unique_ptr<Value> json = JSONReader::Read(raw_json);
- if (json.get() == nullptr) {
- return;
- }
-
- JSONValueConverter<SavedBootParameters> converter;
- if (converter.Convert(*(json.get()), &mRawParameters)) {
- mBrightness = mRawParameters.brightness / kFloatScaleFactor;
- mVolume = mRawParameters.volume / kFloatScaleFactor;
-
- if (mRawParameters.param_names.size() == mRawParameters.param_values.size()) {
- for (size_t i = 0; i < mRawParameters.param_names.size(); i++) {
- mParameters.push_back({
- .key = mRawParameters.param_names[i]->c_str(),
- .value = mRawParameters.param_values[i]->c_str()
- });
- }
- } else {
- ALOGW("Parameter names and values size mismatch");
- }
+ if (!Reader().parse(raw_json, mJson)) {
+ return;
+ }
+
+ // A missing key returns a safe, missing value.
+ // Ignore invalid or missing JSON parameters.
+ Value& jsonValue = mJson[kKeyVolume];
+ if (jsonValue.isDouble()) {
+ mVolume = jsonValue.asFloat();
+ }
+
+ jsonValue = mJson[kKeyBrightness];
+ if (jsonValue.isDouble()) {
+ mBrightness = jsonValue.asFloat();
+ }
+
+ jsonValue = mJson[kKeyParams];
+ if (jsonValue.isObject()) {
+ for (auto &key : jsonValue.getMemberNames()) {
+ Value& value = jsonValue[key];
+ if (value.isString()) {
+ mParameters.push_back({
+ .key = key.c_str(),
+ .value = value.asCString()
+ });
+ }
}
+ }
}
} // namespace android
#include <string>
#include <vector>
-#include <base/json/json_value_converter.h>
#include <boot_action/boot_action.h> // libandroidthings native API.
+#include <json/json.h>
namespace android {
// Exposed for testing. Updates the parameters with new JSON values.
void loadParameters(const std::string& raw_json);
private:
- // Raw boot saved_parameters loaded from .json.
- struct SavedBootParameters {
- int brightness;
- int volume;
- std::vector<std::unique_ptr<std::string>> param_names;
- std::vector<std::unique_ptr<std::string>> param_values;
-
- SavedBootParameters();
- static void RegisterJSONConverter(
- ::base::JSONValueConverter<SavedBootParameters>* converter);
- };
-
void loadParameters();
float mVolume = -1.f;
float mBrightness = -1.f;
std::vector<ABootActionParameter> mParameters;
- // ABootActionParameter is just a raw pointer so we need to keep the
- // original strings around to avoid losing them.
- SavedBootParameters mRawParameters;
+ // Store parsed JSON because mParameters makes a shallow copy.
+ Json::Value mJson;
};
} // namespace android
BootParameters boot_parameters = BootParameters();
boot_parameters.loadParameters(R"(
{
- "brightness":200,
- "volume":100,
- "param_names":["key1","key2"],
- "param_values":["value1","value2"]
+ "brightness":0.2,
+ "volume":0.1,
+ "params":{
+ "key1":"value1",
+ "key2":"value2"
+ }
}
)");
ASSERT_STREQ(parameters[1].value, "value2");
}
-TEST(BootParametersTest, TestMismatchedParameters) {
+TEST(BootParametersTest, TestMalformedParametersAreSkipped) {
BootParameters boot_parameters = BootParameters();
boot_parameters.loadParameters(R"(
{
- "brightness":500,
- "volume":500,
- "param_names":["key1","key2"],
- "param_values":["value1"]
+ "brightness":0.5,
+ "volume":0.5,
+ "params": {
+ "key1":1,
+ "key2":"value2"
+ }
}
)");
EXPECT_FLOAT_EQ(0.5f, boot_parameters.getVolume());
auto parameters = boot_parameters.getParameters();
- ASSERT_EQ(0u, parameters.size());
+ ASSERT_EQ(1u, parameters.size());
+ ASSERT_STREQ(parameters[0].key, "key2");
+ ASSERT_STREQ(parameters[0].value, "value2");
}
-TEST(BootParametersTest, TestMissingParameters) {
+TEST(BootParametersTest, TestMissingParametersHaveDefaults) {
BootParameters boot_parameters = BootParameters();
boot_parameters.loadParameters(R"(
{
- "brightness":500
+ "brightness":0.5
}
)");