summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinkyu Kang <mk7.kang@samsung.com>2015-09-23 11:06:27 +0900
committerMinkyu Kang <mk7.kang@samsung.com>2015-09-24 14:28:11 +0900
commit07777eae2cda3d9fdb5feaaa7cd18c6961b218a4 (patch)
tree279f1c48c310bebbebf5127231d131e95c927a29
parent61f71e5e27e939d31362ffd6f36c036f36e3fee1 (diff)
downloadair_mediahub-07777eae2cda3d9fdb5feaaa7cd18c6961b218a4.tar.gz
air_mediahub-07777eae2cda3d9fdb5feaaa7cd18c6961b218a4.tar.bz2
air_mediahub-07777eae2cda3d9fdb5feaaa7cd18c6961b218a4.zip
add location manager for setting location tag to images
Change-Id: I4729dd89321abd90bb349d34a68b87f4ff67b77d Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
-rw-r--r--CMakeLists.txt3
-rw-r--r--include/util/locmgr.h28
-rw-r--r--org.tizen.mediahub.xml.in2
-rw-r--r--packaging/org.tizen.mediahub.spec2
-rw-r--r--src/layout/gallery.c46
-rw-r--r--src/util/locmgr.c457
6 files changed, 538 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2bacbfd..8d9e4da 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,6 +23,8 @@ pkg_check_modules(PKGS REQUIRED
capi-appfw-application
capi-media-player
capi-ui-efl-util
+ capi-maps-service
+ vconf
app-utils)
IF(NOT DEFINED PACKAGE_NAME)
@@ -73,6 +75,7 @@ src/util/util.c
src/util/playermgr.c
src/util/ctxpopup.c
src/util/progressbar.c
+src/util/locmgr.c
src/data/datamgr.c
src/data/albumdata.c
src/data/folderdata.c
diff --git a/include/util/locmgr.h b/include/util/locmgr.h
new file mode 100644
index 0000000..8b409e4
--- /dev/null
+++ b/include/util/locmgr.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 __AIR_MEDIAHUB_LOCMGR_H__
+#define __AIR_MEDIAHUB_LOCMGR_H__
+
+struct locmgr;
+
+struct locmgr *locmgr_create(void);
+void locmgr_destroy(struct locmgr *m);
+
+bool locmgr_set_location(struct locmgr *m, app_media *am);
+bool locmgr_set_locations(struct locmgr *m, Eina_List *list);
+
+#endif
diff --git a/org.tizen.mediahub.xml.in b/org.tizen.mediahub.xml.in
index a9118bf..c7f48bc 100644
--- a/org.tizen.mediahub.xml.in
+++ b/org.tizen.mediahub.xml.in
@@ -11,5 +11,7 @@
<privilege>http://tizen.org/privilege/content.write</privilege>
<privilege>http://tizen.org/privilege/mediastorage</privilege>
<privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ <privilege>http://tizen.org/privilege/mapservice</privilege>
+ <privilege>http://tizen.org/privilege/internet</privilege>
</privileges>
</manifest>
diff --git a/packaging/org.tizen.mediahub.spec b/packaging/org.tizen.mediahub.spec
index 902e8d8..978ad20 100644
--- a/packaging/org.tizen.mediahub.spec
+++ b/packaging/org.tizen.mediahub.spec
@@ -13,6 +13,8 @@ BuildRequires: pkgconfig(elementary)
BuildRequires: pkgconfig(capi-appfw-application)
BuildRequires: pkgconfig(capi-media-player)
BuildRequires: pkgconfig(capi-ui-efl-util)
+BuildRequires: pkgconfig(capi-maps-service)
+BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(app-utils)
%define _appdir /usr/apps/%{name}
diff --git a/src/layout/gallery.c b/src/layout/gallery.c
index 2d90802..f383829 100644
--- a/src/layout/gallery.c
+++ b/src/layout/gallery.c
@@ -30,6 +30,7 @@
#include "grid/grid.h"
#include "util/listmgr.h"
#include "util/util.h"
+#include "util/locmgr.h"
#define LIST_MEDIA_COND "media_type=0 OR (media_type=1 AND copyright=\"Unknown\")"
@@ -42,6 +43,8 @@
#define BOX_PADDING (62 - GRID_PADDING)
+#define JOB_INTERVAL 1.0
+
struct _priv {
Evas_Object *base;
Evas_Object *layout;
@@ -59,6 +62,8 @@ struct _priv {
int view_mode;
struct grid_data *gdata;
+
+ struct locmgr *locmgr;
};
static void _recent_item_selected(struct _priv *priv, app_media *am)
@@ -175,12 +180,50 @@ static void _destroy_datamgr(struct _priv *priv)
static void _destroy_utils(struct _priv *priv)
{
+ locmgr_destroy(priv->locmgr);
_destroy_datamgr(priv);
listmgr_destroy(priv->listmgr);
free(priv->ldata);
}
+static Eina_Bool _create_location(void *data)
+{
+ struct _priv *priv;
+ struct locmgr *locmgr;
+ struct datamgr *dmgr;
+
+ if (!data) {
+ _ERR("invalid argument");
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ priv = data;
+
+ if (!priv->dmgr) {
+ _ERR("failed to get datamgr");
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ dmgr = priv->dmgr[E_DATA_MEDIA];
+ if (!dmgr) {
+ _ERR("failed to get datamgr");
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ locmgr = locmgr_create();
+ if (!locmgr) {
+ _ERR("failed to create locmgr");
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ priv->locmgr = locmgr;
+
+ locmgr_set_locations(locmgr, dmgr->ops->get_list(dmgr->handle));
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
static bool _create_utils(struct _priv *priv)
{
struct listmgr *listmgr;
@@ -280,6 +323,9 @@ static bool _create(layoutmgr *lmgr, void *data)
goto err3;
}
+ /* add job for set location tag */
+ ecore_timer_add(JOB_INTERVAL, _create_location, priv);
+
return true;
err3:
diff --git a/src/util/locmgr.c b/src/util/locmgr.c
new file mode 100644
index 0000000..0f6bead
--- /dev/null
+++ b/src/util/locmgr.c
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <Elementary.h>
+#include <media_content.h>
+#include <maps_service.h>
+#include <app_debug.h>
+#include <app_media.h>
+#include <vconf.h>
+
+#define MAP_LANG "en-US"
+#define MAP_MAX_RES 1
+#define MAP_MAX_REQ 100
+
+#define LOC_TAG_DEFAULT "Unknown"
+#define LOC_INVALID -200
+
+#define KEY_LOC_PLUGIN "db/app/mediahub/loc_plugin"
+#define KEY_LOC_ID "db/app/mediahub/loc_id"
+#define KEY_LOC_CODE "db/app/mediahub/loc_code"
+
+struct locmgr {
+ maps_service_h maps;
+ maps_preference_h preference;
+ bool supported;
+ int queue;
+ Eina_List *list;
+ char *plugin;
+ char *key;
+};
+
+struct _cb_data {
+ struct locmgr *m;
+ app_media *am;
+};
+
+static void _add_queue(struct locmgr *m);
+
+static void _set_location_tag(app_media *am, const char *str)
+{
+ media_info_h media;
+ int r;
+
+ if (!str)
+ return;
+
+ media = app_media_get_media_handle(am);
+ if (!media) {
+ _ERR("failed to getting media handle");
+ return;
+ }
+
+ r = media_info_set_location_tag(media, str);
+ if (r != MEDIA_CONTENT_ERROR_NONE) {
+ _ERR("failed to set location tag");
+ return;
+ }
+
+ r = media_info_update_to_db(media);
+ if (r != MEDIA_CONTENT_ERROR_NONE) {
+ _ERR("failed to update db");
+ return;
+ }
+
+ app_media_update(am);
+}
+
+static void _reverse_geocode_cb(maps_error_e result, int request_id,
+ int index, int total, maps_address_h address, void *data)
+{
+ struct _cb_data *cdata;
+ struct locmgr *m;
+ app_media *am;
+ char *country;
+ char *city;
+ char str[1024];
+ int r;
+
+ if (!data) {
+ _ERR("invalid parameter");
+ return;
+ }
+
+ cdata = data;
+
+ m = cdata->m;
+ m->queue--;
+
+ if (!m->queue)
+ _add_queue(m);
+
+ am = cdata->am;
+ if (!am) {
+ _ERR("failed to get app media");
+ goto out;
+ }
+
+ if (result != MAPS_ERROR_NONE) {
+ _ERR("failed to get reverse geocode (%d)", result);
+ goto out;
+ }
+
+ if (!address) {
+ _ERR("failed to get address");
+ goto out;
+ }
+
+ r = maps_address_get_country(address, &country);
+ if (r != MAPS_ERROR_NONE || !country) {
+ _ERR("failed to get country (%d)", r);
+ maps_address_destroy(address);
+ goto out;
+ }
+
+ r = maps_address_get_city(address, &city);
+ if (r != MAPS_ERROR_NONE || !city) {
+ _ERR("failed to get city (%d)", r);
+ maps_address_destroy(address);
+ free(country);
+ goto out;
+ }
+
+ snprintf(str, sizeof(str), "%s/%s", city, country);
+ _set_location_tag(am, str);
+
+ maps_address_destroy(address);
+
+ free(country);
+ free(city);
+
+out:
+ free(cdata);
+}
+
+static void _reverse_geocode_req(struct locmgr *m, app_media *am)
+{
+ app_media_info *mi;
+ struct _cb_data *cdata;
+ int r;
+ int id;
+
+ if (!m || !am) {
+ _ERR("invalid argument");
+ return;
+ }
+
+ mi = app_media_get_info(am);
+ if (!mi) {
+ _ERR("failed to get media info");
+ return;
+ }
+
+ if (mi->location_tag)
+ return;
+
+ if ((mi->latitude == LOC_INVALID && mi->longitude == LOC_INVALID) ||
+ (mi->latitude == 0 && mi->longitude == 0)) {
+ _set_location_tag(am, LOC_TAG_DEFAULT);
+ return;
+ }
+
+ cdata = calloc(1, sizeof(*cdata));
+ if (!cdata) {
+ _ERR("failed to allocate");
+ return;
+ }
+
+ cdata->m = m;
+ cdata->am = am;
+
+ r = maps_service_reverse_geocode(m->maps, mi->latitude, mi->longitude,
+ m->preference, _reverse_geocode_cb, cdata, &id);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to get geocode");
+ return;
+ }
+
+ m->queue++;
+}
+
+static void _add_queue(struct locmgr *m)
+{
+ app_media *am;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(m->list, l, am) {
+ if (m->queue >= MAP_MAX_REQ)
+ break;
+
+ _reverse_geocode_req(m, am);
+ m->list = eina_list_remove_list(m->list, l);
+ }
+}
+
+bool locmgr_set_location(struct locmgr *m, app_media *am)
+{
+ if (!m || !am) {
+ _ERR("invalid argument");
+ return false;
+ }
+
+ if (m->queue) {
+ /* service is busy, add to the list */
+ m->list = eina_list_append(m->list, am);
+ return true;
+ }
+
+ _reverse_geocode_req(m, am);
+
+ return true;
+}
+
+bool locmgr_set_locations(struct locmgr *m, Eina_List *list)
+{
+ Eina_List *l;
+
+ if (!m || !list) {
+ _ERR("invalid argument");
+ return false;
+ }
+
+ l = eina_list_clone(list);
+
+ if (m->queue) {
+ /* service is busy, add to the list */
+ m->list = eina_list_merge(m->list, l);
+ return true;
+ }
+
+ m->list = l;
+
+ _add_queue(m);
+
+ return true;
+}
+
+static bool _maps_provider_cb(char *provider, void *data)
+{
+ struct locmgr *m;
+
+ if (!data)
+ return false;
+
+ m = data;
+
+ if (!strcmp(provider, m->plugin))
+ m->supported = true;
+
+ return true;
+}
+
+static int _set_preference(maps_preference_h *preference)
+{
+ int r;
+
+ r = maps_preference_create(preference);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to create preference");
+ return r;
+ }
+
+ r = maps_preference_set_language(*preference, MAP_LANG);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to set language");
+ maps_preference_destroy(*preference);
+ return r;
+ }
+
+ r = maps_preference_set_max_results(*preference, MAP_MAX_RES);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to set max result");
+ maps_preference_destroy(*preference);
+ return r;
+ }
+
+ return MAPS_ERROR_NONE;
+}
+
+static bool _set_plugin(struct locmgr *m)
+{
+ char str[1024];
+ char *id;
+ char *code;
+
+ /*
+ * NOTE:
+ * map service need to set one of map providers
+ * and provider demand a security key for using it.
+ *
+ * mediahub was tested with "HERE" plugin.
+ * You can get app_id and app_code for "HERE" plugin at below website
+ * https://developer.here.com
+ *
+ * please set those 3 vconf values.
+ * plugin: db/app/mediahub/loc_plugin
+ * app_id: db/app/mediahub/loc_id
+ * app_code: db/app/mediahub/loc_code
+ */
+
+ m->plugin = vconf_get_str(KEY_LOC_PLUGIN);
+ if (!m->plugin) {
+ _ERR("Please set plugin to %s", KEY_LOC_PLUGIN);
+ return false;
+ }
+
+ id = vconf_get_str(KEY_LOC_ID);
+ if (!id) {
+ _ERR("Please set app_id to %s", KEY_LOC_ID);
+ goto err_id;
+ }
+
+ code = vconf_get_str(KEY_LOC_CODE);
+ if (!id) {
+ _ERR("Please set app_code to %s", KEY_LOC_CODE);
+ goto err_code;
+ }
+
+ snprintf(str, sizeof(str), "%s/%s", id, code);
+ m->key = strdup(str);
+
+ return true;
+
+err_code:
+ free(id);
+err_id:
+ free(m->plugin);
+ return false;
+}
+
+struct locmgr *locmgr_create(void)
+{
+ struct locmgr *m;
+ maps_service_h maps;
+ maps_preference_h preference;
+ int r;
+ bool s;
+
+ m = calloc(1, sizeof(*m));
+ if (!m) {
+ _ERR("failed to allocate");
+ return false;
+ }
+
+ s = _set_plugin(m);
+ if (!s) {
+ _ERR("can't get location information");
+ goto err;
+ }
+
+ r = maps_service_foreach_provider(_maps_provider_cb, m);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to create maps service");
+ goto err_plugin;
+ }
+
+ if (!m->supported) {
+ _ERR("%s does not support", m->plugin);
+ goto err_plugin;
+ }
+
+ r = maps_service_create(m->plugin, &maps);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to create maps service");
+ goto err_plugin;
+ }
+
+ r = maps_service_set_provider_key(maps, m->key);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to set provider key");
+ goto err_maps;
+ }
+
+ r = maps_service_provider_is_service_supported(maps,
+ MAPS_SERVICE_REVERSE_GEOCODE, &s);
+ if (r != MAPS_ERROR_NONE || !s) {
+ _ERR("not support reverse geocode");
+ goto err_maps;
+ }
+
+ r = _set_preference(&preference);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to create preference");
+ goto err_maps;
+ }
+
+ r = maps_service_set_preference(maps, preference);
+ if (r != MAPS_ERROR_NONE) {
+ _ERR("failed to set preference");
+ goto err_preference;
+ }
+
+ media_content_connect();
+
+ m->maps = maps;
+ m->preference = preference;
+ m->queue = 0;
+
+ return m;
+
+err_preference:
+ maps_preference_destroy(preference);
+err_maps:
+ maps_service_destroy(maps);
+err_plugin:
+ free(m->plugin);
+ free(m->key);
+err:
+ free(m);
+ return NULL;
+}
+
+void locmgr_destroy(struct locmgr *m)
+{
+ if (!m) {
+ _ERR("invalid argument");
+ return;
+ }
+
+ media_content_disconnect();
+
+ if (m->preference) {
+ maps_preference_destroy(m->preference);
+ m->preference = NULL;
+ }
+
+ if (m->maps) {
+ /*
+ * FIXME:
+ * because maps_service_destroy function have a problem,
+ * disable calling this function temporary
+ */
+ /*maps_service_destroy(m->maps);*/
+ m->maps = NULL;
+ }
+
+ if (m->list) {
+ eina_list_free(m->list);
+ m->list = NULL;
+ }
+
+ free(m->plugin);
+ free(m->key);
+ free(m);
+}