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