2 #include <wayland-server.h>
3 #include <tizen-launch-server-protocol.h>
7 #include <libds-tizen/launch.h>
9 #define TIZEN_APPINFO_VERSION 1
11 struct ds_tizen_launch_appinfo_mgr
13 struct wl_global *global;
15 struct wl_list clients;
18 struct wl_listener destroy;
21 struct wl_signal destroy;
22 struct wl_signal set_pid;
23 struct wl_signal set_appid;
24 struct wl_signal metadata_ready;
27 struct wl_resource *resource; //for gtest
30 struct ds_tizen_launch_appinfo_client
32 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr;
34 struct wl_resource *resource;
35 struct wl_client *wl_client;
37 struct wl_list link; // ds_tizen_launch_appinfo_mgr::clients
40 enum ds_tizen_launch_appinfo_owner
42 DS_TIZEN_LAUNCH_APPINFO_OWNER_SERVER,
43 DS_TIZEN_LAUNCH_APPINFO_OWNER_CLIENT,
46 struct ds_tizen_launch_appinfo
48 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr;
52 bool base_output_available;
53 int base_output_width;
54 int base_output_height;
55 enum ds_tizen_launch_appinfo_owner owner;
57 struct wl_list link; //ds_tizen_launch_appinfo_mgr::infos;
60 static void appinfo_mgr_handle_display_destroy(struct wl_listener *listener,
63 static void appinfo_mgr_bind(struct wl_client *wl_client, void *data,
64 uint32_t version, uint32_t id);
66 WL_EXPORT struct ds_tizen_launch_appinfo_mgr *
67 ds_tizen_launch_appinfo_mgr_create(struct wl_display *display)
69 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr;
71 appinfo_mgr = calloc(1, sizeof *appinfo_mgr);
73 ds_err("calloc() failed.");
77 appinfo_mgr->global = wl_global_create(display, &tizen_launch_appinfo_interface,
78 TIZEN_APPINFO_VERSION, appinfo_mgr, appinfo_mgr_bind);
79 if (!appinfo_mgr->global) {
80 ds_err("wl_global_create() failed. tizen_launch_appinfo_interface");
85 wl_list_init(&appinfo_mgr->clients);
86 wl_list_init(&appinfo_mgr->infos);
88 appinfo_mgr->destroy.notify = appinfo_mgr_handle_display_destroy;
89 wl_display_add_destroy_listener(display, &appinfo_mgr->destroy);
91 wl_signal_init(&appinfo_mgr->events.destroy);
92 wl_signal_init(&appinfo_mgr->events.set_pid);
93 wl_signal_init(&appinfo_mgr->events.set_appid);
94 wl_signal_init(&appinfo_mgr->events.metadata_ready);
96 ds_inf("Global create: tizen_launch_appinfo. appinfo_mgr(%p)", appinfo_mgr);
102 ds_tizen_launch_appinfo_mgr_add_destroy_listener(
103 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener)
105 wl_signal_add(&appinfo_mgr->events.destroy, listener);
109 ds_tizen_launch_appinfo_mgr_add_set_pid_listener(
110 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener)
112 wl_signal_add(&appinfo_mgr->events.set_pid, listener);
116 ds_tizen_launch_appinfo_mgr_add_set_appid_listener(
117 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener)
119 wl_signal_add(&appinfo_mgr->events.set_appid, listener);
123 ds_tizen_launch_appinfo_mgr_add_metadata_ready_listener(
124 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr, struct wl_listener *listener)
126 wl_signal_add(&appinfo_mgr->events.metadata_ready, listener);
130 appinfo_mgr_handle_display_destroy(struct wl_listener *listener, void *data)
132 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr;
133 struct ds_tizen_launch_appinfo_client *client, *tmp_client;
134 struct ds_tizen_launch_appinfo *info, *tmp_info;
136 appinfo_mgr = wl_container_of(listener, appinfo_mgr, destroy);
138 ds_inf("Global destroy: appinfo_mgr(%p)", appinfo_mgr);
140 wl_signal_emit_mutable(&appinfo_mgr->events.destroy, appinfo_mgr);
141 wl_list_remove(&appinfo_mgr->destroy.link);
143 wl_list_for_each_safe(client, tmp_client, &appinfo_mgr->clients, link) {
144 wl_list_remove(&client->link);
148 wl_list_for_each_safe(info, tmp_info, &appinfo_mgr->infos, link) {
149 wl_list_remove(&info->link);
154 wl_global_destroy(appinfo_mgr->global);
159 appinfo_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource)
161 wl_resource_destroy(resource);
164 static struct ds_tizen_launch_appinfo *
165 appinfo_mgr_find_with_pid(struct ds_tizen_launch_appinfo_mgr *appinfo_mgr,
168 struct ds_tizen_launch_appinfo *info;
170 wl_list_for_each(info, &appinfo_mgr->infos, link) {
171 if (pid == info->pid)
178 static struct ds_tizen_launch_appinfo *
179 appinfo_mgr_find_with_appid(struct ds_tizen_launch_appinfo_mgr *appinfo_mgr,
182 struct ds_tizen_launch_appinfo *info;
184 wl_list_for_each(info, &appinfo_mgr->infos, link) {
185 if (appid && !strcmp(appid, info->appid))
191 static struct ds_tizen_launch_appinfo *
192 appinfo_mgr_get_info(struct ds_tizen_launch_appinfo_mgr *appinfo_mgr,
193 pid_t pid, const char *appid)
195 struct ds_tizen_launch_appinfo *info = NULL;
198 info = appinfo_mgr_find_with_pid(appinfo_mgr, pid);
200 info = appinfo_mgr_find_with_appid(appinfo_mgr, appid);
206 info = calloc(1, sizeof *info);
208 ds_err("calloc() failed. tizen_appinfo");
215 info->appid = strdup(appid);
217 info->appinfo_mgr = appinfo_mgr;
219 wl_list_insert(&appinfo_mgr->infos, &info->link);
225 appinfo_destroy(struct ds_tizen_launch_appinfo *info)
227 wl_list_remove(&info->link);
233 appinfo_set_pid(struct ds_tizen_launch_appinfo *info, pid_t pid)
235 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr;
236 struct ds_tizen_launch_appinfo *info2, *tmp;
238 if (!info) return false;
239 if (pid < 0) return false;
241 appinfo_mgr = info->appinfo_mgr;
243 wl_list_for_each_safe(info2, tmp, &appinfo_mgr->infos, link) {
244 if ((info2->pid == pid) && (info2 != info)) {
245 ds_inf("removed duplicated appinfo");
247 if (!info->appid) info->appid = strdup(info2->appid);
248 if (!info->base_output_available && info2->base_output_available) {
249 ds_inf("copy base_output variable into appinfo.");
250 info->base_output_available = true;
251 info->base_output_width = info2->base_output_width;
252 info->base_output_height = info2->base_output_height;
254 appinfo_destroy(info2);
259 ds_inf("appinfo(%p) set pid(%u)", info, pid);
261 wl_signal_emit_mutable(&appinfo_mgr->events.set_pid, info);
267 appinfo_set_appid(struct ds_tizen_launch_appinfo *info, const char *appid)
269 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr;
270 struct ds_tizen_launch_appinfo *info2, *tmp;
272 if (!info) return false;
273 if (!appid) return false;
275 appinfo_mgr = info->appinfo_mgr;
277 wl_list_for_each_safe(info2, tmp, &appinfo_mgr->infos, link) {
278 if ((info2->appid && !strcmp(info2->appid, appid)) &&
280 ds_inf("removed duplicated appinfo");
282 if (info->pid < 0) info->pid = info2->pid;
283 if (!info->base_output_available && info2->base_output_available)
285 ds_inf("copy base_output variable into appinfo.");
286 info->base_output_available = true;
287 info->base_output_width = info2->base_output_width;
288 info->base_output_height = info2->base_output_height;
290 appinfo_destroy(info2);
295 info->appid = strdup(appid);
296 ds_inf("appinfo(%p) set appid(%u)", info, appid);
298 wl_signal_emit_mutable(&appinfo_mgr->events.set_appid, info);
304 appinfo_get_base_output_resolution(struct ds_tizen_launch_appinfo *info, int *width, int *height)
306 if (!info) return false;
307 if (!width) return false;
308 if (!height) return false;
310 if (!info->base_output_available) {
315 *width = info->base_output_width;
316 *height = info->base_output_height;
322 appinfo_set_owner(struct ds_tizen_launch_appinfo *info, enum ds_tizen_launch_appinfo_owner owner)
330 appinfo_handle_register_pid(struct wl_client *wl_client,
331 struct wl_resource *resource, uint32_t pid)
333 struct ds_tizen_launch_appinfo_client *client;
334 struct ds_tizen_launch_appinfo *info;
336 client = wl_resource_get_user_data(resource);
339 ds_err("tizen_appinfo: pid is invalid. pid:%u", pid);
343 info = appinfo_mgr_get_info(client->appinfo_mgr, pid, NULL);
345 ds_err("appinfo_mgr_get_info() failed. tizen_appinfo");
346 wl_client_post_no_memory(wl_client);
350 appinfo_set_pid(info, pid);
351 appinfo_set_owner(info, DS_TIZEN_LAUNCH_APPINFO_OWNER_CLIENT);
356 appinfo_handle_deregister_pid(struct wl_client *wl_client,
357 struct wl_resource *resource, uint32_t pid)
359 struct ds_tizen_launch_appinfo_client *client;
360 struct ds_tizen_launch_appinfo *info;
362 client = wl_resource_get_user_data(resource);
364 info = appinfo_mgr_find_with_pid(client->appinfo_mgr, pid);
366 ds_err("tizen_appinfo: no appinfo found by pid(%u)", pid);
370 appinfo_destroy(info);
374 appinfo_handle_set_appid(struct wl_client *wl_client,
375 struct wl_resource *resource, uint32_t pid, const char *appid)
377 struct ds_tizen_launch_appinfo_client *client;
378 struct ds_tizen_launch_appinfo *info;
380 client = wl_resource_get_user_data(resource);
383 ds_err("tizen_appinfo: pid is invalid. pid:%u", pid);
387 info = appinfo_mgr_find_with_pid(client->appinfo_mgr, pid);
389 ds_err("tizen_appinfo: no appinfo found by pid(%u)", pid);
393 appinfo_set_appid(info, appid);
395 /* TODO: base output resolution */
399 WL_EXPORT struct wl_resource *
400 ds_tizen_launch_appinfo_mgr_get_appinfo_resource(
401 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr)
403 return appinfo_mgr->resource;
407 appinfo_handle_get_base_output_resolution(struct wl_client *wl_client,
408 struct wl_resource *resource, uint32_t pid)
410 struct ds_tizen_launch_appinfo_client *client;
411 struct ds_tizen_launch_appinfo *info;
412 int width = 0, height = 0;
414 client = wl_resource_get_user_data(resource);
417 ds_err("tizen_appinfo: pid is invalid. pid:%u", pid);
421 info = appinfo_mgr_find_with_pid(client->appinfo_mgr, pid);
423 ds_err("tizen_appinfo: no appinfo found by pid(%u)", pid);
427 appinfo_get_base_output_resolution(info, &width, &height);
429 client->appinfo_mgr->resource = resource;
432 if (width == 0 && height == 0) {
433 width = 1080; //e_config->configured_output_resolution.w;
434 height = 1920; //e_config->configured_output_resolution.h;
437 ds_inf("send base_output_resolution. size(%d x %d). pid(%u)", width, height, pid);
438 tizen_launch_appinfo_send_base_output_resolution_done(resource, pid, width, height);
442 appinfo_handle_register_appid(struct wl_client *wl_client, struct wl_resource *resource,
445 struct ds_tizen_launch_appinfo_client *client;
446 struct ds_tizen_launch_appinfo *info;
448 client = wl_resource_get_user_data(resource);
450 info = appinfo_mgr_get_info(client->appinfo_mgr, -1, appid);
452 ds_err("appinfo_mgr_get_info() failed. tizen_appinfo");
453 wl_client_post_no_memory(wl_client);
457 appinfo_set_appid(info, appid);
458 appinfo_set_owner(info, DS_TIZEN_LAUNCH_APPINFO_OWNER_CLIENT);
462 appinfo_handle_deregister_appid(struct wl_client *wl_client,
463 struct wl_resource *resource, const char *appid)
465 struct ds_tizen_launch_appinfo_client *client;
466 struct ds_tizen_launch_appinfo *info;
468 client = wl_resource_get_user_data(resource);
470 info = appinfo_mgr_find_with_appid(client->appinfo_mgr, appid);
472 ds_err("tizen_appinfo: no appinfo found by appid(%u)", appid);
476 appinfo_destroy(info);
480 appinfo_handle_set_pid(struct wl_client *wl_client,
481 struct wl_resource *resource, const char *appid, uint32_t pid)
483 struct ds_tizen_launch_appinfo_client *client;
484 struct ds_tizen_launch_appinfo *info;
486 client = wl_resource_get_user_data(resource);
488 info = appinfo_mgr_find_with_appid(client->appinfo_mgr, appid);
490 ds_err("tizen_appinfo: no appinfo found by appid(%u)", appid);
494 appinfo_set_pid(info, pid);
498 appinfo_handle_ready_metadata(struct wl_client *wl_client,
499 struct wl_resource *resource, const char *appid, uint32_t pid)
501 struct ds_tizen_launch_appinfo_client *client;
502 struct ds_tizen_launch_appinfo *info;
504 client = wl_resource_get_user_data(resource);
506 info = appinfo_mgr_find_with_appid(client->appinfo_mgr, appid);
508 ds_err("tizen_appinfo: no appinfo found by appid(%u)", appid);
512 if ((uint32_t)info->pid != pid)
513 appinfo_set_pid(info, pid);
515 wl_signal_emit_mutable(&client->appinfo_mgr->events.metadata_ready, info);
517 /* TODO: base output resolution */
520 static const struct tizen_launch_appinfo_interface appinfo_impl =
522 appinfo_handle_destroy,
523 appinfo_handle_register_pid,
524 appinfo_handle_deregister_pid,
525 appinfo_handle_set_appid,
526 appinfo_handle_get_base_output_resolution,
527 appinfo_handle_register_appid,
528 appinfo_handle_deregister_appid,
529 appinfo_handle_set_pid,
530 appinfo_handle_ready_metadata,
534 _tizen_appinfo_client_handle_destroy(struct wl_resource *resource)
536 struct ds_tizen_launch_appinfo_client *client;
538 client = wl_resource_get_user_data(resource);
540 ds_inf("_tizen_appinfo_client_handle_destroy (client:%p)", client);
542 wl_list_remove(&client->link);
546 static void appinfo_mgr_bind(struct wl_client *wl_client, void *data,
547 uint32_t version, uint32_t id)
549 struct ds_tizen_launch_appinfo_mgr *appinfo_mgr = data;
550 struct ds_tizen_launch_appinfo_client *client;
552 client = calloc(1, sizeof *client);
553 if (client == NULL) {
554 ds_err("calloc() failed. tizen_appinfo");
555 wl_client_post_no_memory(wl_client);
559 ds_inf("tizen_appinfo_client_binds. (client:%p)", client);
561 client->appinfo_mgr = appinfo_mgr;
562 client->wl_client = wl_client;
564 client->resource = wl_resource_create(wl_client,
565 &tizen_launch_appinfo_interface,
566 MIN(version, TIZEN_APPINFO_VERSION), id);
568 if (client->resource == NULL) {
569 ds_err("tizen_appinfo : wl_resource_create() failed.");
571 wl_client_post_no_memory(wl_client);
575 wl_resource_set_implementation(client->resource, &appinfo_impl, client,
576 _tizen_appinfo_client_handle_destroy);
578 wl_list_insert(&appinfo_mgr->clients, &client->link);