Implement ID based contact share method 26/82126/1
authorDoHyun Pyun <dh79.pyun@samsung.com>
Mon, 1 Aug 2016 01:45:54 +0000 (10:45 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Mon, 1 Aug 2016 01:45:54 +0000 (10:45 +0900)
Change-Id: Ibea1bda8d4c8d49e1a15a971099a06c91ff540cc
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
CMakeLists.txt
data/ug-bluetooth-efl.xml
include/bt-type-define.h
include/bt-util.h
packaging/ug-bluetooth-efl.spec
src/libraries/bt-util.c
src/ui/bt-main-view.c

index b5de9e5..a09094d 100644 (file)
@@ -50,6 +50,7 @@ SET(PKG_MODULES
        glib-2.0
        gio-2.0
        dpm
+       contacts-service2
 )
 
 INCLUDE(FindPkgConfig)
index 96647f5..4a1f601 100644 (file)
         <privilege>http://tizen.org/privilege/network.get</privilege>
         <privilege>http://tizen.org/privilege/network.set</privilege>
        <privilege>http://tizen.org/privilege/systemsettings.admin</privilege>
+       <privilege>http://tizen.org/privilege/contact.read</privilege>
     </privileges>
 </manifest>
index 4670f8a..76d571e 100644 (file)
@@ -130,6 +130,8 @@ extern "C" {
 
 #define BT_APPCONTROL_VISIBILITY_MIME "application/x-bluetooth-visibility"
 
+#define BT_VCF_FOLDER_PATH "/tmp/"
+
 /* AppControl Output */
 #define BT_APPCONTROL_ADDRESS "http://tizen.org/appcontrol/data/bluetooth/address"
 #define BT_APPCONTROL_NAME "http://tizen.org/appcontrol/data/bluetooth/name"
index 5906eda..e2b0bd7 100644 (file)
@@ -103,6 +103,10 @@ gboolean _bt_util_is_space_str(const char *name_str);
 void _bt_util_max_len_reached_cb(void *data, Evas_Object *obj,
                                        void *event_info);
 
+char *_bt_util_vcard_create_from_id(int id, bool my_profile, const char *working_dir);
+
+char *_bt_util_vcard_create_from_id_list(const int *id_list, int count, const char *working_dir, volatile bool *cancel);
+
 int _bt_util_create_dpm_context(void *ug_data);
 
 void _bt_util_destroy_dpm_context(void *ug_data);
index 885304b..31d66b2 100644 (file)
@@ -38,6 +38,7 @@ BuildRequires: pkgconfig(capi-appfw-application)
 BuildRequires: pkgconfig(notification)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(contacts-service2)
 BuildRequires: pkgconfig(dpm)
 
 %description
index 538377f..04cf151 100644 (file)
@@ -26,6 +26,9 @@
 #include <aul.h>
 #include <notification.h>
 #include <dpm/restriction.h>
+#include <contacts.h>
+#include <dirent.h>
+#include <fcntl.h>
 
 #include "bt-main-ug.h"
 #include "bt-util.h"
@@ -772,3 +775,253 @@ gboolean _bt_util_is_dpm_restricted(void *handle)
        return (dpm_state == 0) ? TRUE : FALSE;
 }
 
+static bool __bt_util_file_exists(const char *file)
+{
+       bool res = false;
+       if (file) {
+               struct stat st;
+               res = stat(file, &st) == 0 || strcmp(file, "/") == 0;
+       }
+
+       return res;
+}
+
+static bool __bt_util_file_remove(const char *file)
+{
+       bool res = false;
+       if (file) {
+               res = remove(file) == 0;
+       }
+
+       return res;
+}
+
+static char *__bt_util_make_vcard_file_path(const char *working_dir, const char *display_name)
+{
+       char file_path[PATH_MAX] = { 0 };
+       int id = 0;
+
+       if (!working_dir) {
+               return NULL;
+       }
+
+       if (!display_name) {
+               display_name = "Unknown";
+       }
+
+       do {
+               snprintf(file_path, sizeof(file_path), "%s%s-%u.vcf", working_dir, display_name, id);
+               ++id;
+       } while (__bt_util_file_exists(file_path));
+
+       BT_DBG("file_path = %s", file_path);
+
+       return strdup(file_path);
+}
+
+static bool __bt_util_write_vcard_to_file(int fd, contacts_record_h record, bool my_profile)
+{
+       char *vcard_buff = NULL;
+       bool ok = false;
+
+       do {
+               int size_left = 0;
+
+               if (my_profile) {
+                       contacts_vcard_make_from_my_profile(record, &vcard_buff);
+               } else {
+                       contacts_vcard_make_from_person(record, &vcard_buff);
+               }
+
+               if (!vcard_buff) {
+                       BT_ERR("vcard_buff is NULL");
+                       break;
+               }
+
+               size_left = strlen(vcard_buff);
+               while (size_left) {
+                       int written = write(fd, vcard_buff, size_left);
+                       if (written == -1) {
+                               BT_ERR("write() failed: %d", errno);
+                               break;
+                       }
+                       size_left -= written;
+               }
+
+               ok = (size_left == 0);
+       } while (false);
+
+       free(vcard_buff);
+
+       return ok;
+}
+
+static bool __bt_util_write_vcard_to_file_from_id(int fd, int person_id)
+{
+       contacts_record_h record = NULL;
+       bool ok = false;
+
+       do {
+               int ret = contacts_db_get_record(_contacts_person._uri, person_id, &record);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       BT_ERR("contacts_db_get_record() failed: %d", ret);
+                       record = NULL;
+                       break;
+               }
+
+               if (!__bt_util_write_vcard_to_file(fd, record, false)) {
+                       BT_ERR("_write_vcard_to_file() failed");
+                       break;
+               }
+
+               ok = true;
+       } while (false);
+
+       if (record) {
+               contacts_record_destroy(record, true);
+       }
+
+       return ok;
+}
+
+char *_bt_util_vcard_create_from_id(int id, bool my_profile, const char *working_dir)
+{
+       FN_START;
+
+       contacts_record_h record = NULL;
+       char *vcard_path = NULL;
+       int fd = -1;
+       bool ok = false;
+       int ret;
+
+       BT_DBG("id = %i my_profile = %d", id, my_profile);
+
+       ret = contacts_connect();
+       if (ret != CONTACTS_ERROR_NONE)
+               BT_ERR("contacts_connect failed : ct_err = [%d]", ret);
+
+       do {
+               char *display_name = NULL;
+
+               int ret = contacts_db_get_record((my_profile ?
+                               _contacts_my_profile._uri :
+                               _contacts_person._uri), id, &record);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       BT_ERR("contacts_db_get_record() failed: %d", ret);
+                       record = NULL;
+                       break;
+               }
+
+               if (my_profile) {
+                       contacts_record_get_str_p(record, _contacts_my_profile.display_name, &display_name);
+               } else {
+                       contacts_record_get_str_p(record, _contacts_person.display_name, &display_name);
+               }
+
+               vcard_path = __bt_util_make_vcard_file_path(working_dir, "Contact");
+               if (!vcard_path) {
+                       BT_ERR("_make_vcard_file_path() failed");
+                       break;
+               }
+
+               fd = open(vcard_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+               if (fd == -1) {
+                       BT_ERR("open(%s) Failed(%d)", vcard_path, errno);
+                       break;
+               }
+
+               if (!__bt_util_write_vcard_to_file(fd, record, my_profile)) {
+                       BT_ERR("_write_vcard_to_file() failed");
+                       break;
+               }
+
+               ok = true;
+       } while (false);
+
+       ret = contacts_disconnect();
+       if (ret != CONTACTS_ERROR_NONE)
+               BT_ERR("contacts_disconnect failed : ct_err = [%d]", ret);
+
+       if (record) {
+               contacts_record_destroy(record, true);
+       }
+
+       if (fd != -1) {
+               close(fd);
+               if (!ok) {
+                       __bt_util_file_remove(vcard_path);
+               }
+       }
+
+       if (!ok) {
+               free(vcard_path);
+               vcard_path = NULL;
+       }
+
+       FN_END;
+
+       return vcard_path;
+}
+
+char *_bt_util_vcard_create_from_id_list(const int *id_list, int count, const char *working_dir, volatile bool *cancel)
+{
+       FN_START;
+
+       char *vcard_path = NULL;
+       int fd = -1;
+       bool ok = false;
+       int ret;
+
+       if (!id_list || count <= 0) {
+               return NULL;
+       }
+
+       ret = contacts_connect();
+       if (ret != CONTACTS_ERROR_NONE)
+               BT_ERR("contacts_connect failed : ct_err = [%d]", ret);
+
+       do {
+               int i = 0;
+
+               vcard_path = __bt_util_make_vcard_file_path(working_dir, "Contacts");
+               if (!vcard_path) {
+                       BT_ERR("_make_vcard_file_path() failed");
+                       break;
+               }
+
+               fd = open(vcard_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+               if (fd == -1) {
+                       BT_ERR("open(%s) Failed(%d)", vcard_path, errno);
+                       break;
+               }
+
+               for (i = 0; !(*cancel) && (i < count); ++i) {
+                       if (!__bt_util_write_vcard_to_file_from_id(fd, id_list[i])) {
+                               BT_ERR("_composer_write_vcard_to_file() failed");
+                               break;
+                       }
+               }
+
+               ok = (i == count);
+       } while (false);
+
+       ret = contacts_disconnect();
+       if (ret != CONTACTS_ERROR_NONE)
+               BT_ERR("contacts_disconnect failed : ct_err = [%d]", ret);
+
+       if (fd != -1) {
+               close(fd);
+               if (!ok) {
+                       __bt_util_file_remove(vcard_path);
+               }
+       }
+
+       if (!ok) {
+               free(vcard_path);
+               vcard_path = NULL;
+       }
+
+       FN_END;
+
+       return vcard_path;
+}
index 1531afd..8442c51 100644 (file)
@@ -50,6 +50,8 @@
 
 #define MULTI_SHARE_SERVICE_DATA_PATH "http://tizen.org/appcontrol/data/path"
 #define APP_CONTROL_OPERATION_SHARE_CONTACT "http://tizen.org/appcontrol/operation/share_contact"
+#define APP_CONTROL_MIME_CONTACT "application/vnd.tizen.contact"
+#define APP_CONTROL_MY_PROFILE_DATA_TYPE "my_profile"
 #define SERVICE_SHARE_CONTACT_MODE "http://tizen.org/appcontrol/data/social/namecard_share_mode"
 #define SERVICE_SHARE_CONTACT_ITEM "http://tizen.org/appcontrol/data/social/item_type"
 #define SHARE_CONTACT_DATA_PATH "/opt/usr/media/Downloads/.bluetooth"
@@ -4247,65 +4249,101 @@ void __bt_main_parse_service(bt_ug_data *ugd, app_control_h service)
        BT_INFO("operation: %s", operation);
 
        if (g_strcmp0(operation, APP_CONTROL_OPERATION_SHARE) == 0) {
+               char *mime = NULL;
+
                launch_type = strdup("send");
 
-               if (app_control_get_uri(service, (char **)&uri) < 0)
-                       BT_ERR("Get uri error");
+               app_control_get_mime(service, &mime);
 
-               if (uri) {
-                       uri_scheme = g_uri_parse_scheme(uri);
-                       DBG_SECURE("uri_scheme: %s", uri_scheme);
-
-                       if (uri_scheme == NULL) {
-                               /* File transfer */
-                               file_path = g_filename_from_uri(uri, NULL, NULL);
-                               if (app_control_add_extra_data(service, "type", "file") < 0)
-                                       BT_ERR("Fail to add extra data");
-                       } else if (g_strcmp0(uri_scheme, "file") == 0) {
-                               /* File transfer */
-                               file_path = g_filename_from_uri(uri, NULL, NULL);
-                               if (file_path == NULL) {
-                                       file_path = strdup(uri + 7);    /* file:// */
+               if (mime && strcmp(mime, APP_CONTROL_MIME_CONTACT) == 0) {
+                       char *id_str = NULL;
+                       app_control_get_extra_data(service, APP_CONTROL_DATA_ID, &id_str);
+
+                       if (id_str) {
+                               bool my_profile = false;
+                               char *data_type = NULL;
+                               int id = atoi(id_str);
+
+                               app_control_get_extra_data(service, APP_CONTROL_DATA_TYPE, &data_type);
+                               my_profile = data_type && strcmp(data_type, APP_CONTROL_MY_PROFILE_DATA_TYPE) == 0;
+                               file_path = _bt_util_vcard_create_from_id(id, my_profile,
+                                                                                                       BT_VCF_FOLDER_PATH);
+
+                               if (file_path) {
+                                       DBG_SECURE("file path: %s", file_path);
+
+                                       if (app_control_add_extra_data(service, "type", "file") < 0)
+                                               BT_ERR("Fail to add extra data");
+
+                                       if (app_control_add_extra_data_array
+                                               (service, "files", &file_path, 1) < 0)
+                                               BT_ERR("Fail to add extra data");
                                }
-                               if (app_control_add_extra_data(service, "type", "file") < 0)
-                                       BT_ERR("Fail to add extra data");
-                       } else {
-                               if (app_control_add_extra_data(service, "type", "text") < 0)
-                                       BT_ERR("Fail to add extra data");
-                       }
 
-                       if (file_path == NULL) {
-                               BT_ERR("Not include URI info");
-                               file_path = strdup(uri);
+                               free(data_type);
+                               free(id_str);
                        }
-
-                       g_free(uri_scheme);
                } else {
-                       char *value = NULL;
+                       if (app_control_get_uri(service, (char **)&uri) < 0)
+                               BT_ERR("Get uri error");
 
-                       BT_INFO("url is not set");
-                       if (app_control_get_extra_data(service,
-                                       MULTI_SHARE_SERVICE_DATA_PATH, &value) < 0)
-                                       BT_ERR("Fail to get extra data");
+                       if (uri) {
+                               uri_scheme = g_uri_parse_scheme(uri);
+                               DBG_SECURE("uri_scheme: %s", uri_scheme);
+
+                               if (uri_scheme == NULL) {
+                                       /* File transfer */
+                                       file_path = g_filename_from_uri(uri, NULL, NULL);
+                                       if (app_control_add_extra_data(service, "type", "file") < 0)
+                                               BT_ERR("Fail to add extra data");
+                               } else if (g_strcmp0(uri_scheme, "file") == 0) {
+                                       /* File transfer */
+                                       file_path = g_filename_from_uri(uri, NULL, NULL);
+                                       if (file_path == NULL) {
+                                               file_path = strdup(uri + 7);    /* file:// */
+                                       }
+                                       if (app_control_add_extra_data(service, "type", "file") < 0)
+                                               BT_ERR("Fail to add extra data");
+                               } else {
+                                       if (app_control_add_extra_data(service, "type", "text") < 0)
+                                               BT_ERR("Fail to add extra data");
+                               }
+
+                               if (file_path == NULL) {
+                                       BT_ERR("Not include URI info");
+                                       file_path = strdup(uri);
+                               }
 
-                       if (value) {
-                               file_path = g_strdup(value);
-                               free(value);
+                               g_free(uri_scheme);
+                       } else {
+                               char *value = NULL;
 
-                               DBG_SECURE("file_path: %s", file_path);
+                               BT_INFO("url is not set");
+                               if (app_control_get_extra_data(service,
+                                               MULTI_SHARE_SERVICE_DATA_PATH, &value) < 0)
+                                               BT_ERR("Fail to get extra data");
 
-                               if (app_control_add_extra_data(service, "type", "file") < 0)
-                                       BT_ERR("Fail to add extra data");
+                               if (value) {
+                                       file_path = g_strdup(value);
+                                       free(value);
 
-                       } else {
-                               BT_ERR("Not include path info");
-                               goto done;
+                                       DBG_SECURE("file_path: %s", file_path);
+
+                                       if (app_control_add_extra_data(service, "type", "file") < 0)
+                                               BT_ERR("Fail to add extra data");
+
+                               } else {
+                                       BT_ERR("Not include path info");
+                                       goto done;
+                               }
                        }
+
+                       if (app_control_add_extra_data_array
+                           (service, "files", &file_path, 1) < 0)
+                               BT_ERR("Fail to add extra data");
                }
 
-               if (app_control_add_extra_data_array
-                   (service, "files", &file_path, 1) < 0)
-                       BT_ERR("Fail to add extra data");
+               g_free(mime);
        } else if (g_strcmp0(operation, APP_CONTROL_OPERATION_SHARE_TEXT) == 0) {
                BT_DBG("APP_CONTROL_OPERATION_SHARE_TEXT");
 
@@ -4345,17 +4383,69 @@ void __bt_main_parse_service(bt_ug_data *ugd, app_control_h service)
                        BT_ERR("Fail to add extra data");
 
        } else if (g_strcmp0(operation, APP_CONTROL_OPERATION_MULTI_SHARE) == 0) {
-               launch_type = strdup("send");
-
                char **array_value = NULL;
                int array_length;
                int ret, i;
+               char *mime = NULL;
+
+               launch_type = strdup("send");
+
+               int *id_list = NULL;
+               char **person_id = NULL;
+               int person_id_size = 0;
+               bool cancel = false;
+
+               app_control_get_mime(service, &mime);
+
+               if (mime && !strcmp(mime, APP_CONTROL_MIME_CONTACT)) {
+                       if (app_control_get_extra_data_array(service, APP_CONTROL_DATA_ID,
+                                       &person_id, &person_id_size) == APP_CONTROL_ERROR_NONE && person_id) {
+                               int i = 0;
+                               id_list = calloc(person_id_size, sizeof(int));
+                               if (id_list) {
+                                       for (i = 0; i < person_id_size; i++) {
+                                               id_list[i] = atoi(person_id[i]);
+                                       }
+                                       file_path = _bt_util_vcard_create_from_id_list(id_list,
+                                                               person_id_size, BT_VCF_FOLDER_PATH, &cancel);
+                                       if (file_path) {
+                                               DBG_SECURE("file path: %s", file_path);
+
+                                               if (app_control_add_extra_data(service, "type", "file") < 0)
+                                                       BT_ERR("Fail to add extra data");
+
+                                               if (app_control_add_extra_data_array
+                                                       (service, "files", &file_path, 1) < 0)
+                                                       BT_ERR("Fail to add extra data");
+                                       }
+                               free(id_list);
+                               }
+                       }
+                       g_free(person_id);
+               } else {
+                       ret = app_control_get_extra_data_array(service,
+                                                          MULTI_SHARE_SERVICE_DATA_PATH,
+                                                          &array_value, &array_length);
+                       if (ret != APP_CONTROL_ERROR_NONE) {
+                               BT_ERR("Get data error");
+                               if (array_value) {
+                                       for (i = 0; i < array_length; i++) {
+                                               if (array_value[i]) {
+                                                       free(array_value[i]);
+                                               }
+                                       }
+                                       free(array_value);
+                               }
+                               goto done;
+                       }
+
+                       if (app_control_add_extra_data_array
+                           (service, "files", (const char **)array_value,
+                            array_length) < 0)
+                               BT_ERR("Fail to add extra data");
 
-               ret = app_control_get_extra_data_array(service,
-                                                  MULTI_SHARE_SERVICE_DATA_PATH,
-                                                  &array_value, &array_length);
-               if (ret != APP_CONTROL_ERROR_NONE) {
-                       BT_ERR("Get data error");
+                       if (app_control_add_extra_data(service, "type", "file") < 0)
+                               BT_ERR("Fail to add extra data");
                        if (array_value) {
                                for (i = 0; i < array_length; i++) {
                                        if (array_value[i]) {
@@ -4364,24 +4454,9 @@ void __bt_main_parse_service(bt_ug_data *ugd, app_control_h service)
                                }
                                free(array_value);
                        }
-                       goto done;
                }
 
-               if (app_control_add_extra_data_array
-                   (service, "files", (const char **)array_value,
-                    array_length) < 0)
-                       BT_ERR("Fail to add extra data");
-
-               if (app_control_add_extra_data(service, "type", "file") < 0)
-                       BT_ERR("Fail to add extra data");
-               if (array_value) {
-                       for (i = 0; i < array_length; i++) {
-                               if (array_value[i]) {
-                                       free(array_value[i]);
-                               }
-                       }
-                       free(array_value);
-               }
+               g_free(mime);
        } else if (g_strcmp0(operation, BT_APPCONTROL_PICK_OPERATION) == 0) {
                BT_DBG("Pick Operation");
                launch_type = strdup("pick");