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

Commit b8c828f0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Pass saved parameters to boot action"

parents c3bae5c8 6dd64f3a
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -24,6 +24,11 @@ LOCAL_SRC_FILES:= \
    BootAnimationUtil.cpp \

ifeq ($(PRODUCT_IOT),true)

LOCAL_SHARED_LIBRARIES += libchrome

LOCAL_C_INCLUDES += external/libchrome

LOCAL_SRC_FILES += \
    iot/iotbootanimation_main.cpp \
    iot/BootAction.cpp
@@ -84,6 +89,12 @@ LOCAL_SHARED_LIBRARIES := \
    libtinyalsa \
    libbase

ifeq ($(PRODUCT_IOT),true)

LOCAL_INIT_RC := iot/bootanim_iot.rc

endif # PRODUCT_IOT

ifdef TARGET_32_BIT_SURFACEFLINGER
LOCAL_32_BIT_ONLY := true
endif
+95 −2
Original line number Diff line number Diff line
@@ -18,25 +18,96 @@

#define LOG_TAG "BootAction"

#include <dlfcn.h>
#include <fcntl.h>

#include <map>

#include <android-base/file.h>
#include <android-base/strings.h>
#include <base/json/json_parser.h>
#include <base/json/json_value_converter.h>
#include <cpu-features.h>
#include <dlfcn.h>
#include <pio/peripheral_manager_client.h>
#include <utils/Log.h>

using android::base::ReadFileToString;
using android::base::RemoveFileIfExists;
using android::base::Split;
using android::base::Join;
using android::base::StartsWith;
using android::base::EndsWith;
using base::JSONReader;
using base::Value;

namespace android {

// 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;

constexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json";
constexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json";

bool loadParameters(BootAction::SavedBootParameters* parameters)
{
    std::string contents;
    if (!ReadFileToString(kLastBootFile, &contents)) {
        if (errno != ENOENT)
            ALOGE("Unable to read from %s: %s", kLastBootFile, strerror(errno));

        return false;
    }

    std::unique_ptr<Value> json = JSONReader::Read(contents);
    if (json.get() == nullptr) return false;

    JSONValueConverter<BootAction::SavedBootParameters> converter;
    if (!converter.Convert(*(json.get()), parameters)) return false;

    return true;
}

void BootAction::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);
}

BootAction::~BootAction() {
    if (mLibHandle != nullptr) {
        dlclose(mLibHandle);
    }
}

void BootAction::swapBootConfigs() {
    // rename() will fail if next_boot.json doesn't exist, so delete
    // last_boot.json manually first.
    std::string err;
    if (!RemoveFileIfExists(kLastBootFile, &err))
        ALOGE("Unable to delete last boot file: %s", err.c_str());

    if (rename(kNextBootFile, kLastBootFile) && errno != ENOENT)
        ALOGE("Unable to swap boot files: %s", strerror(errno));

    int fd = open(kNextBootFile, O_CREAT, DEFFILEMODE);
    if (fd == -1) {
        ALOGE("Unable to create next boot file: %s", strerror(errno));
    } else {
        // Make next_boot.json writible to everyone so DeviceManagementService
        // can save parameters there.
        if (fchmod(fd, DEFFILEMODE))
            ALOGE("Unable to set next boot file permissions: %s", strerror(errno));
        close(fd);
    }
}

bool BootAction::init(const std::string& libraryPath) {
    APeripheralManagerClient* client = nullptr;
    ALOGD("Connecting to peripheralmanager");
@@ -51,6 +122,28 @@ bool BootAction::init(const std::string& libraryPath) {
    ALOGD("Peripheralmanager is up.");
    APeripheralManagerClient_delete(client);

    float brightness = -1.0f;
    float volume = -1.0f;
    std::vector<BootParameter> parameters;
    SavedBootParameters saved_parameters;

    if (loadParameters(&saved_parameters)) {
        // TODO(b/65462981): Do something with brightness and volume?
        brightness = saved_parameters.brightness / kFloatScaleFactor;
        volume = saved_parameters.volume / kFloatScaleFactor;

        if (saved_parameters.param_names.size() == saved_parameters.param_values.size()) {
            for (size_t i = 0; i < saved_parameters.param_names.size(); i++) {
                parameters.push_back({
                        .key = saved_parameters.param_names[i]->c_str(),
                        .value = saved_parameters.param_values[i]->c_str()
                });
            }
        } else {
            ALOGW("Parameter names and values size mismatch");
        }
    }

    ALOGI("Loading boot action %s", libraryPath.c_str());
    mLibHandle = dlopen(libraryPath.c_str(), RTLD_NOW);
    if (mLibHandle == nullptr) {
@@ -82,7 +175,7 @@ bool BootAction::init(const std::string& libraryPath) {
    }

    ALOGD("Entering boot_action_init");
    bool result = mLibInit();
    bool result = mLibInit(parameters.data(), parameters.size());
    ALOGD("Returned from boot_action_init");
    return result;
}
+25 −1
Original line number Diff line number Diff line
@@ -17,16 +17,40 @@
#ifndef _BOOTANIMATION_BOOTACTION_H
#define _BOOTANIMATION_BOOTACTION_H

#include <map>
#include <string>

#include <base/json/json_value_converter.h>
#include <utils/RefBase.h>

using base::JSONValueConverter;

namespace android {

class BootAction : public RefBase {
public:
    struct BootParameter {
      const char* key;
      const char* value;
    };

    struct SavedBootParameters {
      int brightness;
      int volume;
      ScopedVector<std::string> param_names;
      ScopedVector<std::string> param_values;
      static void RegisterJSONConverter(
          JSONValueConverter<SavedBootParameters>* converter);
    };

    ~BootAction();

    // Rename next_boot.json to last_boot.json so that we don't repeat
    // parameters if there is a crash before the framework comes up.
    // TODO(b/65462981): Is this what we want to do? Should we swap in the
    // framework instead?
    static void swapBootConfigs();

    // libraryPath is a fully qualified path to the target .so library.
    bool init(const std::string& libraryPath);

@@ -41,7 +65,7 @@ public:
    void shutdown();

private:
    typedef bool (*libInit)();
    typedef bool (*libInit)(const BootParameter* parameters, size_t num_parameters);
    typedef void (*libStartPart)(int partNumber, int playNumber);
    typedef void (*libShutdown)();

+2 −0
Original line number Diff line number Diff line
on post-fs-data
    mkdir /data/misc/bootanimation 0777 root root
+4 −0
Original line number Diff line number Diff line
@@ -80,6 +80,10 @@ private:
int main() {
    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);

    // TODO(b/65462981): Should we set brightness/volume here in case the boot
    // animation is disabled?
    BootAction::swapBootConfigs();

    if (bootAnimationDisabled()) {
        ALOGI("boot animation disabled");
        return 0;