Remove product_is_iot.
Test: treehugger Change-Id: I975f86999e4e40c06d6239fbc63e200042d37cc4
This commit is contained in:
@@ -40,27 +40,6 @@ cc_binary {
|
||||
"audioplay.cpp",
|
||||
],
|
||||
|
||||
product_variables: {
|
||||
product_is_iot: {
|
||||
shared_libs: [
|
||||
"libandroidthings",
|
||||
"libandroidthings_protos",
|
||||
"libchrome",
|
||||
"libprotobuf-cpp-lite",
|
||||
],
|
||||
static_libs: ["libjsoncpp"],
|
||||
srcs: [
|
||||
"iot/iotbootanimation_main.cpp",
|
||||
"iot/BootAction.cpp",
|
||||
"iot/BootParameters.cpp",
|
||||
],
|
||||
exclude_srcs: [
|
||||
"bootanimation_main.cpp",
|
||||
"audioplay.cpp",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
init_rc: ["bootanim.rc"],
|
||||
}
|
||||
|
||||
@@ -80,10 +59,4 @@ cc_library_shared {
|
||||
"libGLESv1_CM",
|
||||
"libgui",
|
||||
],
|
||||
|
||||
product_variables: {
|
||||
product_is_iot: {
|
||||
init_rc: ["iot/bootanim_iot.rc"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright (C) 2018 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.
|
||||
//
|
||||
|
||||
// libbootanimation_iot_test
|
||||
// ===========================================================
|
||||
cc_test {
|
||||
name: "libbootanimation_iot_test",
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wunused",
|
||||
"-Wunreachable-code",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libandroidthings",
|
||||
"libandroidthings_protos",
|
||||
"libbase",
|
||||
"libchrome",
|
||||
"liblog",
|
||||
"libprotobuf-cpp-lite",
|
||||
],
|
||||
|
||||
static_libs: ["libjsoncpp"],
|
||||
|
||||
srcs: [
|
||||
"BootParameters.cpp",
|
||||
"BootParameters_test.cpp",
|
||||
],
|
||||
|
||||
enabled: false,
|
||||
product_variables: {
|
||||
product_is_iot: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* 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 "BootAction.h"
|
||||
|
||||
#define LOG_TAG "BootAction"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <pio/peripheral_manager_client.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
BootAction::~BootAction() {
|
||||
if (mLibHandle != nullptr) {
|
||||
dlclose(mLibHandle);
|
||||
}
|
||||
}
|
||||
|
||||
bool BootAction::init(const std::string& libraryPath,
|
||||
const std::unique_ptr<BootParameters>& bootParameters) {
|
||||
APeripheralManagerClient* client = nullptr;
|
||||
ALOGD("Connecting to peripheralmanager");
|
||||
// Wait for peripheral manager to come up.
|
||||
while (client == nullptr) {
|
||||
client = APeripheralManagerClient_new();
|
||||
if (client == nullptr) {
|
||||
ALOGV("peripheralmanager is not up, sleeping before we check again.");
|
||||
usleep(250000);
|
||||
}
|
||||
}
|
||||
ALOGD("Peripheralmanager is up.");
|
||||
APeripheralManagerClient_delete(client);
|
||||
|
||||
|
||||
ALOGI("Loading boot action %s", libraryPath.c_str());
|
||||
mLibHandle = dlopen(libraryPath.c_str(), RTLD_NOW);
|
||||
if (mLibHandle == nullptr) {
|
||||
ALOGE("Unable to load library at %s :: %s",
|
||||
libraryPath.c_str(), dlerror());
|
||||
return false;
|
||||
}
|
||||
|
||||
void* loaded = nullptr;
|
||||
if (!loadSymbol("boot_action_init", &loaded) || loaded == nullptr) {
|
||||
return false;
|
||||
}
|
||||
mLibInit = reinterpret_cast<libInit>(loaded);
|
||||
|
||||
loaded = nullptr;
|
||||
if (!loadSymbol("boot_action_shutdown", &loaded) || loaded == nullptr) {
|
||||
return false;
|
||||
}
|
||||
mLibShutdown = reinterpret_cast<libShutdown>(loaded);
|
||||
|
||||
// StartPart is considered optional, if it isn't exported by the library
|
||||
// we will still call init and shutdown.
|
||||
loaded = nullptr;
|
||||
if (!loadSymbol("boot_action_start_part", &loaded) || loaded == nullptr) {
|
||||
ALOGI("No boot_action_start_part found, action will not be told when "
|
||||
"Animation parts change.");
|
||||
} else {
|
||||
mLibStartPart = reinterpret_cast<libStartPart>(loaded);
|
||||
}
|
||||
|
||||
// SilentBoot is considered optional, if it isn't exported by the library
|
||||
// and the boot is silent, no method is called.
|
||||
loaded = nullptr;
|
||||
if (!loadSymbol("boot_action_silent_boot", &loaded) || loaded == nullptr) {
|
||||
ALOGW("No boot_action_silent_boot found, boot action will not be "
|
||||
"executed during a silent boot.");
|
||||
} else {
|
||||
mLibSilentBoot = reinterpret_cast<libInit>(loaded);
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
const auto& parameters = bootParameters->getParameters();
|
||||
if (bootParameters->isSilentBoot()) {
|
||||
if (mLibSilentBoot != nullptr) {
|
||||
ALOGD("Entering boot_action_silent_boot");
|
||||
result = mLibSilentBoot(parameters.data(), parameters.size());
|
||||
ALOGD("Returned from boot_action_silent_boot");
|
||||
} else {
|
||||
ALOGW("Skipping missing boot_action_silent_boot");
|
||||
}
|
||||
} else {
|
||||
ALOGD("Entering boot_action_init");
|
||||
result = mLibInit(parameters.data(), parameters.size());
|
||||
ALOGD("Returned from boot_action_init");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void BootAction::startPart(int partNumber, int playNumber) {
|
||||
if (mLibStartPart == nullptr) return;
|
||||
|
||||
ALOGD("Entering boot_action_start_part");
|
||||
mLibStartPart(partNumber, playNumber);
|
||||
ALOGD("Returned from boot_action_start_part");
|
||||
}
|
||||
|
||||
void BootAction::shutdown() {
|
||||
ALOGD("Entering boot_action_shutdown");
|
||||
mLibShutdown();
|
||||
ALOGD("Returned from boot_action_shutdown");
|
||||
}
|
||||
|
||||
bool BootAction::loadSymbol(const char* symbol, void** loaded) {
|
||||
*loaded = dlsym(mLibHandle, symbol);
|
||||
if (*loaded == nullptr) {
|
||||
ALOGE("Unable to load symbol : %s :: %s", symbol, dlerror());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* 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_BOOTACTION_H
|
||||
#define _BOOTANIMATION_BOOTACTION_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "BootParameters.h"
|
||||
|
||||
#include <boot_action/boot_action.h> // libandroidthings native API.
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class BootAction : public RefBase {
|
||||
public:
|
||||
~BootAction();
|
||||
|
||||
// libraryPath is a fully qualified path to the target .so library.
|
||||
bool init(const std::string& libraryPath,
|
||||
const std::unique_ptr<BootParameters>& bootParameters);
|
||||
|
||||
// The animation is going to start playing partNumber for the playCount'th
|
||||
// time, update the action as needed.
|
||||
// This is run in the same thread as the boot animation,
|
||||
// you must not block here.
|
||||
void startPart(int partNumber, int playCount);
|
||||
|
||||
// Shutdown the boot action, this will be called shortly before the
|
||||
// process is shut down to allow time for cleanup.
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
typedef bool (*libInit)(const ABootActionParameter* parameters,
|
||||
size_t numParameters);
|
||||
typedef void (*libStartPart)(int partNumber, int playNumber);
|
||||
typedef void (*libShutdown)();
|
||||
|
||||
bool loadSymbol(const char* symbol, void** loaded);
|
||||
|
||||
void* mLibHandle = nullptr;
|
||||
libInit mLibInit = nullptr;
|
||||
libStartPart mLibStartPart = nullptr;
|
||||
libShutdown mLibShutdown = nullptr;
|
||||
|
||||
// Called only if the boot is silent.
|
||||
libInit mLibSilentBoot = nullptr;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
|
||||
#endif // _BOOTANIMATION_BOOTACTION_H
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* 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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <json/json.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
using android::base::ReadFileToString;
|
||||
using android::base::RemoveFileIfExists;
|
||||
using android::base::WriteStringToFile;
|
||||
using Json::ArrayIndex;
|
||||
using Json::Reader;
|
||||
using Json::Value;
|
||||
|
||||
namespace android {
|
||||
|
||||
namespace {
|
||||
|
||||
// Keys for deprecated parameters. Devices that OTA from N to O and that used
|
||||
// the hidden BootParameters API will store these in the JSON blob. To support
|
||||
// the transition from N to O, these keys are mapped to the new parameters.
|
||||
constexpr const char *kKeyLegacyVolume = "volume";
|
||||
constexpr const char *kKeyLegacyAnimationsDisabled = "boot_animation_disabled";
|
||||
constexpr const char *kKeyLegacyParamNames = "param_names";
|
||||
constexpr const char *kKeyLegacyParamValues = "param_values";
|
||||
|
||||
constexpr const char *kNextBootFile = "/data/misc/bootanimation/next_boot.proto";
|
||||
constexpr const char *kLastBootFile = "/data/misc/bootanimation/last_boot.proto";
|
||||
|
||||
constexpr const char *kLegacyNextBootFile = "/data/misc/bootanimation/next_boot.json";
|
||||
constexpr const char *kLegacyLastBootFile = "/data/misc/bootanimation/last_boot.json";
|
||||
|
||||
void removeLegacyFiles() {
|
||||
std::string err;
|
||||
if (!RemoveFileIfExists(kLegacyLastBootFile, &err)) {
|
||||
ALOGW("Unable to delete %s: %s", kLegacyLastBootFile, err.c_str());
|
||||
}
|
||||
|
||||
err.clear();
|
||||
if (!RemoveFileIfExists(kLegacyNextBootFile, &err)) {
|
||||
ALOGW("Unable to delete %s: %s", kLegacyNextBootFile, err.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void createNextBootFile() {
|
||||
errno = 0;
|
||||
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
|
||||
|
||||
// Renames the 'next' boot file to the 'last' file and reads its contents.
|
||||
bool BootParameters::swapAndLoadBootConfigContents(const char *lastBootFile,
|
||||
const char *nextBootFile,
|
||||
std::string *contents) {
|
||||
if (!ReadFileToString(nextBootFile, contents)) {
|
||||
RemoveFileIfExists(lastBootFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (rename(nextBootFile, lastBootFile) && errno != ENOENT)
|
||||
ALOGE("Unable to swap boot files: %s", strerror(errno));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BootParameters::BootParameters() {
|
||||
loadParameters();
|
||||
}
|
||||
|
||||
// Saves the boot parameters state to disk so the framework can read it.
|
||||
void BootParameters::storeParameters() {
|
||||
errno = 0;
|
||||
if (!WriteStringToFile(mProto.SerializeAsString(), kLastBootFile)) {
|
||||
ALOGE("Failed to write boot parameters to %s: %s", kLastBootFile, strerror(errno));
|
||||
}
|
||||
|
||||
// WriteStringToFile sets the file permissions to 0666, but these are not
|
||||
// honored by the system.
|
||||
errno = 0;
|
||||
if (chmod(kLastBootFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
|
||||
ALOGE("Failed to set permissions for %s: %s", kLastBootFile, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
// Load the boot parameters from disk, try the old location and format if the
|
||||
// file does not exist. Note:
|
||||
// - Parse errors result in defaults being used (a normal boot).
|
||||
// - Legacy boot parameters default to a silent boot.
|
||||
void BootParameters::loadParameters() {
|
||||
// Precedence is given to the new file format (.proto).
|
||||
std::string contents;
|
||||
if (swapAndLoadBootConfigContents(kLastBootFile, kNextBootFile, &contents)) {
|
||||
parseBootParameters(contents);
|
||||
} else if (swapAndLoadBootConfigContents(kLegacyLastBootFile, kLegacyNextBootFile, &contents)) {
|
||||
parseLegacyBootParameters(contents);
|
||||
storeParameters();
|
||||
removeLegacyFiles();
|
||||
}
|
||||
|
||||
createNextBootFile();
|
||||
}
|
||||
|
||||
void BootParameters::parseBootParameters(const std::string &contents) {
|
||||
if (!mProto.ParseFromString(contents)) {
|
||||
ALOGW("Failed to parse parameters from %s", kLastBootFile);
|
||||
return;
|
||||
}
|
||||
|
||||
loadStateFromProto();
|
||||
}
|
||||
|
||||
// Parses the JSON in the proto.
|
||||
void BootParameters::parseLegacyBootParameters(const std::string &contents) {
|
||||
Value json;
|
||||
if (!Reader().parse(contents, json)) {
|
||||
ALOGW("Failed to parse parameters from %s", kLegacyLastBootFile);
|
||||
return;
|
||||
}
|
||||
|
||||
int volume = 0;
|
||||
bool bootAnimationDisabled = true;
|
||||
|
||||
Value &jsonValue = json[kKeyLegacyVolume];
|
||||
if (jsonValue.isIntegral()) {
|
||||
volume = jsonValue.asInt();
|
||||
}
|
||||
|
||||
jsonValue = json[kKeyLegacyAnimationsDisabled];
|
||||
if (jsonValue.isIntegral()) {
|
||||
bootAnimationDisabled = jsonValue.asInt() == 1;
|
||||
}
|
||||
|
||||
// Assume a silent boot unless all of the following are true -
|
||||
// 1. The volume is neither 0 nor -1000 (the legacy default value).
|
||||
// 2. The boot animations are explicitly enabled.
|
||||
// Note: brightness was never used.
|
||||
mProto.set_silent_boot((volume == 0) || (volume == -1000) || bootAnimationDisabled);
|
||||
|
||||
Value &keys = json[kKeyLegacyParamNames];
|
||||
Value &values = json[kKeyLegacyParamValues];
|
||||
if (keys.isArray() && values.isArray() && (keys.size() == values.size())) {
|
||||
for (ArrayIndex i = 0; i < keys.size(); ++i) {
|
||||
auto &key = keys[i];
|
||||
auto &value = values[i];
|
||||
if (key.isString() && value.isString()) {
|
||||
auto userParameter = mProto.add_user_parameter();
|
||||
userParameter->set_key(key.asString());
|
||||
userParameter->set_value(value.asString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadStateFromProto();
|
||||
}
|
||||
|
||||
void BootParameters::loadStateFromProto() {
|
||||
// A missing key returns a safe, default value.
|
||||
// Ignore invalid or missing parameters.
|
||||
mIsSilentBoot = mProto.silent_boot();
|
||||
|
||||
for (const auto ¶m : mProto.user_parameter()) {
|
||||
mParameters.push_back({.key = param.key().c_str(), .value = param.value().c_str()});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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 <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boot_action/boot_action.h> // libandroidthings native API.
|
||||
#include <boot_parameters.pb.h>
|
||||
|
||||
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 whether or not this is a silent boot.
|
||||
bool isSilentBoot() const { return mIsSilentBoot; }
|
||||
|
||||
// Returns the additional boot parameters that were set on reboot.
|
||||
const std::vector<ABootActionParameter>& getParameters() const { return mParameters; }
|
||||
|
||||
// Exposed for testing. Sets the parameters to the serialized proto.
|
||||
void parseBootParameters(const std::string &contents);
|
||||
|
||||
// For devices that OTA from N to O.
|
||||
// Exposed for testing. Sets the parameters to the raw JSON.
|
||||
void parseLegacyBootParameters(const std::string &contents);
|
||||
|
||||
// Exposed for testing. Loads the contents from |nextBootFile| and replaces
|
||||
// |lastBootFile| with |nextBootFile|.
|
||||
static bool swapAndLoadBootConfigContents(const char *lastBootFile, const char *nextBootFile,
|
||||
std::string *contents);
|
||||
|
||||
private:
|
||||
void loadParameters();
|
||||
|
||||
// Replaces the legacy JSON blob with the updated version, allowing the
|
||||
// framework to read it.
|
||||
void storeParameters();
|
||||
|
||||
void loadStateFromProto();
|
||||
|
||||
bool mIsSilentBoot = false;
|
||||
|
||||
std::vector<ABootActionParameter> mParameters;
|
||||
|
||||
// Store the proto because mParameters makes a shallow copy.
|
||||
android::things::proto::BootParameters mProto;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
|
||||
#endif // _BOOTANIMATION_BOOT_PARAMETERS_H_
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/test_utils.h>
|
||||
#include <boot_parameters.pb.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(BootParametersTest, TestNoBootParametersIsNotSilent) {
|
||||
android::things::proto::BootParameters proto;
|
||||
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseBootParameters(proto.SerializeAsString());
|
||||
|
||||
ASSERT_FALSE(bootParameters.isSilentBoot());
|
||||
ASSERT_EQ(0u, bootParameters.getParameters().size());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseIsSilent) {
|
||||
android::things::proto::BootParameters proto;
|
||||
proto.set_silent_boot(true);
|
||||
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseBootParameters(proto.SerializeAsString());
|
||||
|
||||
ASSERT_TRUE(bootParameters.isSilentBoot());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseIsNotSilent) {
|
||||
android::things::proto::BootParameters proto;
|
||||
proto.set_silent_boot(false);
|
||||
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseBootParameters(proto.SerializeAsString());
|
||||
|
||||
ASSERT_FALSE(bootParameters.isSilentBoot());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseBootParameters) {
|
||||
android::things::proto::BootParameters proto;
|
||||
proto.set_silent_boot(false);
|
||||
|
||||
auto userParameter = proto.add_user_parameter();
|
||||
userParameter->set_key("key1");
|
||||
userParameter->set_value("value1");
|
||||
|
||||
userParameter = proto.add_user_parameter();
|
||||
userParameter->set_key("key2");
|
||||
userParameter->set_value("value2");
|
||||
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseBootParameters(proto.SerializeAsString());
|
||||
|
||||
auto ¶meters = bootParameters.getParameters();
|
||||
ASSERT_EQ(2u, parameters.size());
|
||||
ASSERT_STREQ(parameters[0].key, "key1");
|
||||
ASSERT_STREQ(parameters[0].value, "value1");
|
||||
ASSERT_STREQ(parameters[1].key, "key2");
|
||||
ASSERT_STREQ(parameters[1].value, "value2");
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseLegacyDisableBootAnimationIsSilent) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":200,
|
||||
"volume":100,
|
||||
"boot_animation_disabled":1,
|
||||
"param_names":[],
|
||||
"param_values":[]
|
||||
}
|
||||
)");
|
||||
|
||||
ASSERT_TRUE(bootParameters.isSilentBoot());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseLegacyZeroVolumeIsSilent) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":200,
|
||||
"volume":0,
|
||||
"boot_animation_disabled":0,
|
||||
"param_names":[],
|
||||
"param_values":[]
|
||||
}
|
||||
)");
|
||||
|
||||
ASSERT_TRUE(bootParameters.isSilentBoot());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseLegacyDefaultVolumeIsSilent) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":200,
|
||||
"volume":-1000,
|
||||
"boot_animation_disabled":0,
|
||||
"param_names":[],
|
||||
"param_values":[]
|
||||
}
|
||||
)");
|
||||
|
||||
ASSERT_TRUE(bootParameters.isSilentBoot());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseLegacyNotSilent) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":200,
|
||||
"volume":500,
|
||||
"boot_animation_disabled":0,
|
||||
"param_names":[],
|
||||
"param_values":[]
|
||||
}
|
||||
)");
|
||||
|
||||
ASSERT_FALSE(bootParameters.isSilentBoot());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseLegacyParameters) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":200,
|
||||
"volume":100,
|
||||
"boot_animation_disabled":1,
|
||||
"param_names":["key1", "key2"],
|
||||
"param_values":["value1", "value2"]
|
||||
}
|
||||
)");
|
||||
|
||||
auto parameters = bootParameters.getParameters();
|
||||
ASSERT_EQ(2u, parameters.size());
|
||||
ASSERT_STREQ(parameters[0].key, "key1");
|
||||
ASSERT_STREQ(parameters[0].value, "value1");
|
||||
ASSERT_STREQ(parameters[1].key, "key2");
|
||||
ASSERT_STREQ(parameters[1].value, "value2");
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestParseLegacyZeroParameters) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":200,
|
||||
"volume":100,
|
||||
"boot_animation_disabled":1,
|
||||
"param_names":[],
|
||||
"param_values":[]
|
||||
}
|
||||
)");
|
||||
|
||||
ASSERT_EQ(0u, bootParameters.getParameters().size());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestMalformedLegacyParametersAreSkipped) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":500,
|
||||
"volume":500,
|
||||
"boot_animation_disabled":0,
|
||||
"param_names":["key1", "key2"],
|
||||
"param_values":[1, "value2"]
|
||||
}
|
||||
)");
|
||||
|
||||
auto parameters = bootParameters.getParameters();
|
||||
ASSERT_EQ(1u, parameters.size());
|
||||
ASSERT_STREQ(parameters[0].key, "key2");
|
||||
ASSERT_STREQ(parameters[0].value, "value2");
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestLegacyUnequalParameterSizesAreSkipped) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":500,
|
||||
"volume":500,
|
||||
"boot_animation_disabled":0,
|
||||
"param_names":["key1", "key2"],
|
||||
"param_values":["value1"]
|
||||
}
|
||||
)");
|
||||
|
||||
ASSERT_EQ(0u, bootParameters.getParameters().size());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestMissingLegacyBootParametersIsSilent) {
|
||||
BootParameters bootParameters = BootParameters();
|
||||
bootParameters.parseLegacyBootParameters(R"(
|
||||
{
|
||||
"brightness":500
|
||||
}
|
||||
)");
|
||||
|
||||
EXPECT_TRUE(bootParameters.isSilentBoot());
|
||||
ASSERT_EQ(0u, bootParameters.getParameters().size());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestLastFileIsRemovedOnError) {
|
||||
TemporaryFile lastFile;
|
||||
TemporaryDir tempDir;
|
||||
std::string nonExistentFilePath(std::string(tempDir.path) + "/nonexistent");
|
||||
std::string contents;
|
||||
|
||||
BootParameters::swapAndLoadBootConfigContents(lastFile.path, nonExistentFilePath.c_str(),
|
||||
&contents);
|
||||
|
||||
struct stat buf;
|
||||
ASSERT_EQ(-1, lstat(lastFile.path, &buf));
|
||||
ASSERT_TRUE(contents.empty());
|
||||
}
|
||||
|
||||
TEST(BootParametersTest, TestNextFileIsRemovedLastFileExistsOnSuccess) {
|
||||
TemporaryFile lastFile;
|
||||
TemporaryFile nextFile;
|
||||
|
||||
base::WriteStringToFile("foo", nextFile.path);
|
||||
|
||||
std::string contents;
|
||||
// Expected side effects:
|
||||
// - |next_file| is moved to |last_file|
|
||||
// - |contents| is the contents of |next_file| before being moved.
|
||||
BootParameters::swapAndLoadBootConfigContents(lastFile.path, nextFile.path, &contents);
|
||||
|
||||
struct stat buf;
|
||||
ASSERT_EQ(0, lstat(lastFile.path, &buf));
|
||||
ASSERT_EQ(-1, lstat(nextFile.path, &buf));
|
||||
ASSERT_EQ(contents, "foo");
|
||||
|
||||
contents.clear();
|
||||
ASSERT_TRUE(base::ReadFileToString(lastFile.path, &contents));
|
||||
ASSERT_EQ(contents, "foo");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace android
|
||||
@@ -1,2 +0,0 @@
|
||||
on post-fs-data
|
||||
mkdir /data/misc/bootanimation 0777 root root
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "IotBootAnimation"
|
||||
|
||||
#include <base/files/file_util.h>
|
||||
#include <binder/IPCThreadState.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <sys/resource.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/threads.h>
|
||||
#include <BootAnimation.h>
|
||||
|
||||
#include "BootAction.h"
|
||||
#include "BootAnimationUtil.h"
|
||||
#include "BootParameters.h"
|
||||
|
||||
using namespace android;
|
||||
|
||||
// Create a typedef for readability.
|
||||
typedef android::BootAnimation::Animation Animation;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const char* kDefaultLibName = "libbootaction.so";
|
||||
|
||||
class BootActionAnimationCallbacks : public android::BootAnimation::Callbacks {
|
||||
public:
|
||||
BootActionAnimationCallbacks(std::unique_ptr<BootParameters> bootParameters)
|
||||
: mBootParameters(std::move(bootParameters)) {}
|
||||
|
||||
void init(const Vector<Animation::Part>&) override {
|
||||
std::string library_path("/oem/lib/");
|
||||
|
||||
// This value is optionally provided by the user and will be written to
|
||||
// /oem/oem.prop.
|
||||
char property[PROP_VALUE_MAX] = {0};
|
||||
property_get("ro.oem.bootactions.lib", property, kDefaultLibName);
|
||||
library_path += property;
|
||||
|
||||
if (!::base::PathExists(::base::FilePath(library_path))) {
|
||||
ALOGI("Skipping boot actions: %s does not exist", library_path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
mBootAction = new BootAction();
|
||||
if (!mBootAction->init(library_path, mBootParameters)) {
|
||||
mBootAction = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
void playPart(int partNumber, const Animation::Part&, int playNumber) override {
|
||||
if (mBootAction != nullptr) {
|
||||
mBootAction->startPart(partNumber, playNumber);
|
||||
}
|
||||
};
|
||||
|
||||
void shutdown() override {
|
||||
if (mBootAction != nullptr) {
|
||||
// If we have a bootaction we want to wait until we are actually
|
||||
// told to shut down. If the animation exits early keep the action
|
||||
// running.
|
||||
char value[PROPERTY_VALUE_MAX] = {0};
|
||||
for (int exitRequested = 0; exitRequested == 0; ) {
|
||||
property_get("service.bootanim.exit", value, "0");
|
||||
exitRequested = atoi(value);
|
||||
|
||||
// Poll value at 10hz.
|
||||
if (exitRequested == 0) {
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
mBootAction->shutdown();
|
||||
// Give it two seconds to shut down.
|
||||
sleep(2);
|
||||
mBootAction = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<BootParameters> mBootParameters;
|
||||
sp<BootAction> mBootAction = nullptr;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
|
||||
|
||||
// Clear our params for next boot no matter what.
|
||||
std::unique_ptr<BootParameters> bootParameters(new BootParameters());
|
||||
|
||||
if (bootAnimationDisabled()) {
|
||||
ALOGI("boot animation disabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
waitForSurfaceFlinger();
|
||||
|
||||
sp<ProcessState> proc(ProcessState::self());
|
||||
ProcessState::self()->startThreadPool();
|
||||
|
||||
bool isSilentBoot = bootParameters->isSilentBoot();
|
||||
sp<BootActionAnimationCallbacks> callbacks =
|
||||
new BootActionAnimationCallbacks(std::move(bootParameters));
|
||||
|
||||
// On silent boot, animations aren't displayed.
|
||||
if (isSilentBoot) {
|
||||
callbacks->init({});
|
||||
} else {
|
||||
sp<BootAnimation> boot = new BootAnimation(callbacks);
|
||||
}
|
||||
|
||||
IPCThreadState::self()->joinThreadPool();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user