Loading cmds/bootanimation/Android.mk +3 −2 Original line number Diff line number Diff line Loading @@ -31,12 +31,13 @@ LOCAL_SHARED_LIBRARIES += \ LOCAL_SRC_FILES += \ iot/iotbootanimation_main.cpp \ iot/BootAction.cpp iot/BootAction.cpp \ iot/BootParameters.cpp \ LOCAL_SHARED_LIBRARIES += \ libandroidthings \ libbase \ libbinder libbinder \ LOCAL_STATIC_LIBRARIES += cpufeatures Loading cmds/bootanimation/iot/BootAction.cpp +2 −99 Original line number Diff line number Diff line Loading @@ -19,96 +19,20 @@ #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 <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) { bool BootAction::init(const std::string& libraryPath, const std::vector<ABootActionParameter>& parameters) { APeripheralManagerClient* client = nullptr; ALOGD("Connecting to peripheralmanager"); // Wait for peripheral manager to come up. Loading @@ -122,27 +46,6 @@ bool BootAction::init(const std::string& libraryPath) { ALOGD("Peripheralmanager is up."); APeripheralManagerClient_delete(client); float brightness = -1.0f; float volume = -1.0f; std::vector<ABootActionParameter> 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); Loading cmds/bootanimation/iot/BootAction.h +3 −20 Original line number Diff line number Diff line Loading @@ -17,38 +17,21 @@ #ifndef _BOOTANIMATION_BOOTACTION_H #define _BOOTANIMATION_BOOTACTION_H #include <map> #include <string> #include <vector> #include <base/json/json_value_converter.h> #include <boot_action/boot_action.h> // libandroidthings native API. #include <utils/RefBase.h> using base::JSONValueConverter; namespace android { class BootAction : public RefBase { public: 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); bool init(const std::string& libraryPath, const std::vector<ABootActionParameter>& parameters); // The animation is going to start playing partNumber for the playCount'th // time, update the action as needed. Loading cmds/bootanimation/iot/BootParameters.cpp 0 → 100644 +124 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "BootParameters.h" #define LOG_TAG "BootParameters" #include <fcntl.h> #include <string> #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; 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; constexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json"; constexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json"; void 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 writable to everyone so DeviceManagementService // can save saved_parameters there. if (fchmod(fd, DEFFILEMODE)) ALOGE("Unable to set next boot file permissions: %s", strerror(errno)); close(fd); } } } // 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() { std::string contents; if (!ReadFileToString(kLastBootFile, &contents)) { if (errno != ENOENT) ALOGE("Unable to read from %s: %s", kLastBootFile, strerror(errno)); return; } std::unique_ptr<Value> json = JSONReader::Read(contents); 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"); } } } } // namespace android cmds/bootanimation/iot/BootParameters.h 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _BOOTANIMATION_BOOT_PARAMETERS_H_ #define _BOOTANIMATION_BOOT_PARAMETERS_H_ #include <list> #include <vector> #include <base/json/json_value_converter.h> #include <boot_action/boot_action.h> // libandroidthings native API. namespace android { // Provides access to the parameters set by DeviceManager.reboot(). class BootParameters { public: // Constructor loads the parameters for this boot and swaps the param files // to clear the parameters for next boot. BootParameters(); // Returns true if volume/brightness were explicitly set on reboot. bool hasVolume() const { return mVolume >= 0; } bool hasBrightness() const { return mBrightness >= 0; } // Returns volume/brightness in [0,1], or -1 if unset. float getVolume() const { return mVolume; } float getBrightness() const { return mBrightness; } // Returns the additional boot parameters that were set on reboot. const std::vector<ABootActionParameter>& getParameters() const { return mParameters; } private: // Raw boot saved_parameters loaded from .json. struct SavedBootParameters { int brightness; int volume; ScopedVector<std::string> param_names; ScopedVector<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; }; } // namespace android #endif // _BOOTANIMATION_BOOT_PARAMETERS_H_ Loading
cmds/bootanimation/Android.mk +3 −2 Original line number Diff line number Diff line Loading @@ -31,12 +31,13 @@ LOCAL_SHARED_LIBRARIES += \ LOCAL_SRC_FILES += \ iot/iotbootanimation_main.cpp \ iot/BootAction.cpp iot/BootAction.cpp \ iot/BootParameters.cpp \ LOCAL_SHARED_LIBRARIES += \ libandroidthings \ libbase \ libbinder libbinder \ LOCAL_STATIC_LIBRARIES += cpufeatures Loading
cmds/bootanimation/iot/BootAction.cpp +2 −99 Original line number Diff line number Diff line Loading @@ -19,96 +19,20 @@ #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 <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) { bool BootAction::init(const std::string& libraryPath, const std::vector<ABootActionParameter>& parameters) { APeripheralManagerClient* client = nullptr; ALOGD("Connecting to peripheralmanager"); // Wait for peripheral manager to come up. Loading @@ -122,27 +46,6 @@ bool BootAction::init(const std::string& libraryPath) { ALOGD("Peripheralmanager is up."); APeripheralManagerClient_delete(client); float brightness = -1.0f; float volume = -1.0f; std::vector<ABootActionParameter> 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); Loading
cmds/bootanimation/iot/BootAction.h +3 −20 Original line number Diff line number Diff line Loading @@ -17,38 +17,21 @@ #ifndef _BOOTANIMATION_BOOTACTION_H #define _BOOTANIMATION_BOOTACTION_H #include <map> #include <string> #include <vector> #include <base/json/json_value_converter.h> #include <boot_action/boot_action.h> // libandroidthings native API. #include <utils/RefBase.h> using base::JSONValueConverter; namespace android { class BootAction : public RefBase { public: 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); bool init(const std::string& libraryPath, const std::vector<ABootActionParameter>& parameters); // The animation is going to start playing partNumber for the playCount'th // time, update the action as needed. Loading
cmds/bootanimation/iot/BootParameters.cpp 0 → 100644 +124 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "BootParameters.h" #define LOG_TAG "BootParameters" #include <fcntl.h> #include <string> #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; 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; constexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json"; constexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json"; void 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 writable to everyone so DeviceManagementService // can save saved_parameters there. if (fchmod(fd, DEFFILEMODE)) ALOGE("Unable to set next boot file permissions: %s", strerror(errno)); close(fd); } } } // 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() { std::string contents; if (!ReadFileToString(kLastBootFile, &contents)) { if (errno != ENOENT) ALOGE("Unable to read from %s: %s", kLastBootFile, strerror(errno)); return; } std::unique_ptr<Value> json = JSONReader::Read(contents); 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"); } } } } // namespace android
cmds/bootanimation/iot/BootParameters.h 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _BOOTANIMATION_BOOT_PARAMETERS_H_ #define _BOOTANIMATION_BOOT_PARAMETERS_H_ #include <list> #include <vector> #include <base/json/json_value_converter.h> #include <boot_action/boot_action.h> // libandroidthings native API. namespace android { // Provides access to the parameters set by DeviceManager.reboot(). class BootParameters { public: // Constructor loads the parameters for this boot and swaps the param files // to clear the parameters for next boot. BootParameters(); // Returns true if volume/brightness were explicitly set on reboot. bool hasVolume() const { return mVolume >= 0; } bool hasBrightness() const { return mBrightness >= 0; } // Returns volume/brightness in [0,1], or -1 if unset. float getVolume() const { return mVolume; } float getBrightness() const { return mBrightness; } // Returns the additional boot parameters that were set on reboot. const std::vector<ABootActionParameter>& getParameters() const { return mParameters; } private: // Raw boot saved_parameters loaded from .json. struct SavedBootParameters { int brightness; int volume; ScopedVector<std::string> param_names; ScopedVector<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; }; } // namespace android #endif // _BOOTANIMATION_BOOT_PARAMETERS_H_