*/
+#include <glib.h>
#include <errno.h>
#include "log.h"
#include "device-notifier.h"
struct device_notifier {
int id;
-
+ int priority; /* descending order */
bool deleted;
+
enum device_notifier_type type;
int (*func)(void *data);
static GList *device_notifier_list;
static guint idl;
-
#define FIND_NOTIFIER(a, b, d, e, f) \
SYS_G_LIST_FOREACH(a, b, d) \
if (e == d->e && f == (d->f))
NOTIFY_STR(DEVICE_NOTIFIER_ULTRAPOWERSAVING),
};
-int __register_notifier(enum device_notifier_type type, notify_cb func, const char *caller)
+static gint compare_priority(gconstpointer a, gconstpointer b)
+{
+ /* descending order */
+ return ((const struct device_notifier *)b)->priority - ((const struct device_notifier *)a)->priority + 1;
+}
+
+int __register_notifier(enum device_notifier_type type, notify_cb func, int priority, const char *caller)
{
GList *n;
struct device_notifier *notifier;
}
notifier->type = type;
+ notifier->priority = priority;
notifier->func = func;
- SYS_G_LIST_APPEND(device_notifier_list, notifier);
+ device_notifier_list = g_list_insert_sorted(device_notifier_list, notifier, compare_priority);
return 0;
}
int __register_notifier_udata(enum device_notifier_type type,
notify_cb_udata func_udata, void *user_data,
- destroy_cb_udata func_destroy_udata, const char *caller)
+ destroy_cb_udata func_destroy_udata, int priority, const char *caller)
{
struct device_notifier *notifier;
static int id = 1;
}
notifier->id = id;
+ notifier->priority = priority;
notifier->type = type;
notifier->func_udata = func_udata;
notifier->user_data = user_data;
notifier->destroyer = func_destroy_udata;
- SYS_G_LIST_APPEND(device_notifier_list, notifier);
+ device_notifier_list = g_list_insert_sorted(device_notifier_list, notifier, compare_priority);
++id;
/*
* This is for internal callback method.
*/
-int __register_notifier(enum device_notifier_type type, notify_cb func, const char *caller);
-#define register_notifier(type, func) __register_notifier(type, func, __func__)
+int __register_notifier(enum device_notifier_type type, notify_cb func, int priority, const char *caller);
+#define register_notifier(type, func) __register_notifier(type, func, 0, __func__)
+#define register_notifier_priority(type, func, prio) __register_notifier(type, func, prio, __func__)
+
int __unregister_notifier(enum device_notifier_type type, notify_cb func, const char *caller);
#define unregister_notifier(type, func) __unregister_notifier(type, func, __func__)
-int __register_notifier_udata(enum device_notifier_type type, notify_cb_udata func, void *user_data,
- destroy_cb_udata func_destroy, const char *caller);
+int __register_notifier_udata(enum device_notifier_type type, notify_cb_udata func,
+ void *user_data, destroy_cb_udata func_destroy, int priority, const char *caller);
#define register_notifier_udata(type, func, user_data, func_destroy) \
- __register_notifier_udata(type, func, user_data, func_destroy, __func__)
+ __register_notifier_udata(type, func, user_data, func_destroy, 0, __func__)
+#define register_notifier_udata_priority(type, func, user_data, func_destroy, prio) \
+ __register_notifier_udata(type, func, user_data, func_destroy, prio, __func__)
+
int __unregister_notifier_udata(int id, const char *caller);
#define unregister_notifier_udata(id) __unregister_notifier_udata(id, __func__)
-#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <shared/device-notifier.h>
device_notify_once(DEVICE_NOTIFIER_LOWBAT, (void *)(intptr_t) 0x9a9a9a9a);
}
+static void test_device_notify_priority_p1(void **state)
+{
+ int id1, id2, id3;
+
+ id1 = register_notifier_udata_priority(DEVICE_NOTIFIER_DISPLAY_LOCK, notify_callback_udata,
+ (void *)(intptr_t) 0x11111111, NULL, -300);
+ assert_in_range(id1, 1, INT_MAX);
+
+ id2 = register_notifier_udata_priority(DEVICE_NOTIFIER_DISPLAY_LOCK, notify_callback_udata,
+ (void *)(intptr_t) 0x22222222, NULL, 500);
+ assert_in_range(id2, 1, INT_MAX);
+
+ id3 = register_notifier_udata_priority(DEVICE_NOTIFIER_DISPLAY_LOCK, notify_callback_udata,
+ (void *)(intptr_t) 0x33333333, NULL, -300);
+ assert_in_range(id3, 1, INT_MAX);
+
+ /* id2 will be invoked first */
+ expect_value(notify_callback_udata, data, 0x1234);
+ expect_value(notify_callback_udata, udata, 0x22222222);
+ /* id1, id3 invocation follows it,
+ * and those are invoked in the order in which they were registered */
+ expect_value(notify_callback_udata, data, 0x1234);
+ expect_value(notify_callback_udata, udata, 0x11111111);
+ expect_value(notify_callback_udata, data, 0x1234);
+ expect_value(notify_callback_udata, udata, 0x33333333);
+
+ device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)(intptr_t)0x1234);
+}
+
static int run_device_notifier_test(void)
{
static const struct CMUnitTest testsuite[] = {
cmocka_unit_test(test_device_notify_once_p),
cmocka_unit_test(test_destroy_callback_p1),
cmocka_unit_test(test_destroy_callback_p2),
+ cmocka_unit_test(test_device_notify_priority_p1),
};
return cmocka_run_group_tests(testsuite, NULL, NULL);