Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dfaa9c5e authored by Mickey Keeley's avatar Mickey Keeley
Browse files

BootParameters: Use new JSON reader

* Update JSON blob that BootParameters reads from.
* Change JSON reader to allow custom keys.

Bug: 78524407
Test: Builds. Unit tests pass. End to end flow with RebootActivity
passes values as expected.

Change-Id: I2966f560de4aaf045125946c7fbe1becd47354be
parent 953f1093
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ LOCAL_SHARED_LIBRARIES += \
    libandroidthings \
    libchrome \

LOCAL_STATIC_LIBRARIES += \
    libjsoncpp

LOCAL_SRC_FILES += \
    iot/iotbootanimation_main.cpp \
    iot/BootAction.cpp \
+3 −0
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ LOCAL_SHARED_LIBRARIES := \
    libchrome \
    liblog \

LOCAL_STATIC_LIBRARIES += \
    libjsoncpp

LOCAL_SRC_FILES := \
    BootParameters.cpp \
    BootParameters_test.cpp \
+34 −44
Original line number Diff line number Diff line
@@ -18,29 +18,25 @@

#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";
@@ -69,19 +65,6 @@ void swapBootConfigs() {

}  // 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();
@@ -100,25 +83,32 @@ void BootParameters::loadParameters() {
}

void BootParameters::loadParameters(const std::string& raw_json) {
    std::unique_ptr<Value> json = JSONReader::Read(raw_json);
    if (json.get() == nullptr) {
  if (!Reader().parse(raw_json, mJson)) {
    return;
  }

    JSONValueConverter<SavedBootParameters> converter;
    if (converter.Convert(*(json.get()), &mRawParameters)) {
        mBrightness = mRawParameters.brightness / kFloatScaleFactor;
        mVolume = mRawParameters.volume / kFloatScaleFactor;
  // 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();
  }

        if (mRawParameters.param_names.size() == mRawParameters.param_values.size()) {
            for (size_t i = 0; i < mRawParameters.param_names.size(); i++) {
  jsonValue = mJson[kKeyParams];
  if (jsonValue.isObject()) {
    for (auto &key : jsonValue.getMemberNames()) {
      Value& value = jsonValue[key];
      if (value.isString()) {
        mParameters.push_back({
                        .key = mRawParameters.param_names[i]->c_str(),
                        .value = mRawParameters.param_values[i]->c_str()
          .key = key.c_str(),
          .value = value.asCString()
        });
      }
        } else {
            ALOGW("Parameter names and values size mismatch");
    }
  }
}
+3 −16
Original line number Diff line number Diff line
@@ -21,8 +21,8 @@
#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 {

@@ -47,27 +47,14 @@ public:
    // 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
+18 −12
Original line number Diff line number Diff line
@@ -26,10 +26,12 @@ TEST(BootParametersTest, TestParseValidParameters) {
  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"
      }
    }
  )");

@@ -46,14 +48,16 @@ TEST(BootParametersTest, TestParseValidParameters) {
  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"
      }
    }
  )");

@@ -63,14 +67,16 @@ TEST(BootParametersTest, TestMismatchedParameters) {
  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
    }
  )");