154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell/* 254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * Copyright (C) 2017 The Android Open Source Project 354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * 454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * Licensed under the Apache License, Version 2.0 (the "License"); 554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * you may not use this file except in compliance with the License. 654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * You may obtain a copy of the License at 754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * 854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * http://www.apache.org/licenses/LICENSE-2.0 954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * 1054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * Unless required by applicable law or agreed to in writing, software 1154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * distributed under the License is distributed on an "AS IS" BASIS, 1254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * See the License for the specific language governing permissions and 1454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell * limitations under the License. 1554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell */ 1654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 1754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#include "BootParameters.h" 1854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 1954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#define LOG_TAG "BootParameters" 2054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 2154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#include <fcntl.h> 2254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 2354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#include <string> 2454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 2554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#include <android-base/file.h> 2654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#include <base/json/json_parser.h> 2754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#include <base/json/json_reader.h> 2854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#include <base/json/json_value_converter.h> 2954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell#include <utils/Log.h> 3054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 3154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellusing android::base::RemoveFileIfExists; 3254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellusing android::base::ReadFileToString; 3354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellusing base::JSONReader; 3454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellusing base::JSONValueConverter; 3554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellusing base::Value; 3654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 3754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellnamespace android { 3854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 3954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellnamespace { 4054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 4154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell// Brightness and volume are stored as integer strings in next_boot.json. 4254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell// They are divided by this constant to produce the actual float values in 4354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell// range [0.0, 1.0]. This constant must match its counterpart in 4454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell// DeviceManager. 4554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellconstexpr const float kFloatScaleFactor = 1000.0f; 4654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 4754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellconstexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json"; 4854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellconstexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json"; 4954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 5054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellvoid swapBootConfigs() { 5154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell // rename() will fail if next_boot.json doesn't exist, so delete 5254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell // last_boot.json manually first. 5354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell std::string err; 5454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (!RemoveFileIfExists(kLastBootFile, &err)) 5554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell ALOGE("Unable to delete last boot file: %s", err.c_str()); 5654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 5754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (rename(kNextBootFile, kLastBootFile) && errno != ENOENT) 5854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell ALOGE("Unable to swap boot files: %s", strerror(errno)); 5954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 6054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell int fd = open(kNextBootFile, O_CREAT, DEFFILEMODE); 6154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (fd == -1) { 6254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell ALOGE("Unable to create next boot file: %s", strerror(errno)); 6354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell } else { 6454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell // Make next_boot.json writable to everyone so DeviceManagementService 6554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell // can save saved_parameters there. 6654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (fchmod(fd, DEFFILEMODE)) 6754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell ALOGE("Unable to set next boot file permissions: %s", strerror(errno)); 6854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell close(fd); 6954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell } 7054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell} 7154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 7254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell} // namespace 7354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 7454a8fe4bbe446bdc394ef87e52252fcc1c031db1David PursellBootParameters::SavedBootParameters::SavedBootParameters() 7554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell : brightness(-kFloatScaleFactor), volume(-kFloatScaleFactor) {} 7654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 7754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellvoid BootParameters::SavedBootParameters::RegisterJSONConverter( 7854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell JSONValueConverter<SavedBootParameters>* converter) { 7954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell converter->RegisterIntField("brightness", &SavedBootParameters::brightness); 8054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell converter->RegisterIntField("volume", &SavedBootParameters::volume); 8154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell converter->RegisterRepeatedString("param_names", 8254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell &SavedBootParameters::param_names); 8354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell converter->RegisterRepeatedString("param_values", 8454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell &SavedBootParameters::param_values); 8554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell} 8654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 8754a8fe4bbe446bdc394ef87e52252fcc1c031db1David PursellBootParameters::BootParameters() { 8854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell swapBootConfigs(); 8954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell loadParameters(); 9054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell} 9154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 9254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursellvoid BootParameters::loadParameters() { 9354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell std::string contents; 9454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (!ReadFileToString(kLastBootFile, &contents)) { 9554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (errno != ENOENT) 9654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell ALOGE("Unable to read from %s: %s", kLastBootFile, strerror(errno)); 9754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 9854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell return; 9954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell } 10054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 10154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell std::unique_ptr<Value> json = JSONReader::Read(contents); 10254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (json.get() == nullptr) { 10354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell return; 10454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell } 10554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 10654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell JSONValueConverter<SavedBootParameters> converter; 10754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (converter.Convert(*(json.get()), &mRawParameters)) { 10854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell mBrightness = mRawParameters.brightness / kFloatScaleFactor; 10954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell mVolume = mRawParameters.volume / kFloatScaleFactor; 11054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 11154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell if (mRawParameters.param_names.size() == mRawParameters.param_values.size()) { 11254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell for (size_t i = 0; i < mRawParameters.param_names.size(); i++) { 11354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell mParameters.push_back({ 11454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell .key = mRawParameters.param_names[i]->c_str(), 11554a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell .value = mRawParameters.param_values[i]->c_str() 11654a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell }); 11754a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell } 11854a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell } else { 11954a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell ALOGW("Parameter names and values size mismatch"); 12054a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell } 12154a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell } 12254a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell} 12354a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell 12454a8fe4bbe446bdc394ef87e52252fcc1c031db1David Pursell} // namespace android 125