aidl: battery: Switch to using JSON config for sysfs paths
This commit is contained in:
@@ -10,6 +10,7 @@ cc_binary {
|
||||
init_rc: ["vendor.samsung_ext.framework.battery-service.rc"],
|
||||
vintf_fragments: ["vendor.samsung_ext.framework.battery-service.xml"],
|
||||
srcs: [
|
||||
"JSONParser.cpp",
|
||||
"SmartCharge.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
@@ -21,11 +22,19 @@ cc_binary {
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libsafestoi",
|
||||
"libjsoncpp",
|
||||
"android.hardware.health@2.0",
|
||||
"android.hardware.health-V1-ndk",
|
||||
"vendor.samsung_ext.framework.battery-V1-ndk",
|
||||
],
|
||||
whole_static_libs: ["libhealthhalutils"],
|
||||
system_ext_specific: true,
|
||||
required: ["battery.default"],
|
||||
required: ["smartcharge_nodes_json"],
|
||||
}
|
||||
|
||||
prebuilt_etc {
|
||||
name: "smartcharge_nodes_json",
|
||||
src: "smartcharge_nodes.json",
|
||||
filename_from_src: true,
|
||||
system_ext_specific: true,
|
||||
}
|
||||
|
||||
136
aidl/battery/default/JSONParser.cpp
Normal file
136
aidl/battery/default/JSONParser.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "JSONParser.hpp"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
void ConfigParser::handler_OpenFile(const std::string &node,
|
||||
const std::string &data) {
|
||||
LOG(DEBUG) << "Opening file: " << data;
|
||||
std::ifstream file(node);
|
||||
std::string line;
|
||||
|
||||
if (file) {
|
||||
file >> line;
|
||||
} else {
|
||||
PLOG(ERROR) << "Failed to read file";
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigParser::handler_WriteFile(const std::string &node,
|
||||
const std::string &data) {
|
||||
LOG(DEBUG) << "Writing to file: " << data;
|
||||
std::ofstream file(node);
|
||||
if (file) {
|
||||
file << data;
|
||||
} else {
|
||||
PLOG(ERROR) << "Failed to write to file";
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a pair with the matching device and its match quality.
|
||||
std::pair<Json::Value, ConfigParser::MatchQuality>
|
||||
ConfigParser::lookupEntry(const SearchEntry &search) {
|
||||
std::pair<Json::Value, MatchQuality> current = {root, MatchQuality::NO_MATCH};
|
||||
for (const auto &devices : root) {
|
||||
if (devices["codename"].asString() == search.codename) {
|
||||
current = {devices, MatchQuality::EXACT};
|
||||
break;
|
||||
}
|
||||
if (devices["vendor"].asString() == search.vendor) {
|
||||
current = {devices, MatchQuality::MATCHES_VENDOR};
|
||||
}
|
||||
}
|
||||
if (current.second == MatchQuality::NO_MATCH) {
|
||||
LOG(ERROR) << "No matching device found";
|
||||
return current;
|
||||
}
|
||||
LOG(DEBUG) << "Found a match with quality: ";
|
||||
switch (current.second) {
|
||||
case MatchQuality::EXACT:
|
||||
LOG(DEBUG) << "EXACT";
|
||||
break;
|
||||
case MatchQuality::MATCHES_VENDOR:
|
||||
LOG(DEBUG) << "MATCHES_VENDOR";
|
||||
break;
|
||||
case MatchQuality::NO_MATCH:
|
||||
break;
|
||||
};
|
||||
return current;
|
||||
}
|
||||
|
||||
ConfigParser::ConfigParser(const std::string &path) {
|
||||
std::ifstream file(path);
|
||||
if (!file.is_open()) {
|
||||
PLOG(ERROR) << "Failed to open file";
|
||||
return;
|
||||
}
|
||||
file >> root;
|
||||
}
|
||||
|
||||
std::function<void(bool)> ConfigParser::findEntry(const SearchEntry &search) {
|
||||
constexpr int ENABLE_FN_INDEX = 0;
|
||||
constexpr int DISABLE_FN_INDEX = 1;
|
||||
std::array<std::function<void(void)>, 2> handlers;
|
||||
|
||||
const auto current = lookupEntry(search);
|
||||
if (current.second == MatchQuality::NO_MATCH) {
|
||||
return [](bool) {};
|
||||
}
|
||||
|
||||
for (const auto &action : current.first["actions"]) {
|
||||
if (!action["action"].isString()) {
|
||||
LOG(ERROR) << "Invalid action type";
|
||||
return [](bool) {};
|
||||
}
|
||||
const std::string actionType = action["action"].asString();
|
||||
const std::string node = action["node"].asString();
|
||||
const std::string handlerName = action["handler"].asString();
|
||||
const std::string handlerData = action["handler_data"].asString();
|
||||
|
||||
if (actionType == "enable") {
|
||||
for (const auto &handler : m_handlers) {
|
||||
if (handler.first == handlerName) {
|
||||
handlers[ENABLE_FN_INDEX] = [callback = handler.second, node,
|
||||
handlerData]() {
|
||||
callback(node, handlerData);
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!handlers[ENABLE_FN_INDEX]) {
|
||||
LOG(ERROR) << "No handlers found for enable action";
|
||||
return [](bool) {};
|
||||
}
|
||||
} else if (actionType == "disable") {
|
||||
for (const auto &handler : m_handlers) {
|
||||
if (handler.first == handlerName) {
|
||||
handlers[DISABLE_FN_INDEX] = [callback = handler.second, node,
|
||||
handlerData]() {
|
||||
callback(node, handlerData);
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!handlers[DISABLE_FN_INDEX]) {
|
||||
LOG(ERROR) << "No handlers found for disable action";
|
||||
return [](bool) {};
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << "Invalid action type";
|
||||
return [](bool) {};
|
||||
}
|
||||
}
|
||||
return [handlers](bool enable) {
|
||||
if (enable) {
|
||||
handlers[ENABLE_FN_INDEX]();
|
||||
} else {
|
||||
handlers[DISABLE_FN_INDEX]();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
46
aidl/battery/default/JSONParser.hpp
Normal file
46
aidl/battery/default/JSONParser.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <json/json.h>
|
||||
#include <functional>
|
||||
|
||||
class ConfigParser {
|
||||
public:
|
||||
struct SearchEntry;
|
||||
|
||||
private:
|
||||
Json::Value root;
|
||||
struct Handler {
|
||||
std::function<void(const std::string &, const std::string &)> handler;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
static void handler_OpenFile(const std::string &node,
|
||||
const std::string &data);
|
||||
|
||||
static void handler_WriteFile(const std::string &node,
|
||||
const std::string &data);
|
||||
|
||||
// Takes a node path and data
|
||||
using HandlerFunction =
|
||||
std::function<void(const std::string &, const std::string &)>;
|
||||
// Takes name and handler function
|
||||
using HandlerType = std::pair<std::string, HandlerFunction>;
|
||||
|
||||
std::vector<HandlerType> m_handlers = {
|
||||
{"OpenFile", handler_OpenFile},
|
||||
{"WriteFile", handler_WriteFile},
|
||||
};
|
||||
|
||||
enum class MatchQuality { EXACT, MATCHES_VENDOR, NO_MATCH };
|
||||
|
||||
// Returns a pair with the matching device and its match quality.
|
||||
std::pair<Json::Value, MatchQuality> lookupEntry(const SearchEntry &search);
|
||||
|
||||
public:
|
||||
ConfigParser(const std::string &path);
|
||||
|
||||
struct SearchEntry {
|
||||
std::string codename;
|
||||
std::string vendor;
|
||||
};
|
||||
|
||||
std::function<void(bool)> findEntry(const SearchEntry &search);
|
||||
};
|
||||
@@ -5,17 +5,17 @@
|
||||
*/
|
||||
|
||||
#include "SmartCharge.h"
|
||||
#include "modules/include/battery.h"
|
||||
#include "JSONParser.hpp"
|
||||
|
||||
#include <GetServiceSupport.h>
|
||||
#include <SafeStoi.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <dlfcn.h>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
@@ -37,22 +37,18 @@ static constexpr int kInvalidCfg = -1;
|
||||
|
||||
static const char kSmartChargeConfigProp[] = "persist.ext.smartcharge.config";
|
||||
static const char kSmartChargeEnabledProp[] = "persist.ext.smartcharge.enabled";
|
||||
static const char kSmartChargeOverrideProp[] = "ro.hardware.battery";
|
||||
static const char kComma = ',';
|
||||
|
||||
template <typename T>
|
||||
using is_integral_or_bool =
|
||||
std::enable_if_t<std::is_integral_v<T> || std::is_same_v<T, bool>, bool>;
|
||||
|
||||
static inline bool isValidBool(const int val) {
|
||||
return val == !!val;
|
||||
}
|
||||
static inline bool isValidBool(const int val) { return val == !!val; }
|
||||
static inline bool verifyConfig(const int lower, const int upper) {
|
||||
return !(upper <= lower || upper > 95 || (0 <= lower && lower < 50));
|
||||
}
|
||||
|
||||
template <typename T, is_integral_or_bool<T> = true>
|
||||
struct ConfigPair {
|
||||
template <typename T, is_integral_or_bool<T> = true> struct ConfigPair {
|
||||
T first, second;
|
||||
std::string toString(void) {
|
||||
return std::to_string(first) + kComma + std::to_string(second);
|
||||
@@ -74,8 +70,7 @@ bool fromString(const std::string &v, ConfigPair<U> *pair) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool fromString(const std::string &v, ConfigPair<bool> *pair) {
|
||||
template <> bool fromString(const std::string &v, ConfigPair<bool> *pair) {
|
||||
ConfigPair<int> tmp{};
|
||||
if (fromString<int>(v, &tmp) && isValidBool(tmp.first) &&
|
||||
isValidBool(tmp.second)) {
|
||||
@@ -86,11 +81,10 @@ bool fromString(const std::string &v, ConfigPair<bool> *pair) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool getAndParse(const char *prop, ConfigPair<U> *pair) {
|
||||
template <typename U> bool getAndParse(const char *prop, ConfigPair<U> *pair) {
|
||||
std::string propval = GetProperty(prop, "");
|
||||
if (!propval.empty()) {
|
||||
return fromString(propval, pair);
|
||||
return fromString(propval, pair);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -115,7 +109,8 @@ void SmartCharge::loadHealthImpl(void) {
|
||||
healthState = USE_HEALTH_HIDL;
|
||||
ALOGD("%s: Connected to health HIDL V2.0 HAL", __func__);
|
||||
hidl_death_recp = new hidl_health_death_recipient(health_hidl);
|
||||
auto ret = health_hidl->linkToDeath(hidl_death_recp, reinterpret_cast<uint64_t>(this));
|
||||
auto ret = health_hidl->linkToDeath(hidl_death_recp,
|
||||
reinterpret_cast<uint64_t>(this));
|
||||
linkToDeathSuccess = ret.isOk();
|
||||
reason = ret.description();
|
||||
} else {
|
||||
@@ -125,9 +120,9 @@ void SmartCharge::loadHealthImpl(void) {
|
||||
healthState = USE_HEALTH_AIDL;
|
||||
ALOGD("%s: Connected to health AIDL HAL", __func__);
|
||||
aidl_death_recp = ndk::ScopedAIBinder_DeathRecipient(
|
||||
AIBinder_DeathRecipient_new(onServiceDied)
|
||||
);
|
||||
auto ret = AIBinder_linkToDeath(health_aidl->asBinder().get(), aidl_death_recp.get(), this);
|
||||
AIBinder_DeathRecipient_new(onServiceDied));
|
||||
auto ret = AIBinder_linkToDeath(health_aidl->asBinder().get(),
|
||||
aidl_death_recp.get(), this);
|
||||
linkToDeathSuccess = ret == STATUS_OK;
|
||||
reason = ndk::ScopedAStatus(AStatus_fromStatus(ret)).getDescription();
|
||||
}
|
||||
@@ -151,35 +146,14 @@ bool SmartCharge::loadAndParseConfigProp(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef __LP64__
|
||||
#define LIB_PATH "/system_ext/lib64/hw/"
|
||||
#else
|
||||
#define LIB_PATH "/system_ext/lib/hw/"
|
||||
#endif
|
||||
void SmartCharge::loadConfiguration(void) {
|
||||
ConfigParser parser("/system_ext/etc/smartcharge_nodes.json");
|
||||
|
||||
void SmartCharge::loadImplLibrary(void) {
|
||||
const static std::string filename = "battery." +
|
||||
GetProperty(kSmartChargeOverrideProp, "default") + ".so";
|
||||
const static std::string path = LIB_PATH + filename;
|
||||
|
||||
ALOGI("%s: Try dlopen '%s'", __func__, path.c_str());
|
||||
handle = dlopen(path.c_str(), RTLD_NOW);
|
||||
if (handle) {
|
||||
setChargableFunc = reinterpret_cast<void(*)(const bool)>(
|
||||
dlsym(handle, MODULE_SYM_NAME));
|
||||
|
||||
if (setChargableFunc) {
|
||||
ALOGD("%s: " MODULE_SYM_NAME " function loaded", __func__);
|
||||
} else {
|
||||
ALOGE("%s: Failed to find " MODULE_SYM_NAME " symbol", __func__);
|
||||
// Unused handle, close it
|
||||
dlclose(handle);
|
||||
}
|
||||
} else {
|
||||
ALOGE("%s: %s", __func__, dlerror() ?: "unknown");
|
||||
}
|
||||
setChargableFunc = parser.findEntry({GetProperty("ro.product.device", ""),
|
||||
GetProperty("ro.product.manufacturer", "")});
|
||||
if (!setChargableFunc) {
|
||||
setChargableFunc = [] (const bool) {};
|
||||
ALOGD("%s: Using stub for setChargableFunc", __func__);
|
||||
setChargableFunc = [](const bool) {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +176,7 @@ SmartCharge::SmartCharge(void) {
|
||||
bool ret;
|
||||
|
||||
loadHealthImpl();
|
||||
loadImplLibrary();
|
||||
loadConfiguration();
|
||||
|
||||
ret = loadAndParseConfigProp();
|
||||
if (ret) {
|
||||
@@ -227,12 +201,12 @@ void SmartCharge::startLoop(bool withrestart) {
|
||||
BatteryStatus status_aidl = BatteryStatus::UNKNOWN;
|
||||
auto ret = health_aidl->getCapacity(&per);
|
||||
if (!ret.isOk()) {
|
||||
per = ret.getStatus();
|
||||
per = ret.getStatus();
|
||||
break;
|
||||
}
|
||||
ret = health_aidl->getChargeStatus(&status_aidl);
|
||||
if (!ret.isOk()) {
|
||||
per = ret.getStatus();
|
||||
per = ret.getStatus();
|
||||
break;
|
||||
}
|
||||
switch (status_aidl) {
|
||||
@@ -243,15 +217,15 @@ void SmartCharge::startLoop(bool withrestart) {
|
||||
case BatteryStatus::DISCHARGING:
|
||||
case BatteryStatus::NOT_CHARGING:
|
||||
current = ChargeStatus::OFF;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
break;
|
||||
}
|
||||
case USE_HEALTH_HIDL: {
|
||||
using ::android::hardware::health::V2_0::Result;
|
||||
using ::android::hardware::health::V1_0::BatteryStatus;
|
||||
using ::android::hardware::health::V2_0::Result;
|
||||
|
||||
ScopedLock _(hal_health_lock);
|
||||
Result res = Result::UNKNOWN;
|
||||
@@ -264,10 +238,11 @@ void SmartCharge::startLoop(bool withrestart) {
|
||||
per = -(static_cast<int>(res));
|
||||
break;
|
||||
}
|
||||
health_hidl->getChargeStatus([&res, &status_hidl](Result hal_res, BatteryStatus hal_value) {
|
||||
res = hal_res;
|
||||
status_hidl = hal_value;
|
||||
});
|
||||
health_hidl->getChargeStatus(
|
||||
[&res, &status_hidl](Result hal_res, BatteryStatus hal_value) {
|
||||
res = hal_res;
|
||||
status_hidl = hal_value;
|
||||
});
|
||||
if (res != Result::SUCCESS) {
|
||||
per = -(static_cast<int>(res));
|
||||
break;
|
||||
@@ -304,7 +279,8 @@ void SmartCharge::startLoop(bool withrestart) {
|
||||
skip = true;
|
||||
|
||||
if (current != policy && !skip) {
|
||||
ALOGD("%s: Updating current, current %d, policy %d", __func__, current, policy);
|
||||
ALOGD("%s: Updating current, current %d, policy %d", __func__, current,
|
||||
policy);
|
||||
switch (policy) {
|
||||
case ChargeStatus::OFF:
|
||||
setChargableFunc(false);
|
||||
@@ -320,7 +296,8 @@ void SmartCharge::startLoop(bool withrestart) {
|
||||
skip = false;
|
||||
if (cv.wait_for(lock, 5s) == std::cv_status::no_timeout) {
|
||||
// cv signaled, exit now if kRunning is false
|
||||
if (!kRunning) break;
|
||||
if (!kRunning)
|
||||
break;
|
||||
}
|
||||
}
|
||||
ALOGD("%s: --", __func__);
|
||||
@@ -329,12 +306,14 @@ void SmartCharge::startLoop(bool withrestart) {
|
||||
void SmartCharge::createLoopThread(bool restart) {
|
||||
ScopedLock _(thread_lock);
|
||||
ALOGD("%s: create thread", __func__);
|
||||
kLoopThread = std::make_shared<std::thread>(&SmartCharge::startLoop, this, restart);
|
||||
kLoopThread =
|
||||
std::make_shared<std::thread>(&SmartCharge::startLoop, this, restart);
|
||||
kRunning = true;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus SmartCharge::setChargeLimit(int32_t upper_, int32_t lower_) {
|
||||
ALOGD("%s: upper: %d, lower: %d, kRun: %d", __func__, upper_, lower_, kRunning.load());
|
||||
ALOGD("%s: upper: %d, lower: %d, kRun: %d", __func__, upper_, lower_,
|
||||
kRunning.load());
|
||||
if (!verifyConfig(lower_, upper_))
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
if (kRunning)
|
||||
@@ -390,56 +369,50 @@ ndk::ScopedAStatus SmartCharge::activate(bool enable, bool restart) {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
binder_status_t SmartCharge::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
|
||||
Dl_info info;
|
||||
void *addr;
|
||||
auto tryLockFn = [](std::mutex& m) {
|
||||
const std::unique_lock<std::mutex> lk{m, std::try_to_lock};
|
||||
return !lk.owns_lock();
|
||||
binder_status_t SmartCharge::dump(int fd, const char ** /* args */,
|
||||
uint32_t /* numArgs */) {
|
||||
auto tryLockFn = [](std::mutex &m) {
|
||||
const std::unique_lock<std::mutex> lk{m, std::try_to_lock};
|
||||
return !lk.owns_lock();
|
||||
};
|
||||
|
||||
dprintf(fd, "Loop thread running: %d\n", kRunning.load());
|
||||
if (kRunning) {
|
||||
dprintf(fd, "Loop thread charge control state: ");
|
||||
switch (status) {
|
||||
case ChargeStatus::ON:
|
||||
dprintf(fd, "ON");
|
||||
break;
|
||||
case ChargeStatus::OFF:
|
||||
dprintf(fd, "OFF");
|
||||
break;
|
||||
}
|
||||
dprintf(fd, "\n");
|
||||
dprintf(fd, "Loop thread charge control state: ");
|
||||
switch (status) {
|
||||
case ChargeStatus::ON:
|
||||
dprintf(fd, "ON");
|
||||
break;
|
||||
case ChargeStatus::OFF:
|
||||
dprintf(fd, "OFF");
|
||||
break;
|
||||
}
|
||||
dprintf(fd, "\n");
|
||||
}
|
||||
dprintf(fd, "Configuration (upper/lower): %d %d\n", upper, lower);
|
||||
dprintf(fd, "Mutex locked (config/thread/cv) %d %d %d\n", tryLockFn(config_lock),
|
||||
tryLockFn(thread_lock), tryLockFn(kCVLock));
|
||||
dprintf(fd, "Mutex locked (config/thread/cv) %d %d %d\n",
|
||||
tryLockFn(config_lock), tryLockFn(thread_lock), tryLockFn(kCVLock));
|
||||
dprintf(fd, "Connected Health HAL: ");
|
||||
switch (healthState) {
|
||||
case USE_HEALTH_AIDL:
|
||||
dprintf(fd, "AIDL Health HAL V1");
|
||||
break;
|
||||
case USE_HEALTH_HIDL:
|
||||
dprintf(fd, "HIDL Health HAL V2.0");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case USE_HEALTH_AIDL:
|
||||
dprintf(fd, "AIDL Health HAL V1");
|
||||
break;
|
||||
case USE_HEALTH_HIDL:
|
||||
dprintf(fd, "HIDL Health HAL V2.0");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
dprintf(fd, "\n");
|
||||
addr = dlsym(handle, MODULE_SYM_NAME);
|
||||
if (dladdr(addr, &info) != 0) {
|
||||
dprintf(fd, "Impl library path: %s\n", info.dli_fname);
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
using ::android::hardware::interfacesEqual;
|
||||
|
||||
void hidl_health_death_recipient::serviceDied(uint64_t cookie,
|
||||
const wp<::android::hidl::base::V1_0::IBase>& who) {
|
||||
if (mHealth != nullptr && interfacesEqual(mHealth, who.promote())) {
|
||||
onServiceDied(reinterpret_cast<void*>(cookie));
|
||||
}
|
||||
void hidl_health_death_recipient::serviceDied(
|
||||
uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase> &who) {
|
||||
if (mHealth != nullptr && interfacesEqual(mHealth, who.promote())) {
|
||||
onServiceDied(reinterpret_cast<void *>(cookie));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace battery
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include <aidl/android/hardware/health/BnHealth.h>
|
||||
#include <healthhalutils/HealthHalUtils.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
@@ -62,7 +60,6 @@ class SmartCharge : public BnSmartCharge {
|
||||
// Used by above condition_variable
|
||||
std::mutex kCVLock;
|
||||
|
||||
void* handle;
|
||||
std::function<void(const bool)> setChargableFunc;
|
||||
|
||||
sp<IHealth> health_hidl;
|
||||
@@ -84,7 +81,7 @@ class SmartCharge : public BnSmartCharge {
|
||||
} status;
|
||||
|
||||
bool loadAndParseConfigProp();
|
||||
void loadImplLibrary();
|
||||
void loadConfiguration();
|
||||
void loadEnabledAndStart();
|
||||
|
||||
public:
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
cc_library_headers {
|
||||
name: "aidl_battery_module_headers",
|
||||
export_include_dirs: ["include"],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "aidl_battery_module_defaults",
|
||||
header_libs: ["aidl_battery_module_headers"],
|
||||
relative_install_path: "hw",
|
||||
compile_multilib: "first",
|
||||
system_ext_specific: true,
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "battery.default",
|
||||
defaults: ["aidl_battery_module_defaults"],
|
||||
srcs: ["DefaultImpl.cpp"],
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#include <battery.h>
|
||||
#include <fstream>
|
||||
|
||||
static const char kChargeCtlSysfs[] =
|
||||
"/sys/class/power_supply/battery/batt_slate_mode";
|
||||
|
||||
extern "C" void setChargable(bool enable) {
|
||||
std::ofstream p(kChargeCtlSysfs);
|
||||
if (p)
|
||||
p << !enable;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#include <battery.h>
|
||||
|
||||
extern "C"
|
||||
void setChargable(bool enable) {
|
||||
(void) enable;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* setChargable - Target specific method of enabling charge.
|
||||
*
|
||||
* @param enable Enable charging or not
|
||||
* @return void
|
||||
*/
|
||||
extern void setChargable(const bool enable);
|
||||
|
||||
#define MODULE_SYM_NAME "setChargable"
|
||||
|
||||
__END_DECLS
|
||||
35
aidl/battery/default/smartcharge_nodes.json
Normal file
35
aidl/battery/default/smartcharge_nodes.json
Normal file
@@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"codename": "tb128fu",
|
||||
"vendor": "lenovo",
|
||||
"actions": [
|
||||
{
|
||||
"action": "enable",
|
||||
"node": "/sys/class/power_supply/battery/StartCharging_Test",
|
||||
"handler": "OpenFile"
|
||||
},
|
||||
{
|
||||
"action": "disable",
|
||||
"node": "/sys/class/power_supply/battery/StopCharging_Test",
|
||||
"handler": "OpenFile"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"vendor": "samsung",
|
||||
"actions": [
|
||||
{
|
||||
"action": "enable",
|
||||
"node": "/sys/class/power_supply/battery/batt_slate_mode",
|
||||
"handler": "WriteFile",
|
||||
"handler_data": "0"
|
||||
},
|
||||
{
|
||||
"action": "disable",
|
||||
"node": "/sys/class/power_supply/battery/batt_slate_mode",
|
||||
"handler": "WriteFile",
|
||||
"handler_data": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -2,5 +2,3 @@ persist.ext. u:object_r:ext_prop:s0
|
||||
persist.ext.smartcharge. u:object_r:ext_smartcharge_prop:s0
|
||||
persist.ext.flashlight. u:object_r:ext_flashlight_prop:s0
|
||||
persist.ext.logdump. u:object_r:ext_logger_prop:s0
|
||||
|
||||
ro.hardware.battery u:object_r:exported_default_prop:s0 exact string
|
||||
|
||||
Reference in New Issue
Block a user