--- /dev/null
+#ifndef LIBDS_TIZEN_APPINFO_H
+#define LIBDS_TIZEN_APPINFO_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ds_tizen_appinfo_mgr;
+struct ds_tizen_appinfo;
+
+struct ds_tizen_appinfo_mgr *
+ds_tizen_appinfo_mgr_create(struct wl_display *display);
+
+void
+ds_tizen_appinfo_mgr_add_destroy_listener(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener);
+
+void
+ds_tizen_appinfo_mgr_add_set_pid_listener(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener);
+
+void
+ds_tizen_appinfo_mgr_add_set_appid_listener(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener);
+
+void
+ds_tizen_appinfo_mgr_add_metadata_ready_listener(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener);
+
+//for gtest
+struct wl_resource *
+ds_tizen_appinfo_mgr_get_appinfo_resource(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
BuildRequires: pkgconfig(wayland-protocols)
BuildRequires: pkgconfig(tizen-extension-server)
BuildRequires: pkgconfig(tizen-extension-client)
+BuildRequires: pkgconfig(tizen-launch-server)
+BuildRequires: pkgconfig(tizen-launch-client)
BuildRequires: pkgconfig(pixman-1)
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(xkbcommon)
%description clipboard-devel
Development package for tizen clipboard
+## libds-tizen-launch
+%package launch
+Summary: Library for tizen launch
+Group: Development/Libraries
+
+%description launch
+Library for tizen launch
+
+%package launch-devel
+Summary: Development package for tizen launch
+Group: Development/Libraries
+
+%description launch-devel
+Development package for tizen launch
+
%prep
%setup -q
cp %{SOURCE1001} .
%{_libdir}/pkgconfig/libds-tizen-clipboard.pc
%{_libdir}/libds-tizen-clipboard.so
%{_bindir}/libds-tizen-clipboard-tests
+
+%files launch
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license LICENSE
+%{_libdir}/libds-tizen-launch.so.*
+
+%files launch-devel
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license LICENSE
+%{_includedir}/libds-tizen/launch/appinfo.h
+%{_libdir}/pkgconfig/libds-tizen-launch.pc
+%{_libdir}/libds-tizen-launch.so
+%{_bindir}/libds-tizen-launch-appinfo-tests
--- /dev/null
+#include <stdlib.h>
+#include <wayland-server.h>
+#include <tizen-launch-server-protocol.h>
+#include <libds/log.h>
+
+#include "util.h"
+#include <libds-tizen/launch/appinfo.h>
+
+#define TIZEN_APPINFO_VERSION 1
+
+struct ds_tizen_appinfo_mgr
+{
+ struct wl_global *global;
+
+ struct wl_list clients;
+ struct wl_list infos;
+
+ struct wl_listener destroy;
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal set_pid;
+ struct wl_signal set_appid;
+ struct wl_signal metadata_ready;
+ } events;
+
+ struct wl_resource *resource; //for gtest
+};
+
+struct ds_tizen_appinfo_client
+{
+ struct ds_tizen_appinfo_mgr *appinfo_mgr;
+
+ struct wl_resource *resource;
+ struct wl_client *wl_client;
+
+ struct wl_list link; // ds_tizen_appinfo_mgr::clients
+};
+
+enum ds_tizen_appinfo_owner
+{
+ DS_TIZEN_APPINFO_OWNER_SERVER,
+ DS_TIZEN_APPINFO_OWNER_CLIENT,
+};
+
+struct ds_tizen_appinfo
+{
+ struct ds_tizen_appinfo_mgr *appinfo_mgr;
+
+ pid_t pid;
+ char *appid;
+ bool base_output_available;
+ int base_output_width;
+ int base_output_height;
+ enum ds_tizen_appinfo_owner owner;
+
+ struct wl_list link; //ds_tizen_appinfo_mgr::infos;
+};
+
+static void appinfo_mgr_handle_display_destroy(struct wl_listener *listener,
+ void *data);
+
+static void appinfo_mgr_bind(struct wl_client *wl_client, void *data,
+ uint32_t version, uint32_t id);
+
+WL_EXPORT struct ds_tizen_appinfo_mgr *
+ds_tizen_appinfo_mgr_create(struct wl_display *display)
+{
+ struct ds_tizen_appinfo_mgr *appinfo_mgr;
+
+ appinfo_mgr = calloc(1, sizeof *appinfo_mgr);
+ if (!appinfo_mgr) {
+ ds_err("calloc() failed.");
+ return NULL;
+ }
+
+ appinfo_mgr->global = wl_global_create(display, &tizen_launch_appinfo_interface,
+ TIZEN_APPINFO_VERSION, appinfo_mgr, appinfo_mgr_bind);
+ if (!appinfo_mgr->global) {
+ ds_err("wl_global_create() failed. tizen_launch_appinfo_interface");
+ free(appinfo_mgr);
+ return NULL;
+ }
+
+ wl_list_init(&appinfo_mgr->clients);
+ wl_list_init(&appinfo_mgr->infos);
+
+ appinfo_mgr->destroy.notify = appinfo_mgr_handle_display_destroy;
+ wl_display_add_destroy_listener(display, &appinfo_mgr->destroy);
+
+ wl_signal_init(&appinfo_mgr->events.destroy);
+ wl_signal_init(&appinfo_mgr->events.set_pid);
+ wl_signal_init(&appinfo_mgr->events.set_appid);
+ wl_signal_init(&appinfo_mgr->events.metadata_ready);
+
+ ds_inf("Global create: tizen_launch_appinfo. appinfo_mgr(%p)", appinfo_mgr);
+
+ return appinfo_mgr;
+}
+
+WL_EXPORT void
+ds_tizen_appinfo_mgr_add_destroy_listener(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener)
+{
+ wl_signal_add(&appinfo_mgr->events.destroy, listener);
+}
+
+WL_EXPORT void
+ds_tizen_appinfo_mgr_add_set_pid_listener(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener)
+{
+ wl_signal_add(&appinfo_mgr->events.set_pid, listener);
+}
+
+WL_EXPORT void
+ds_tizen_appinfo_mgr_add_set_appid_listener(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener)
+{
+ wl_signal_add(&appinfo_mgr->events.set_appid, listener);
+}
+
+WL_EXPORT void
+ds_tizen_appinfo_mgr_add_metadata_ready_listener(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr, struct wl_listener *listener)
+{
+ wl_signal_add(&appinfo_mgr->events.metadata_ready, listener);
+}
+
+static void
+appinfo_mgr_handle_display_destroy(struct wl_listener *listener, void *data)
+{
+ struct ds_tizen_appinfo_mgr *appinfo_mgr;
+ struct ds_tizen_appinfo_client *client, *tmp_client;
+ struct ds_tizen_appinfo *info, *tmp_info;
+
+ appinfo_mgr = wl_container_of(listener, appinfo_mgr, destroy);
+
+ ds_inf("Global destroy: appinfo_mgr(%p)", appinfo_mgr);
+
+ wl_signal_emit(&appinfo_mgr->events.destroy, appinfo_mgr);
+ wl_list_remove(&appinfo_mgr->destroy.link);
+
+ wl_list_for_each_safe(client, tmp_client, &appinfo_mgr->clients, link) {
+ wl_list_remove(&client->link);
+ free(client);
+ }
+
+ wl_list_for_each_safe(info, tmp_info, &appinfo_mgr->infos, link) {
+ wl_list_remove(&info->link);
+ free(info->appid);
+ free(info);
+ }
+
+ wl_global_destroy(appinfo_mgr->global);
+ free(appinfo_mgr);
+}
+
+static void
+appinfo_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static struct ds_tizen_appinfo *
+appinfo_mgr_find_with_pid(struct ds_tizen_appinfo_mgr *appinfo_mgr,
+ pid_t pid)
+{
+ struct ds_tizen_appinfo *info;
+
+ wl_list_for_each(info, &appinfo_mgr->infos, link) {
+ if (pid == info->pid)
+ return info;
+ }
+
+ return NULL;
+}
+
+static struct ds_tizen_appinfo *
+appinfo_mgr_find_with_appid(struct ds_tizen_appinfo_mgr *appinfo_mgr,
+ const char *appid)
+{
+ struct ds_tizen_appinfo *info;
+
+ wl_list_for_each(info, &appinfo_mgr->infos, link) {
+ if (appid && !strcmp(appid, info->appid))
+ return info;
+ }
+
+ return NULL;
+}
+static struct ds_tizen_appinfo *
+appinfo_mgr_get_info(struct ds_tizen_appinfo_mgr *appinfo_mgr,
+ pid_t pid, const char *appid)
+{
+ struct ds_tizen_appinfo *info = NULL;
+
+ if (pid > 0)
+ info = appinfo_mgr_find_with_pid(appinfo_mgr, pid);
+ else if (appid)
+ info = appinfo_mgr_find_with_appid(appinfo_mgr, appid);
+
+ if (info) {
+ return info;
+ }
+
+ info = calloc(1, sizeof *info);
+ if (info == NULL) {
+ ds_err("calloc() failed. tizen_appinfo");
+ return NULL;
+ }
+
+ if (pid > 0)
+ info->pid = pid;
+ else if (appid)
+ info->appid = strdup(appid);
+
+ info->appinfo_mgr = appinfo_mgr;
+
+ wl_list_insert(&appinfo_mgr->infos, &info->link);
+
+ return info;
+}
+
+static void
+appinfo_destroy(struct ds_tizen_appinfo *info)
+{
+ wl_list_remove(&info->link);
+ free(info->appid);
+ free(info);
+}
+
+static bool
+appinfo_set_pid(struct ds_tizen_appinfo *info, pid_t pid)
+{
+ struct ds_tizen_appinfo_mgr *appinfo_mgr;
+ struct ds_tizen_appinfo *info2, *tmp;
+
+ if (!info) return false;
+ if (pid < 0) return false;
+
+ appinfo_mgr = info->appinfo_mgr;
+
+ wl_list_for_each_safe(info2, tmp, &appinfo_mgr->infos, link) {
+ if ((info2->pid == pid) && (info2 != info)) {
+ ds_inf("removed duplicated appinfo");
+
+ if (!info->appid) info->appid = strdup(info2->appid);
+ if (!info->base_output_available && info2->base_output_available) {
+ ds_inf("copy base_output variable into appinfo.");
+ info->base_output_available = true;
+ info->base_output_width = info2->base_output_width;
+ info->base_output_height = info2->base_output_height;
+ }
+ appinfo_destroy(info2);
+ }
+ }
+
+ info->pid = pid;
+ ds_inf("appinfo(%p) set pid(%u)", info, pid);
+
+ wl_signal_emit(&appinfo_mgr->events.set_pid, info);
+
+ return true;
+}
+
+static bool
+appinfo_set_appid(struct ds_tizen_appinfo *info, const char *appid)
+{
+ struct ds_tizen_appinfo_mgr *appinfo_mgr;
+ struct ds_tizen_appinfo *info2, *tmp;
+
+ if (!info) return false;
+ if (!appid) return false;
+
+ appinfo_mgr = info->appinfo_mgr;
+
+ wl_list_for_each_safe(info2, tmp, &appinfo_mgr->infos, link) {
+ if ((info2->appid && !strcmp(info2->appid, appid)) &&
+ (info2 != info)) {
+ ds_inf("removed duplicated appinfo");
+
+ if (info->pid < 0) info->pid = info2->pid;
+ if (!info->base_output_available && info2->base_output_available)
+ {
+ ds_inf("copy base_output variable into appinfo.");
+ info->base_output_available = true;
+ info->base_output_width = info2->base_output_width;
+ info->base_output_height = info2->base_output_height;
+ }
+ appinfo_destroy(info2);
+ }
+ }
+
+ free(info->appid);
+ info->appid = strdup(appid);
+ ds_inf("appinfo(%p) set appid(%u)", info, appid);
+
+ wl_signal_emit(&appinfo_mgr->events.set_appid, info);
+
+ return true;
+}
+
+static bool
+appinfo_get_base_output_resolution(struct ds_tizen_appinfo *info, int *width, int *height)
+{
+ if (!info) return false;
+ if (!width) return false;
+ if (!height) return false;
+
+ if (!info->base_output_available) {
+ *width = 0;
+ *height = 0;
+ return false;
+ }
+ *width = info->base_output_width;
+ *height = info->base_output_height;
+
+ return true;
+}
+
+static void
+appinfo_set_owner(struct ds_tizen_appinfo *info, enum ds_tizen_appinfo_owner owner)
+{
+ if (!info) return;
+
+ info->owner = owner;
+}
+
+static void
+appinfo_handle_register_pid(struct wl_client *wl_client,
+ struct wl_resource *resource, uint32_t pid)
+{
+ struct ds_tizen_appinfo_client *client;
+ struct ds_tizen_appinfo *info;
+
+ client = wl_resource_get_user_data(resource);
+
+ if (pid <= 0) {
+ ds_err("tizen_appinfo: pid is invalid. pid:%u", pid);
+ return;
+ }
+
+ info = appinfo_mgr_get_info(client->appinfo_mgr, pid, NULL);
+ if (info == NULL) {
+ ds_err("appinfo_mgr_get_info() failed. tizen_appinfo");
+ wl_client_post_no_memory(wl_client);
+ return;
+ }
+
+ appinfo_set_pid(info, pid);
+ appinfo_set_owner(info, DS_TIZEN_APPINFO_OWNER_CLIENT);
+}
+
+
+static void
+appinfo_handle_deregister_pid(struct wl_client *wl_client,
+ struct wl_resource *resource, uint32_t pid)
+{
+ struct ds_tizen_appinfo_client *client;
+ struct ds_tizen_appinfo *info;
+
+ client = wl_resource_get_user_data(resource);
+
+ info = appinfo_mgr_find_with_pid(client->appinfo_mgr, pid);
+ if (info == NULL) {
+ ds_err("tizen_appinfo: no appinfo found by pid(%u)", pid);
+ return;
+ }
+
+ appinfo_destroy(info);
+}
+
+static void
+appinfo_handle_set_appid(struct wl_client *wl_client,
+ struct wl_resource *resource, uint32_t pid, const char *appid)
+{
+ struct ds_tizen_appinfo_client *client;
+ struct ds_tizen_appinfo *info;
+
+ client = wl_resource_get_user_data(resource);
+
+ if (pid <= 0) {
+ ds_err("tizen_appinfo: pid is invalid. pid:%u", pid);
+ return;
+ }
+
+ info = appinfo_mgr_find_with_pid(client->appinfo_mgr, pid);
+ if (info == NULL) {
+ ds_err("tizen_appinfo: no appinfo found by pid(%u)", pid);
+ return;
+ }
+
+ appinfo_set_appid(info, appid);
+
+ /* TODO: base output resolution */
+}
+
+//for gtest
+WL_EXPORT struct wl_resource *
+ds_tizen_appinfo_mgr_get_appinfo_resource(
+ struct ds_tizen_appinfo_mgr *appinfo_mgr)
+{
+ return appinfo_mgr->resource;
+}
+
+static void
+appinfo_handle_get_base_output_resolution(struct wl_client *wl_client,
+ struct wl_resource *resource, uint32_t pid)
+{
+ struct ds_tizen_appinfo_client *client;
+ struct ds_tizen_appinfo *info;
+ int width = 0, height = 0;
+
+ client = wl_resource_get_user_data(resource);
+
+ if (pid <= 0) {
+ ds_err("tizen_appinfo: pid is invalid. pid:%u", pid);
+ goto finish;
+ }
+
+ info = appinfo_mgr_find_with_pid(client->appinfo_mgr, pid);
+ if (info == NULL) {
+ ds_err("tizen_appinfo: no appinfo found by pid(%u)", pid);
+ goto finish;
+ }
+
+ appinfo_get_base_output_resolution(info, &width, &height);
+
+ client->appinfo_mgr->resource = resource;
+
+finish:
+ if (width == 0 && height == 0) {
+ width = 1080; //e_config->configured_output_resolution.w;
+ height = 1920; //e_config->configured_output_resolution.h;
+ }
+
+ ds_inf("send base_output_resolution. size(%d x %d). pid(%u)", width, height, pid);
+ tizen_launch_appinfo_send_base_output_resolution_done(resource, pid, width, height);
+}
+
+static void
+appinfo_handle_register_appid(struct wl_client *wl_client, struct wl_resource *resource,
+ const char *appid)
+{
+ struct ds_tizen_appinfo_client *client;
+ struct ds_tizen_appinfo *info;
+
+ client = wl_resource_get_user_data(resource);
+
+ info = appinfo_mgr_get_info(client->appinfo_mgr, -1, appid);
+ if (info == NULL) {
+ ds_err("appinfo_mgr_get_info() failed. tizen_appinfo");
+ wl_client_post_no_memory(wl_client);
+ return;
+ }
+
+ appinfo_set_appid(info, appid);
+ appinfo_set_owner(info, DS_TIZEN_APPINFO_OWNER_CLIENT);
+}
+
+static void
+appinfo_handle_deregister_appid(struct wl_client *wl_client,
+ struct wl_resource *resource, const char *appid)
+{
+ struct ds_tizen_appinfo_client *client;
+ struct ds_tizen_appinfo *info;
+
+ client = wl_resource_get_user_data(resource);
+
+ info = appinfo_mgr_find_with_appid(client->appinfo_mgr, appid);
+ if (info == NULL) {
+ ds_err("tizen_appinfo: no appinfo found by appid(%u)", appid);
+ return;
+ }
+
+ appinfo_destroy(info);
+}
+
+static void
+appinfo_handle_set_pid(struct wl_client *wl_client,
+ struct wl_resource *resource, const char *appid, uint32_t pid)
+{
+ struct ds_tizen_appinfo_client *client;
+ struct ds_tizen_appinfo *info;
+
+ client = wl_resource_get_user_data(resource);
+
+ info = appinfo_mgr_find_with_appid(client->appinfo_mgr, appid);
+ if (info == NULL) {
+ ds_err("tizen_appinfo: no appinfo found by appid(%u)", appid);
+ return;
+ }
+
+ appinfo_set_pid(info, pid);
+}
+
+static void
+appinfo_handle_ready_metadata(struct wl_client *wl_client,
+ struct wl_resource *resource, const char *appid, uint32_t pid)
+{
+ struct ds_tizen_appinfo_client *client;
+ struct ds_tizen_appinfo *info;
+
+ client = wl_resource_get_user_data(resource);
+
+ info = appinfo_mgr_find_with_appid(client->appinfo_mgr, appid);
+ if (info == NULL) {
+ ds_err("tizen_appinfo: no appinfo found by appid(%u)", appid);
+ return;
+ }
+
+ if (info->pid != pid)
+ appinfo_set_pid(info, pid);
+
+ wl_signal_emit(&client->appinfo_mgr->events.metadata_ready, info);
+
+ /* TODO: base output resolution */
+}
+
+static const struct tizen_launch_appinfo_interface appinfo_impl =
+{
+ appinfo_handle_destroy,
+ appinfo_handle_register_pid,
+ appinfo_handle_deregister_pid,
+ appinfo_handle_set_appid,
+ appinfo_handle_get_base_output_resolution,
+ appinfo_handle_register_appid,
+ appinfo_handle_deregister_appid,
+ appinfo_handle_set_pid,
+ appinfo_handle_ready_metadata,
+};
+
+static void
+_tizen_appinfo_client_handle_destroy(struct wl_resource *resource)
+{
+ struct ds_tizen_appinfo_client *client;
+
+ client = wl_resource_get_user_data(resource);
+
+ ds_inf("_tizen_appinfo_client_handle_destroy (client:%p)", client);
+
+ wl_list_remove(&client->link);
+ free(client);
+}
+
+static void appinfo_mgr_bind(struct wl_client *wl_client, void *data,
+ uint32_t version, uint32_t id)
+{
+ struct ds_tizen_appinfo_mgr *appinfo_mgr = data;
+ struct ds_tizen_appinfo_client *client;
+
+ client = calloc(1, sizeof *client);
+ if (client == NULL) {
+ ds_err("calloc() failed. tizen_appinfo");
+ wl_client_post_no_memory(wl_client);
+ return;
+ }
+
+ ds_inf("tizen_appinfo_client_binds. (client:%p)", client);
+
+ client->appinfo_mgr = appinfo_mgr;
+ client->wl_client = wl_client;
+
+ client->resource = wl_resource_create(wl_client,
+ &tizen_launch_appinfo_interface,
+ MIN(version, TIZEN_APPINFO_VERSION), id);
+
+ if (client->resource == NULL) {
+ ds_err("tizen_appinfo : wl_resource_create() failed.");
+ free(client);
+ wl_client_post_no_memory(wl_client);
+ return;
+ }
+
+ wl_resource_set_implementation(client->resource, &appinfo_impl, client,
+ _tizen_appinfo_client_handle_destroy);
+
+ wl_list_insert(&appinfo_mgr->clients, &client->link);
+}
--- /dev/null
+libds_tizen_launch_files = [
+ 'appinfo.c',
+]
+
+libds_tizen_launch_deps = [
+ deps_libds_tizen,
+ dependency('tizen-launch-server', required: true),
+]
+
+lib_libds_tizen_launch = shared_library('ds-tizen-launch', libds_tizen_launch_files,
+ dependencies: libds_tizen_launch_deps,
+ include_directories: [ common_inc, include_directories('.'), include_directories('..') ],
+ version: meson.project_version(),
+ install: true
+)
+
+deps_libds_tizen_launch = declare_dependency(
+ link_with: lib_libds_tizen_launch,
+ dependencies: libds_tizen_launch_deps,
+ include_directories: [ common_inc, include_directories('.') ],
+)
+
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(lib_libds_tizen_launch,
+ version: meson.project_version(),
+ filebase: 'libds-tizen-launch',
+ name: 'libds-tizen-launch',
+ description: 'tizen launch extension of libds-tizen for tizen platform',
+)
subdir('dpms')
subdir('indicator')
subdir('clipboard')
+subdir('launch')
install_dir: libds_tizen_bindir,
install : true
)
+
+## appinfo tests
+tc_launch_appinfo_files = [
+ 'tc_main.cpp',
+ 'tc_launch_appinfo.cpp',
+]
+
+executable('libds-tizen-launch-appinfo-tests',
+ [
+ tc_mock_files,
+ tc_launch_appinfo_files
+ ],
+ dependencies: [
+ deps_test_common,
+ deps_libds_tizen_launch,
+ ],
+ install_dir: libds_tizen_bindir,
+ install : true
+)
--- /dev/null
+#include "tc_main.h"
+#include "mockclient.h"
+#include "mockcompositor.h"
+#include <libds-tizen/launch/appinfo.h>
+#include <tizen-launch-server-protocol.h>
+#include <tizen-launch-client-protocol.h>
+
+#define TIZEN_APPINFO_VERSION 1
+
+class MockAppinfoCompositor : public MockCompositor
+{
+public:
+ MockAppinfoCompositor()
+ : MockCompositor(&MockAppinfoCompositor::TestSetup, this)
+ {
+ ds_inf("%s : this(%p)", __func__, this);
+
+ // initialize the flags to check
+ bDestroyed = false;
+
+ bSetPid = false;
+ bSetAppid = false;
+ bMetadataReady = false;
+ }
+
+ ~MockAppinfoCompositor()
+ {
+ ds_inf("%s : this(%p)", __func__, this);
+ }
+
+ static void TestSetup(void *data)
+ {
+ MockAppinfoCompositor *mockComp =
+ static_cast<MockAppinfoCompositor *>(data);
+ Compositor *comp = mockComp->compositor;
+
+ ds_inf("%s: mockComp(%p)", __func__, mockComp);
+
+ mockComp->mAppinfoMgr = ds_tizen_appinfo_mgr_create(comp->display);
+
+ // destroy listener
+ mockComp->mDestroyListener.notify =
+ MockAppinfoCompositor::DestroyCallback;
+ mockComp->mDestroyListener.parent = mockComp;
+ ds_tizen_appinfo_mgr_add_destroy_listener(mockComp->mAppinfoMgr,
+ &mockComp->mDestroyListener);
+
+ // set_pid listener
+ mockComp->mSetPidListener.notify =
+ MockAppinfoCompositor::SetPidCallback;
+ mockComp->mSetPidListener.parent = mockComp;
+ ds_tizen_appinfo_mgr_add_set_pid_listener(mockComp->mAppinfoMgr,
+ &mockComp->mSetPidListener);
+
+ // set_appid listener
+ mockComp->mSetAppidListener.notify =
+ MockAppinfoCompositor::SetAppidCallback;
+ mockComp->mSetAppidListener.parent = mockComp;
+ ds_tizen_appinfo_mgr_add_set_appid_listener(mockComp->mAppinfoMgr,
+ &mockComp->mSetAppidListener);
+
+ // metadata_ready listener
+ mockComp->mMetadataReadyListener.notify =
+ MockAppinfoCompositor::MetadataReadyCallback;
+ mockComp->mMetadataReadyListener.parent = mockComp;
+ ds_tizen_appinfo_mgr_add_metadata_ready_listener(
+ mockComp->mAppinfoMgr,
+ &mockComp->mMetadataReadyListener);
+ }
+
+ static void DestroyCallback(struct wl_listener *listener, void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockAppinfoCompositor *mockComp =
+ reinterpret_cast<DestroyListener *>(listener)->parent;
+
+ mockComp->bDestroyed = true;
+ }
+
+ static void SetPidCallback(struct wl_listener *listener, void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockAppinfoCompositor *mockComp =
+ reinterpret_cast<SetPidListener *>(listener)->parent;
+ struct ds_tizen_appinfo *info = static_cast<struct ds_tizen_appinfo *>(data);
+
+ ds_inf("%s: mockComp(%p), appinfo(%p)", __func__, mockComp, info);
+
+ mockComp->bSetPid = true;
+ }
+
+ static void SetAppidCallback(struct wl_listener *listener, void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockAppinfoCompositor *mockComp =
+ reinterpret_cast<SetAppidListener *>(listener)->parent;
+ struct ds_tizen_appinfo *info = static_cast<struct ds_tizen_appinfo *>(data);
+
+ ds_inf("%s: mockComp(%p), appinfo(%p)", __func__, mockComp, info);
+
+ mockComp->bSetAppid = true;
+ }
+
+
+ static void MetadataReadyCallback(struct wl_listener *listener, void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockAppinfoCompositor *mockComp =
+ reinterpret_cast<MetadataReadyListener *>(listener)->parent;
+ struct ds_tizen_appinfo *info = static_cast<struct ds_tizen_appinfo *>(data);
+
+ ds_inf("%s: mockComp(%p), appinfo(%p)", __func__, mockComp, info);
+
+ mockComp->bMetadataReady = true;
+ }
+
+ void SendBaseOutputResolutionDone(uint32_t pid, uint32_t width, uint32_t height)
+ {
+ ds_inf("%s", __func__);
+
+ wl_resource *res_appinfo = ds_tizen_appinfo_mgr_get_appinfo_resource(mAppinfoMgr);
+
+ tizen_launch_appinfo_send_base_output_resolution_done(res_appinfo, pid, width, height);
+ }
+
+public:
+ bool bDestroyed;
+ bool bSetPid;
+ bool bSetAppid;
+ bool bMetadataReady;
+
+private:
+ struct ds_tizen_appinfo_mgr *mAppinfoMgr;
+ struct DestroyListener: ::wl_listener {
+ MockAppinfoCompositor *parent;
+ };
+ DestroyListener mDestroyListener;
+ struct SetPidListener: ::wl_listener {
+ MockAppinfoCompositor *parent;
+ };
+ SetPidListener mSetPidListener;
+ struct SetAppidListener: ::wl_listener {
+ MockAppinfoCompositor *parent;
+ };
+ SetAppidListener mSetAppidListener;
+ struct MetadataReadyListener: ::wl_listener {
+ MockAppinfoCompositor *parent;
+ };
+ MetadataReadyListener mMetadataReadyListener;
+};
+
+class MockAppinfoClient : public MockClient
+{
+public:
+ MockAppinfoClient()
+ : bBaseOutputResolutionDone(false),
+ mBaseOutputResolutionWidth(0),
+ mBaseOutputResolutionHeight(0),
+ compositor_res(nullptr),
+ tizen_launch_appinfo(nullptr)
+ {}
+ MockAppinfoClient(const struct wl_registry_listener *listener)
+ : MockClient(listener, this)
+ {
+ ds_inf("%s", __func__);
+
+ bBaseOutputResolutionDone = false;
+ mBaseOutputResolutionWidth = 0;
+ mBaseOutputResolutionHeight = 0;
+ }
+ ~MockAppinfoClient()
+ {
+ ds_inf("%s", __func__);
+ }
+
+ void SetWlCompositor(struct wl_compositor *global_res)
+ {
+ ds_inf("%s", __func__);
+
+ compositor_res = global_res;
+ }
+
+ struct wl_compositor *GetWlCompositor()
+ {
+ ds_inf("%s", __func__);
+
+ return compositor_res;
+ }
+
+ void SetTizenAppinfo(struct tizen_launch_appinfo *global_res)
+ {
+ ds_inf("%s", __func__);
+ tizen_launch_appinfo = global_res;
+ }
+
+ struct tizen_launch_appinfo *GetTizenAppinfo()
+ {
+ ds_inf("%s", __func__);
+
+ return tizen_launch_appinfo;
+ }
+
+public:
+ bool bBaseOutputResolutionDone;
+ uint32_t mBaseOutputResolutionWidth;
+ uint32_t mBaseOutputResolutionHeight;
+
+private:
+ struct wl_compositor *compositor_res;
+ struct tizen_launch_appinfo *tizen_launch_appinfo;
+};
+
+static void
+client_tizen_appinfo_cb_base_output_resolution_done(void *data,
+ struct tizen_launch_appinfo *appinfo, uint32_t pid,
+ uint32_t width, uint32_t height)
+{
+ ds_inf("%s", __func__);
+
+ MockAppinfoClient *client = static_cast<MockAppinfoClient *>(data);
+
+ client->bBaseOutputResolutionDone = true;
+ client->mBaseOutputResolutionWidth = width;
+ client->mBaseOutputResolutionHeight = height;
+}
+
+static const struct tizen_launch_appinfo_listener appinfo_cb_listener = {
+ .base_output_resolution_done = client_tizen_appinfo_cb_base_output_resolution_done,
+};
+
+static void
+client_registry_cb_global(void *data, struct wl_registry *registry,
+ uint32_t name, const char *interface, uint32_t version)
+{
+ ds_inf("%s", __func__);
+
+ MockAppinfoClient *client = static_cast<MockAppinfoClient *>(data);
+ struct wl_compositor *compositor_res;
+ struct tizen_launch_appinfo *tizen_launch_appinfo;
+
+ if (!strcmp(interface, "wl_compositor")) {
+ compositor_res = (struct wl_compositor *)wl_registry_bind(registry,
+ name, &wl_compositor_interface, 1);
+ if (compositor_res == nullptr) {
+ ds_err("wl_registry_bind() failed. wl_compositor resource.");
+ return;
+ }
+ client->SetWlCompositor(compositor_res);
+ } else if (!strcmp(interface, "tizen_launch_appinfo")) {
+ tizen_launch_appinfo = (struct tizen_launch_appinfo *)wl_registry_bind(registry,
+ name, &tizen_launch_appinfo_interface, TIZEN_APPINFO_VERSION);
+ if (tizen_launch_appinfo == nullptr) {
+ ds_err("wl_registry_bind() failed. tizen_launch_appinfo resource.");
+ return;
+ }
+ client->SetTizenAppinfo(tizen_launch_appinfo);
+
+ tizen_launch_appinfo_add_listener(tizen_launch_appinfo, &appinfo_cb_listener,
+ client);
+ }
+}
+
+static void
+client_registry_cb_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name)
+{
+ ds_inf("%s", __func__);
+
+ MockAppinfoClient *client = static_cast<MockAppinfoClient *>(data);
+ struct wl_compositor *compositor_res = client->GetWlCompositor();
+ struct tizen_launch_appinfo *appinfo_res = client->GetTizenAppinfo();
+
+ tizen_launch_appinfo_destroy(appinfo_res);
+ wl_compositor_destroy(compositor_res);
+}
+
+static const struct wl_registry_listener registry_listener = {
+ .global = client_registry_cb_global,
+ .global_remove = client_registry_cb_global_remove
+};
+
+class AppinfoTest : public ::testing::Test
+{
+public:
+ void SetUp(void) override;
+ void TearDown(void) override;
+
+ MockAppinfoCompositor *comp;
+ MockAppinfoClient *client;
+ struct wl_compositor *compositor_res;
+ struct tizen_launch_appinfo *appinfo_res;
+};
+
+void
+AppinfoTest::SetUp(void)
+{
+ ds_inf("%s", __func__);
+
+ comp = new MockAppinfoCompositor();
+ client = new MockAppinfoClient(®istry_listener);
+ compositor_res = client->GetWlCompositor();
+ appinfo_res = client->GetTizenAppinfo();
+
+ client->RoundTrip();
+}
+
+void
+AppinfoTest::TearDown(void)
+{
+ ds_inf("%s", __func__);
+
+ client->RoundTrip();
+
+ delete client;
+ delete comp;
+}
+
+TEST_F(AppinfoTest, Create_P)
+{
+ EXPECT_TRUE(true);
+}
+
+TEST_F(AppinfoTest, Req_TizenAppinfoRegisterPid)
+{
+ uint32_t pid = 1234;
+
+ tizen_launch_appinfo_register_pid(appinfo_res, pid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetPid);
+}
+
+TEST_F(AppinfoTest, Req_TizenAppinfoSetAppid)
+{
+ uint32_t pid = 1234;
+ const char *appid = "org.tizen.libds-tizen-appinfo-test";
+
+ tizen_launch_appinfo_register_pid(appinfo_res, pid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetPid);
+
+ tizen_launch_appinfo_set_appid(appinfo_res, pid, appid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetAppid);
+}
+
+TEST_F(AppinfoTest, Req_TizenAppinfoRegisterAppid)
+{
+ const char *appid = "org.tizen.libds-tizen-appinfo-test";
+
+ tizen_launch_appinfo_register_appid(appinfo_res, appid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetAppid);
+}
+
+TEST_F(AppinfoTest, Req_TizenAppinfoSetPid)
+{
+ uint32_t pid = 1234;
+ const char *appid = "org.tizen.libds-tizen-appinfo-test";
+
+ tizen_launch_appinfo_register_appid(appinfo_res, appid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetAppid);
+
+ tizen_launch_appinfo_set_pid(appinfo_res, appid, pid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetPid);
+}
+
+TEST_F(AppinfoTest, Req_TizenAppinfoMetadataReady)
+{
+ const char *appid = "org.tizen.libds-tizen-appinfo-test";
+ uint32_t pid = 1234;
+
+ tizen_launch_appinfo_register_appid(appinfo_res, appid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetAppid);
+
+ tizen_launch_appinfo_ready_metadata(appinfo_res, appid, pid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bMetadataReady);
+}
+
+TEST_F(AppinfoTest, Req_TizenAppinfoGetBaseOutputResolution)
+{
+ uint32_t pid = 1234;
+
+ tizen_launch_appinfo_register_pid(appinfo_res, pid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetPid);
+
+ tizen_launch_appinfo_get_base_output_resolution(appinfo_res, pid);
+ client->RoundTrip();
+
+ EXPECT_TRUE(client->bBaseOutputResolutionDone);
+ EXPECT_TRUE(client->mBaseOutputResolutionWidth == 1080); //default value
+ EXPECT_TRUE(client->mBaseOutputResolutionHeight == 1920); // default value
+}
+
+TEST_F(AppinfoTest, Ev_TizenAppinfoBaseOutputResolutionDone)
+{
+ uint32_t pid = 1234, width = 1920, height = 1080;
+
+ tizen_launch_appinfo_register_pid(appinfo_res, pid);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSetPid);
+
+ tizen_launch_appinfo_get_base_output_resolution(appinfo_res, pid);
+ client->RoundTrip();
+
+ comp->SendBaseOutputResolutionDone(pid, width, height);
+ comp->Process();
+
+ client->RoundTrip();
+ EXPECT_TRUE(client->bBaseOutputResolutionDone);
+ EXPECT_TRUE(client->mBaseOutputResolutionWidth == 1920);
+ EXPECT_TRUE(client->mBaseOutputResolutionHeight == 1080);
+}