ivi-resource-manager: add appid mapping
authorJaska Uimonen <jaska.uimonen@helsinki.fi>
Tue, 25 Jun 2013 20:29:32 +0000 (23:29 +0300)
committerKrisztian Litkey <krisztian.litkey@intel.com>
Thu, 8 Jan 2015 16:37:08 +0000 (18:37 +0200)
src/Makefile.am
src/plugins/ivi-resource-manager/appid.c [new file with mode: 0644]
src/plugins/ivi-resource-manager/appid.h [new file with mode: 0644]
src/plugins/ivi-resource-manager/audio.c
src/plugins/ivi-resource-manager/plugin-ivi-resource-manager.c
src/plugins/ivi-resource-manager/plugin-ivi-resource-manager.h

index a612363..16ef3ac 100644 (file)
@@ -1336,7 +1336,8 @@ PLUGIN_IVI_RESOURCE_MANAGER_REGULAR_SOURCES =                                 \
                plugins/ivi-resource-manager/plugin-ivi-resource-manager.c  \
                plugins/ivi-resource-manager/class.c                        \
                plugins/ivi-resource-manager/screen.c                       \
-               plugins/ivi-resource-manager/audio.c
+               plugins/ivi-resource-manager/audio.c                        \
+               plugins/ivi-resource-manager/appid.c
 PLUGIN_IVI_RESOURCE_MANAGER_SOURCES =                                      \
                $(PLUGIN_IVI_RESOURCE_MANAGER_REGULAR_SOURCES)              \
                 plugin-ivi-resource-manager-func-info.c
diff --git a/src/plugins/ivi-resource-manager/appid.c b/src/plugins/ivi-resource-manager/appid.c
new file mode 100644 (file)
index 0000000..8b8d92f
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2012, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  * Neither the name of Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include "appid.h"
+
+#define APP_DIR   "/opt/apps"
+#define APP_MAX   1024
+
+typedef struct appid_map_s   appid_map_t;
+
+struct appid_map_s {
+    const char *id;
+    const char *exe;
+};
+
+struct mrp_resmgr_appid_s {
+    mrp_resmgr_data_t *data;
+    mrp_htbl_t *map;
+};
+
+static void map_init(mrp_resmgr_appid_t *, const char *);
+static void map_add_entry(mrp_resmgr_appid_t *, const char *, const char *);
+static void map_free_entry(void *, void *);
+
+static int pid2exe(const char *, char *, size_t);
+
+
+mrp_resmgr_appid_t *mrp_resmgr_appid_create(mrp_resmgr_data_t *data)
+{
+    mrp_resmgr_appid_t *appid;
+    mrp_htbl_config_t cfg;
+
+    cfg.nentry = APP_MAX;
+    cfg.comp = mrp_string_comp;
+    cfg.hash =  mrp_string_hash;
+    cfg.free = map_free_entry;
+    cfg.nbucket = cfg.nentry / 8;
+
+    if ((appid = mrp_allocz(sizeof(*appid)))) {
+        appid->data = data;
+        appid->map = mrp_htbl_create(&cfg);
+
+        map_init(appid, APP_DIR);
+    }
+
+    return appid;
+}
+
+
+void mrp_resmgr_appid_destroy(mrp_resmgr_appid_t *appid)
+{
+    if (appid) {
+        mrp_htbl_destroy(appid->map, TRUE);
+        mrp_free(appid);
+    }
+}
+
+const char *mrp_resmgr_appid_find_by_pid(mrp_resmgr_appid_t *appid,
+                                         const char *pid)
+{
+    char exe[PATH_MAX];
+    appid_map_t *entry;
+
+    if (pid2exe(pid, exe, PATH_MAX) < 0)
+        goto failed;
+
+    if (!(entry = mrp_htbl_lookup(appid->map, exe)))
+        goto failed;
+
+
+    return entry->id;
+    
+ failed:
+    return NULL;
+}
+
+static void map_init(mrp_resmgr_appid_t *appid, const char *dir_path)
+{
+    DIR *dir, *bindir;
+    struct dirent *dirent, *binent;
+    struct stat stat;
+    const char *id;
+    char subdir_path[PATH_MAX];
+    char bindir_path[PATH_MAX];
+    char exe[PATH_MAX];
+
+    if (!(dir = opendir(dir_path))) {
+        mrp_log_error("iiv-resource-manager: can't open directory %s: %s",
+                      dir_path, strerror(errno));
+        return;
+    }
+
+    while ((dirent = readdir(dir))) {
+        id = dirent->d_name;
+
+        snprintf(subdir_path, sizeof(subdir_path), "%s/%s", dir_path, id);
+
+        if (lstat(subdir_path, &stat) < 0) {
+            mrp_log_error("ivi-resource-manager: can't stat %s: %s",
+                          subdir_path, strerror(errno));
+            continue;
+        }
+
+        if (!S_ISDIR(stat.st_mode) || id[0] == '.')
+            continue;
+
+        snprintf(bindir_path, sizeof(bindir_path), "%s/bin", subdir_path);
+
+        if (!(bindir = opendir(bindir_path))) {
+            mrp_log_error("ivi-resource-manager: can't open directory %s: %s",
+                          bindir_path, strerror(errno));
+            continue;
+        }
+
+        while ((binent = readdir(bindir))) {
+            snprintf(exe, sizeof(exe), "%s/%s", bindir_path, binent->d_name);
+
+            if (lstat(exe, &stat) < 0) {
+                mrp_log_error("ivi-resource-manager: can't stat %s: %s",
+                              exe, strerror(errno));
+                continue;
+            }
+
+            if (!S_ISREG(stat.st_mode) || !(stat.st_mode & 0111))
+                continue;
+
+            map_add_entry(appid, id, exe);
+        }
+
+        closedir(bindir);
+
+    } /* while dirent */
+
+    closedir(dir);
+}
+
+static void map_add_entry(mrp_resmgr_appid_t *appid,
+                          const char *id,
+                          const char *exe)
+{
+    appid_map_t *entry;
+
+    if (!(entry = mrp_allocz(sizeof(*entry))) ||
+        !(entry->id = mrp_strdup(id)) ||
+        !(entry->exe = mrp_strdup(exe)))
+    {
+        mrp_log_error("ivi-resource-manager: can't allocate memory");
+        return;
+    }
+
+    mrp_htbl_insert(appid->map, (void *)entry->exe, entry);
+
+    mrp_log_info("ivi-resource-manager: map exe %s => appid %s",
+                 entry->exe, entry->id);
+}
+
+static void map_free_entry(void *key, void *object)
+{
+    appid_map_t *me = (appid_map_t *)object;
+
+    MRP_UNUSED(key);
+
+    free((void *)me->id);
+    free((void *)me->exe);
+    free((void *)me);
+}
+
+static int pid2exe(const char *pid, char *buf, size_t len)
+{
+    FILE *f;
+    char path[PATH_MAX];
+    char *p;
+    int st = -1;
+
+    if (pid && buf && len > 0) {
+        snprintf(path, sizeof(path), "/proc/%s/cmdline", pid);
+
+        if ((f = fopen(path, "r"))) {
+            if (fgets(buf, len-1, f)) {
+                if ((p = strchr(buf, ' ')))
+                    *p = '\0';
+                else if ((p = strchr(buf, '\n')))
+                    *p = '\0';
+                st = 0;
+            }
+            fclose(f);
+        }
+    }
+
+    if (st < 0)
+        mrp_log_info("ivi-resource-manager: pid2exe(%s) failed", pid);
+    else
+        mrp_log_info("ivi-resource-manager: pid %s => exe %s", pid, buf);
+
+    return st;
+}
+
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */
diff --git a/src/plugins/ivi-resource-manager/appid.h b/src/plugins/ivi-resource-manager/appid.h
new file mode 100644 (file)
index 0000000..20d63b7
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  * Neither the name of Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_IVI_RESOURCE_MANAGER_APPID_H__
+#define __MURPHY_IVI_RESOURCE_MANAGER_APPID_H__
+
+#include "plugin-ivi-resource-manager.h"
+
+mrp_resmgr_appid_t *mrp_resmgr_appid_create(mrp_resmgr_data_t *);
+void mrp_resmgr_appid_destroy(mrp_resmgr_appid_t *);
+
+const char *mrp_resmgr_appid_find_by_pid(mrp_resmgr_appid_t *, const char *);
+
+
+#endif  /* __MURPHY_IVI_RESOURCE_MANAGER_APPID_H__ */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */
index f0f5b2d..bfade9f 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "audio.h"
 #include "class.h"
+#include "appid.h"
 
 #define RESOURCE_NAME       "audio_playback"
 #define ACTIVE_SCREEN_TABLE "active_screen"
@@ -122,6 +123,7 @@ static void resource_class_move_resource(mrp_resmgr_class_t *,
 static uint32_t resource_key(audio_resource_t *);
 static bool resource_is_active(mrp_resmgr_audio_t *, uint32_t,
                                audio_resource_t *);
+static void resource_fix_appid(mrp_resmgr_audio_t *, mrp_resource_t *);
 
 static void get_active_screens(mrp_resmgr_audio_t *, mrp_zone_t *);
 
@@ -268,9 +270,9 @@ int mrp_resmgr_audio_print(mrp_resmgr_audio_t *audio,
 }
 
 static audio_resource_t *audio_resource_create(mrp_resmgr_audio_t *audio,
-                                                 mrp_zone_t *zone,
-                                                 mrp_resource_t *res,
-                                                 mrp_application_class_t *ac)
+                                               mrp_zone_t *zone,
+                                               mrp_resource_t *res,
+                                               mrp_application_class_t *ac)
 {
     mrp_resmgr_data_t *data;
     uint32_t zone_id;
@@ -292,6 +294,8 @@ static audio_resource_t *audio_resource_create(mrp_resmgr_audio_t *audio,
         mrp_log_error("ivi-resource-manager: can't obtain resmgr class");
     }
     else {
+        resource_fix_appid(audio, res);
+
         if ((ar = mrp_allocz(sizeof(*ar)))) {
             mrp_list_init(&ar->link);
             ar->res = res;
@@ -535,6 +539,45 @@ static bool resource_is_active(mrp_resmgr_audio_t *audio,
     return false;
 }
 
+static void resource_fix_appid(mrp_resmgr_audio_t *audio, mrp_resource_t *res)
+{
+    mrp_resmgr_data_t *data;
+    mrp_attr_t attr, attrs[2];
+    const char *appid;
+    const char *pid;
+
+    data = audio->data;
+    appid = NULL;
+    pid = 0;
+
+    if (mrp_resource_read_attribute(res, PID_ATTRIDX, &attr)) {
+        if (attr.type == mqi_string) {
+            if (strcmp(attr.value.string, "<unknown>"))
+                pid = attr.value.string;
+        }
+    }
+
+    if (mrp_resource_read_attribute(res, APPID_ATTRIDX, &attr)) {
+        if (attr.type == mqi_string) {
+            if (strcmp(attr.value.string, "<undefined>"))
+                appid = attr.value.string;
+        }
+    }
+
+    if (!appid && pid) {
+        appid = mrp_resmgr_appid_find_by_pid(mrp_resmgr_get_appid(data), pid);
+
+        if (appid) {
+            memset(attrs, 0, sizeof(attrs));
+            attrs[0].name = audio_attrs[APPID_ATTRIDX].name;
+            attrs[0].type = mqi_string;
+            attrs[0].value.string = appid;
+
+            mrp_resource_write_attributes(res, attrs);
+        }
+    }
+}
+
 static void get_active_screens(mrp_resmgr_audio_t *audio, mrp_zone_t *zone)
 {
     static const char *zone_name;
index 7d2462b..d486f28 100644 (file)
 
 #include "screen.h"
 #include "audio.h"
+#include "appid.h"
 
 struct mrp_resmgr_data_s {
     mrp_plugin_t        *plugin;
     mrp_event_watch_t   *w;
     mrp_resmgr_screen_t *screen;
     mrp_resmgr_audio_t  *audio;
+    mrp_resmgr_appid_t  *appid;
     mrp_htbl_t          *resources;
     int                  ndepend;
     const char         **depends;
@@ -143,6 +145,30 @@ void *mrp_resmgr_lookup_resource(mrp_resmgr_data_t *data, mrp_resource_t *key)
     return mrp_htbl_lookup(data->resources, key);
 }
 
+mrp_resmgr_screen_t *mrp_resmgr_get_screen(mrp_resmgr_data_t *data)
+{
+    MRP_ASSERT(data, "invalid argument");
+    MRP_ASSERT(data->screen, "confused with data structures");
+
+    return data->screen;
+}
+
+mrp_resmgr_audio_t *mrp_resmgr_get_audio(mrp_resmgr_data_t *data)
+{
+    MRP_ASSERT(data, "invalid argument");
+    MRP_ASSERT(data->audio, "confused with data structures");
+
+    return data->audio;
+}
+
+mrp_resmgr_appid_t *mrp_resmgr_get_appid(mrp_resmgr_data_t *data)
+{
+    MRP_ASSERT(data, "invalid argument");
+    MRP_ASSERT(data->appid, "confused with data structures");
+
+    return data->appid;
+}
+
 static void print_resources_cb(mrp_console_t *c, void *user_data,
                                int argc, char **argv)
 {
@@ -263,6 +289,7 @@ static void event_cb(mrp_event_watch_t *w, int id, mrp_msg_t *event_data,
                 if (!strcmp(inst, plugin->instance)) {
                     data->screen = mrp_resmgr_screen_create(data);
                     data->audio  = mrp_resmgr_audio_create(data);
+                    data->appid  = mrp_resmgr_appid_create(data);
 
                     add_depenedencies_to_resolver(data);
                 }
@@ -364,6 +391,8 @@ static void manager_exit(mrp_plugin_t *plugin)
 
     if ((data = plugin->data) && data == resmgr_data) {
         mrp_resmgr_screen_destroy(data->screen);
+        mrp_resmgr_audio_destroy(data->audio);
+        mrp_resmgr_appid_destroy(data->appid);
     }
 }
 
index 3caa8cb..8980251 100644 (file)
 #ifndef __MURPHY_IVI_RESOURCE_MANAGER_H__
 #define __MURPHY_IVI_RESOURCE_MANAGER_H__
 
+#include <murphy/resource/data-types.h>
+
+
 typedef struct mrp_resmgr_data_s      mrp_resmgr_data_t;
 typedef struct mrp_resmgr_screen_s    mrp_resmgr_screen_t;
 typedef struct mrp_resmgr_audio_s     mrp_resmgr_audio_t;
 typedef struct mrp_resmgr_class_s     mrp_resmgr_class_t;
-
+typedef struct mrp_resmgr_appid_s     mrp_resmgr_appid_t;
 
 
 void  mrp_resmgr_register_dependency(mrp_resmgr_data_t *, const char *);
@@ -45,6 +48,11 @@ void *mrp_resmgr_remove_resource(mrp_resmgr_data_t *, mrp_zone_t *,
                                  mrp_resource_t *);
 void *mrp_resmgr_lookup_resource(mrp_resmgr_data_t *, mrp_resource_t *);
 
+mrp_resmgr_screen_t *mrp_resmgr_get_screen(mrp_resmgr_data_t *);
+mrp_resmgr_audio_t *mrp_resmgr_get_audio(mrp_resmgr_data_t *);
+mrp_resmgr_appid_t *mrp_resmgr_get_appid(mrp_resmgr_data_t *);
+
+
 #endif  /* __MURPHY_IVI_RESOURCE_MANAGER_H__ */
 
 /*