Add charger indication receiver in Gnss Hidl
Register HEALTH Hal client in all Gnss Hidl impl to acquire charger indication. Change-Id: I3fcc00dd14a95e2375ab27a8c84c260300f9e90d CRs-fixed: 2411445
This commit is contained in:
parent
51426e477b
commit
89583a78f0
10 changed files with 388 additions and 7 deletions
|
@ -28,7 +28,8 @@ LOCAL_HEADER_LIBRARIES := \
|
|||
libgps.utils_headers \
|
||||
libloc_core_headers \
|
||||
libloc_pla_headers \
|
||||
liblocation_api_headers
|
||||
liblocation_api_headers \
|
||||
liblocbatterylistener_headers
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog \
|
||||
|
@ -38,6 +39,10 @@ LOCAL_SHARED_LIBRARIES := \
|
|||
libcutils \
|
||||
libutils \
|
||||
android.hardware.gnss@1.0 \
|
||||
android.hardware.health@1.0 \
|
||||
android.hardware.health@2.0 \
|
||||
android.hardware.power@1.2 \
|
||||
libbase
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += \
|
||||
libloc_core \
|
||||
|
@ -46,6 +51,8 @@ LOCAL_SHARED_LIBRARIES += \
|
|||
liblocation_api \
|
||||
|
||||
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||
LOCAL_STATIC_LIBRARIES := liblocbatterylistener
|
||||
LOCAL_STATIC_LIBRARIES += libhealthhalutils
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#define LOG_TAG "LocSvc_GnssInterface"
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
#include <fstream>
|
||||
#include <log_util.h>
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include <cutils/properties.h>
|
||||
#include "Gnss.h"
|
||||
#include <LocationUtil.h>
|
||||
#include "battery_listener.h"
|
||||
|
||||
typedef const GnssInterface* (getLocationInterface)();
|
||||
|
||||
|
@ -44,8 +46,13 @@ void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who
|
|||
}
|
||||
}
|
||||
|
||||
void location_on_battery_status_changed(bool charging) {
|
||||
LOC_LOGd("%s: battery status changed to %s charging", __func__, charging ? "" : "not ");
|
||||
}
|
||||
Gnss::Gnss() {
|
||||
ENTRY_LOG_CALLFLOW();
|
||||
// register health client to listen on battery change
|
||||
loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
|
||||
// clear pending GnssConfig
|
||||
memset(&mPendingConfig, 0, sizeof(GnssConfig));
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ LOCAL_HEADER_LIBRARIES := \
|
|||
libgps.utils_headers \
|
||||
libloc_core_headers \
|
||||
libloc_pla_headers \
|
||||
liblocation_api_headers
|
||||
liblocation_api_headers \
|
||||
liblocbatterylistener_headers
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog \
|
||||
|
@ -39,6 +40,10 @@ LOCAL_SHARED_LIBRARIES := \
|
|||
libutils \
|
||||
android.hardware.gnss@1.0 \
|
||||
android.hardware.gnss@1.1 \
|
||||
android.hardware.health@1.0 \
|
||||
android.hardware.health@2.0 \
|
||||
android.hardware.power@1.2 \
|
||||
libbase
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += \
|
||||
libloc_core \
|
||||
|
@ -47,6 +52,8 @@ LOCAL_SHARED_LIBRARIES += \
|
|||
liblocation_api \
|
||||
|
||||
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||
LOCAL_STATIC_LIBRARIES := liblocbatterylistener
|
||||
LOCAL_STATIC_LIBRARIES += libhealthhalutils
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#define LOG_TAG "LocSvc_GnssInterface"
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
#include <fstream>
|
||||
#include <log_util.h>
|
||||
|
@ -27,6 +28,8 @@
|
|||
#include "Gnss.h"
|
||||
#include <LocationUtil.h>
|
||||
|
||||
#include "battery_listener.h"
|
||||
|
||||
typedef const GnssInterface* (getLocationInterface)();
|
||||
|
||||
#define IMAGES_INFO_FILE "/sys/devices/soc0/images"
|
||||
|
@ -84,8 +87,13 @@ void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who
|
|||
}
|
||||
}
|
||||
|
||||
void location_on_battery_status_changed(bool charging) {
|
||||
LOC_LOGd("%s: battery status changed to %s charging", __func__, charging ? "" : "not ");
|
||||
}
|
||||
Gnss::Gnss() {
|
||||
ENTRY_LOG_CALLFLOW();
|
||||
// register health client to listen on battery change
|
||||
loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
|
||||
// clear pending GnssConfig
|
||||
memset(&mPendingConfig, 0, sizeof(GnssConfig));
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ LOCAL_HEADER_LIBRARIES := \
|
|||
libgps.utils_headers \
|
||||
libloc_core_headers \
|
||||
libloc_pla_headers \
|
||||
liblocation_api_headers
|
||||
liblocation_api_headers \
|
||||
liblocbatterylistener_headers
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog \
|
||||
|
@ -50,7 +51,11 @@ LOCAL_SHARED_LIBRARIES := \
|
|||
android.hardware.gnss@1.1 \
|
||||
android.hardware.gnss@2.0 \
|
||||
android.hardware.gnss.measurement_corrections@1.0 \
|
||||
android.hardware.gnss.visibility_control@1.0
|
||||
android.hardware.gnss.visibility_control@1.0 \
|
||||
android.hardware.health@1.0 \
|
||||
android.hardware.health@2.0 \
|
||||
android.hardware.power@1.2 \
|
||||
libbase
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += \
|
||||
libloc_core \
|
||||
|
@ -59,6 +64,8 @@ LOCAL_SHARED_LIBRARIES += \
|
|||
liblocation_api \
|
||||
|
||||
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||
LOCAL_STATIC_LIBRARIES := liblocbatterylistener
|
||||
LOCAL_STATIC_LIBRARIES += libhealthhalutils
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#define LOG_TAG "LocSvc_GnssInterface"
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
#include <fstream>
|
||||
#include <log_util.h>
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include <cutils/properties.h>
|
||||
#include "Gnss.h"
|
||||
#include "LocationUtil.h"
|
||||
#include "battery_listener.h"
|
||||
|
||||
typedef const GnssInterface* (getLocationInterface)();
|
||||
|
||||
|
@ -85,8 +87,13 @@ void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who
|
|||
}
|
||||
}
|
||||
|
||||
void location_on_battery_status_changed(bool charging) {
|
||||
LOC_LOGd("%s: battery status changed to %s charging", __func__, charging ? "" : "not ");
|
||||
}
|
||||
Gnss::Gnss() {
|
||||
ENTRY_LOG_CALLFLOW();
|
||||
// register health client to listen on battery change
|
||||
loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
|
||||
// clear pending GnssConfig
|
||||
memset(&mPendingConfig, 0, sizeof(GnssConfig));
|
||||
mGnssDeathRecipient = new GnssDeathRecipient(this);
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
LOCAL_PATH := $(call my-dir)
|
||||
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
|
||||
include $(CLEAR_VARS)
|
||||
DIR_LIST := $(LOCAL_PATH)
|
||||
include $(DIR_LIST)/utils/Android.mk
|
||||
ifeq ($(GNSS_HIDL_VERSION),2.0)
|
||||
include $(LOCAL_PATH)/2.0/Android.mk
|
||||
include $(DIR_LIST)/2.0/Android.mk
|
||||
else
|
||||
ifeq ($(GNSS_HIDL_VERSION),1.1)
|
||||
include $(LOCAL_PATH)/1.1/Android.mk
|
||||
include $(DIR_LIST)/1.1/Android.mk
|
||||
else
|
||||
include $(LOCAL_PATH)/1.0/Android.mk
|
||||
include $(DIR_LIST)/1.0/Android.mk
|
||||
endif #GNSS HIDL 1.1
|
||||
endif #GNSS HIDL 2.0
|
||||
else #QMAA flag set, build dummy android.hardware.gnss@1.0-impl-qti
|
||||
|
|
37
android/utils/Android.mk
Normal file
37
android/utils/Android.mk
Normal file
|
@ -0,0 +1,37 @@
|
|||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := liblocbatterylistener
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
|
||||
LOCAL_CFLAGS += $(GNSS_CFLAGS)
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH) \
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
battery_listener.cpp
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog \
|
||||
libhidlbase \
|
||||
libhidltransport \
|
||||
libhwbinder \
|
||||
libcutils \
|
||||
libutils \
|
||||
android.hardware.health@1.0 \
|
||||
android.hardware.health@2.0 \
|
||||
android.hardware.power@1.2 \
|
||||
libbase
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := libhealthhalutils
|
||||
LOCAL_CFLAGS += -DBATTERY_LISTENER_ENABLED
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := liblocbatterylistener_headers
|
||||
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
|
||||
|
||||
include $(BUILD_HEADER_LIBRARY)
|
||||
|
||||
|
266
android/utils/battery_listener.cpp
Normal file
266
android/utils/battery_listener.cpp
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "battery_listener.h"
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#endif
|
||||
#define LOG_TAG "LocSvc_BatteryListener"
|
||||
|
||||
#include <android/hidl/manager/1.0/IServiceManager.h>
|
||||
#include <android/hardware/health/2.0/IHealth.h>
|
||||
#include <healthhalutils/HealthHalUtils.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
#include <thread>
|
||||
using android::hardware::interfacesEqual;
|
||||
using android::hardware::Return;
|
||||
using android::hardware::Void;
|
||||
using android::hardware::health::V1_0::BatteryStatus;
|
||||
using android::hardware::health::V1_0::toString;
|
||||
using android::hardware::health::V2_0::get_health_service;
|
||||
using android::hardware::health::V2_0::HealthInfo;
|
||||
using android::hardware::health::V2_0::IHealth;
|
||||
using android::hardware::health::V2_0::Result;
|
||||
using android::hidl::manager::V1_0::IServiceManager;
|
||||
using namespace std::literals::chrono_literals;
|
||||
|
||||
static bool sIsBatteryListened = false;
|
||||
namespace android {
|
||||
|
||||
#define GET_HEALTH_SVC_RETRY_CNT 5
|
||||
#define GET_HEALTH_SVC_WAIT_TIME_MS 500
|
||||
|
||||
struct BatteryListenerImpl : public hardware::health::V2_0::IHealthInfoCallback,
|
||||
public hardware::hidl_death_recipient {
|
||||
typedef std::function<void(bool)> cb_fn_t;
|
||||
BatteryListenerImpl(cb_fn_t cb);
|
||||
virtual ~BatteryListenerImpl ();
|
||||
virtual hardware::Return<void> healthInfoChanged(
|
||||
const hardware::health::V2_0::HealthInfo& info);
|
||||
virtual void serviceDied(uint64_t cookie,
|
||||
const wp<hidl::base::V1_0::IBase>& who);
|
||||
bool isCharging() {
|
||||
std::lock_guard<std::mutex> _l(mLock);
|
||||
return statusToBool(mStatus);
|
||||
}
|
||||
private:
|
||||
sp<hardware::health::V2_0::IHealth> mHealth;
|
||||
status_t init();
|
||||
BatteryStatus mStatus;
|
||||
cb_fn_t mCb;
|
||||
std::mutex mLock;
|
||||
std::condition_variable mCond;
|
||||
std::unique_ptr<std::thread> mThread;
|
||||
bool mDone;
|
||||
bool statusToBool(const BatteryStatus &s) const {
|
||||
return (s == BatteryStatus::CHARGING) ||
|
||||
(s == BatteryStatus::FULL);
|
||||
}
|
||||
};
|
||||
|
||||
status_t BatteryListenerImpl::init()
|
||||
{
|
||||
int tries = 0;
|
||||
|
||||
if (mHealth != NULL)
|
||||
return INVALID_OPERATION;
|
||||
|
||||
do {
|
||||
mHealth = hardware::health::V2_0::get_health_service();
|
||||
if (mHealth != NULL)
|
||||
break;
|
||||
usleep(GET_HEALTH_SVC_WAIT_TIME_MS * 1000);
|
||||
tries++;
|
||||
} while(tries < GET_HEALTH_SVC_RETRY_CNT);
|
||||
|
||||
if (mHealth == NULL) {
|
||||
ALOGE("no health service found, retries %d", tries);
|
||||
return NO_INIT;
|
||||
} else {
|
||||
ALOGI("Get health service in %d tries", tries);
|
||||
}
|
||||
mStatus = BatteryStatus::UNKNOWN;
|
||||
auto ret = mHealth->getChargeStatus([&](Result r, BatteryStatus status) {
|
||||
if (r != Result::SUCCESS) {
|
||||
ALOGE("batterylistener: cannot get battery status");
|
||||
return;
|
||||
}
|
||||
mStatus = status;
|
||||
});
|
||||
if (!ret.isOk())
|
||||
ALOGE("batterylistener: get charge status transaction error");
|
||||
|
||||
if (mStatus == BatteryStatus::UNKNOWN)
|
||||
ALOGW("batterylistener: init: invalid battery status");
|
||||
mDone = false;
|
||||
mThread = std::make_unique<std::thread>([this]() {
|
||||
std::unique_lock<std::mutex> l(mLock);
|
||||
BatteryStatus local_status = mStatus;
|
||||
while (!mDone) {
|
||||
if (local_status == mStatus) {
|
||||
mCond.wait(l);
|
||||
continue;
|
||||
}
|
||||
local_status = mStatus;
|
||||
switch (local_status) {
|
||||
// NOT_CHARGING is a special event that indicates, a battery is connected,
|
||||
// but not charging. This is seen for approx a second
|
||||
// after charger is plugged in. A charging event is eventually received.
|
||||
// We must try to avoid an unnecessary cb to HAL
|
||||
// only to call it again shortly.
|
||||
// An option to deal with this transient event would be to ignore this.
|
||||
// Or process this event with a slight delay (i.e cancel this event
|
||||
// if a different event comes in within a timeout
|
||||
case BatteryStatus::NOT_CHARGING : {
|
||||
auto mStatusnot_ncharging =
|
||||
[this, local_status]() { return mStatus != local_status; };
|
||||
mCond.wait_for(l, 3s, mStatusnot_ncharging);
|
||||
if (mStatusnot_ncharging()) // i.e event changed
|
||||
break;
|
||||
[[clang::fallthrough]]; //explicit fall-through between switch labels
|
||||
}
|
||||
default:
|
||||
bool c = statusToBool(local_status);
|
||||
ALOGI("healthInfo cb thread: cb %s", c ? "CHARGING" : "NOT CHARGING");
|
||||
l.unlock();
|
||||
mCb(c);
|
||||
l.lock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
auto reg = mHealth->registerCallback(this);
|
||||
if (!reg.isOk()) {
|
||||
ALOGE("Transaction error in registeringCb to HealthHAL death: %s",
|
||||
reg.description().c_str());
|
||||
}
|
||||
|
||||
auto linked = mHealth->linkToDeath(this, 0 /* cookie */);
|
||||
if (!linked.isOk() || linked == false) {
|
||||
ALOGE("Transaction error in linking to HealthHAL death: %s", linked.description().c_str());
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
BatteryListenerImpl::BatteryListenerImpl(cb_fn_t cb) :
|
||||
mCb(cb)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
BatteryListenerImpl::~BatteryListenerImpl()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> _l(mLock);
|
||||
if (mHealth != NULL)
|
||||
mHealth->unlinkToDeath(this);
|
||||
auto r = mHealth->unlinkToDeath(this);
|
||||
if (!r.isOk() || r == false) {
|
||||
ALOGE("Transaction error in unregister to HealthHAL death: %s",
|
||||
r.description().c_str());
|
||||
}
|
||||
}
|
||||
mDone = true;
|
||||
mThread->join();
|
||||
}
|
||||
|
||||
void BatteryListenerImpl::serviceDied(uint64_t cookie __unused,
|
||||
const wp<hidl::base::V1_0::IBase>& who)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> _l(mLock);
|
||||
if (mHealth == NULL || !interfacesEqual(mHealth, who.promote())) {
|
||||
ALOGE("health not initialized or unknown interface died");
|
||||
return;
|
||||
}
|
||||
ALOGI("health service died, reinit");
|
||||
mDone = true;
|
||||
}
|
||||
mThread->join();
|
||||
std::lock_guard<std::mutex> _l(mLock);
|
||||
init();
|
||||
}
|
||||
|
||||
// this callback seems to be a SYNC callback and so
|
||||
// waits for return before next event is issued.
|
||||
// therefore we need not have a queue to process
|
||||
// NOT_CHARGING and CHARGING concurrencies.
|
||||
// Replace single var by a list if this assumption is broken
|
||||
Return<void> BatteryListenerImpl::healthInfoChanged(
|
||||
const hardware::health::V2_0::HealthInfo& info)
|
||||
{
|
||||
ALOGV("healthInfoChanged: %d", info.legacy.batteryStatus);
|
||||
std::unique_lock<std::mutex> l(mLock);
|
||||
if (info.legacy.batteryStatus != mStatus) {
|
||||
mStatus = info.legacy.batteryStatus;
|
||||
mCond.notify_one();
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
static sp<BatteryListenerImpl> batteryListener;
|
||||
status_t batteryPropertiesListenerInit(BatteryListenerImpl::cb_fn_t cb)
|
||||
{
|
||||
ALOGV("batteryPropertiesListenerInit entry");
|
||||
batteryListener = new BatteryListenerImpl(cb);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t batteryPropertiesListenerDeinit()
|
||||
{
|
||||
batteryListener.clear();
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool batteryPropertiesListenerIsCharging()
|
||||
{
|
||||
return batteryListener->isCharging();
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
void loc_extn_battery_properties_listener_init(battery_status_change_fn_t fn)
|
||||
{
|
||||
ALOGV("loc_extn_battery_properties_listener_init entry");
|
||||
if (!sIsBatteryListened) {
|
||||
std::thread t1(android::batteryPropertiesListenerInit,
|
||||
[=](bool charging) { fn(charging); });
|
||||
t1.detach();
|
||||
sIsBatteryListened = true;
|
||||
}
|
||||
}
|
||||
|
||||
void loc_extn_battery_properties_listener_deinit()
|
||||
{
|
||||
android::batteryPropertiesListenerDeinit();
|
||||
}
|
||||
|
||||
bool loc_extn_battery_properties_is_charging()
|
||||
{
|
||||
return android::batteryPropertiesListenerIsCharging();
|
||||
}
|
32
android/utils/battery_listener.h
Normal file
32
android/utils/battery_listener.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
typedef void (* battery_status_change_fn_t)(bool);
|
||||
void loc_extn_battery_properties_listener_init(battery_status_change_fn_t fn);
|
||||
void loc_extn_battery_properties_listener_deinit();
|
||||
bool loc_extn_battery_properties_is_charging();
|
Loading…
Reference in a new issue