Add battery plugin for wearable and mobile 50/235150/10
authorlokilee73 <changjoo.lee@samsung.com>
Tue, 2 Jun 2020 05:35:10 +0000 (14:35 +0900)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Mon, 8 Jun 2020 05:46:17 +0000 (05:46 +0000)
Wearable plugin
 - check_power_supply_noti
 - update_ovp
 - display_changed: relaunch health popup on LCDON

Mobile plugin
 - check_power_supply_noti
 - update_ovp
 - display_changed
 - added dbus signal handler: abnormal_popup_dbus_signal_handler

Change-Id: I86a08e0f8d61e997fa0fc424e32d6d8c1de5cf96
Signed-off-by: lokilee73 <changjoo.lee@samsung.com>
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
CMakeLists.txt
packaging/deviced.spec
plugins/mobile/battery/battery-notification.c
plugins/wearable/battery/CMakeLists.txt [new file with mode: 0644]
plugins/wearable/battery/battery-notification.c [new file with mode: 0644]
src/battery/battery-ops.h
src/battery/power-supply.c
src/battery/power-supply.h

index bcc2520..c2cda03 100644 (file)
@@ -315,6 +315,7 @@ ADD_SUBDIRECTORY(plugins/wearable/display)
 ADD_SUBDIRECTORY(plugins/tv/display)
 ADD_SUBDIRECTORY(plugins/iot/display)
 ADD_SUBDIRECTORY(plugins/mobile/battery)
+ADD_SUBDIRECTORY(plugins/wearable/battery)
 INSTALL_CONF(conf mobile-display)
 INSTALL_CONF(conf wearable-display)
 INSTALL_CONF(conf tv-display)
index 86c11b8..d119d2a 100644 (file)
@@ -223,6 +223,7 @@ mv %{_libdir}/mobile-battery.so %{_libdir}/deviced/battery.so
 mv %{_sysconfdir}/deviced/wearable-display.conf %{_sysconfdir}/deviced/display.conf
 mkdir -p %{_libdir}/deviced
 mv %{_libdir}/wearable-display.so %{_libdir}/deviced/display.so
+mv %{_libdir}/wearable-battery.so %{_libdir}/deviced/battery.so
 
 %post plugin-profile-tv
 mv %{_sysconfdir}/deviced/tv-display.conf %{_sysconfdir}/deviced/display.conf
@@ -307,6 +308,7 @@ mv %{_libdir}/iot-display.so %{_libdir}/deviced/display.so
 %defattr(-,root,root,-)
 %config %{_sysconfdir}/deviced/wearable-display.conf
 %{_libdir}/wearable-display.so
+%{_libdir}/wearable-battery.so
 %{_unitdir}/rndis.service
 %{_bindir}/rndis.sh
 
index 15df6b7..5ba04e0 100644 (file)
 #include "power-supply.h"
 #include "lowbat-handler.h"
 #include "battery-ops.h"
+#include "display/core.h"
 #include "display/display-ops.h"
 #include "display/poll.h"
 #include "shared/eventsystem.h"
+#include "core/device-notifier.h"
+
 
 #define METHOD_LOW_NOTI_ON          "BatteryLowNotiOn"
 #define METHOD_LOW_NOTI_UPDATE      "BatteryLowNotiUpdate"
@@ -47,6 +50,8 @@ enum event_noti_type {
        NOTI_UPDATE = 0,
 };
 
+static guint abnormal_timer;
+
 static int noti_low = NOTI_NONE;
 static int noti_crit = NOTI_NONE;
 
@@ -292,9 +297,84 @@ static void remove_health_popup(void)
                _E("Failed to launch remove battery popup(%d)", ret);
 }
 
+static int check_power_supply_noti(void)
+{
+       return 1;
+}
+
+static void update_ovp(enum battery_noti_status status)
+{
+       _I("charge %d ovp %d(old %d)", battery.charge_now, battery.health, old_battery.health);
+
+       old_battery.health = battery.health;
+       if (status == DEVICE_NOTI_ON)
+               battery_pm_change_internal(INTERNAL_LOCK_POPUP, LCD_DIM);
+       else
+               battery_pm_change_internal(INTERNAL_LOCK_POPUP, LCD_NORMAL);
+       device_notify(DEVICE_NOTIFIER_BATTERY_OVP, (void *)&battery.health);
+}
+
+static void health_timer_reset(void)
+{
+       abnormal_timer = 0;
+}
+
+static gboolean health_timer_cb(void *data)
+{
+       health_timer_reset();
+
+       if (battery.health != HEALTH_LOW && battery.health != HEALTH_HIGH)
+               return G_SOURCE_REMOVE;
+
+       CRITICAL_LOG("Popup: Battery health status is not good, %s.", battery.health_s);
+       device_notify(DEVICE_NOTIFIER_BATTERY_HEALTH, (void *)&battery.health);
+       battery_pm_change_internal(INTERNAL_LOCK_POPUP, LCD_DIM);
+       if (disp_plgn.pm_unlock_internal)
+               disp_plgn.pm_unlock_internal(INTERNAL_LOCK_POPUP, LCD_OFF, PM_SLEEP_MARGIN);
+       if (disp_plgn.pm_lock_internal)
+               disp_plgn.pm_lock_internal(INTERNAL_LOCK_POPUP, LCD_DIM, STAY_CUR_STATE, 0);
+       if (battery.health == HEALTH_LOW)
+               battery_charge_err_low_act(NULL);
+       else if (battery.health == HEALTH_HIGH)
+               battery_charge_err_high_act(NULL);
+       return G_SOURCE_REMOVE;
+}
+
+static void abnormal_popup_dbus_signal_handler(GDBusConnection  *conn,
+               const gchar      *sender,
+               const gchar      *path,
+               const gchar      *iface,
+               const gchar      *name,
+               GVariant         *param,
+               gpointer          user_data)
+
+{
+       if (battery.health == HEALTH_GOOD)
+               return;
+
+       _I("Restart health timer.");
+       abnormal_timer = g_timeout_add_seconds(ABNORMAL_CHECK_TIMER_INTERVAL,
+                                               health_timer_cb, NULL);
+       if (abnormal_timer == 0)
+               _E("Failed to add abnormal check timer.");
+}
+
+static int display_changed(void *data)
+{
+       static enum state_t state;
+
+       if (!data)
+               return state;
+
+       state = *(int *)data;
+
+       return state;
+}
+
 static void battery_notification_init(void *data)
 {
        struct battery_plugin *plugin = (struct battery_plugin *)data;
+       int ret;
 
        if (!plugin)
                return;
@@ -305,6 +385,17 @@ static void battery_notification_init(void *data)
 
        plugin->changed_battery_cf = changed_battery_cf;
        plugin->remove_health_popup = remove_health_popup;
+       plugin->check_power_supply_noti = check_power_supply_noti;
+       plugin->update_ovp = update_ovp;
+
+       plugin->display_changed = display_changed;
+
+       ret = subscribe_dbus_signal(NULL, DEVICED_PATH_SYSNOTI,
+               DEVICED_INTERFACE_SYSNOTI, SIGNAL_CHARGEERR_RESPONSE, abnormal_popup_dbus_signal_handler, NULL, NULL);
+       if (ret <= 0)
+               _E("Failed to init dbus signal: %d", ret);
+
+       register_notifier(DEVICE_NOTIFIER_LCD, display_changed);
 }
 
 static const struct battery_ops battery_notification_ops = {
diff --git a/plugins/wearable/battery/CMakeLists.txt b/plugins/wearable/battery/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1932820
--- /dev/null
@@ -0,0 +1,28 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(wearable-battery C)
+
+FILE(GLOB ALL_SRCS "*.c")
+SET(SRCS ${ALL_SRCS})
+ADD_SOURCE(${CMAKE_SOURCE_DIR}/src/battery COMMON_SRCS)
+SET(SRCS ${SRCS} ${COMMON_SRCS})
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/core ${CMAKE_SOURCE_DIR}/src/battery)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(libpkgs REQUIRED
+       dlog
+       glib-2.0
+       gio-2.0
+       gio-unix-2.0
+       libinput)
+
+FOREACH(flag ${libpkgs_CFLAGS})
+       SET(EXTRA_LIB_CFLAGS "${EXTRA_LIB_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_LIB_CFLAGS}")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${libpkgs_LDFLAGS} shared)
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES OUTPUT_NAME wearable-battery)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
diff --git a/plugins/wearable/battery/battery-notification.c b/plugins/wearable/battery/battery-notification.c
new file mode 100644 (file)
index 0000000..8ab24f4
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <time.h>
+#include <glib.h>
+
+#include "display/core.h"
+#include "core/log.h"
+#include "core/device-notifier.h"
+#include "power-supply.h"
+#include "battery-ops.h"
+#include "battery.h"
+#include "dd-display.h"
+
+static int display_changed(void *data)
+{
+       static enum state_t old;
+       static enum state_t state;
+
+       if (!data)
+               return state;
+
+       old = state;
+       state = *(int *)data;
+
+       if (battery.health != HEALTH_LOW && battery.health != HEALTH_HIGH)
+               return state;
+
+       /* relaunch health popup on LCDON */
+       if ((old == S_SLEEP || old == S_LCDOFF)
+               && (state == S_LCDDIM || state == S_NORMAL))
+               relaunch_health_popup();
+
+       return state;
+}
+
+static int check_power_supply_noti(void)
+{
+       int block;
+
+       if (vconf_get_bool("db/setting/blockmode_wearable", &block) != 0)
+               return 1;
+       if (block == 0)
+               return 1;
+       return 0;
+}
+
+static void update_ovp(enum battery_noti_status status)
+{
+       static int old = DEVICE_NOTI_OFF;
+
+       if (old == status)
+               return;
+
+       old = status;
+       _I("Charge(%d) ovp(%d, old: %d) with lcd(%s)", battery.charge_now, battery.health,
+               old_battery.health, (status == DEVICE_NOTI_ON) ? "dim" : "normal");
+
+       old_battery.health = battery.health;
+       device_notify(DEVICE_NOTIFIER_BATTERY_OVP, (void *)&battery.health);
+       battery_pm_change_internal(INTERNAL_LOCK_POPUP, LCD_NORMAL);
+}
+
+static void battery_notification_init(void *data)
+{
+       struct battery_plugin *plugin = (struct battery_plugin *)data;
+
+       if (!plugin)
+               return;
+
+       _D("Add plugins for battery notification.");
+       plugin->check_power_supply_noti = check_power_supply_noti;
+       plugin->update_ovp = update_ovp;
+
+       plugin->display_changed = display_changed;
+
+       register_notifier(DEVICE_NOTIFIER_LCD, display_changed);
+}
+
+static const struct battery_ops battery_notification_ops = {
+       .name     = "battery_notification",
+       .init     = battery_notification_init,
+};
+
+BATTERY_OPS_REGISTER(&battery_notification_ops)
index 67376ef..a8397f0 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <errno.h>
 #include "core/common.h"
+#include "power-supply.h"
+#include <libsyscommon/dbus-system.h>
 
 struct battery_ops {
        char *name;
@@ -38,6 +40,10 @@ struct battery_plugin {
 
        int (*changed_battery_cf) (int status);
        void (*remove_health_popup) (void);
+
+       int (*display_changed) (void *);
+       int (*check_power_supply_noti) (void);
+       void (*update_ovp) (enum battery_noti_status status);
        /* Add plugins here */
 };
 extern struct battery_plugin battery_plgn;
index ffc6d6a..09f16bc 100644 (file)
 #define CHARGER_D2D_TYPE            110
 #define WIRELESS_CHARGER_CONNECTED  2
 
-#define SIGNAL_CHARGEERR_RESPONSE "ChargeErrResponse"
 #define SIGNAL_TEMP_GOOD          "TempGood"
 
-#define ABNORMAL_CHECK_TIMER_INTERVAL 60
-
 #define METHOD_FULL_NOTI_ON   "BatteryFullNotiOn"
 #define METHOD_FULL_NOTI_OFF  "BatteryFullNotiOff"
 #define METHOD_CHARGE_NOTI_ON "BatteryChargeNotiOn"
@@ -96,13 +93,13 @@ struct battery_status old_battery;
 static int noti_id;
 static int online_status;
 static int abnormal_health_popup_timer;
+static bool launching_health_popup;
 
 static guint power_timer;
 static device_notifier_state_e old_state = -1;
 
 bool battery_do_not_disturb(void);
-static int battery_pm_change_internal(int pid, int s_bits);
-static int display_changed(void *data);
+int battery_pm_change_internal(int pid, int s_bits);
 static int booting_done(void *data);
 static void update_health(enum battery_noti_status status);
 
@@ -204,27 +201,17 @@ out:
        g_variant_unref(var);
 }
 
-int check_power_supply_noti(void)
-{
-       int block;
-
-       if (vconf_get_bool("db/setting/blockmode_wearable", &block) != 0)
-               return 1;
-       if (block == 0)
-               return 1;
-       return 0;
-}
-
 static int send_full_noti(enum charge_full_type state)
 {
        int ret = 0;
-       int noti;
+       int noti = 0;
        int retry;
 
-       noti = check_power_supply_noti();
+       if (battery_plgn.check_power_supply_noti)
+               noti = battery_plgn.check_power_supply_noti();
 
        if (!noti)
-               return noti;
+               return ret;
 
        switch (state) {
        case CHARGING_FULL:
@@ -240,7 +227,7 @@ static int send_full_noti(enum charge_full_type state)
                        }
                }
                _E("Failed to call dbus method: %d", ret);
-       break;
+               break;
        case CHARGING_NOT_FULL:
                if (noti_id <= 0)
                        return -EPERM;
@@ -258,7 +245,7 @@ static int send_full_noti(enum charge_full_type state)
                        }
                }
                _E("Failed to call dbus method: %d", ret);
-       break;
+               break;
        }
        return ret;
 }
@@ -372,7 +359,6 @@ int power_supply_broadcast(char *sig, int status)
 static void noti_batt_full(void)
 {
        static int bat_full_noti;
-       int noti;
 
        if (!battery.charge_full && bat_full_noti == 1) {
                power_supply_noti(DEVICE_NOTI_BATT_FULL, DEVICE_NOTI_OFF);
@@ -383,9 +369,8 @@ static void noti_batt_full(void)
        if (battery.charge_full && bat_full_noti == 0) {
                power_supply_noti(DEVICE_NOTI_BATT_FULL, DEVICE_NOTI_ON);
                bat_full_noti = 1;
-               /* turn on LCD, if battery is full charged */
-               noti = check_power_supply_noti();
-               if (noti) {
+               /* turn on LCD, if battery is fully charged */
+               if (battery_plgn.check_power_supply_noti && battery_plgn.check_power_supply_noti()) {
                        battery_pm_change_internal(INTERNAL_LOCK_BATTERY_FULL, LCD_NORMAL);
                } else
                        _I("Block LCD.");
@@ -458,6 +443,11 @@ static void update_present(enum battery_noti_status status)
 
 static void launch_health_popup(void)
 {
+       if (launching_health_popup)
+               return;
+
+       launching_health_popup = true;
+
        device_notify(DEVICE_NOTIFIER_BATTERY_HEALTH, (void *)&battery.health);
        battery_pm_change_internal(INTERNAL_LOCK_POPUP, LCD_NORMAL);
        battery_pm_change_internal(INTERNAL_LOCK_POPUP, LCD_DIM);
@@ -469,6 +459,8 @@ static void launch_health_popup(void)
                battery_charge_err_low_act(NULL);
        else if (battery.health == HEALTH_HIGH)
                battery_charge_err_high_act(NULL);
+
+       launching_health_popup = false;
 }
 
 /* Warning popup for every 1 minutes until
@@ -508,20 +500,28 @@ static void update_health(enum battery_noti_status status)
        }
 }
 
-static void update_ovp(enum battery_noti_status status)
+void relaunch_health_popup(void)
 {
-       static int old = DEVICE_NOTI_OFF;
-
-       if (old == status)
+       if (launching_health_popup)
                return;
 
-       old = status;
-       _I("Charge(%d) ovp(%d, old: %d) with lcd(%s)", battery.charge_now, battery.health,
-               old_battery.health, (status == DEVICE_NOTI_ON) ? "dim" : "normal");
+       launching_health_popup = true;
 
-       old_battery.health = battery.health;
-       device_notify(DEVICE_NOTIFIER_BATTERY_OVP, (void *)&battery.health);
-       battery_pm_change_internal(INTERNAL_LOCK_POPUP, LCD_NORMAL);
+       if (abnormal_health_popup_timer)
+               g_source_remove(abnormal_health_popup_timer);
+
+       if (disp_plgn.pm_unlock_internal)
+               disp_plgn.pm_unlock_internal(INTERNAL_LOCK_POPUP, LCD_OFF, PM_SLEEP_MARGIN);
+       if (disp_plgn.pm_lock_internal)
+               disp_plgn.pm_lock_internal(INTERNAL_LOCK_POPUP, LCD_DIM, STAY_CUR_STATE, LCD_DIM_TIME_IN_BATTERY_HEALTH);
+       if (battery.health == HEALTH_LOW)
+               battery_charge_err_low_act(NULL);
+       else if (battery.health == HEALTH_HIGH)
+               battery_charge_err_high_act(NULL);
+
+       abnormal_health_popup_timer = g_timeout_add_seconds(ABNORMAL_CHECK_TIMER_INTERVAL, health_popup_cb, NULL);
+
+       launching_health_popup = false;
 }
 
 static void check_abnormal_status(void)
@@ -538,10 +538,13 @@ static void check_abnormal_status(void)
        else if (battery.present != PRESENT_ABNORMAL && old_battery.present == PRESENT_ABNORMAL)
                update_present(DEVICE_NOTI_OFF);
 
-       if (old_battery.health != HEALTH_OVP && battery.health == HEALTH_OVP)
-               update_ovp(DEVICE_NOTI_ON);
-       else if (battery.health != HEALTH_OVP && old_battery.health == HEALTH_OVP)
-               update_ovp(DEVICE_NOTI_OFF);
+       if (old_battery.health != HEALTH_OVP && battery.health == HEALTH_OVP) {
+               if (battery_plgn.update_ovp)
+                       battery_plgn.update_ovp(DEVICE_NOTI_ON);
+       } else if (battery.health != HEALTH_OVP && old_battery.health == HEALTH_OVP) {
+               if (battery_plgn.update_ovp)
+                       battery_plgn.update_ovp(DEVICE_NOTI_OFF);
+       }
 }
 
 static bool update_online(void)
@@ -1437,30 +1440,32 @@ static int booting_done(void *data)
 
 bool battery_do_not_disturb(void)
 {
-       int block = 0;
+       int block = 0, theater = 0, night = 0;
        int r;
 
-       if (display_changed(NULL) == S_LCDOFF) {
-               r = vconf_get_bool(VCONFKEY_SETAPPL_BLOCKMODE_WEARABLE_BOOL, &block);
-               if (r < 0)
-                       _E("Failed to set vconf value for blockmode wearable: %d", vconf_get_ext_errno());
-               r = vconf_get_bool(VCONFKEY_SETAPPL_THEATER_MODE_ENABLE, &block);
-               if (r < 0)
-                       _E("Failed to set vconf value for theator mode enable: %d", vconf_get_ext_errno());
-               r = vconf_get_bool(VCONFKEY_SETAPPL_GOODNIGHT_MODE_ENABLE, &block);
-               if (r < 0)
-                       _E("Failed to set vconf value for goodnight mode enable: %d", vconf_get_ext_errno());
+       if (battery_plgn.display_changed) {
+               if (battery_plgn.display_changed(NULL) == S_LCDOFF) {
+                       r = vconf_get_bool(VCONFKEY_SETAPPL_BLOCKMODE_WEARABLE_BOOL, &block);
+                       if (r < 0)
+                               _E("Failed to set vconf value for blockmode wearable: %d", vconf_get_ext_errno());
+                       r = vconf_get_bool(VCONFKEY_SETAPPL_THEATER_MODE_ENABLE, &theater);
+                       if (r < 0)
+                               _E("Failed to set vconf value for theator mode enable: %d", vconf_get_ext_errno());
+                       r = vconf_get_bool(VCONFKEY_SETAPPL_GOODNIGHT_MODE_ENABLE, &night);
+                       if (r < 0)
+                               _E("Failed to set vconf value for goodnight mode enable: %d", vconf_get_ext_errno());
+               }
        }
 
-       if (block != 0) {
-               _I("Skip lcd and popup(block %d).", block);
+       if (block != 0 || theater != 0 || night != 0) {
+               _I("Skip lcd and popup(block %d theater %d night %d).", block, theater, night);
                return true;
        }
 
        return false;
 }
 
-static int battery_pm_change_internal(int pid, int s_bits)
+int battery_pm_change_internal(int pid, int s_bits)
 {
        if (battery_do_not_disturb())
                return 0;
@@ -1471,18 +1476,6 @@ static int battery_pm_change_internal(int pid, int s_bits)
        return 0;
 }
 
-static int display_changed(void *data)
-{
-       static enum state_t state;
-
-       if (!data)
-               return state;
-
-       state = *(int *)data;
-
-       return state;
-}
-
 static int load_uevent(struct parse_result *result, void *user_data)
 {
        struct battery_status *info = user_data;
@@ -1635,16 +1628,12 @@ static void power_supply_init(void *data)
        power_supply_timer_start();
 
        register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
-       register_notifier(DEVICE_NOTIFIER_LCD, display_changed);
        register_notifier(DEVICE_NOTIFIER_EVENT_HANDLER, event_handler_state_changed);
 
        ret = dbus_handle_add_dbus_object(NULL, DEVICED_PATH_BATTERY, &dbus_interface);
        if (ret < 0)
                _E("Failed to init dbus method: %d", ret);
 
-       if (ret <= 0)
-               _E("Failed to init dbus signal: %d", ret);
-
        battery_ops_init((void *)&battery_plgn);
 }
 
index 34bb993..af4fb0c 100644 (file)
@@ -21,6 +21,9 @@
 #define __POWER_SUPPLY_H__
 
 #define CHARGER_TYPE_SIGNAL        "ChargerType"
+#define SIGNAL_CHARGEERR_RESPONSE "ChargeErrResponse"
+
+#define ABNORMAL_CHECK_TIMER_INTERVAL 60
 
 enum device_change_type {
        DEVICE_CHANGE_ABNORMAL,
@@ -119,6 +122,8 @@ extern struct battery_status battery;
 extern struct battery_status old_battery;
 
 int power_supply_broadcast(char *sig, int status);
+int battery_pm_change_internal(int pid, int s_bits);
+void relaunch_health_popup(void);
 
 #define CHARGER_STATUS_SIGNAL      "ChargerStatus"
 #define CHARGE_NOW_SIGNAL          "ChargeNow"