2 // Copyright (c) 2015 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * This file represents the entry point for the activity recognition HAL module.
22 #include <utils/Log.h>
23 #include <sys/epoll.h>
24 #include <sys/eventfd.h>
25 #include <sys/ioctl.h>
26 #include <sys/types.h>
31 #include <hardware/sensors.h>
34 #include "activity_event_utils.h"
35 #include <linux/iio/events.h>
36 #include <linux/iio/types.h>
38 #define MODULE_VERSION 1
41 #define MODULE_NAME "Activity recognition HAL"
42 #define MODULE_AUTHOR "Intel"
44 #define CONTROL_FD (-1)
48 * This table maps syfs entries in scan_elements directories to sensor types,
49 * and will also be used to determine other sysfs names as well as the iio
50 * device number associated to a specific sensor.
52 sensor_catalog_entry_t sensor_catalog[] = {
55 .type = SENSOR_TYPE_SIGNIFICANT_MOTION,
60 DECLARE_VOID_CHANNEL("still")
63 { DECLARE_GENERIC_EVENT("activity", "still", "thresh", "rising") },
64 { DECLARE_GENERIC_EVENT("activity", "still", "thresh", "falling") },
68 DECLARE_VOID_CHANNEL("walking")
71 { DECLARE_GENERIC_EVENT("activity", "walking", "thresh", "rising") },
72 { DECLARE_GENERIC_EVENT("activity", "walking", "thresh", "falling") },
76 DECLARE_VOID_CHANNEL("running")
79 { DECLARE_GENERIC_EVENT("activity", "running", "thresh", "rising") },
80 { DECLARE_GENERIC_EVENT("activity", "running", "thresh", "falling") },
87 unsigned int catalog_size = ARRAY_SIZE(sensor_catalog);
89 /* All possible activities - see activity_recognition.h */
90 static char const* sysfs_activity_names[MAX_ACTIVITIES] = {
99 /* Internal HAL info */
100 static struct activity_event_info supported_activities[MAX_ACTIVITIES + 1];
101 /* Android framework level description (activities' name). The element on the
102 * first position (0) is reserved for the FLUSH COMPLETE event, thus we have
103 * (MAX_ACTIVITIES + 1) possible activities.
105 static char const* supported_activity_names[MAX_ACTIVITIES + 1];
106 /* Supported activities count */
107 static unsigned int count;
109 static int poll_fd, control_fd, exit_fd;
110 static pthread_t control_thread;
112 static activity_recognition_callback_procs_t activity_dev_callback;
113 static pthread_mutex_t callback_mutex;
115 static int instances_count;
117 static void register_activity_callback(const struct activity_recognition_device *dev __attribute((unused)),
118 const activity_recognition_callback_procs_t* callback)
120 pthread_mutex_lock(&callback_mutex);
121 activity_dev_callback.activity_callback = callback->activity_callback;
122 pthread_mutex_unlock(&callback_mutex);
125 static bool check_activity_event(uint32_t activity_handle, uint32_t event_type)
127 if (activity_handle > count)
130 /* Also return false if the handle is 0 - this is reserved for flush
131 * event, that is currently not supported. */
132 if (activity_handle == 0)
135 switch (event_type) {
136 case ACTIVITY_EVENT_ENTER:
137 case ACTIVITY_EVENT_EXIT:
139 case ACTIVITY_EVENT_FLUSH_COMPLETE:
140 /* Not supported yet */
146 static int set_activity_event_state(const struct activity_recognition_device *dev __attribute((unused)),
147 uint32_t activity_handle, uint32_t event_type,
150 uint64_t control_code;
153 /* Check received index boundaries */
154 if (!check_activity_event(activity_handle, event_type)) {
155 ALOGE("Received invalid <activity %d, event %d> %s request\n",
156 activity_handle, event_type, action);
160 control_code = get_control_code((uint8_t) 1,
161 (uint8_t) activity_handle,
162 (uint8_t) event_type);
164 ret = write(control_fd, &control_code, sizeof(control_code));
166 ALOGE("Error writing to control fd to %s activity event\n", action);
170 ALOGI("Sent %s <%s, %i> request\n", action, supported_activity_names[activity_handle], event_type);
175 static int enable_activity_event(const struct activity_recognition_device *dev,
176 uint32_t activity_handle, uint32_t event_type,
177 int64_t max_batch_report_latency_ns __attribute((unused)))
179 return set_activity_event_state(dev, activity_handle, event_type, "enable");
182 static int disable_activity_event(const struct activity_recognition_device *dev,
183 uint32_t activity_handle, uint32_t event_type)
185 return set_activity_event_state(dev, activity_handle, event_type, "disable");
189 * For now, just report that the function call has been made, since we yet do
190 * not have a batch FIFO device.
192 static int flush(const struct activity_recognition_device *dev __attribute((unused)))
194 ALOGV("Flushing...\n");
199 static void process_disabling_activity_ev(uint8_t activity, uint8_t event);
201 static int close_device(struct hw_device_t *device __attribute((unused)))
203 int j, ret, exit_ping;
206 if (!instances_count)
214 /* Send exit request to the worker thread and close resources. We can
215 * write anything to the exit fd, we just need the event.
218 write(exit_fd, &exit_ping, sizeof(exit_ping));
220 /* Wait for worker thread to finish in order to release shared
223 pthread_join(control_thread, NULL);
225 /* Close exit fd after sending the canceling request. */
226 ret = epoll_ctl(poll_fd, EPOLL_CTL_DEL, exit_fd, NULL);
228 ALOGE("Error deleting exit fd from polling pool\n");
231 /* Clean control data. */
232 ret = epoll_ctl(poll_fd, EPOLL_CTL_DEL, control_fd, NULL);
234 ALOGE("Error deleting control fd from polling pool\n");
237 /* Disable all monitored <activity, event> pairs. This step should be
238 * the last one, after worker thread has ended in order to avoid
239 * supported_activities data corruption and avoid using another lock.
241 for (i = 1; i <= count; i++)
242 for (j = 0; j < MAX_EVENTS_PER_ACTIVITY; j++)
243 if (supported_activities[i].monitored[j])
244 process_disabling_activity_ev(
246 supported_activities[i].event[j]->event_type);
250 pthread_mutex_destroy(&callback_mutex);
252 ALOGI("Successfully closed device\n");
258 * Finds the event given by type in the sensor's channel structure and retrieves
260 * Equivalence (activity HAL naming - sensor HAL naming):
261 * ACTIVITY_EVENT_ENTER - "rising"
262 * ACTIVITY_EVENT_EXIT - "falling"
264 static int get_ev_index(int ev_type, channel_descriptor_t *chann)
270 case ACTIVITY_EVENT_ENTER:
273 case ACTIVITY_EVENT_EXIT:
281 for (i = 0; i < chann->num_events; i++) {
282 if (strcmp(ev_dir, chann->event[i].dir) == 0)
289 static int set_event_enabling(int dev_num, const char *en_path, int value)
294 ret = snprintf(path, sizeof(EVENTS_PATH) + sizeof(en_path), EVENTS_PATH "%s", dev_num, en_path);
298 return sysfs_write_int(path, value);
302 static void process_enabling_activity_ev(uint8_t activity, uint8_t event)
304 struct activity_event_info *activ = supported_activities + activity;
305 channel_descriptor_t *chann;
306 struct activity_event *ev;
308 struct epoll_event ev_data;
309 int dev_fd, ev_index, ret;
311 bool open_now = false;
313 /* Allocate event structure and populate it */
314 ev = malloc(sizeof(*ev));
316 ALOGE("Error allocating activity event for enabling\n");
320 ev->event_type = (uint32_t) event;
321 ev->activity = (uint32_t) activity;
324 /* The event fd is one per device, so we need to check if we have not
325 * retrieved it already when monitoring another <activity, event> pair.
326 * If it has not been retrieved, get it and update all other activities
327 * associated with the same device.
329 if (activ->event_fd == -1) {
330 ret = snprintf(path, sizeof(DEV_FILE_PATH), DEV_FILE_PATH, activ->dev_num);
334 dev_fd = open(path, O_RDONLY | O_NONBLOCK);
338 ret = ioctl(dev_fd, IIO_GET_EVENT_FD_IOCTL, &activ->event_fd);
345 ev_data.events = EPOLLIN;
346 ev_data.data.fd = activ->event_fd;
347 ret = epoll_ctl(poll_fd, EPOLL_CTL_ADD, activ->event_fd, &ev_data);
351 /* Update all other activities generated by this device */
352 for (i = 1; i <= count; i++)
353 if (supported_activities[i].dev_num == activ->dev_num)
354 supported_activities[i].event_fd = activ->event_fd;
357 /* Activate the event */
358 chann = sensor_catalog[activ->sensor_catalog_index].channel + activ->channel_index;
359 ev_index = get_ev_index((int)event, chann);
361 ALOGE("Invalid event index: %d\n", ev_index);
364 ret = set_event_enabling(activ->dev_num, chann->event[ev_index].ev_en_path, 1);
368 /* Internally mark that the <activity, event> pair is being monitored.
369 * We keep the same event index in our activity structure as is in the
370 * channel descriptor structure.
372 activ->event[ev_index] = ev;
373 activ->monitored[ev_index] = true;
374 activ->event_count++;
380 close(activ->event_fd);
381 for (i = 1; i <= count; i++)
382 if (supported_activities[i].dev_num == activ->dev_num)
383 supported_activities[i].event_fd = -1;
389 static bool device_not_monitored(int dev_num)
393 for (i = 1; i <= count; i++)
394 if (supported_activities[i].dev_num == dev_num &&
395 supported_activities[i].event_count > 0) {
402 static void process_disabling_activity_ev(uint8_t activity, uint8_t event)
404 struct activity_event_info *activ = supported_activities + activity;
405 channel_descriptor_t *chann;
409 /* Deactivate the event. */
410 chann = sensor_catalog[activ->sensor_catalog_index].channel + activ->channel_index;
411 ev_index = get_ev_index((int)event, chann);
413 ALOGE("Invalid event index: %d\n", ev_index);
415 ret = set_event_enabling(activ->dev_num, chann->event[ev_index].ev_en_path, 0);
417 ALOGE("Could not deactivate event - writing error\n");
420 /* Mark that the <activity, event> pair is not monitored any longer. */
421 activ->monitored[ev_index] = false;
422 activ->event_count--;
424 /* Close the event fd if this is the last pair monitored for the given
425 * device and remove it from the polling pool.
427 if (device_not_monitored(activ->dev_num)) {
428 ret = epoll_ctl(poll_fd, EPOLL_CTL_DEL, activ->event_fd, NULL);
430 ALOGE("Error removing event fd from polling pool\n");
434 close(activ->event_fd);
435 for (i = 1; i <= count; i++)
436 if (supported_activities[i].dev_num == activ->dev_num)
437 supported_activities[i].event_fd = -1;
440 /* Free resources. */
441 free(activ->event[ev_index]);
442 activ->event[ev_index] = NULL;
445 static void process_control_event(void)
447 struct control_event_data control_data;
448 uint64_t control_code;
451 /* Read control data from the control fd and interpret it */
452 ret = read(control_fd, &control_code, sizeof(control_code));
454 ALOGW("Error reading from control fd\n");
458 get_control_data(control_code, &control_data);
460 if (control_data.enable)
461 process_enabling_activity_ev(control_data.activity, control_data.event);
463 process_disabling_activity_ev(control_data.activity, control_data.event);
466 static int get_activity_index(int modifier)
470 /* Start from 1 since 0 is reserved for FLUSH_COMPLETE event. */
471 for (i = 1; i <= count; i++)
472 if (supported_activities[i].modifier == modifier)
478 static void process_activity_event(int fd, struct activity_event events[], int *count)
480 struct iio_event_data event;
481 int ret, chann_type, ev_type, ev_dir, ev_modifier, index, activity_index;
483 /* Retrieve event. */
484 ret = read(fd, &event, sizeof(event));
486 ALOGE("Error reading event\n");
490 /* Extract fields we are interested in and check the generated event. */
491 chann_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event.id);
492 if (chann_type != IIO_ACTIVITY) {
493 ALOGW("Event came from other than an activity channel\n");
497 ev_modifier = IIO_EVENT_CODE_EXTRACT_MODIFIER(event.id);
498 switch (ev_modifier) {
500 case IIO_MOD_WALKING:
501 case IIO_MOD_RUNNING:
502 activity_index = get_activity_index(ev_modifier);
503 if (activity_index >= 0)
506 ALOGW("Incompatible modifier - none of the supported activities is present\n");
510 ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event.id);
511 if (ev_type != IIO_EV_TYPE_THRESH) {
512 ALOGW("Event type is not threshold\n");
516 ev_dir = IIO_EVENT_CODE_EXTRACT_DIR(event.id);
518 case IIO_EV_DIR_RISING:
519 ev_dir = ACTIVITY_EVENT_ENTER;
521 case IIO_EV_DIR_FALLING:
522 ev_dir = ACTIVITY_EVENT_EXIT;
525 ALOGW("Incompatible event direction - only RISING and FALLING supported\n");
529 /* Add the activity event to the array for further processing. */
531 events[index].event_type = ev_dir;
532 events[index].activity = activity_index;
533 events[index].timestamp = event.timestamp;
539 static void* events_routine(void *arg __attribute((unused)))
541 struct epoll_event events[MAX_ACTIVITIES + 2];
542 struct activity_event data_events[MAX_ACTIVITIES];
543 int no_events, i, no_activity_events;
546 ALOGV("Waiting for sensor events ...\n");
548 no_activity_events = 0;
549 no_events = epoll_wait(poll_fd, events, MAX_ACTIVITIES + 2, -1);
550 if (no_events == -1) {
551 ALOGE("epoll_wait error %s\n", strerror(errno));
555 for (i = 0; i < no_events; i++)
556 if (events[i].events == EPOLLIN) {
557 int data = events[i].data.fd;
560 process_activity_event(data,
562 &no_activity_events);
565 process_control_event();
570 ALOGW("Invalid event user data: %d \n", events[i].data.fd);
574 ALOGW("Epoll events %i not expected\n", events[i].events);
576 /* Call the callback function for the retrieved events (if it
579 pthread_mutex_lock(&callback_mutex);
580 if (activity_dev_callback.activity_callback) {
581 activity_dev_callback.activity_callback(
582 &activity_dev_callback,
586 pthread_mutex_unlock(&callback_mutex);
590 static int set_up_control_data(void)
592 struct epoll_event control_ev, exit_ev;
595 ret = pthread_mutex_init(&callback_mutex, NULL);
599 /* Maximum fds is maximum activities + 1 control fd + 1 exit fd */
600 poll_fd = epoll_create(MAX_ACTIVITIES + 2);
604 goto poll_control_err;
606 control_fd = eventfd(0, 0);
607 if (control_fd == -1) {
609 goto poll_control_err;
612 control_ev.events = EPOLLIN;
613 /* Set data field to event file descriptor */
614 control_ev.data.fd = CONTROL_FD;
615 ret = epoll_ctl(poll_fd, EPOLL_CTL_ADD, control_fd, &control_ev);
617 goto control_data_err;
619 exit_fd = eventfd(0, 0);
621 ALOGE("Error allocating exit fd\n");
622 goto exit_control_err;
624 exit_ev.events = EPOLLIN;
625 exit_ev.data.fd = EXIT_FD;
626 ret = epoll_ctl(poll_fd, EPOLL_CTL_ADD, exit_fd, &exit_ev);
628 ALOGE("Error adding exit fd to the polling pool\n");
632 /* Start worker thread to wait on all event sources */
633 ret = pthread_create(&control_thread, NULL, events_routine, NULL);
640 epoll_ctl(poll_fd, EPOLL_CTL_DEL, exit_fd, NULL);
644 epoll_ctl(poll_fd, EPOLL_CTL_DEL, control_fd, NULL);
653 /* Returns the IIO_MOD_* equivalent to the given name. */
654 static int get_modifier_as_int(const char* mod)
656 if (strncmp(mod, "still", sizeof("still")) == 0)
657 return IIO_MOD_STILL;
659 if (strncmp(mod, "walking", sizeof("walking")) == 0)
660 return IIO_MOD_WALKING;
662 if (strncmp(mod, "running", sizeof("running")) == 0)
663 return IIO_MOD_RUNNING;
668 static void add_activity(int sensor_catalog_index, int channel_index,
669 int dev_num, const char *name)
671 int index, i, modifier;
673 if (count == MAX_ACTIVITIES) {
674 ALOGE("Trying to add more than supported activities!\n");
678 modifier = get_modifier_as_int(name);
680 ALOGE("Invalid channel name as modifier: %s\n", name);
686 for (i = 0; i < MAX_EVENTS_PER_ACTIVITY; i++) {
687 supported_activities[index].event[i] = NULL;
688 supported_activities[index].monitored[i] = false;
690 supported_activities[index].modifier = modifier;
691 supported_activities[index].event_count = 0;
692 supported_activities[index].sensor_catalog_index = sensor_catalog_index;
693 supported_activities[index].channel_index = channel_index;
694 supported_activities[index].dev_num = dev_num;
695 supported_activities[index].event_fd = -1;
697 supported_activity_names[index] = name;
700 static bool is_activity_valid(const char *activity_name)
704 /* Look if this activity has not been already added */
705 for (i = 1; i <= count; i++)
706 if (strcmp(supported_activity_names[i], activity_name) == 0)
709 /* Check that the found activity is recognized by this API */
710 for (i = 0; i < MAX_ACTIVITIES; i++)
711 if (strcmp(sysfs_activity_names[i], activity_name) == 0)
717 /* Get all possible activities provided by the IIO sensors */
718 static void discover_activity_events(void)
720 channel_descriptor_t *chann;
721 int i, num_channels, dev_num;
723 char event_sensors[catalog_size];
725 /* Discover event sensors */
726 for (dev_num = 0; dev_num < MAX_DEVICES; dev_num++) {
727 discover_sensors(dev_num, EVENTS_PATH, event_sensors, check_event_sensors);
728 for (index = 0; index < catalog_size; index++) {
729 if (!event_sensors[index])
732 num_channels = sensor_catalog[index].num_channels;
733 for (i = 0; i < num_channels; i++) {
734 chann = sensor_catalog[index].channel + i;
736 if (is_activity_valid(chann->name))
737 add_activity(index, i, dev_num, chann->name);
742 ALOGI("Discovered %d activities\n", count);
745 static int open_module(const struct hw_module_t *module, const char *id,
746 struct hw_device_t **device)
748 static struct activity_recognition_device activity_dev;
751 if (strncmp(id, ACTIVITY_RECOGNITION_HARDWARE_INTERFACE, sizeof(ACTIVITY_RECOGNITION_HARDWARE_INTERFACE)) != 0)
754 activity_dev.common.tag = HARDWARE_DEVICE_TAG;
755 activity_dev.common.version = ACTIVITY_RECOGNITION_API_VERSION_0_1;
756 activity_dev.common.module = (struct hw_module_t *) module;
757 activity_dev.common.close = close_device;
759 activity_dev.register_activity_callback = register_activity_callback;
760 activity_dev.enable_activity_event = enable_activity_event;
761 activity_dev.disable_activity_event = disable_activity_event;
762 activity_dev.flush = flush;
764 *device = &activity_dev.common;
766 if (instances_count == 0) {
767 discover_activity_events();
768 ret = set_up_control_data();
770 ALOGI("Initialized activity recognition HAL (exit code %i)\n", ret);
778 static struct hw_module_methods_t module_methods = {
783 static int get_supported_activities_list(struct activity_recognition_module *module __attribute((unused)),
784 char const* const* *activity_list)
786 *activity_list = supported_activity_names + 1;
791 /* Module descriptor visible to the Android framework. */
792 struct activity_recognition_module __attribute__ ((visibility ("default")))
793 HAL_MODULE_INFO_SYM = {
795 .tag = HARDWARE_MODULE_TAG,
796 .module_api_version = MODULE_VERSION,
797 .hal_api_version = HAL_VERSION,
798 .id = ACTIVITY_RECOGNITION_HARDWARE_MODULE_ID,
800 .author = MODULE_AUTHOR,
801 .methods = &module_methods,
803 .get_supported_activities_list = get_supported_activities_list