1 /*
2  * Copyright (C) 2018 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 "LearnedCapacityBackupRestore.h"
18 
19 namespace device {
20 namespace google {
21 namespace bonito {
22 namespace health {
23 
24 static constexpr char kChgFullDesignFile[] = "sys/class/power_supply/bms/charge_full_design";
25 static constexpr char kChgFullFile[] = "sys/class/power_supply/bms/charge_full";
26 static constexpr char kSysCFPersistFile[] = "/persist/battery/qcom_charge_full";
27 static constexpr int kBuffSize = 256;
28 
LearnedCapacityBackupRestore()29 LearnedCapacityBackupRestore::LearnedCapacityBackupRestore() {}
30 
Restore()31 void LearnedCapacityBackupRestore::Restore() {
32     ReadPersistData();
33     ReadNominalCapacity();
34     ReadCapacity();
35     UpdateAndSave();
36 }
37 
Backup()38 void LearnedCapacityBackupRestore::Backup() {
39     ReadCapacity();
40     UpdateAndSave();
41 }
42 
ReadPersistData()43 void LearnedCapacityBackupRestore::ReadPersistData() {
44     std::string buffer;
45 
46     if (!android::base::ReadFileToString(std::string(kSysCFPersistFile), &buffer)) {
47         LOG(ERROR) << "Cannot read the storage file";
48         return;
49     }
50 
51     if (sscanf(buffer.c_str(), "%d", &sw_cap_) < 1)
52         LOG(ERROR) << "data format is wrong in the storage file: " << buffer;
53     else
54         LOG(INFO) << "Storage data: " << buffer;
55 }
56 
SaveToStorage()57 void LearnedCapacityBackupRestore::SaveToStorage() {
58     char strData[kBuffSize];
59 
60     snprintf(strData, kBuffSize, "%d", sw_cap_);
61 
62     LOG(INFO) << "Save to Storage: " << strData;
63 
64     if (!android::base::WriteStringToFile(strData, std::string(kSysCFPersistFile)))
65         LOG(ERROR) << "Write file error: " << strerror(errno);
66 }
67 
ReadNominalCapacity()68 void LearnedCapacityBackupRestore::ReadNominalCapacity() {
69     std::string buffer;
70 
71     if (!android::base::ReadFileToString(std::string(kChgFullDesignFile), &buffer)) {
72         LOG(ERROR) << "Read nominal capacity error: " << strerror(errno);
73         return;
74     }
75 
76     buffer = android::base::Trim(buffer);
77 
78     if (sscanf(buffer.c_str(), "%d", &nom_cap_) < 1)
79         LOG(ERROR) << "Failed to parse nominal capacity: " << buffer;
80     else
81         LOG(INFO) << "nominal capacity: " << buffer;
82 }
83 
ReadCapacity()84 void LearnedCapacityBackupRestore::ReadCapacity() {
85     std::string buffer;
86 
87     if (!android::base::ReadFileToString(std::string(kChgFullFile), &buffer)) {
88         LOG(ERROR) << "Read capacity error: " << strerror(errno);
89         return;
90     }
91 
92     buffer = android::base::Trim(buffer);
93 
94     if (sscanf(buffer.c_str(), "%d", &hw_cap_) < 1)
95         LOG(ERROR) << "Failed to parse capacity: " << buffer;
96     else
97         LOG(INFO) << "capacity: " << buffer;
98 }
99 
SaveToSRAM()100 void LearnedCapacityBackupRestore::SaveToSRAM() {
101     char strData[kBuffSize];
102 
103     snprintf(strData, kBuffSize, "%d", hw_cap_);
104 
105     LOG(INFO) << "Save to SRAM: " << strData;
106 
107     if (!android::base::WriteStringToFile(strData, std::string(kChgFullFile)))
108         LOG(ERROR) << "Write data error: " << strerror(errno);
109 }
110 
UpdateAndSave()111 void LearnedCapacityBackupRestore::UpdateAndSave() {
112     bool backup = false;
113     bool restore = false;
114     if (hw_cap_) {
115         if (((hw_cap_ != sw_cap_) && (hw_cap_ != nom_cap_)) ||
116             (sw_cap_ == 0)) {
117             sw_cap_ = hw_cap_;
118             backup = true;
119         } else if ((sw_cap_ > 0) && (hw_cap_ == nom_cap_)) {
120             hw_cap_ = sw_cap_;
121             restore = true;
122         }
123     }
124     if (restore)
125         SaveToSRAM();
126     if (backup)
127         SaveToStorage();
128 }
129 
130 }  // namespace health
131 }  // namespace bonito
132 }  // namespace google
133 }  // namespace device
134