Move screenshot storing to manager 35/126235/1 tizen_3.0_tv accepted/tizen/3.0/common/20170508.152941 accepted/tizen/3.0/ivi/20170508.050304 accepted/tizen/3.0/mobile/20170508.050232 accepted/tizen/3.0/tv/20170508.050243 accepted/tizen/3.0/wearable/20170508.050255 submit/tizen_3.0-common/20170508.080135 submit/tizen_3.0-common/20170508.081301 submit/tizen_3.0-common/20170508.091535 submit/tizen_3.0/20170421.095711 submit/tizen_3.0_common/20170508.091735 submit/tizen_3.0_tv/20170427.113216
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 20 Apr 2017 13:52:46 +0000 (16:52 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 20 Apr 2017 13:52:46 +0000 (16:52 +0300)
Change-Id: Id31ba8135075c4f265819f4ecb2f3525686f78b1
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
helper/libdaprobe.c
include/daprobe.h
probe_screenshot/dacapture_wayland.c

index 9dec44d..5b56caa 100755 (executable)
@@ -630,6 +630,64 @@ const char *msg_code_to_srt(enum AppMessageType type)
        }
 }
 
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+static bool do_send(int fd, void *data, size_t len, int flags)
+{
+       const size_t CHUNK_SIZE = 1024;
+
+       while (len) {
+               size_t sz = MIN(len, CHUNK_SIZE);
+               ssize_t ret = send(fd, data, sz, flags);
+
+               if (ret == -1) {
+                       PRINTERR("Cannot send data, len=%zu, err=%d",
+                                sz, errno);
+                       break;
+               } else if ((size_t)ret == sz) {
+                       len -= sz;
+                       data += sz;
+                       continue;
+               } else {
+                       PRINTERR("Cannot send data, len=%zu, send_len=%zu",
+                                sz, ret);
+                       break;
+               }
+       }
+
+       return !len;
+}
+
+static void do_msg_send(int fd, enum AppMessageType type,
+                       void *data, size_t len)
+{
+       struct msg_header {
+               int type;
+               int length;
+       };
+
+       struct msg_header header = {
+               .type = type,
+               .length = len,
+       };
+
+       do_send(fd, &header, sizeof(header), MSG_NOSIGNAL);
+       do_send(fd, data, len, MSG_NOSIGNAL);
+}
+
+void msg_send(enum AppMessageType type, void *data, size_t len)
+{
+       int fd = gTraceInfo.socket.daemonSock;
+       pthread_mutex_t *mutex = &gTraceInfo.socket.sockMutex;
+
+       if (fd == -1)
+               return;
+
+       real_pthread_mutex_lock(mutex);
+       do_msg_send(fd, type, data, len);
+       real_pthread_mutex_unlock(mutex);
+}
+
+
 bool printLog(log_t *log, int msgType)
 {
        ssize_t res, len;
index 921062f..4cd0c28 100644 (file)
@@ -97,6 +97,7 @@ int update_heap_memory_size(bool isAdd, size_t size);
 bool print_log_fmt(int msgType, const char *func_name, int line, ...);
 bool print_log_str(int msgType, char *st);
 bool printLog(log_t* log, int msgType);
+void msg_send(enum AppMessageType type, void *data, size_t len);
 
 void *rtdl_next(const char *symname);
 void *rtld_default(const char *symname);
index b379ef5..d219905 100755 (executable)
@@ -44,6 +44,7 @@
 #include <pthread.h>           // for mutex
 #include <sys/param.h>         // MIN, MAX
 #include <sys/mman.h>          // mmap
+#include <errno.h>
 
 #include <Ecore.h>
 #include <Evas.h>
@@ -622,6 +623,158 @@ void current_angle_set(int angle)
        __current_angle = angle;
 }
 
+
+struct file_data {
+       size_t len;
+       void *data;
+};
+
+static size_t fsize(int fd)
+{
+       struct stat st;
+       if (fstat(fd, &st) != 0)
+                return 0;
+       return st.st_size;
+}
+
+static int do_read_file(int fd, void *data, size_t len)
+{
+       while (len) {
+               ssize_t n = read(fd, data, len);
+               if (n == -1) {
+                       if (errno == EINTR)
+                               continue;
+
+                       return -errno;
+               } else if (n == 0) {
+                       return -EPERM;
+               }
+
+               len -= n;
+               data += n;
+       }
+
+       return 0;
+}
+
+static struct file_data *file_data_create(const char *path)
+{
+       int fd, ret;
+       struct file_data *fdata;
+       const size_t MAX_FILE_SIZE = 32 * 1024 * 1024;
+
+       fdata = malloc(sizeof(*fdata));
+       if (!fdata) {
+               PRINTERR("Out of memory");
+               return NULL;
+       }
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1) {
+               PRINTERR("Cannot open '%s', errno=%d", path, fd);
+               goto free_fdata;
+       }
+
+       fdata->len = fsize(fd);
+       if (!fdata->len) {
+               PRINTERR("Cannot calculate file size, path='%s'", path);
+               goto close_fd;
+       }
+
+       if (fdata->len > MAX_FILE_SIZE) {
+               PRINTERR("file size is very long, len=%zu", fdata->len);
+               goto close_fd;
+       }
+
+       fdata->data = malloc(fdata->len);
+       if (!fdata->data) {
+               PRINTERR("Out of memory");
+               goto close_fd;
+       }
+
+       ret = do_read_file(fd, fdata->data, fdata->len);
+       if (ret) {
+               PRINTERR("Cannot read file, ret=%d", ret);
+               goto free_data;
+       }
+
+       close(fd);
+       return fdata;
+
+free_data:
+       free(fdata->data);
+close_fd:
+       close(fd);
+free_fdata:
+       free(fdata);
+       return NULL;
+}
+
+static void file_data_free(struct file_data *data)
+{
+       free(data->data);
+       free(data);
+}
+
+
+static size_t screenshot_pack_info(char *buf)
+{
+       /* pack probe */
+       PREPARE_LOCAL_BUF_THOUGH(buf);
+       PACK_COMMON_BEGIN(MSG_PROBE_SCREENSHOT, API_ID_captureScreen, "", 0);
+       /* Pack any address, cause this is not an event probe */
+       PACK_COMMON_END_THOUGH('d', 0, 0, 0, 0xffffffff);
+
+       return BUF_PTR - LOCAL_BUF;
+}
+
+static int screenshot_send_to_socket(const char *path)
+{
+       struct file_data *fdata;
+       char sh_info[256];
+       void *buf, *p;
+       size_t sh_info_len, buf_size;
+
+       fdata = file_data_create(path);
+       if (!fdata)
+               return -1;
+
+       /* pack common colums */
+       sh_info_len = screenshot_pack_info(sh_info);
+
+       /* format:
+        *
+        * |  sh_info  |                 |
+        * +----+------+-------+---------+
+        * |len | data | angle | img.png |
+        * |  4 |  ... |   4   |   ...   |
+        *
+        */
+       buf_size = 4 + sh_info_len + 4 + fdata->len;
+       buf = malloc(buf_size);
+       if (!buf) {
+               PRINTERR("Out of memory");
+               file_data_free(fdata);
+               return -1;
+       }
+
+       /* pack sh_info */
+       p = pack_int32(buf, sh_info_len);
+       p = pack_bin(p, sh_info, sh_info_len);
+
+       /* pack angle */
+       p = pack_int32(p, current_angle_get());
+
+       /* pack img.png */
+       p = pack_bin(p, fdata->data, fdata->len);
+
+       /* send screenshot to manager */
+       msg_send(APP_MSG_IMAGE, buf, buf_size);
+       file_data_free(fdata);
+
+       return 0;
+}
+
 int captureScreen()
 {
        static pthread_mutex_t captureScreenLock = PTHREAD_MUTEX_INITIALIZER;
@@ -637,35 +790,15 @@ int captureScreen()
                 getCurrentEventIndex());
 
        ret = __capture_screnshot_wayland(dstpath);
-       if (ret == -EAGAIN)
-               ret = __capture_screnshot_wayland(dstpath);
-       if (!ret) {
-               if (chmod(dstpath, 0777) == -1)
-                       PRINTWRN("cannot chmod -R777 <%s>", dstpath);
-
-               /* welcome to the hell */
-               log_t log;
-               PREPARE_LOCAL_BUF_THOUGH((char *)&log);
-
-               /* skip header */
-               LOCAL_BUF += offsetof(log_t, data);
-               /* pack screenshot name */
-               BUF_PTR = pack_string(LOCAL_BUF, dstpath); /* file name */
-               LOCAL_BUF = BUF_PTR;
-
-               /* pack probe */
-               PACK_COMMON_BEGIN(MSG_PROBE_SCREENSHOT, API_ID_captureScreen, "", 0);
-               /* Pack any address, cause this is not an event probe */
-               PACK_COMMON_END_THOUGH('d', 0, 0, 0, 0xffffffff);
-               PACK_SCREENSHOT(dstpath, current_angle_get());
-               SET_MSG_LEN();
-               log.length = GET_MSG_LEN() + MSG_HDR_LEN + strlen(dstpath) + 1;
-
-               /* send all message */
-               printLog(&log, APP_MSG_IMAGE);
-               ret = 0;
+       if (ret) {
+               PRINTERR("Cannot capture screenshot, ret=%d", ret);
+               goto unlock;
        }
 
+       ret = screenshot_send_to_socket(dstpath);
+       remove(dstpath);
+
+unlock:
        pthread_mutex_unlock(&captureScreenLock);
        return ret;
 }