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 31 using android::base::RemoveFileIfExists; 32 using android::base::ReadFileToString; 33 using base::JSONReader; 34 using base::JSONValueConverter; 35 using base::Value; 36 37 namespace android { 38 39 namespace { 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. 45 constexpr const float kFloatScaleFactor = 1000.0f; 46 47 constexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json"; 48 constexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json"; 49 50 void 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 74 BootParameters::SavedBootParameters::SavedBootParameters() 75 : brightness(-kFloatScaleFactor), volume(-kFloatScaleFactor) {} 76 77 void 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 87 BootParameters::BootParameters() { 88 swapBootConfigs(); 89 loadParameters(); 90 } 91 92 void 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