1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "power_supply_provider.h"
17 #include <dirent.h>
18 #include <fcntl.h>
19 #include <fstream>
20 #include <securec.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include "battery_log.h"
25 #include "battery_config.h"
26 #include "osal_mem.h"
27 
28 namespace OHOS {
29 namespace HDI {
30 namespace Battery {
31 namespace V2_0 {
32 namespace {
33 constexpr int32_t MAX_SYSFS_SIZE = 64;
34 constexpr int32_t MAX_BUFF_SIZE = 128;
35 constexpr int32_t INVALID_BATT_INT_VALUE = -1;
36 constexpr int32_t STR_TO_LONG_LEN = 10;
37 constexpr int32_t UVOL_TO_MVOL = 1000;
38 constexpr int32_t MKDIR_WAIT_TIME = 1;
39 constexpr int32_t NUM_ZERO = 0;
40 const std::string POWER_SUPPLY_BASE_PATH = "/sys/class/power_supply";
41 const std::string MOCK_POWER_SUPPLY_BASE_PATH = "/data/service/el0/battery";
42 const std::string POWER_SUPPLY_BATTERY = "Battery";
43 const std::string BATTERY_KEY_CAPACITY = "POWER_SUPPLY_CAPACITY=";
44 const std::string BATTERY_KEY_VOLTAGE = "POWER_SUPPLY_VOLTAGE_NOW=";
45 const std::string BATTERY_KEY_TEMPERATURE = "POWER_SUPPLY_TEMP=";
46 const std::string BATTERY_KEY_HEALTH = "POWER_SUPPLY_HEALTH=";
47 const std::string BATTERY_KEY_CHARGE_STATUS = "POWER_SUPPLY_STATUS=";
48 const std::string BATTERY_KEY_PRESENT = "POWER_SUPPLY_PRESENT=";
49 const std::string BATTERY_KEY_TECHNOLOGY = "POWER_SUPPLY_TECHNOLOGY=";
50 const std::string BATTERY_KEY_CHARGE_COUNTER = "POWER_SUPPLY_CHARGE_COUNTER=";
51 const std::string BATTERY_KEY_TOTAL_ENERGY = "POWER_SUPPLY_TOTAL_ENERGY=";
52 const std::string BATTERY_KEY_REMAIN_ENERGY = "POWER_SUPPLY_REMAIN_ENERGY=";
53 const std::string BATTERY_KEY_CURRENT_AVERAGE = "POWER_SUPPLY_CURRENT_AVERAGE=";
54 const std::string BATTERY_KEY_CURRENT_NOW = "POWER_SUPPLY_CURRENT_NOW=";
55 const std::string INVALID_STRING_VALUE = "invalid";
56 const std::string BATTERY_NODE_PATH = "battery";
57 }
58 
59 BatterydInfo g_batteryInfo;
60 
61 struct StringEnumMap {
62     const char* str;
63     int32_t enumVal;
64 };
65 
66 struct BatteryAssigner {
67     const char* prefix;
68     const size_t prefixLen;
69     void (*Assigner)(const char*, struct BatterydInfo*);
70 };
71 
PowerSupplyProvider()72 PowerSupplyProvider::PowerSupplyProvider()
73 {
74     path_ = POWER_SUPPLY_BASE_PATH;
75     index_ = 0;
76 }
77 
~PowerSupplyProvider()78 PowerSupplyProvider::~PowerSupplyProvider()
79 {
80     std::lock_guard<std::mutex> lock(mutex_);
81     for (auto it = nodeCacheFiles_.begin(); it != nodeCacheFiles_.end();) {
82         int32_t fd = it->second;
83         close(fd);
84         it++;
85     }
86     nodeCacheFiles_.clear();
87 }
88 
ParseInt(const char * str)89 inline int32_t PowerSupplyProvider::ParseInt(const char* str)
90 {
91     return static_cast<int32_t>(strtol(str, nullptr, STR_TO_LONG_LEN));
92 }
93 
Trim(char * str)94 inline void PowerSupplyProvider::Trim(char* str)
95 {
96     if (str == nullptr) {
97         return;
98     }
99 
100     size_t strc = strcspn(str, "\n");
101     if (strc >= strlen(str)) {
102         return;
103     }
104 
105     str[strc] = 0;
106 }
107 
CapacityAssigner(const char * str,struct BatterydInfo * info)108 inline void PowerSupplyProvider::CapacityAssigner(const char* str, struct BatterydInfo* info)
109 {
110     info->capacity_ = ParseInt(str); // default in percent format
111 }
112 
TotalEnergyAssigner(const char * str,struct BatterydInfo * info)113 inline void PowerSupplyProvider::TotalEnergyAssigner(const char* str, struct BatterydInfo* info)
114 {
115     info->totalEnergy_ = ParseInt(str);
116 }
117 
RemainEnergyAssigner(const char * str,struct BatterydInfo * info)118 inline void PowerSupplyProvider::RemainEnergyAssigner(const char* str, struct BatterydInfo* info)
119 {
120     info->remainEnergy_ = ParseInt(str);
121 }
122 
VoltageAssigner(const char * str,struct BatterydInfo * info)123 inline void PowerSupplyProvider::VoltageAssigner(const char* str, struct BatterydInfo* info)
124 {
125     info->voltage_ = ParseInt(str) / UVOL_TO_MVOL; // convert to millivolt(mV) format
126 }
127 
TemperatureAssigner(const char * str,struct BatterydInfo * info)128 inline void PowerSupplyProvider::TemperatureAssigner(const char* str, struct BatterydInfo* info)
129 {
130     info->temperature_ = ParseInt(str);
131 }
132 
HealthStateEnumConverter(const char * str)133 int32_t PowerSupplyProvider::HealthStateEnumConverter(const char* str)
134 {
135     struct StringEnumMap healthStateEnumMap[] = {
136         { "Good", BATTERY_HEALTH_GOOD },
137         { "Cold", BATTERY_HEALTH_COLD },
138         { "Warm", BATTERY_HEALTH_GOOD }, // JEITA specification
139         { "Cool", BATTERY_HEALTH_GOOD }, // JEITA specification
140         { "Hot", BATTERY_HEALTH_OVERHEAT }, // JEITA specification
141         { "Overheat", BATTERY_HEALTH_OVERHEAT },
142         { "Over voltage", BATTERY_HEALTH_OVERVOLTAGE },
143         { "Dead", BATTERY_HEALTH_DEAD },
144         { "Unknown", BATTERY_HEALTH_UNKNOWN },
145         { "Unspecified failure", BATTERY_HEALTH_UNKNOWN },
146         { nullptr, BATTERY_HEALTH_UNKNOWN },
147     };
148 
149     for (int32_t i = 0; healthStateEnumMap[i].str; ++i) {
150         if (strcmp(str, healthStateEnumMap[i].str) == 0) {
151             return healthStateEnumMap[i].enumVal;
152         }
153     }
154 
155     return BATTERY_HEALTH_UNKNOWN;
156 }
157 
HealthStateAssigner(const char * str,struct BatterydInfo * info)158 inline void PowerSupplyProvider::HealthStateAssigner(const char* str, struct BatterydInfo* info)
159 {
160     info->healthState_ = HealthStateEnumConverter(str);
161 }
162 
ChargeStateEnumConverter(const char * str)163 int32_t PowerSupplyProvider::ChargeStateEnumConverter(const char* str)
164 {
165     struct StringEnumMap chargeStateEnumMap[] = {
166         { "Discharging", CHARGE_STATE_NONE },
167         { "Charging", CHARGE_STATE_ENABLE },
168         { "Full", CHARGE_STATE_FULL },
169         { "Not charging", CHARGE_STATE_DISABLE },
170         { "Unknown", CHARGE_STATE_RESERVED },
171         { nullptr, CHARGE_STATE_RESERVED },
172     };
173 
174     for (int32_t i = 0; chargeStateEnumMap[i].str; ++i) {
175         if (strcmp(str, chargeStateEnumMap[i].str) == 0) {
176             return chargeStateEnumMap[i].enumVal;
177         }
178     }
179 
180     return CHARGE_STATE_RESERVED;
181 }
182 
ChargeTypeEumConverter(const char * str)183 int32_t PowerSupplyProvider::ChargeTypeEumConverter(const char* str)
184 {
185     struct StringEnumMap chargeTypeEnumMap[] = {
186         { "0", CHARGE_TYPE_NONE },
187         { "1", CHARGE_TYPE_WIRED_NORMAL },
188         { "2", CHARGE_TYPE_WIRED_QUICK },
189         { "3", CHARGE_TYPE_WIRED_SUPER_QUICK },
190         { "4", CHARGE_TYPE_WIRELESS_NORMAL },
191         { "5", CHARGE_TYPE_WIRELESS_QUICK },
192         { "6", CHARGE_TYPE_WIRELESS_SUPER_QUICK },
193         { nullptr, CHARGE_TYPE_NONE },
194     };
195 
196     for (int32_t i = 0; chargeTypeEnumMap[i].str; ++i) {
197         if (strcmp(str, chargeTypeEnumMap[i].str) == 0) {
198             return chargeTypeEnumMap[i].enumVal;
199         }
200     }
201 
202     return CHARGE_TYPE_NONE;
203 }
204 
ChargeStateAssigner(const char * str,struct BatterydInfo * info)205 inline void PowerSupplyProvider::ChargeStateAssigner(const char* str, struct BatterydInfo* info)
206 {
207     info->chargeState_ = ChargeStateEnumConverter(str);
208 }
209 
PresentAssigner(const char * str,struct BatterydInfo * info)210 inline void PowerSupplyProvider::PresentAssigner(const char* str, struct BatterydInfo* info)
211 {
212     info->present_ = static_cast<int8_t>(ParseInt(str));
213 }
214 
TechnologyAssigner(const char * str,struct BatterydInfo * info)215 inline void PowerSupplyProvider::TechnologyAssigner(const char* str, struct BatterydInfo* info)
216 {
217     info->technology_ = str;
218 }
219 
ChargeCounterAssigner(const char * str,struct BatterydInfo * info)220 inline void PowerSupplyProvider::ChargeCounterAssigner(const char* str, struct BatterydInfo* info)
221 {
222     info->chargeCounter_ = ParseInt(str);
223 }
224 
CurrentAverageAssigner(const char * str,struct BatterydInfo * info)225 inline void PowerSupplyProvider::CurrentAverageAssigner(const char* str, struct BatterydInfo* info)
226 {
227     info->curAverage_ = ParseInt(str);
228 }
229 
CurrentNowAssigner(const char * str,struct BatterydInfo * info)230 inline void PowerSupplyProvider::CurrentNowAssigner(const char* str, struct BatterydInfo* info)
231 {
232     info->curNow_ = ParseInt(str);
233 }
234 
FormatPath(std::string & path,size_t size,const char * format,const char * basePath,const char * name) const235 void PowerSupplyProvider::FormatPath(std::string& path,
236     size_t size, const char* format, const char* basePath, const char* name) const
237 {
238     char buff[PATH_MAX] = {0};
239     if (strcpy_s(buff, PATH_MAX, path.c_str()) != EOK) {
240         BATTERY_HILOGW(FEATURE_BATT_INFO, "failed to copy path of %{public}s", name);
241         return;
242     }
243 
244     if (snprintf_s(buff, PATH_MAX, size - 1, format, basePath, name) == -1) {
245         BATTERY_HILOGW(FEATURE_BATT_INFO, "failed to format path of %{public}s", name);
246         return;
247     }
248     path.assign(buff, strlen(buff));
249 }
250 
FormatSysfsPaths()251 void PowerSupplyProvider::FormatSysfsPaths()
252 {
253     // Format paths for power supply types
254     FormatPath(batterySysfsInfo_.capacityPath, PATH_MAX, "%s/%s/capacity", path_.c_str(),
255                nodeNamePathMap_["capacity"].c_str());
256     FormatPath(batterySysfsInfo_.voltagePath, PATH_MAX, "%s/%s/voltage_now", path_.c_str(),
257                nodeNamePathMap_["voltage_now"].c_str());
258     FormatPath(batterySysfsInfo_.temperaturePath, PATH_MAX, "%s/%s/temp", path_.c_str(),
259                nodeNamePathMap_["temp"].c_str());
260     FormatPath(batterySysfsInfo_.healthStatePath, PATH_MAX, "%s/%s/health", path_.c_str(),
261                nodeNamePathMap_["health"].c_str());
262     FormatPath(batterySysfsInfo_.chargeStatePath, PATH_MAX, "%s/%s/status", path_.c_str(),
263                nodeNamePathMap_["status"].c_str());
264     FormatPath(batterySysfsInfo_.presentPath, PATH_MAX, "%s/%s/present", path_.c_str(),
265                nodeNamePathMap_["present"].c_str());
266     FormatPath(batterySysfsInfo_.chargeCounterPath, PATH_MAX, "%s/%s/charge_counter", path_.c_str(),
267                nodeNamePathMap_["charge_counter"].c_str());
268     FormatPath(batterySysfsInfo_.technologyPath, PATH_MAX, "%s/%s/technology", path_.c_str(),
269                nodeNamePathMap_["technology"].c_str());
270     FormatPath(batterySysfsInfo_.totalEnergyPath, PATH_MAX, "%s/%s/charge_full", path_.c_str(),
271                nodeNamePathMap_["charge_full"].c_str());
272     FormatPath(batterySysfsInfo_.curAveragePath, PATH_MAX, "%s/%s/current_avg", path_.c_str(),
273                nodeNamePathMap_["current_avg"].c_str());
274     FormatPath(batterySysfsInfo_.curNowPath, PATH_MAX, "%s/%s/current_now", path_.c_str(),
275                nodeNamePathMap_["current_now"].c_str());
276     FormatPath(batterySysfsInfo_.remainEnergyPath, PATH_MAX, "%s/%s/charge_now", path_.c_str(),
277                nodeNamePathMap_["charge_now"].c_str());
278 }
279 
ReadSysfsFile(const char * path,char * buf,size_t size)280 int32_t PowerSupplyProvider::ReadSysfsFile(const char* path, char* buf, size_t size)
281 {
282     int32_t fd = -1;
283 
284     {
285         std::lock_guard<std::mutex> lock(mutex_);
286         auto item = nodeCacheFiles_.find(path);
287         if (item != nodeCacheFiles_.end()) {
288             fd = item->second;
289         }
290     }
291 
292     if (fd != -1) {
293         ssize_t readSize = pread(fd, buf, size - 1, 0);
294         buf[readSize] = '\0';
295         Trim(buf);
296         return HDF_SUCCESS;
297     }
298 
299     fd = open(path, O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
300     if (fd < NUM_ZERO) {
301         BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to open file %{public}s, errno: %{public}d", path, errno);
302         return HDF_ERR_IO;
303     }
304 
305     ssize_t readSize = read(fd, buf, size - 1);
306     buf[readSize] = '\0';
307     Trim(buf);
308     {
309         std::lock_guard<std::mutex> lock(mutex_);
310         nodeCacheFiles_.insert(std::make_pair(path, fd));
311     }
312 
313     return HDF_SUCCESS;
314 }
315 
ReadBatterySysfsToBuff(const char * path,char * buf,size_t size)316 int32_t PowerSupplyProvider::ReadBatterySysfsToBuff(const char* path, char* buf, size_t size)
317 {
318     int32_t ret = ReadSysfsFile(path, buf, size);
319     if (ret != HDF_SUCCESS) {
320         BATTERY_HILOGW(FEATURE_BATT_INFO, "read path(%{public}s) failed, ret: %{public}d",
321             (path != nullptr ? path : "NULL"), ret);
322         return ret;
323     }
324 
325     return HDF_SUCCESS;
326 }
327 
GetPluggedTypeName(char * buf,size_t size)328 void PowerSupplyProvider::GetPluggedTypeName(char* buf, size_t size)
329 {
330     std::string onlineNode = "USB";
331     int32_t ret;
332     int32_t online;
333     std::string onlinePath = path_ + "/" + onlineNode + "/" + "online";
334     ret = ReadSysfsFile(onlinePath.c_str(), buf, size);
335     online = ParseInt(buf);
336     auto iter = nodeNames_.begin();
337     while (!online && iter != nodeNames_.end()) {
338         if (*iter == "USB") {
339             iter++;
340             continue;
341         }
342         onlinePath = path_ + "/" + *iter + "/" + "online";
343         ret = ReadSysfsFile(onlinePath.c_str(), buf, size);
344         if (ret != HDF_SUCCESS) {
345             BATTERY_HILOGD(FEATURE_BATT_INFO, "read online path failed in loop, ret: %{public}d", ret);
346         }
347         online = ParseInt(buf);
348         if (online) {
349             onlineNode = *iter;
350             break;
351         }
352         iter++;
353     }
354 
355     if (ret != HDF_SUCCESS) {
356         BATTERY_HILOGD(FEATURE_BATT_INFO, "read online path failed, ret: %{public}d", ret);
357         return;
358     }
359 
360     if (!online) {
361         BATTERY_HILOGW(FEATURE_BATT_INFO, "charger is not online, so no type return");
362         return;
363     }
364 
365     std::string typeNode = onlineNode;
366     std::string typePath = path_ + "/" + typeNode + "/" + "type";
367     ret = ReadSysfsFile(typePath.c_str(), buf, size);
368     if (ret != HDF_SUCCESS) {
369         BATTERY_HILOGW(FEATURE_BATT_INFO, "read type path failed, ret: %{public}d", ret);
370         return;
371     }
372     Trim(buf);
373 }
374 
PluggedTypeEnumConverter(const char * str) const375 int32_t PowerSupplyProvider::PluggedTypeEnumConverter(const char* str) const
376 {
377     struct StringEnumMap pluggedTypeEnumMap[] = {
378         { "USB", PLUGGED_TYPE_USB },
379         { "USB_PD_DRP", PLUGGED_TYPE_USB },
380         { "Wireless", PLUGGED_TYPE_WIRELESS },
381         { "Mains", PLUGGED_TYPE_AC },
382         { "UPS", PLUGGED_TYPE_AC },
383         { "USB_ACA", PLUGGED_TYPE_AC },
384         { "USB_C", PLUGGED_TYPE_AC },
385         { "USB_CDP", PLUGGED_TYPE_AC },
386         { "USB_DCP", PLUGGED_TYPE_AC },
387         { "USB_HVDCP", PLUGGED_TYPE_AC },
388         { "USB_PD", PLUGGED_TYPE_AC },
389         { "Unknown", PLUGGED_TYPE_BUTT },
390         { nullptr, PLUGGED_TYPE_BUTT },
391     };
392 
393     for (int32_t i = 0; pluggedTypeEnumMap[i].str; ++i) {
394         if (strcmp(str, pluggedTypeEnumMap[i].str) == 0) {
395             return pluggedTypeEnumMap[i].enumVal;
396         }
397     }
398     return PLUGGED_TYPE_BUTT;
399 }
400 
ParsePluggedMaxCurrent(int32_t * maxCurrent)401 int32_t PowerSupplyProvider::ParsePluggedMaxCurrent(int32_t* maxCurrent)
402 {
403     char buf[MAX_BUFF_SIZE] = {0};
404     GetPluggedTypeName(buf, sizeof(buf));
405     std::string currentMaxNode = POWER_SUPPLY_BATTERY;
406 
407     const auto& item = nodeNamePathMap_.find("current_max");
408     if (item != nodeNamePathMap_.end()) {
409         currentMaxNode = item->second;
410     }
411 
412     std::string currentMaxPath = POWER_SUPPLY_BASE_PATH + "/" + currentMaxNode + "/" + "current_max";
413     int32_t ret = ReadBatterySysfsToBuff(currentMaxPath.c_str(), buf, sizeof(buf));
414     if (ret != HDF_SUCCESS) {
415         return ret;
416     }
417     int32_t value = ParseInt(buf);
418     *maxCurrent = value;
419 
420     return HDF_SUCCESS;
421 }
422 
ParsePluggedMaxVoltage(int32_t * maxVoltage)423 int32_t PowerSupplyProvider::ParsePluggedMaxVoltage(int32_t* maxVoltage)
424 {
425     char buf[MAX_BUFF_SIZE] = {0};
426     GetPluggedTypeName(buf, sizeof(buf));
427     std::string voltageMaxNode = POWER_SUPPLY_BATTERY;
428 
429     const auto& item = nodeNamePathMap_.find("voltage_max");
430     if (item != nodeNamePathMap_.end()) {
431         voltageMaxNode = item->second;
432     }
433 
434     std::string voltageMaxPath = POWER_SUPPLY_BASE_PATH + "/" + voltageMaxNode + "/" + "voltage_max";
435     int32_t ret = ReadBatterySysfsToBuff(voltageMaxPath.c_str(), buf, sizeof(buf));
436     if (ret != HDF_SUCCESS) {
437         return ret;
438     }
439     int32_t value = ParseInt(buf);
440     *maxVoltage = value;
441 
442     return HDF_SUCCESS;
443 }
444 
UpdateInfoByReadSysFile(struct BatterydInfo * info)445 void PowerSupplyProvider::UpdateInfoByReadSysFile(struct BatterydInfo* info)
446 {
447     ParseCapacity(&info->capacity_);
448     ParseVoltage(&info->voltage_);
449     ParseTemperature(&info->temperature_);
450     ParseHealthState(&info->healthState_);
451     ParseChargeState(&info->chargeState_);
452     ParseChargeCounter(&info->chargeCounter_);
453     ParseCurrentNow(&info->curNow_);
454     ParseCurrentAverage(&info->curAverage_);
455     ParseRemainEnergy(&info->remainEnergy_);
456     ParseTotalEnergy(&info->totalEnergy_);
457     ParsePresent(&info->present_);
458 
459     info->pluggedType_ = PLUGGED_TYPE_NONE;
460     ParsePluggedType(&info->pluggedType_);
461 
462     info->pluggedMaxCurrent_ = INVALID_BATT_INT_VALUE;
463     ParsePluggedMaxCurrent(&info->pluggedMaxCurrent_);
464 
465     info->pluggedMaxVoltage_ = INVALID_BATT_INT_VALUE;
466     ParsePluggedMaxVoltage(&info->pluggedMaxVoltage_);
467 
468     info->technology_ = INVALID_STRING_VALUE;
469     ParseTechnology(info->technology_);
470 
471     CopyBatteryInfo(info);
472 }
473 
ParseUeventToBatterydInfo(const char * msg,struct BatterydInfo * info)474 void PowerSupplyProvider::ParseUeventToBatterydInfo(const char* msg, struct BatterydInfo* info)
475 {
476     static struct BatteryAssigner batteryAssigners[] = {
477         { BATTERY_KEY_CAPACITY.c_str(), BATTERY_KEY_CAPACITY.length(), CapacityAssigner },
478         { BATTERY_KEY_TOTAL_ENERGY.c_str(), BATTERY_KEY_TOTAL_ENERGY.length(), TotalEnergyAssigner },
479         { BATTERY_KEY_REMAIN_ENERGY.c_str(), BATTERY_KEY_REMAIN_ENERGY.length(), RemainEnergyAssigner },
480         { BATTERY_KEY_VOLTAGE.c_str(), BATTERY_KEY_VOLTAGE.length(), VoltageAssigner },
481         { BATTERY_KEY_TEMPERATURE.c_str(), BATTERY_KEY_TEMPERATURE.length(), TemperatureAssigner },
482         { BATTERY_KEY_HEALTH.c_str(), BATTERY_KEY_HEALTH.length(), HealthStateAssigner },
483         { BATTERY_KEY_CHARGE_STATUS.c_str(), BATTERY_KEY_CHARGE_STATUS.length(), ChargeStateAssigner },
484         { BATTERY_KEY_PRESENT.c_str(), BATTERY_KEY_PRESENT.length(), PresentAssigner },
485         { BATTERY_KEY_TECHNOLOGY.c_str(), BATTERY_KEY_TECHNOLOGY.length(), TechnologyAssigner },
486         { BATTERY_KEY_CHARGE_COUNTER.c_str(), BATTERY_KEY_CHARGE_COUNTER.length(), ChargeCounterAssigner },
487         { BATTERY_KEY_CURRENT_AVERAGE.c_str(), BATTERY_KEY_CURRENT_AVERAGE.length(), CurrentAverageAssigner },
488         { BATTERY_KEY_CURRENT_NOW.c_str(), BATTERY_KEY_CURRENT_NOW.length(), CurrentNowAssigner },
489         { nullptr, 0, nullptr } // end of the array
490     };
491 
492     while (*msg) {
493         for (int32_t i = 0; batteryAssigners[i].prefix; ++i) {
494             if (!strncmp(msg, batteryAssigners[i].prefix, batteryAssigners[i].prefixLen)) {
495                 BATTERY_HILOGD(FEATURE_BATT_INFO, "msg: %{public}s", msg);
496                 msg += batteryAssigners[i].prefixLen;
497                 batteryAssigners[i].Assigner(msg, info);
498                 break;
499             }
500         }
501         while (*msg++) {} // move to next
502     }
503 
504     info->pluggedType_ = PLUGGED_TYPE_NONE;
505     ParsePluggedType(&info->pluggedType_);
506 
507     info->pluggedMaxCurrent_ = INVALID_BATT_INT_VALUE;
508     ParsePluggedMaxCurrent(&info->pluggedMaxCurrent_);
509 
510     info->pluggedMaxVoltage_ = INVALID_BATT_INT_VALUE;
511     ParsePluggedMaxVoltage(&info->pluggedMaxVoltage_);
512 
513     info->technology_ = INVALID_STRING_VALUE;
514     ParseTechnology(info->technology_);
515 
516     CopyBatteryInfo(info);
517 }
518 
CopyBatteryInfo(const struct BatterydInfo * info) const519 void PowerSupplyProvider::CopyBatteryInfo(const struct BatterydInfo* info) const
520 {
521     g_batteryInfo.capacity_ = info->capacity_;
522     g_batteryInfo.voltage_ = info->voltage_;
523     g_batteryInfo.temperature_ = info->temperature_;
524     g_batteryInfo.healthState_ = info->healthState_;
525     g_batteryInfo.pluggedType_ = info->pluggedType_;
526     g_batteryInfo.pluggedMaxCurrent_ = info->pluggedMaxCurrent_;
527     g_batteryInfo.pluggedMaxVoltage_ = info->pluggedMaxVoltage_;
528     g_batteryInfo.chargeState_ = info->chargeState_;
529     g_batteryInfo.chargeCounter_ = info->chargeCounter_;
530     g_batteryInfo.curNow_ = info->curNow_;
531     g_batteryInfo.curAverage_ = info->curAverage_;
532     g_batteryInfo.totalEnergy_ = info->totalEnergy_;
533     g_batteryInfo.remainEnergy_ = info->remainEnergy_;
534     g_batteryInfo.present_ = info->present_;
535     g_batteryInfo.technology_ = info->technology_;
536 }
537 
SetSysFilePath(const std::string & path)538 void PowerSupplyProvider::SetSysFilePath(const std::string& path)
539 {
540     if (path.empty()) {
541         BATTERY_HILOGI(FEATURE_BATT_INFO, "path is empty");
542         return;
543     }
544     path_ = path;
545 }
546 
CreateFile(const std::string & path,const std::string & content)547 void PowerSupplyProvider::CreateFile(const std::string& path, const std::string& content)
548 {
549     if (access(path.c_str(), F_OK) == 0) {
550         return;
551     }
552 
553     std::ofstream stream(path.c_str());
554     if (!stream.is_open()) {
555         BATTERY_HILOGE(FEATURE_BATT_INFO, "cannot create file");
556         return;
557     }
558     stream << content.c_str() << std::endl;
559     stream.close();
560 }
561 
InitBatteryPath()562 void PowerSupplyProvider::InitBatteryPath()
563 {
564     std::string sysLowercaseBatteryPath = "/sys/class/power_supply/battery";
565 
566     if (access(sysLowercaseBatteryPath.c_str(), F_OK) == 0) {
567         BATTERY_HILOGI(FEATURE_BATT_INFO, "system battery path is exist");
568         return;
569     } else {
570         std::string sysCapitalBatteryPath = "/sys/class/power_supply/Battery";
571         if (access(sysCapitalBatteryPath.c_str(), F_OK) == 0) {
572             BATTERY_HILOGI(FEATURE_BATT_INFO, "system Battery path is exist");
573             return;
574         }
575         InitDefaultSysfs();
576     }
577     InitChargerSysfs();
578 }
579 
InitPowerSupplySysfs()580 int32_t PowerSupplyProvider::InitPowerSupplySysfs()
581 {
582     DIR* dir = nullptr;
583     struct dirent* entry = nullptr;
584     index_ = 0;
585 
586     dir = opendir(path_.c_str());
587     if (dir == nullptr) {
588         BATTERY_HILOGE(FEATURE_BATT_INFO, "cannot open path_");
589         return HDF_ERR_IO;
590     }
591 
592     while (true) {
593         entry = readdir(dir);
594         if (entry == nullptr) {
595             break;
596         }
597 
598         if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
599             continue;
600         }
601 
602         if (entry->d_type == DT_DIR || entry->d_type == DT_LNK) {
603             if (index_ >= MAX_SYSFS_SIZE) {
604                 BATTERY_HILOGW(FEATURE_BATT_INFO, "too many power supply types");
605                 break;
606             }
607             nodeNames_.emplace_back(entry->d_name);
608             index_++;
609         }
610     }
611     nodeNamePathMap_.clear();
612     TraversalNode();
613     FormatSysfsPaths();
614     BATTERY_HILOGD(FEATURE_BATT_INFO, "init power supply sysfs nodes, total count %{public}d", index_);
615     closedir(dir);
616 
617     return HDF_SUCCESS;
618 }
619 
InitChargerSysfs()620 void PowerSupplyProvider::InitChargerSysfs()
621 {
622     auto& batteryConfig = BatteryConfig::GetInstance();
623     batteryConfig.ParseConfig();
624     BatteryConfig::ChargerConfig chargerConfig = batteryConfig.GetChargerConfig();
625 
626     std::string mockCurrentLimitPath = chargerConfig.currentPath;
627     if (access(mockCurrentLimitPath.c_str(), 0) == -1) {
628         CreateFile(mockCurrentLimitPath, "0");
629     }
630 
631     std::string mockVoltageLimitPath = chargerConfig.voltagePath;
632     if (access(mockVoltageLimitPath.c_str(), 0) == -1) {
633         CreateFile(mockVoltageLimitPath, "0");
634     }
635 
636     std::string mockChargeTypePath = chargerConfig.chargeTypePath;
637     if (access(mockChargeTypePath.c_str(), 0) == -1) {
638         CreateFile(mockChargeTypePath, "0");
639     }
640 }
641 
TraversalNode()642 void PowerSupplyProvider::TraversalNode()
643 {
644     nodeNamePathMap_.insert(std::make_pair("type", ""));
645     nodeNamePathMap_.insert(std::make_pair("online", ""));
646     nodeNamePathMap_.insert(std::make_pair("current_max", ""));
647     nodeNamePathMap_.insert(std::make_pair("voltage_max", ""));
648     nodeNamePathMap_.insert(std::make_pair("capacity", ""));
649     nodeNamePathMap_.insert(std::make_pair("voltage_now", ""));
650     nodeNamePathMap_.insert(std::make_pair("temp", ""));
651     nodeNamePathMap_.insert(std::make_pair("health", ""));
652     nodeNamePathMap_.insert(std::make_pair("status", ""));
653     nodeNamePathMap_.insert(std::make_pair("present", ""));
654     nodeNamePathMap_.insert(std::make_pair("charge_counter", ""));
655     nodeNamePathMap_.insert(std::make_pair("technology", ""));
656     nodeNamePathMap_.insert(std::make_pair("charge_full", ""));
657     nodeNamePathMap_.insert(std::make_pair("current_avg", ""));
658     nodeNamePathMap_.insert(std::make_pair("current_now", ""));
659     nodeNamePathMap_.insert(std::make_pair("charge_now", ""));
660 
661     auto iter = nodeNames_.begin();
662     while (iter != nodeNames_.end()) {
663         if (*iter == "battery") {
664             CheckSubfolderNode(*iter);
665             iter = nodeNames_.erase(iter);
666         } else {
667             iter++;
668         }
669     }
670 
671     iter = nodeNames_.begin();
672     while (iter != nodeNames_.end()) {
673         if (*iter == POWER_SUPPLY_BATTERY) {
674             CheckSubfolderNode(*iter);
675             iter = nodeNames_.erase(iter);
676         } else {
677             iter++;
678         }
679     }
680 
681     for (auto& nodeName : nodeNames_) {
682         CheckSubfolderNode(nodeName);
683     }
684 }
685 
CheckSubfolderNode(const std::string & path)686 void PowerSupplyProvider::CheckSubfolderNode(const std::string& path)
687 {
688     DIR *dir = nullptr;
689     struct dirent* entry = nullptr;
690     std::string batteryPath = path_ + "/" + path;
691     if (batteryPath.c_str() == nullptr) {
692         BATTERY_HILOGE(FEATURE_BATT_INFO, "the batteryPath is empty.");
693         return;
694     }
695     dir = opendir(batteryPath.c_str());
696     if (dir == nullptr) {
697         BATTERY_HILOGE(FEATURE_BATT_INFO, "subfolder file is not exist.");
698         return;
699     }
700 
701     while (true) {
702         entry = readdir(dir);
703         if (entry == nullptr) {
704             break;
705         }
706 
707         if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
708             continue;
709         }
710 
711         if (entry->d_type == DT_DIR || entry->d_type == DT_LNK) {
712             continue;
713         }
714 
715         if ((strcmp(entry->d_name, "type") == 0) && (nodeNamePathMap_["type"].empty()) &&
716             (strcasecmp(path.c_str(), BATTERY_NODE_PATH.c_str()) != 0)) {
717             nodeNamePathMap_["type"] = path;
718         }
719 
720         for (auto& iter : nodeNamePathMap_) {
721             if ((strcmp(entry->d_name, iter.first.c_str()) == 0) && (nodeNamePathMap_[iter.first].empty())) {
722                 nodeNamePathMap_[iter.first] = path;
723             }
724         }
725     }
726     closedir(dir);
727 }
728 
ParseCapacity(int32_t * capacity)729 int32_t PowerSupplyProvider::ParseCapacity(int32_t* capacity)
730 {
731     char buf[MAX_BUFF_SIZE] = {0};
732 
733     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.capacityPath.c_str(), buf, sizeof(buf));
734     if (ret != HDF_SUCCESS) {
735         return ret;
736     }
737 
738     int32_t value = ParseInt(buf);
739     *capacity = value;
740 
741     return HDF_SUCCESS;
742 }
743 
ParseTotalEnergy(int32_t * totalEnergy)744 int32_t PowerSupplyProvider::ParseTotalEnergy(int32_t* totalEnergy)
745 {
746     char buf[MAX_BUFF_SIZE] = {0};
747 
748     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.totalEnergyPath.c_str(), buf, sizeof(buf));
749     if (ret != HDF_SUCCESS) {
750         return ret;
751     }
752 
753     int32_t value = ParseInt(buf);
754     *totalEnergy = value;
755 
756     return HDF_SUCCESS;
757 }
758 
ParseCurrentAverage(int32_t * curAverage)759 int32_t PowerSupplyProvider::ParseCurrentAverage(int32_t* curAverage)
760 {
761     char buf[MAX_BUFF_SIZE] = {0};
762 
763     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.curAveragePath.c_str(), buf, sizeof(buf));
764     if (ret != HDF_SUCCESS) {
765         return ret;
766     }
767 
768     int32_t value = ParseInt(buf);
769     *curAverage = value;
770 
771     return HDF_SUCCESS;
772 }
773 
ParseCurrentNow(int32_t * curNow)774 int32_t PowerSupplyProvider::ParseCurrentNow(int32_t* curNow)
775 {
776     char buf[MAX_BUFF_SIZE] = {0};
777 
778     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.curNowPath.c_str(), buf, sizeof(buf));
779     if (ret != HDF_SUCCESS) {
780         return ret;
781     }
782 
783     int32_t value = ParseInt(buf);
784     *curNow = value;
785 
786     return HDF_SUCCESS;
787 }
788 
ParseRemainEnergy(int32_t * remainEnergy)789 int32_t PowerSupplyProvider::ParseRemainEnergy(int32_t* remainEnergy)
790 {
791     char buf[MAX_BUFF_SIZE] = {0};
792 
793     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.remainEnergyPath.c_str(), buf, sizeof(buf));
794     if (ret != HDF_SUCCESS) {
795         return ret;
796     }
797 
798     int32_t value = ParseInt(buf);
799     *remainEnergy = value;
800 
801     return HDF_SUCCESS;
802 }
803 
ParseVoltage(int32_t * voltage)804 int32_t PowerSupplyProvider::ParseVoltage(int32_t* voltage)
805 {
806     char buf[MAX_BUFF_SIZE] = {0};
807     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.voltagePath.c_str(), buf, sizeof(buf));
808     if (ret != HDF_SUCCESS) {
809         return ret;
810     }
811 
812     int32_t value = ParseInt(buf);
813     *voltage = value;
814 
815     return HDF_SUCCESS;
816 }
817 
ParseTemperature(int32_t * temperature)818 int32_t PowerSupplyProvider::ParseTemperature(int32_t* temperature)
819 {
820     char buf[MAX_BUFF_SIZE] = {0};
821     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.temperaturePath.c_str(), buf, sizeof(buf));
822     if (ret != HDF_SUCCESS) {
823         return ret;
824     }
825 
826     int32_t value = ParseInt(buf);
827     *temperature = value;
828 
829     return HDF_SUCCESS;
830 }
831 
ParseHealthState(int32_t * healthState)832 int32_t PowerSupplyProvider::ParseHealthState(int32_t* healthState)
833 {
834     char buf[MAX_BUFF_SIZE] = {0};
835     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.healthStatePath.c_str(), buf, sizeof(buf));
836     if (ret != HDF_SUCCESS) {
837         return ret;
838     }
839 
840     Trim(buf);
841     *healthState = HealthStateEnumConverter(buf);
842     return HDF_SUCCESS;
843 }
844 
ParsePluggedType(int32_t * pluggedType)845 int32_t PowerSupplyProvider::ParsePluggedType(int32_t* pluggedType)
846 {
847     char buf[MAX_BUFF_SIZE] = {0};
848     GetPluggedTypeName(buf, sizeof(buf));
849     int32_t type = PluggedTypeEnumConverter(buf);
850     if (type == PLUGGED_TYPE_BUTT) {
851         BATTERY_HILOGD(FEATURE_BATT_INFO, "not support the online type %{public}s", buf);
852         return HDF_ERR_NOT_SUPPORT;
853     }
854 
855     *pluggedType = type;
856     return HDF_SUCCESS;
857 }
858 
ParseChargeState(int32_t * chargeState)859 int32_t PowerSupplyProvider::ParseChargeState(int32_t* chargeState)
860 {
861     char buf[MAX_BUFF_SIZE] = {0};
862     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.chargeStatePath.c_str(), buf, sizeof(buf));
863     if (ret != HDF_SUCCESS) {
864         return ret;
865     }
866 
867     Trim(buf);
868     *chargeState = ChargeStateEnumConverter(buf);
869     return HDF_SUCCESS;
870 }
871 
ParsePresent(int8_t * present)872 int32_t PowerSupplyProvider::ParsePresent(int8_t* present)
873 {
874     char buf[MAX_BUFF_SIZE] = {0};
875     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.presentPath.c_str(), buf, sizeof(buf));
876     if (ret != HDF_SUCCESS) {
877         return ret;
878     }
879 
880     auto value = static_cast<int8_t>(ParseInt(buf));
881     *present = value;
882     return HDF_SUCCESS;
883 }
884 
ParseChargeCounter(int32_t * chargeCounter)885 int32_t PowerSupplyProvider::ParseChargeCounter(int32_t* chargeCounter)
886 {
887     char buf[MAX_BUFF_SIZE] = {0};
888     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.chargeCounterPath.c_str(), buf, sizeof(buf));
889     if (ret != HDF_SUCCESS) {
890         return ret;
891     }
892 
893     int32_t value = ParseInt(buf);
894     *chargeCounter = value;
895 
896     return HDF_SUCCESS;
897 }
898 
ParseTechnology(std::string & technology)899 int32_t PowerSupplyProvider::ParseTechnology(std::string& technology)
900 {
901     char buf[MAX_BUFF_SIZE] = {0};
902     int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.technologyPath.c_str(), buf, sizeof(buf));
903     if (ret != HDF_SUCCESS) {
904         return ret;
905     }
906 
907     technology.assign(buf, strlen(buf));
908     return HDF_SUCCESS;
909 }
910 
ParseChargeType(int32_t * chargeType,std::string & chargeTypePath)911 int32_t PowerSupplyProvider::ParseChargeType(int32_t* chargeType, std::string& chargeTypePath)
912 {
913     char buf[MAX_BUFF_SIZE] = {0};
914     int32_t ret = ReadBatterySysfsToBuff(chargeTypePath.c_str(), buf, sizeof(buf));
915     if (ret != HDF_SUCCESS) {
916         return ret;
917     }
918 
919     Trim(buf);
920     *chargeType = ChargeTypeEumConverter(buf);
921     return HDF_SUCCESS;
922 }
923 
GetBatteryInfo()924 BatterydInfo PowerSupplyProvider::GetBatteryInfo()
925 {
926     UpdateInfoByReadSysFile(&g_batteryInfo);
927     return g_batteryInfo;
928 }
929 
CreateMockTechPath(std::string & mockTechPath)930 void PowerSupplyProvider::CreateMockTechPath(std::string& mockTechPath)
931 {
932     BATTERY_HILOGI(FEATURE_BATT_INFO, "create mockFilePath path");
933     CreateFile(mockTechPath + "/capacity", "1000");
934     CreateFile(mockTechPath + "/current_avg", "1000");
935     CreateFile(mockTechPath + "/current_now", "1000");
936     CreateFile(mockTechPath + "/health", "Over voltage");
937     CreateFile(mockTechPath + "/present", "0");
938     CreateFile(mockTechPath + "/status", "Not charging");
939     CreateFile(mockTechPath + "/type", "Unknown");
940     CreateFile(mockTechPath + "/temp", "345");
941     CreateFile(mockTechPath + "/technology", "Li-ion");
942 }
943 
CreateMockChargerPath(std::string & mockChargerPath)944 void PowerSupplyProvider::CreateMockChargerPath(std::string& mockChargerPath)
945 {
946     BATTERY_HILOGI(FEATURE_BATT_INFO, "create mockFilePath path");
947     CreateFile(mockChargerPath + "/type", "USB");
948     CreateFile(mockChargerPath + "/constant_charge_current", "0");
949     CreateFile(mockChargerPath + "/health", "Good");
950     CreateFile(mockChargerPath + "/online", "1");
951     CreateFile(mockChargerPath + "/status", "Charging");
952 }
953 
CreateMockBatteryPath(std::string & mockBatteryPath)954 void PowerSupplyProvider::CreateMockBatteryPath(std::string& mockBatteryPath)
955 {
956     BATTERY_HILOGI(FEATURE_BATT_INFO, "create mockFilePath path");
957     CreateFile(mockBatteryPath + "/capacity", "11");
958     CreateFile(mockBatteryPath + "/charge_control_limit", "0");
959     CreateFile(mockBatteryPath + "/charge_counter", "4000000");
960     CreateFile(mockBatteryPath + "/charge_full", "4000000");
961     CreateFile(mockBatteryPath + "/charge_now", "4000000");
962     CreateFile(mockBatteryPath + "/constant_charge_current", "0");
963     CreateFile(mockBatteryPath + "/current_avg", "1000");
964     CreateFile(mockBatteryPath + "/current_now", "1000");
965     CreateFile(mockBatteryPath + "/health", "Good");
966     CreateFile(mockBatteryPath + "/input_current_limit", "0");
967     CreateFile(mockBatteryPath + "/online", "1");
968     CreateFile(mockBatteryPath + "/present", "0");
969     CreateFile(mockBatteryPath + "/status", "Charging");
970     CreateFile(mockBatteryPath + "/temp", "222");
971     CreateFile(mockBatteryPath + "/voltage_avg", "4123456");
972     CreateFile(mockBatteryPath + "/voltage_now", "4123456");
973     CreateFile(mockBatteryPath + "/type", "Battery");
974 }
975 
InitDefaultSysfs()976 void PowerSupplyProvider::InitDefaultSysfs()
977 {
978     std::string mockBatteryPath = MOCK_POWER_SUPPLY_BASE_PATH + "/battery";
979     std::string mockChargerPath = MOCK_POWER_SUPPLY_BASE_PATH + "/ohos_charger";
980     std::string mockTechPath = MOCK_POWER_SUPPLY_BASE_PATH + "/ohos-fgu";
981 
982     if (access(mockBatteryPath.c_str(), 0) == -1) {
983         mkdir(mockBatteryPath.c_str(), S_IRWXU | S_IRWXG);
984         sleep(MKDIR_WAIT_TIME);
985     }
986 
987     if (access(mockChargerPath.c_str(), 0) == -1) {
988         mkdir(mockChargerPath.c_str(), S_IRWXU);
989         sleep(MKDIR_WAIT_TIME);
990     }
991 
992     if (access(mockTechPath.c_str(), 0) == -1) {
993         mkdir(mockTechPath.c_str(), S_IRWXU);
994         sleep(MKDIR_WAIT_TIME);
995     }
996 
997     CreateMockTechPath(mockTechPath);
998     CreateMockChargerPath(mockChargerPath);
999     CreateMockBatteryPath(mockBatteryPath);
1000     path_ = MOCK_POWER_SUPPLY_BASE_PATH;
1001 }
1002 
SetChargingLimit(const std::vector<ChargingLimit> & chargerLimitList,std::string & currentPath,std::string & voltagePath)1003 int32_t PowerSupplyProvider::SetChargingLimit(const std::vector<ChargingLimit>& chargerLimitList,
1004     std::string& currentPath, std::string& voltagePath)
1005 {
1006     BATTERY_HILOGD(FEATURE_BATT_INFO, "enter");
1007     if (chargerLimitList.empty()) {
1008         BATTERY_HILOGE(FEATURE_BATT_INFO, "the parameter is empty");
1009         return HDF_ERR_INVALID_PARAM;
1010     }
1011 
1012     std::string limitPath;
1013     std::string chargeLimitStr;
1014     for (const auto& iter : chargerLimitList) {
1015         if (iter.type == ChargingLimitType::TYPE_CURRENT) {
1016             limitPath = currentPath;
1017         } else if (iter.type == ChargingLimitType::TYPE_VOLTAGE) {
1018             limitPath = voltagePath;
1019         }
1020         chargeLimitStr = chargeLimitStr + (iter.protocol + " " + std::to_string(iter.value) + "\n");
1021     }
1022 
1023     int32_t ret = SetConfigByPath(limitPath, chargeLimitStr);
1024     if (ret < HDF_SUCCESS) {
1025         return ret;
1026     }
1027     BATTERY_HILOGD(FEATURE_BATT_INFO, "Exit");
1028     return HDF_SUCCESS;
1029 }
1030 
SetConfigByPath(const std::string & path,const std::string & value)1031 int32_t PowerSupplyProvider::SetConfigByPath(const std::string& path, const std::string& value)
1032 {
1033     BATTERY_HILOGI(FEATURE_BATT_INFO, "SetConfigByPath enter, path: %{public}s, value:%{public}s",
1034         path.c_str(), value.c_str());
1035     if (path.empty()) {
1036         BATTERY_HILOGE(FEATURE_BATT_INFO, "the featurePath is empty");
1037         return HDF_ERR_INVALID_PARAM;
1038     }
1039 
1040     int32_t fd = open(path.c_str(), O_TRUNC | O_WRONLY);
1041     if (fd < NUM_ZERO) {
1042         BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to open file %{public}s, errno: %{public}d",
1043             path.c_str(), errno);
1044         return HDF_ERR_IO;
1045     }
1046 
1047     ssize_t size = static_cast<ssize_t>(value.length());
1048     if (write(fd, value.c_str(), size) != size) {
1049         BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to write file %{public}s, errno: %{public}d",
1050             path.c_str(), errno);
1051         close(fd);
1052         return HDF_ERR_IO;
1053     }
1054     close(fd);
1055 
1056     BATTERY_HILOGD(FEATURE_BATT_INFO, "SetConfigByPath exit");
1057     return HDF_SUCCESS;
1058 }
1059 
GetConfigByPath(const std::string & path,std::string & result)1060 int32_t PowerSupplyProvider::GetConfigByPath(const std::string& path, std::string& result)
1061 {
1062     if (path.empty()) {
1063         BATTERY_HILOGE(FEATURE_BATT_INFO, "the featurePath is empty");
1064         result = "";
1065         return HDF_ERR_INVALID_PARAM;
1066     }
1067 
1068     char buf[MAX_BUFF_SIZE] = {0};
1069     int32_t ret = ReadBatterySysfsToBuff(path.c_str(), buf, sizeof(buf));
1070     if (ret != HDF_SUCCESS) {
1071         BATTERY_HILOGE(FEATURE_BATT_INFO, "read config failed, path: %{public}s", path.c_str());
1072         result = "";
1073         return ret;
1074     }
1075     Trim(buf);
1076     result = buf;
1077     BATTERY_HILOGI(FEATURE_BATT_INFO, "GetConfigByPath(%{public}s) exit, value:%{public}s",
1078         path.c_str(), result.c_str());
1079     return HDF_SUCCESS;
1080 }
1081 
CheckPathExists(const std::string & path,bool & result)1082 int32_t PowerSupplyProvider::CheckPathExists(const std::string& path, bool& result)
1083 {
1084     if (path.empty()) {
1085         BATTERY_HILOGE(FEATURE_BATT_INFO, "the path is empty");
1086         result = false;
1087         return HDF_ERR_INVALID_PARAM;
1088     }
1089     result = access(path.c_str(), F_OK) == 0;
1090     BATTERY_HILOGI(FEATURE_BATT_INFO, "CheckPathExists(%{public}s) exit, value:%{public}d", path.c_str(), result);
1091     return HDF_SUCCESS;
1092 }
1093 }  // namespace V2_0
1094 }  // namespace Battery
1095 }  // namespace HDI
1096 }  // namespace OHOS
1097