1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "BootParameters.h" 18 19#define LOG_TAG "BootParameters" 20 21#include <fcntl.h> 22 23#include <string> 24 25#include <android-base/file.h> 26#include <base/json/json_parser.h> 27#include <base/json/json_reader.h> 28#include <base/json/json_value_converter.h> 29#include <utils/Log.h> 30 31using android::base::RemoveFileIfExists; 32using android::base::ReadFileToString; 33using base::JSONReader; 34using base::JSONValueConverter; 35using base::Value; 36 37namespace android { 38 39namespace { 40 41// Brightness and volume are stored as integer strings in next_boot.json. 42// They are divided by this constant to produce the actual float values in 43// range [0.0, 1.0]. This constant must match its counterpart in 44// DeviceManager. 45constexpr const float kFloatScaleFactor = 1000.0f; 46 47constexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json"; 48constexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json"; 49 50void swapBootConfigs() { 51 // rename() will fail if next_boot.json doesn't exist, so delete 52 // last_boot.json manually first. 53 std::string err; 54 if (!RemoveFileIfExists(kLastBootFile, &err)) 55 ALOGE("Unable to delete last boot file: %s", err.c_str()); 56 57 if (rename(kNextBootFile, kLastBootFile) && errno != ENOENT) 58 ALOGE("Unable to swap boot files: %s", strerror(errno)); 59 60 int fd = open(kNextBootFile, O_CREAT, DEFFILEMODE); 61 if (fd == -1) { 62 ALOGE("Unable to create next boot file: %s", strerror(errno)); 63 } else { 64 // Make next_boot.json writable to everyone so DeviceManagementService 65 // can save saved_parameters there. 66 if (fchmod(fd, DEFFILEMODE)) 67 ALOGE("Unable to set next boot file permissions: %s", strerror(errno)); 68 close(fd); 69 } 70} 71 72} // namespace 73 74BootParameters::SavedBootParameters::SavedBootParameters() 75 : brightness(-kFloatScaleFactor), volume(-kFloatScaleFactor) {} 76 77void BootParameters::SavedBootParameters::RegisterJSONConverter( 78 JSONValueConverter<SavedBootParameters>* converter) { 79 converter->RegisterIntField("brightness", &SavedBootParameters::brightness); 80 converter->RegisterIntField("volume", &SavedBootParameters::volume); 81 converter->RegisterRepeatedString("param_names", 82 &SavedBootParameters::param_names); 83 converter->RegisterRepeatedString("param_values", 84 &SavedBootParameters::param_values); 85} 86 87BootParameters::BootParameters() { 88 swapBootConfigs(); 89 loadParameters(); 90} 91 92void BootParameters::loadParameters() { 93 std::string contents; 94 if (!ReadFileToString(kLastBootFile, &contents)) { 95 if (errno != ENOENT) 96 ALOGE("Unable to read from %s: %s", kLastBootFile, strerror(errno)); 97 98 return; 99 } 100 101 std::unique_ptr<Value> json = JSONReader::Read(contents); 102 if (json.get() == nullptr) { 103 return; 104 } 105 106 JSONValueConverter<SavedBootParameters> converter; 107 if (converter.Convert(*(json.get()), &mRawParameters)) { 108 mBrightness = mRawParameters.brightness / kFloatScaleFactor; 109 mVolume = mRawParameters.volume / kFloatScaleFactor; 110 111 if (mRawParameters.param_names.size() == mRawParameters.param_values.size()) { 112 for (size_t i = 0; i < mRawParameters.param_names.size(); i++) { 113 mParameters.push_back({ 114 .key = mRawParameters.param_names[i]->c_str(), 115 .value = mRawParameters.param_values[i]->c_str() 116 }); 117 } 118 } else { 119 ALOGW("Parameter names and values size mismatch"); 120 } 121 } 122} 123 124} // namespace android 125