#include <signal.h> // for sigemptyset, sigset_t, sigaddset, ...
#include <unistd.h> // for write
#include <sys/wait.h>
+#include <pwd.h>
+#include <grp.h>
#include "daemon.h"
#include "utils.h"
return res;
}
+
+static int do_fchown(int fd, const char *user, const char *group)
+{
+ struct group *grp;
+ struct passwd *pwd;
+ uid_t uid;
+ gid_t gid;
+
+ pwd = getpwnam(user);
+ if (!pwd) {
+ LOGE("Failed to get uid, '%s'\n", user);
+ return -1;
+ }
+ uid = pwd->pw_uid;
+
+ grp = getgrnam(group);
+ if (!grp) {
+ LOGE("Failed to get gid, '%s'\n", group);
+ return -1;
+ }
+ gid = grp->gr_gid;
+
+ if (fchown(fd, uid, gid) == -1) {
+ LOGE("chown fail, user=%s group=%s\n", user, group);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int screenshot_save(char *path, const void *data, size_t len)
+{
+ int fd, ret = 0;
+
+ /* save to file */
+ fd = mkstemp(path);
+ if (fd == -1) {
+ LOGE("Cannot make temp file\n");
+ return -1;
+ }
+
+ ret = do_fchown(fd, "owner", "users");
+ if (ret) {
+ LOGE("chown fail\n");
+ goto close_fd;
+ }
+
+ ret = fchmod(fd, 0777);
+ if (ret) {
+ LOGE("cannot chmod -R777 <%s>", path);
+ goto close_fd;
+ }
+
+ write(fd, data, len);
+ LOGI("Save screenshot: '%s'\n", path);
+
+close_fd:
+ close(fd);
+ if (ret)
+ remove(path);
+ return ret;
+}
+
+static void send_screenshot_msg(const char *path, uint32_t angle,
+ const char *sh_info, size_t sh_info_len)
+{
+ void *p;
+ struct msg_data_t *msg;
+ size_t path_len = strnlen(path, PATH_MAX);
+ size_t payload_len = sh_info_len + path_len + 1 + 4;
+
+ msg = malloc(sizeof(*msg) + payload_len);
+ if (!msg) {
+ LOGE("Out of memory\n");
+ return;
+ }
+
+ p = msg;
+
+ /* pack sh_info */
+ memcpy(p, sh_info, sh_info_len);
+ p += sh_info_len;
+
+ /* pack path */
+ memcpy(p, path, path_len + 1);
+ p += path_len + 1;
+
+ /* pack angle */
+ pack_int32(p, angle);
+ p += 4;
+
+ msg->len = p - (void *)msg + 20;
+
+ if (write_to_buf(msg) != 0)
+ LOGE("write to buf fail\n");
+
+ free(msg);
+}
+
+static void processing_app_msg_image(const void *data, size_t len)
+{
+ char path[] = "/tmp/screenshot_XXXXXX";
+ uint32_t angle;
+ const char *sh_data;
+
+ size_t sh_len;
+
+ const char *sh_info;
+ size_t sh_info_len;
+
+ if (len < 4) {
+ LOGE("Message is very small\n");
+ return;
+ }
+
+ /* get sh_info_len */
+ sh_info_len = *(uint32_t *)data;
+ data += 4;
+
+ sh_info = data;
+ data += sh_info_len;
+
+ angle = *(uint32_t *)data;
+ data += 4;
+
+ sh_data = data;
+ sh_len = len - 4 - sh_info_len - 4;
+
+ if (!screenshot_save(path, sh_data, sh_len))
+ send_screenshot_msg(path, angle, sh_info, sh_info_len);
+ else
+ LOGE("Cannot save screenshot\n");
+}
+
static void* recvThread(void* data)
{
const size_t data_len = 16 * 1024 * 1024;
// don't send to host
LOGI("EXTRA '%s'\n", msg->data);
continue;
- } else if (log.type == APP_MSG_ERROR) {
+ } else if (msg->type == APP_MSG_ERROR) {
// don't send to host
LOGE("EXTRA '%s'\n", msg->data);
continue;
- } else if (log.type == APP_MSG_WARNING) {
+ } else if (msg->type == APP_MSG_WARNING) {
// don't send to host
LOGW("EXTRA '%s'\n", msg->data);
continue;
- } else if (log.type == APP_MSG_IMAGE) {
- /* need chsmak */
- void *p = msg->data;
- char *file_name = p;
-
- if (access(file_name, F_OK) != -1) {
- LOGI("APP_MSG_IMAGE> <%s>\n", file_name);
- } else {
- LOGE("APP_MSG_IMAGE> File not found <%s>\n",
- file_name);
- continue;
- }
-
- if (chsmack(file_name) == 0) {
- /* exctract probe message */
- p += strnlen(file_name, PATH_MAX) + 1;
- struct msg_data_t *msg_data = (struct msg_data_t *)(p);
-
- /* check packed size */
- if (msg->length != strnlen(file_name, PATH_MAX) + 1 +
- sizeof(*msg_data) + msg_data->len) {
- LOGE("Bad packed message\n");
- continue;
- }
-
- if (write_to_buf(msg_data) != 0)
- LOGE("write to buf fail\n");
- } else {
- LOGE("chsmack fail\n");
- }
-
-
+ } else if (msg->type == APP_MSG_IMAGE) {
+ processing_app_msg_image(msg->data, msg->length);
continue;
} else if (msg->type == APP_MSG_GET_UI_HIERARCHY) {
enum ErrorCode err_code = ERR_UNKNOWN;