Enum=2001
DeviceNotifier=DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED
ActionBroadcast=yes
+WakeLockDurationSec=5
[EventAction]
Name=CHARGER_DISCONNECTED
Enum=2002
DeviceNotifier=DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED
ActionBroadcast=yes
+WakeLockDurationSec=5
DetectionRangeMsec=0,2000
TriggerType=edge
ActionBroadcast=yes
+WakeLockDurationSec=5
[EventAction]
Name=SHORTKEY_LEVEL
#include "shared/device-notifier.h"
#include "shared/log.h"
+#include "shared/event.h"
#include "battery/battery-ops.h"
#include "power/power.h"
/* which action to do on receiving an event */
enum device_notifier_type action;
void *user_data;
+
+ /* hold wakelock for a duration on detecting the event */
+ int wakelock_duration;
};
static struct battery_event_handler *handler_connected;
parse_action(handler, prop->value);
} else if (MATCH(prop->key, "ActionBroadcast")) {
handler->broadcast = MATCH(prop->value, "yes");
+ } else if (MATCH(prop->key, "WakeLockDurationSec")) {
+ sscanf(prop->value, "%d", &handler->wakelock_duration);
}
}
static int charger_connected_callback(void *data)
{
_D("event=%s(%d), action=%d", handler_connected->name, handler_connected->id, handler_connected->action);
- device_notify(handler_connected->action, handler_connected->user_data);
+
+ if (handler_connected->wakelock_duration)
+ event_acquire_wakelock(handler_connected->id, handler_connected->wakelock_duration);
+
+ if (handler_connected->action)
+ device_notify(handler_connected->action, handler_connected->user_data);
return 0;
}
static int charger_disconnected_callback(void *data)
{
_D("event=%s(%d), action=%d", handler_disconnected->name, handler_disconnected->id, handler_disconnected->action);
- device_notify(handler_disconnected->action, handler_disconnected->user_data);
+
+ if (handler_disconnected->wakelock_duration)
+ event_acquire_wakelock(handler_disconnected->id, handler_disconnected->wakelock_duration);
+
+ if (handler_disconnected->action)
+ device_notify(handler_disconnected->action, handler_disconnected->user_data);
return 0;
}
parse_change_state(ieu, prop->value);
} else if (MATCH(prop->key, "ActionBroadcast")) {
ieu->broadcast = MATCH(prop->value, "yes");
+ } else if (MATCH(prop->key, "WakeLockDurationSec")) {
+ sscanf(prop->value, "%d", &ieu->wakelock_duration);
}
}
enum trigger_type type;
unsigned long interval[2];
+ /* level-trigger timer */
+ int timer;
+
/* condition for triggering action */
struct condition_vconf cv;
- /* broadcast upon occuring this event */
+ /* broadcast upon occuring the event */
int broadcast;
/* which action to do on receiving an event */
enum device_notifier_type notifier;
void *user_data;
- /* level-trigger timer */
- int timer;
+ /* hold wakelock for a duration on detecting the event */
+ int wakelock_duration;
};
struct input_config {
*/
#include <time.h>
+#include <stdint.h>
#include <libinput.h>
#include <linux/input.h>
#include <glib.h>
#include "shared/devices.h"
#include "shared/device-notifier.h"
#include "shared/log.h"
+#include "shared/event.h"
#include "input-config.h"
#define KEYVALUE_PRESS 1
#define KEYVALUE_RELEASE 0
-static gboolean level_triggered(gpointer data)
+static gboolean level_event_detected(gpointer data)
{
struct input_event_unit *ieu = (struct input_event_unit *) data;
ieu->timer = 0;
+ _D("Detected level event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
+
if (check_input_event_condition(ieu) == 0) {
- _D("Skip(level) event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname);
+ _D("Skip triggering event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname);
return G_SOURCE_REMOVE;
}
- _D("Trigger(level) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
- device_notify(ieu->notifier, ieu->user_data);
+ if (ieu->broadcast)
+ event_broadcast_id(ieu->id);
+
+ if (ieu->wakelock_duration > 0)
+ event_acquire_wakelock(ieu->id, ieu->wakelock_duration);
+
+ if (ieu->notifier)
+ device_notify(ieu->notifier, ieu->user_data);
return G_SOURCE_REMOVE;
}
-static void edge_triggered(struct input_event_unit *ieu)
+static void edge_event_detected(struct input_event_unit *ieu)
{
+ _D("Detected edge event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
+
if (check_input_event_condition(ieu) == 0) {
- _D("Skip(edge) event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname);
+ _D("Skip triggering event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname);
return;
}
- _D("Trigger(edge) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
- device_notify(ieu->notifier, ieu->user_data);
+ if (ieu->broadcast)
+ event_broadcast_id(ieu->id);
+
+ if (ieu->wakelock_duration > 0)
+ event_acquire_wakelock(ieu->id, ieu->wakelock_duration);
+
+ if (ieu->notifier)
+ device_notify(ieu->notifier, ieu->user_data);
}
static void start_event_timer(struct input_config *ic)
if (ieu->type == TRIGGER_TYPE_LEVEL) {
if (ieu->timer)
g_source_remove(ieu->timer);
- ieu->timer = g_timeout_add(ieu->interval[0], level_triggered, (gpointer) ieu);
+ ieu->timer = g_timeout_add(ieu->interval[0], level_event_detected, (gpointer) ieu);
}
}
}
ieu->timer = 0;
}
- /* trigger edge-trigger action */
+ /* detected edge-trigger event */
if (lapse >= ieu->interval[0] && lapse < ieu->interval[1] && ieu->type == TRIGGER_TYPE_EDGE)
- edge_triggered(ieu);
+ edge_event_detected(ieu);
}
}
EL_KEY_BLUETOOTH,
EL_CHARGER,
+ EL_EVENT_ACTION,
/* add eventlock type here */
EL_MAX,
};
set_bit(eventlock, type);
setcount = count_set_bit(eventlock);
- _D("Set eventlock of type=%d, current number of eventlock=%d", type, setcount);
+ _I("Set eventlock of type=%d, current number of eventlock=%d", type, setcount);
if (setcount == 1) {
sys_set_str("/sys/power/wake_lock", EVENT_LOCK);
- _D("Acquired eventlock");
+ _I("Acquired eventlock");
}
}
clear_bit(eventlock, type);
setcount = count_set_bit(eventlock);
- _D("Unset eventlock of type=%d, current number of eventlock=%d", type, setcount);
+ _I("Unset eventlock of type=%d, current number of eventlock=%d", type, setcount);
if (setcount == 0) {
sys_set_str("/sys/power/wake_unlock", EVENT_LOCK);
- _D("Released eventlock");
+ _I("Released eventlock");
}
}
config_parse(BATTERY_CONF_FILE, check_charger_wakelock, &charger_wakelock);
+ /* general events, mostly defined by configuration file */
+ register_power_event_lock_controller(EL_EVENT_ACTION,
+ DEVICE_NOTIFIER_EVENT_ACQUIRE_WAKELOCK,
+ DEVICE_NOTIFIER_EVENT_RELEASE_WAKELOCK);
+
+ /* key input event */
register_power_event_lock_controller(EL_KEY,
DEVICE_NOTIFIER_KEY_PRESS,
DEVICE_NOTIFIER_KEY_RELEASE);
+ /* charger event */
if (charger_wakelock) {
register_power_event_lock_controller(EL_CHARGER,
DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED,
NOTIFY_STR(DEVICE_NOTIFIER_EXTCON_COUNT),
NOTIFY_STR(DEVICE_NOTIFIER_KEY_PRESS),
NOTIFY_STR(DEVICE_NOTIFIER_KEY_RELEASE),
+ NOTIFY_STR(DEVICE_NOTIFIER_EVENT_ACQUIRE_WAKELOCK),
+ NOTIFY_STR(DEVICE_NOTIFIER_EVENT_RELEASE_WAKELOCK),
/* Purpose of calling methods of different modules
* Use prefix DEVICE_NOTIFIER_REQUEST */
DEVICE_NOTIFIER_EXTCON_COUNT,
DEVICE_NOTIFIER_KEY_PRESS,
DEVICE_NOTIFIER_KEY_RELEASE,
+ DEVICE_NOTIFIER_EVENT_ACQUIRE_WAKELOCK,
+ DEVICE_NOTIFIER_EVENT_RELEASE_WAKELOCK,
/* Purpose of calling methods of different modules
* Use prefix DEVICE_NOTIFIER_REQUEST */
--- /dev/null
+/*
+ * deviced
+ *
+ * Copyright (c) 2022 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 <glib.h>
+#include <stdint.h>
+
+#include "device-notifier.h"
+#include "log.h"
+
+static int wakelock_counter;
+
+static gboolean event_release_wakelock(gpointer data)
+{
+ int eventid = (int)(intptr_t) data;
+
+ --wakelock_counter;
+
+ _D("Decreased counter=%d, eventid=%d", wakelock_counter, eventid);
+
+ if (wakelock_counter == 0)
+ device_notify(DEVICE_NOTIFIER_EVENT_RELEASE_WAKELOCK, NULL);
+
+ return G_SOURCE_REMOVE;
+}
+
+void event_acquire_wakelock(int eventid, int timeout)
+{
+ if (timeout <= 0)
+ return;
+
+ ++wakelock_counter;
+
+ _D("Increased counter=%d, eventid=%d, timeout=%d", wakelock_counter, eventid, timeout);
+ g_timeout_add_seconds(timeout, event_release_wakelock, (gpointer)(intptr_t) eventid);
+
+ if (wakelock_counter == 1)
+ device_notify(DEVICE_NOTIFIER_EVENT_ACQUIRE_WAKELOCK, NULL);
+}
--- /dev/null
+/*
+ * deviced
+ *
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __DD_EVENT_H__
+#define __DD_EVENT_H__
+
+#include <libsyscommon/libgdbus.h>
+
+#define DEVICED_PATH_EVENT "/Org/Tizen/System/DeviceD/Event"
+#define DEVICED_INTERFACE_EVENT "org.tizen.system.deviced.Event"
+#define DEVICED_SIGNAME_ID "Id"
+
+static inline void event_broadcast_id(int id)
+{
+ _I("Broadcast eventid=%d", id);
+
+ gdbus_signal_emit(NULL,
+ DEVICED_PATH_EVENT,
+ DEVICED_INTERFACE_EVENT,
+ DEVICED_SIGNAME_ID,
+ g_variant_new("(i)", id));
+}
+
+/**
+ * Hold wakelock for a specified timeout.
+ * The parameter eventid is only used for logging
+ */
+void event_acquire_wakelock(int eventid, int timeout);
+
+#endif //__DD_EVENT_H__