Add screen-type info for trigger_focused
[platform/core/appfw/aul-1.git] / src / aul_screen_connector.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <stdbool.h>
20 #include <stdlib.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23 #include <glib.h>
24 #include <bundle.h>
25 #include <bundle_internal.h>
26
27 #include "aul_util.h"
28 #include "aul_api.h"
29 #include "aul.h"
30 #include "aul_sock.h"
31 #include "aul_app_com.h"
32 #include "aul_screen_connector.h"
33
34 struct aul_screen_viewer_s {
35         aul_app_com_connection_h conn;
36         aul_screen_viewer_cb callback;
37         aul_screen_type_e type;
38         bool priv;
39         unsigned int ref;
40         void *user_data;
41 };
42
43 static unsigned int ref;
44
45 static unsigned int __get_ref(void)
46 {
47         return ++ref;
48 }
49
50 static int __add_screen_viewer(int type, bool priv, unsigned int ref)
51 {
52         int ret;
53         bundle *b;
54         char buf[MAX_PID_STR_BUFSZ];
55
56         b = bundle_create();
57         if (b == NULL) {
58                 _E("out of memory");
59                 return -1;
60         }
61
62         snprintf(buf, sizeof(buf), "%d", type);
63         ret = bundle_add(b, AUL_K_SCREEN_TYPE, buf);
64         if (ret != BUNDLE_ERROR_NONE) {
65                 _E("Failed to add screen type(%d)", type);
66                 bundle_free(b);
67                 return -1;
68         }
69
70         snprintf(buf, sizeof(buf), "%u", ref);
71         ret = bundle_add(b, AUL_K_VIEWER_REF, buf);
72         if (ret != BUNDLE_ERROR_NONE) {
73                 _E("Failed to add viewer reference(%u)", ref);
74                 bundle_free(b);
75                 return -1;
76         }
77
78         if (priv) {
79                 ret = bundle_add(b, AUL_K_PRIVATE, "true");
80                 if (ret != BUNDLE_ERROR_NONE) {
81                         _E("Failed to add bundle data");
82                         bundle_free(b);
83                         return -1;
84                 }
85         }
86
87         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
88                         ADD_SCREEN_VIEWER, b, AUL_SOCK_NOREPLY);
89         bundle_free(b);
90         if (ret < 0)
91                 return -1;
92
93         return 0;
94 }
95
96 static int __remove_screen_viewer(int type, bool priv, unsigned int ref)
97 {
98         int ret;
99         bundle *b;
100         char buf[MAX_PID_STR_BUFSZ];
101
102         b = bundle_create();
103         if (b == NULL) {
104                 _E("out of memory");
105                 return -1;
106         }
107
108         snprintf(buf, sizeof(buf), "%d", type);
109         ret = bundle_add(b, AUL_K_SCREEN_TYPE, buf);
110         if (ret != BUNDLE_ERROR_NONE) {
111                 _E("Failed to add view mode");
112                 bundle_free(b);
113                 return -1;
114         }
115
116         snprintf(buf, sizeof(buf), "%u", ref);
117         ret = bundle_add(b, AUL_K_VIEWER_REF, buf);
118         if (ret != BUNDLE_ERROR_NONE) {
119                 _E("Failed to add viewer reference(%u)", ref);
120                 bundle_free(b);
121                 return -1;
122         }
123
124         if (priv) {
125                 ret = bundle_add(b, AUL_K_PRIVATE, "true");
126                 if (ret != BUNDLE_ERROR_NONE) {
127                         _E("Failed to add bundle data");
128                         bundle_free(b);
129                         return -1;
130                 }
131         }
132
133         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
134                         REMOVE_SCREEN_VIEWER, b, AUL_SOCK_NOREPLY);
135         bundle_free(b);
136         if (ret < 0)
137                 return -1;
138
139         return 0;
140 }
141
142 static int __app_screen_event_cb(const char *endpoint, aul_app_com_result_e res,
143                 bundle *envelope, void *user_data)
144 {
145         aul_screen_viewer_h handle = (aul_screen_viewer_h)user_data;
146         char *appid = NULL;
147         char *instance_id = NULL;
148         unsigned int *surf = NULL;
149         int *pid = NULL;
150         size_t size;
151         char *event = NULL;
152         aul_screen_connector_event_type_e event_type;
153
154         bundle_get_str(envelope, "__AUL_SC_EVENT__", &event);
155         if (event == NULL) {
156                 _E("Failed to get screen connector event");
157                 return -1;
158         } else if (strcmp(event, "add_screen") == 0) {
159                 event_type = AUL_SCREEN_CONNECTOR_EVENT_TYPE_ADD;
160         } else if (strcmp(event, "remove_screen") == 0) {
161                 event_type = AUL_SCREEN_CONNECTOR_EVENT_TYPE_REMOVE;
162         } else if (strcmp(event, "update_screen") == 0) {
163                 event_type = AUL_SCREEN_CONNECTOR_EVENT_TYPE_UPDATE;
164         } else if (strcmp(event, "focus_screen") == 0) {
165                 event_type = AUL_SCREEN_CONNECTOR_EVENT_TYPE_FOCUS;
166         } else {
167                 _E("Unknown event type(%s)", event);
168                 return -1;
169         }
170
171         bundle_get_str(envelope, "__AUL_SC_APPID__", &appid);
172         if (appid == NULL) {
173                 _E("Failed to get appid");
174                 return -1;
175         }
176
177         bundle_get_byte(envelope, "__AUL_SC_SURFACE__",
178                         (void **)&surf, &size);
179         if (surf == NULL) {
180                 _E("Failed to get surface");
181                 return -1;
182         }
183
184         bundle_get_byte(envelope, "__AUL_SC_PID__", (void **)&pid, &size);
185         if (pid == NULL) {
186                 _E("Failed to get pid");
187                 return -1;
188         }
189         bundle_get_str(envelope, "__AUL_SC_INSTANCE_ID__", &instance_id);
190
191         if (handle->callback) {
192                 handle->callback(appid, instance_id, *pid, *surf,
193                                 event_type, handle->user_data);
194         }
195         _D("appid(%s), instance_id(%s), pid(%d), surface(%d), event_type(%d)",
196                         appid, instance_id, *pid, *surf, event_type);
197
198         return 0;
199 }
200
201 static int __screen_viewer_fini(aul_screen_viewer_h screen_viewer)
202 {
203         int ret;
204
205         if (screen_viewer->conn) {
206                 aul_app_com_leave(screen_viewer->conn);
207                 screen_viewer->conn = NULL;
208         }
209
210         ret = __remove_screen_viewer(screen_viewer->type, screen_viewer->priv,
211                         screen_viewer->ref);
212         if (ret < 0) {
213                 _E("Failed to remove screen watcher");
214                 return -1;
215         }
216
217         return 0;
218 }
219
220 static int __screen_viewer_init(aul_screen_viewer_h screen_viewer)
221 {
222         int ret;
223         char endpoint[128];
224         pid_t pid = getpid();
225
226         snprintf(endpoint, sizeof(endpoint), "app_screen_event:%u:%d",
227                         screen_viewer->ref, pid);
228         aul_app_com_create(endpoint, NULL, __app_screen_event_cb,
229                         screen_viewer, &screen_viewer->conn);
230         if (screen_viewer->conn == NULL) {
231                 _E("Failed to create app com");
232                 return -1;
233         }
234
235         ret = __add_screen_viewer(screen_viewer->type, screen_viewer->priv,
236                         screen_viewer->ref);
237         if (ret < 0) {
238                 _E("Failed to add screen watcher");
239                 return -1;
240         }
241
242         return 0;
243 }
244
245 API int aul_screen_connector_add_screen_viewer(aul_screen_viewer_cb callback,
246                 aul_screen_type_e type, bool priv,
247                 void *data, aul_screen_viewer_h *handle)
248 {
249         struct aul_screen_viewer_s *screen_viewer;
250
251         if (handle == NULL || callback == NULL ||
252                         !(type & AUL_SCREEN_TYPE_ALL)) {
253                 _E("Invalid parameter");
254                 return AUL_R_EINVAL;
255         }
256
257         screen_viewer = (struct aul_screen_viewer_s *)calloc(1,
258                         sizeof(struct aul_screen_viewer_s));
259         if (screen_viewer == NULL) {
260                 _E("Out of memory");
261                 return AUL_R_EINVAL;
262         }
263
264         screen_viewer->callback = callback;
265         screen_viewer->type = type;
266         screen_viewer->priv = priv;
267         screen_viewer->ref = __get_ref();
268         screen_viewer->user_data = data;
269
270         if (__screen_viewer_init(screen_viewer) < 0) {
271                 __screen_viewer_fini(screen_viewer);
272                 free(screen_viewer);
273                 return AUL_R_ERROR;
274         }
275         *handle = screen_viewer;
276
277         return AUL_R_OK;
278 }
279
280 API int aul_screen_connector_remove_screen_viewer(aul_screen_viewer_h handle)
281 {
282         if (handle == NULL)
283                 return AUL_R_EINVAL;
284
285         __screen_viewer_fini(handle);
286         free(handle);
287
288         return AUL_R_OK;
289 }
290
291 API int aul_screen_connector_add_app_screen(const char *instance_id,
292                 unsigned int surf)
293 {
294         int ret;
295         bundle *b;
296         char buf[MAX_PID_STR_BUFSZ];
297
298         b = bundle_create();
299         if (b == NULL) {
300                 _E("out of memory");
301                 return AUL_R_ERROR;
302         }
303
304         snprintf(buf, sizeof(buf), "%d", surf);
305         ret = bundle_add(b, AUL_K_WID, buf);
306         if (ret != BUNDLE_ERROR_NONE) {
307                 _E("Failed to add surf");
308                 bundle_free(b);
309                 return AUL_R_ERROR;
310         }
311
312         if (instance_id) {
313                 ret = bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
314                 if (ret != BUNDLE_ERROR_NONE) {
315                         _E("Failed to add instance id");
316                         bundle_free(b);
317                         return AUL_R_ERROR;
318                 }
319         }
320
321         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
322                         ADD_APP_SCREEN, b, AUL_SOCK_NOREPLY);
323         bundle_free(b);
324         if (ret < 0) {
325                 _E("Failed to add app screen");
326                 return ret;
327         }
328
329         return AUL_R_OK;
330 }
331
332 API int aul_screen_connector_remove_app_screen(const char *instance_id)
333 {
334         int ret;
335         bundle *b;
336
337         b = bundle_create();
338         if (b == NULL) {
339                 _E("out of memory");
340                 return AUL_R_ERROR;
341         }
342
343         if (instance_id) {
344                 ret = bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
345                 if (ret != BUNDLE_ERROR_NONE) {
346                         _E("Failed to add instance id");
347                         bundle_free(b);
348                         return AUL_R_ERROR;
349                 }
350         }
351
352         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
353                         REMOVE_APP_SCREEN, b, AUL_SOCK_NOREPLY);
354         bundle_free(b);
355         if (ret < 0) {
356                 _E("Failed to remove app screen");
357                 return ret;
358         }
359
360         return AUL_R_OK;
361 }
362
363 API int aul_screen_connector_send_update_request(const char *appid,
364                 const char *instance_id)
365 {
366         int ret;
367         bundle *b;
368
369         if (appid == NULL) {
370                 _E("Invalid parameter");
371                 return -1;
372         }
373
374         b = bundle_create();
375         if (b == NULL) {
376                 _E("out of memory");
377                 return AUL_R_ERROR;
378         }
379
380         ret = bundle_add(b, AUL_K_APPID, appid);
381         if (ret != BUNDLE_ERROR_NONE) {
382                 _E("Failed to add appid");
383                 bundle_free(b);
384                 return AUL_R_ERROR;
385         }
386
387         if (instance_id) {
388                 ret = bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
389                 if (ret != BUNDLE_ERROR_NONE) {
390                         _E("Failed to add instance id");
391                         bundle_free(b);
392                         return AUL_R_ERROR;
393                 }
394         }
395
396         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
397                         APP_UPDATE_REQUESTED, b, AUL_SOCK_NOREPLY);
398         bundle_free(b);
399         if (ret < 0) {
400                 _E("Failed to update app screen");
401                 return ret;
402         }
403
404         return AUL_R_OK;
405 }
406
407 static bundle *__send_request_with_surface_id(int cmd, unsigned int surface_id)
408 {
409         app_pkt_t *pkt = NULL;
410         bundle *b;
411         int fd;
412         int r;
413
414         b = bundle_create();
415         if (b == NULL) {
416                 _E("Out of memory");
417                 return NULL;
418         }
419
420         r = bundle_add_byte(b, "__AUL_SC_SURFACE__",
421                         &surface_id, sizeof(unsigned int));
422         if (r != BUNDLE_ERROR_NONE) {
423                 _E("Failed to add surface id(%u)", surface_id);
424                 bundle_free(b);
425                 return NULL;
426         }
427
428         fd = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), cmd, b,
429                         AUL_SOCK_ASYNC);
430         bundle_free(b);
431         if (fd < 0) {
432                 _E("Failed to send request(%d)", cmd);
433                 return NULL;
434         }
435
436         aul_sock_recv_reply_pkt(fd, &pkt);
437         if (pkt == NULL) {
438                 _E("Failed to receive the packet");
439                 return NULL;
440         }
441
442         b = bundle_decode(pkt->data, pkt->len);
443         free(pkt);
444         if (b == NULL) {
445                 _E("Failed to decode bundle data");
446                 return NULL;
447         }
448
449         return b;
450 }
451
452 API int aul_screen_connector_get_appid_by_surface_id(unsigned int surface_id,
453                 char **appid)
454 {
455         const char *val;
456         bundle *b;
457
458         if (appid == NULL) {
459                 _E("Invalid parameter");
460                 return AUL_R_ERROR;
461         }
462
463         b = __send_request_with_surface_id(APP_GET_APPID_BY_SURFACE_ID,
464                         surface_id);
465         if (b == NULL)
466                 return AUL_R_ERROR;
467
468         val = bundle_get_val(b, AUL_K_APPID);
469         if (val == NULL) {
470                 _E("Failed to get appid");
471                 bundle_free(b);
472                 return AUL_R_ERROR;
473         }
474
475         *appid = strdup(val);
476         if (*appid == NULL) {
477                 _E("Out of memory");
478                 bundle_free(b);
479                 return AUL_R_ERROR;
480         }
481         bundle_free(b);
482
483         return AUL_R_OK;
484 }
485
486 API int aul_screen_connector_get_instance_id_by_surface_id(
487                 unsigned int surface_id, char **instance_id)
488 {
489         const char *val;
490         bundle *b;
491
492         if (instance_id == NULL) {
493                 _E("Invalid parameter");
494                 return AUL_R_ERROR;
495         }
496
497         b = __send_request_with_surface_id(APP_GET_INSTANCE_ID_BY_SURFACE_ID,
498                         surface_id);
499         if (b == NULL)
500                 return AUL_R_ERROR;
501
502         val = bundle_get_val(b, AUL_K_INSTANCE_ID);
503         if (val == NULL) {
504                 _E("Failed to get instance id");
505                 bundle_free(b);
506                 return AUL_R_ERROR;
507         }
508
509         *instance_id = strdup(val);
510         if (*instance_id == NULL) {
511                 _E("Out of memory");
512                 bundle_free(b);
513                 return AUL_R_ERROR;
514         }
515         bundle_free(b);
516
517         return AUL_R_OK;
518 }
519
520
521 API int aul_screen_connector_update_screen_viewer_status(
522                 aul_screen_status_e status, unsigned int provider_surf)
523 {
524         char buf[32];
525         bundle *b;
526         int ret;
527
528         if (status < AUL_SCREEN_STATUS_RESUME ||
529                         status > AUL_SCREEN_STATUS_PAUSE) {
530                 _E("Invalid parameter");
531                 return AUL_R_ERROR;
532         }
533
534         b = bundle_create();
535         if (b == NULL) {
536                 _E("Out of memory");
537                 return AUL_R_ERROR;
538         }
539
540         snprintf(buf, sizeof(buf), "%u", provider_surf);
541         ret = bundle_add(b, AUL_K_WID, buf);
542         if (ret != BUNDLE_ERROR_NONE) {
543                 _E("Failed to add provider surface id");
544                 bundle_free(b);
545                 return AUL_R_ERROR;
546         }
547
548         snprintf(buf, sizeof(buf), "%d", status);
549         ret = bundle_add(b, "__AUL_SC_VIEWER_STATUS__", buf);
550         if (ret != BUNDLE_ERROR_NONE) {
551                 _E("Failed to add screen status");
552                 bundle_free(b);
553                 return AUL_R_ERROR;
554         }
555
556         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
557                         UPDATE_SCREEN_VIEWER_STATUS, b, AUL_SOCK_NOREPLY);
558         bundle_free(b);
559
560         return ret;
561 }
562
563 API int aul_screen_connector_trigger_focused_force()
564 {
565         int ret;
566         char buf[MAX_PID_STR_BUFSZ];
567         bundle *b;
568
569         b = bundle_create();
570         if (b == NULL) {
571                 _E("out of memory");
572                 return -1;
573         }
574
575         snprintf(buf, sizeof(buf), "%d", AUL_SCREEN_TYPE_UI);
576         ret = bundle_add(b, AUL_K_SCREEN_TYPE, buf);
577         if (ret != BUNDLE_ERROR_NONE) {
578                 _E("Failed to add view mode");
579                 bundle_free(b);
580                 return -1;
581         }
582
583         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
584                 TRIGGER_APP_SCREEN_FOCUSED_FORCE, b, AUL_SOCK_NOREPLY);
585         bundle_free(b);
586
587         return ret;
588 }