#define INSTANCE_TYPE_NORMAL 0
#define INSTANCE_TYPE_MONITOR 1
+#define RESOURCE_TYPE_ALL (-1)
+#define RESOURCE_ATTR_ALL (~0ULL)
+
struct syscommon_resman_resource {
char *name;
int id;
struct resource_event_data {
int id;
+ int resource_type;
+ int attr_mask;
syscommon_resman_resource_event_cb callback;
+ void *user_data;
};
static int set_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
static int unset_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
static bool is_resource_attr_interested(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
static void
-notify_resource_event(int resource_type, int resource_id, int attr_id, const void *data, int count);
+notify_resource_event(int resource_type, int resource_id, u_int64_t attr_id, const void *data, int count);
static GList *g_resource_driver_head;
static GList *g_resource_event_data_list;
}
static void
-notify_resource_event(int resource_type, int resource_id, int attr_id, const void *data, int count)
+notify_resource_event(int resource_type, int resource_id, u_int64_t attr_id, const void *data, int count)
{
GList *elem;
struct resource_event_data *event_data;
event_data = (struct resource_event_data *) elem->data;
assert(event_data);
- event_data->callback(resource_type, resource_id, attr_id, data, count);
+
+ if ((event_data->resource_type != RESOURCE_TYPE_ALL) && (event_data->resource_type != resource_type))
+ continue;
+
+ if ((event_data->attr_mask & attr_id) == 0)
+ continue;
+
+ event_data->callback(resource_type, resource_id, attr_id, data, event_data->user_data, count);
}
}
return (_event_data->id - _id);
}
-int
-syscommon_resman_subscribe_resource_event(syscommon_resman_resource_event_cb callback, int *id)
+int syscommon_resman_subscribe_resource_attribute_event(int resource_type,
+ u_int64_t attr_mask, syscommon_resman_resource_event_cb callback, void *user_data, int *id)
{
struct resource_event_data *event_data = NULL;
*event_data = (struct resource_event_data) {
.id = alloc_resource_id(),
- .callback = callback
+ .resource_type = resource_type,
+ .attr_mask = attr_mask,
+ .callback = callback,
+ .user_data = user_data,
};
g_resource_event_data_list = g_list_append(g_resource_event_data_list, event_data);
return 0;
}
-void syscommon_resman_unsubscribe_resource_event(int id)
+int syscommon_resman_subscribe_resource_event(int resource_type,
+ syscommon_resman_resource_event_cb callback, void *user_data, int *id)
+{
+ return syscommon_resman_subscribe_resource_attribute_event(resource_type,
+ RESOURCE_ATTR_ALL, callback, user_data, id);
+}
+
+int syscommon_resman_subscribe_event(syscommon_resman_resource_event_cb callback,
+ void *user_data, int *id)
+{
+ return syscommon_resman_subscribe_resource_event(RESOURCE_TYPE_ALL, callback, user_data, id);
+}
+
+void syscommon_resman_unsubscribe_event(int id)
{
GList *list;
--- /dev/null
+#include <stdio.h>
+
+#include <libsyscommon/resource-manager.h>
+#include <libsyscommon/resource-type.h>
+
+#include "common-interface.h"
+#include "battery-interface.h"
+#include "../test-main.h"
+
+static int test_battery_get(int resource_id,
+ const struct syscommon_resman_resource_attribute *attr,
+ void *data)
+{
+ int ret = 0;
+ resource_attr_data_t attr_data = { 0, };
+
+ switch (attr->id) {
+ case BATTERY_ATTR_INT:
+ attr_data.i32 = mock_type(int);
+ break;
+ case BATTERY_ATTR_UINT:
+ attr_data.u32 = mock_type(uint32_t);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = mock_type(int);
+
+ if (ret < 0)
+ return ret;
+
+ switch (attr->type) {
+ case SYSCOMMON_RESMAN_DATA_TYPE_INT:
+ *(int32_t *) data = attr_data.i32;
+ break;
+ case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
+ *(int64_t *) data = attr_data.i64;
+ break;
+ case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
+ *(uint32_t *) data = attr_data.u32;
+ break;
+ case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
+ *(uint64_t *) data = attr_data.u64;
+ break;
+ case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
+ *(double *) data = attr_data.d;
+ break;
+ case SYSCOMMON_RESMAN_DATA_TYPE_PTR:
+ *(void **) data = attr_data.p;
+ break;
+ case SYSCOMMON_RESMAN_DATA_TYPE_BOOLEAN:
+ *(bool *) data = attr_data.b;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int test_battery_set(int resource_id,
+ const struct syscommon_resman_resource_attribute *attr,
+ const void *data, int count)
+{
+ check_expected_ptr(data);
+
+ return mock_type(int);
+}
+
+static const struct syscommon_resman_resource_attribute battery_attrs[] = {
+ {
+ .name = "BATTERY_ATTR_INT",
+ .id = BATTERY_ATTR_INT,
+ .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,
+ .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
+ .ops = {
+ .get = test_battery_get,
+ .set = test_battery_set,
+ .is_supported = syscommon_resman_resource_attr_supported_always,
+ },
+ } ,{
+ .name = "BATTERY_ATTR_UINT",
+ .id = BATTERY_ATTR_UINT,
+ .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT,
+ .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
+ .ops = {
+ .get = test_battery_get,
+ .set = test_battery_set,
+ .is_supported = syscommon_resman_resource_attr_supported_always,
+ },
+ }
+};
+
+static const struct syscommon_resman_resource_driver battery_resource_driver = {
+ .name = "test-battery",
+ .type = TEST_RESOURCE_TYPE_BATTERY,
+ .flag = SYSCOMMON_RESMAN_RESOURCE_DRIVER_FLAG_COUNT_ONLY_ONE,
+ .attrs = battery_attrs,
+ .num_attrs = sizeof(battery_attrs)/sizeof(battery_attrs[0]),
+};
+
+int create_battery_resource(void)
+{
+ int resource_id;
+ int ret;
+
+ ret = syscommon_resman_create_resource(&resource_id, TEST_RESOURCE_TYPE_BATTERY);
+ assert_int_equal(ret, 0);
+
+ return resource_id;
+}
+
+void delete_battery_resource(int resource_id)
+{
+ syscommon_resman_delete_resource(resource_id);
+}
+
+void setup_battery_resource_driver(void)
+{
+ /**
+ * Instead of using macro SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER(),
+ * use function.
+ *
+ * There two macros, SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER() and TESTSUITE(),
+ * are both using __attribute__((constructor)). And its order cannot be explicitly
+ * specified. However, the SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER() must be followed
+ * by the TESTSUITE(). Therefore, explicitly registers the driver via setup function
+ * prior to the execution of the testsuite.
+ */
+ syscommon_resman_add_resource_driver(&battery_resource_driver);
+}
#include "common-interface.h"
#include "display-interface.h"
+#include "battery-interface.h"
#include "resource-display.h"
+#include "resource-battery.h"
+
#include "../test-main.h"
+static int setup_resource_drivers(void **state)
+{
+ setup_display_resource_driver();
+ setup_battery_resource_driver();
+
+ return 0;
+}
+
static void test_create_resource_pass(void **state)
{
int resource_id;
delete_display_resource(resource_id);
}
-static void test_event_callback1(int resource_type, int resource_id, int attr_id, const void *data, int count)
+static void test_event_callback1(int resource_type, int resource_id, int attr_id, const void *data, void *user_data, int count)
{
check_expected(resource_type);
check_expected(resource_id);
check_expected(count);
}
-static void test_event_callback2(int resource_type, int resource_id, int attr_id, const void *data, int count)
+static void test_event_callback2(int resource_type, int resource_id, int attr_id, const void *data, void *user_data, int count)
{
check_expected(resource_type);
check_expected(resource_id);
resource_id1 = create_display_resource();
resource_id2 = create_display_resource();
- ret = syscommon_resman_subscribe_resource_event(test_event_callback1, &callback_id1);
+ ret = syscommon_resman_subscribe_event(test_event_callback1, NULL, &callback_id1);
assert_int_equal(ret, 0);
/* configure mock setter, success */
assert_int_equal(ret, 0);
/* register additional callback2 */
- ret = syscommon_resman_subscribe_resource_event(test_event_callback2, &callback_id2);
+ ret = syscommon_resman_subscribe_event(test_event_callback2, NULL, &callback_id2);
assert_int_equal(ret, 0);
/* second try, configure mock setter, success */
assert_int_equal(ret, 0);
/* unregister the callback1 */
- syscommon_resman_unsubscribe_resource_event(callback_id1);
+ syscommon_resman_unsubscribe_event(callback_id1);
/* third try, configure mock setter, success */
int_value = 10101;
assert_int_equal(ret, 0);
/* unregister the callback2 */
- syscommon_resman_unsubscribe_resource_event(callback_id2);
+ syscommon_resman_unsubscribe_event(callback_id2);
/* the last try, configure mock setter, success */
double_value = 5959.95;
int callback_id;
int ret;
- ret = syscommon_resman_subscribe_resource_event(NULL, &callback_id);
+ ret = syscommon_resman_subscribe_event(NULL, NULL, &callback_id);
assert_int_equal(ret, -EINVAL);
}
{
int ret;
- ret = syscommon_resman_subscribe_resource_event(test_event_callback1, NULL);
+ ret = syscommon_resman_subscribe_event(test_event_callback1, NULL, NULL);
assert_int_equal(ret, -EINVAL);
}
resource_id = create_display_resource();
- ret = syscommon_resman_subscribe_resource_event(test_event_callback1, &callback_id);
+ ret = syscommon_resman_subscribe_event(test_event_callback1, NULL, &callback_id);
assert_int_equal(ret, 0);
/* configure mock setter, fail */
ret = syscommon_resman_set_resource_attr_int(resource_id, DISPLAY_ATTR_INT, value);
assert_int_equal(ret, -ENOENT);
- syscommon_resman_unsubscribe_resource_event(callback_id);
+ syscommon_resman_unsubscribe_event(callback_id);
delete_display_resource(resource_id);
}
-static int setup_resource_drivers(void **state)
+static void test_subscribe_resource_event_pass(void **state)
{
- setup_display_resource_driver();
+ int display_resource_id;
+ int battery_resource_id;
+ int callback_id;
+ int int_value = -12345;
+ uint32_t uint_value = 494949;
+ int ret;
- return 0;
+ display_resource_id = create_display_resource();
+ battery_resource_id = create_battery_resource();
+
+ ret = syscommon_resman_subscribe_resource_event(TEST_RESOURCE_TYPE_BATTERY,
+ test_event_callback1, NULL, &callback_id);
+ assert_int_equal(ret, 0);
+
+ /* Test 1: subscribe battery event, generate display event */
+ /* configure display mock setter, success */
+ expect_memory(test_display_set, data, &int_value, sizeof(int));
+ will_return(test_display_set, 0);
+ /* do not configure mock callback as it is only invoked by battery setter */
+
+ ret = syscommon_resman_set_resource_attr_int(display_resource_id, DISPLAY_ATTR_INT, int_value);
+ assert_int_equal(ret, 0);
+
+ /* Test 2: subscribe battery event, generate battery event BATTERY_ATTR_INT */
+ /* configure battery mock setter, success */
+ expect_memory(test_battery_set, data, &int_value, sizeof(int));
+ will_return(test_battery_set, 0);
+ /* configure battery mock callback1 */
+ expect_value(test_event_callback1, resource_type, TEST_RESOURCE_TYPE_BATTERY);
+ expect_value(test_event_callback1, resource_id, battery_resource_id);
+ expect_value(test_event_callback1, attr_id, BATTERY_ATTR_INT);
+ expect_memory(test_event_callback1, data, &int_value, sizeof(int));
+ expect_value(test_event_callback1, count, 1);
+
+ ret = syscommon_resman_set_resource_attr_int(battery_resource_id, BATTERY_ATTR_INT, int_value);
+ assert_int_equal(ret, 0);
+
+ /* Test 3: subscribe battery event, generate battery event BATTERY_ATTR_UINT */
+ /* configure battery mock setter, success */
+ expect_memory(test_battery_set, data, &uint_value, sizeof(int));
+ will_return(test_battery_set, 0);
+ /* configure battery mock callback1 */
+ expect_value(test_event_callback1, resource_type, TEST_RESOURCE_TYPE_BATTERY);
+ expect_value(test_event_callback1, resource_id, battery_resource_id);
+ expect_value(test_event_callback1, attr_id, BATTERY_ATTR_UINT);
+ expect_memory(test_event_callback1, data, &uint_value, sizeof(uint32_t));
+ expect_value(test_event_callback1, count, 1);
+
+ ret = syscommon_resman_set_resource_attr_uint(battery_resource_id, BATTERY_ATTR_UINT, uint_value);
+ assert_int_equal(ret, 0);
+
+ syscommon_resman_unsubscribe_event(callback_id);
+ delete_display_resource(display_resource_id);
+ delete_battery_resource(battery_resource_id);
+}
+
+static void test_subscribe_resource_event_fail_invalid_parameter_1(void **state)
+{
+ int ret;
+ int callback_id;
+
+ ret = syscommon_resman_subscribe_resource_event(TEST_RESOURCE_TYPE_BATTERY,
+ NULL, NULL, &callback_id);
+ assert_int_equal(ret, -EINVAL);
+}
+
+static void test_subscribe_resource_event_fail_invalid_parameter_2(void **state)
+{
+ int ret;
+
+ ret = syscommon_resman_subscribe_resource_event(TEST_RESOURCE_TYPE_BATTERY,
+ test_event_callback1, NULL, NULL);
+ assert_int_equal(ret, -EINVAL);
+}
+
+static void test_subscribe_resource_attribute_event_pass(void **state)
+{
+ int display_resource_id;
+ int battery_resource_id;
+ int callback_id;
+ int int_value = -12345;
+ uint32_t uint_value = 494949;
+ double double_value = -100.001;
+ int ret;
+
+ display_resource_id = create_display_resource();
+ battery_resource_id = create_battery_resource();
+
+ ret = syscommon_resman_subscribe_resource_attribute_event(TEST_RESOURCE_TYPE_DISPLAY,
+ DISPLAY_ATTR_INT | DISPLAY_ATTR_DOUBLE, test_event_callback1, NULL, &callback_id);
+ assert_int_equal(ret, 0);
+
+ /* Test 1: subscribe display event, generate battery event */
+ /* configure battery mock setter, success */
+ expect_memory(test_battery_set, data, &int_value, sizeof(int));
+ will_return(test_battery_set, 0);
+ /* do not configure mock callback as it is only invoked by display setter */
+
+ ret = syscommon_resman_set_resource_attr_int(battery_resource_id, BATTERY_ATTR_INT, int_value);
+ assert_int_equal(ret, 0);
+
+ /* Test 2: subscribe display event, generate display event that we aren't interested in */
+ /* configure display mock setter, success */
+ expect_memory(test_display_set, data, &uint_value, sizeof(uint32_t));
+ will_return(test_display_set, 0);
+ /* do not configure mock callback as it is not interesting display event*/
+
+ ret = syscommon_resman_set_resource_attr_uint(display_resource_id, DISPLAY_ATTR_UINT, uint_value);
+ assert_int_equal(ret, 0);
+
+ /* Test 3: subscribe display event, generate display event that we are interested in */
+ /* configure display mock setter, success */
+ expect_memory(test_display_set, data, &double_value, sizeof(double));
+ will_return(test_display_set, 0);
+ /* configure display mock callback1 */
+ expect_value(test_event_callback1, resource_type, TEST_RESOURCE_TYPE_DISPLAY);
+ expect_value(test_event_callback1, resource_id, display_resource_id);
+ expect_value(test_event_callback1, attr_id, DISPLAY_ATTR_DOUBLE);
+ expect_memory(test_event_callback1, data, &double_value, sizeof(double));
+ expect_value(test_event_callback1, count, 1);
+
+ ret = syscommon_resman_set_resource_attr_double(display_resource_id, DISPLAY_ATTR_DOUBLE, double_value);
+ assert_int_equal(ret, 0);
+
+ syscommon_resman_unsubscribe_event(callback_id);
+ delete_display_resource(display_resource_id);
+ delete_battery_resource(battery_resource_id);
+}
+
+static void test_subscribe_resource_attribute_event_fail_invalid_parameter_1(void **state)
+{
+ int ret;
+ int callback_id;
+
+ ret = syscommon_resman_subscribe_resource_attribute_event(TEST_RESOURCE_TYPE_BATTERY,
+ BATTERY_ATTR_INT, NULL, NULL, &callback_id);
+ assert_int_equal(ret, -EINVAL);
+}
+
+static void test_subscribe_resource_attribute_event_fail_invalid_parameter_2(void **state)
+{
+ int ret;
+
+ ret = syscommon_resman_subscribe_resource_attribute_event(TEST_RESOURCE_TYPE_BATTERY,
+ BATTERY_ATTR_INT, test_event_callback1, NULL, NULL);
+ assert_int_equal(ret, -EINVAL);
}
static const struct CMUnitTest resource_manager_testsuite[] = {
cmocka_unit_test(test_subscribe_event_fail_invalid_parameter_1),
cmocka_unit_test(test_subscribe_event_fail_invalid_parameter_2),
cmocka_unit_test(test_subscribe_event_fail_setter),
+
+ cmocka_unit_test(test_subscribe_resource_event_pass),
+ cmocka_unit_test(test_subscribe_resource_event_fail_invalid_parameter_1),
+ cmocka_unit_test(test_subscribe_resource_event_fail_invalid_parameter_2),
+
+ cmocka_unit_test(test_subscribe_resource_attribute_event_pass),
+ cmocka_unit_test(test_subscribe_resource_attribute_event_fail_invalid_parameter_1),
+ cmocka_unit_test(test_subscribe_resource_attribute_event_fail_invalid_parameter_2),
};
TESTSUITE_FIXTURE(resource_manager_testsuite, setup_resource_drivers, NULL);