Add screen connector trigger focus 58/226458/2
authorDaehyeon Jung <darrenh.jung@samsung.com>
Tue, 3 Mar 2020 03:43:51 +0000 (12:43 +0900)
committerDaehyeon Jung <darrenh.jung@samsung.com>
Thu, 5 Mar 2020 04:06:05 +0000 (13:06 +0900)
Change-Id: I98cd8e7d26a53e8f39866592b17fd1ff62ffaa3a
Signed-off-by: Daehyeon Jung <darrenh.jung@samsung.com>
modules/ui-core/src/amd_screen_connector.c

index aa1949e510873eaf81f2d26ecf1b526f9fa301e4..b992846f03fe0aeff5bb8a697f718be73f3abe42 100644 (file)
@@ -58,6 +58,7 @@ struct viewer_info_s {
 
 struct user_info_s {
        uid_t uid;
+       struct app_screen_s *last_focused_app_screen;
        GList *screen_viewer_list;
        GList *app_screen_list;
 };
@@ -211,6 +212,7 @@ static struct user_info_s *__create_user_info(uid_t uid)
        user_info->uid = uid;
        user_info->screen_viewer_list = NULL;
        user_info->app_screen_list = NULL;
+       user_info->last_focused_app_screen = NULL;
 
        return user_info;
 }
@@ -296,6 +298,20 @@ static void __send_app_screen_updated(gpointer data, gpointer user_data)
        __send_app_screen_event(viewer_info, app_screen, "update_screen");
 }
 
+static void __send_app_screen_focused(gpointer data, gpointer user_data)
+{
+       struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
+       struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
+
+       if (viewer_info->pid == app_screen->pid)
+               return;
+       if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
+               return;
+       if (!(viewer_info->screen_type & app_screen->screen_type))
+               return;
+       __send_app_screen_event(viewer_info, app_screen, "focus_screen");
+}
+
 static gint __compare_app_screen_instance_id(gconstpointer a, gconstpointer b)
 {
        struct app_screen_s *app_screen = (struct app_screen_s *)a;
@@ -754,6 +770,9 @@ static int __screen_connector_remove_app_screen(int pid,
        user_info->app_screen_list = g_list_remove(user_info->app_screen_list,
                        app_screen);
        __destroy_app_screen(app_screen);
+       if (user_info->last_focused_app_screen == app_screen)
+               user_info->last_focused_app_screen = NULL;
+
        LOGD("pid(%d), instance_id(%s)", pid, instance_id);
 
        return 0;
@@ -831,6 +850,63 @@ static int __screen_connector_update_app_screen(int pid, unsigned int surf,
        return 0;
 }
 
+static int __screen_connector_focus_app_screen(int pid, unsigned int surf,
+               uid_t uid)
+{
+       amd_app_status_h app_status;
+       app_group_h app_group;
+       struct user_info_s *user_info;
+       struct app_screen_s *app_screen;
+       const char *appid;
+       const char *instance_id;
+       int leader_pid;
+       int effective_pid;
+       GList *found;
+
+       user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+       if (user_info == NULL)
+               return -1;
+
+       effective_pid = _status_get_effective_pid(pid);
+       if (effective_pid < 0)
+               return -1;
+
+       app_group = __find_app_group_by_pid(effective_pid);
+       leader_pid = _app_group_get_leader_pid(app_group);
+       if (leader_pid > 0)
+               pid = leader_pid;
+       else
+               pid = effective_pid;
+
+       app_status = amd_app_status_find_by_pid(pid);
+       if (app_status == NULL) {
+               LOGW("Failed to find app status info - pid(%d), uid(%d)",
+                               pid, uid);
+               return -1;
+       }
+
+       if (amd_app_status_is_home_app(app_status))
+               return 0;
+
+       appid = amd_app_status_get_appid(app_status);
+       instance_id = amd_app_status_get_instance_id(app_status);
+
+       found = g_list_find_custom(user_info->app_screen_list, instance_id,
+                       __compare_instance_id);
+       if (found == NULL)
+               return -1;
+
+       app_screen = (struct app_screen_s *)found->data;
+
+       user_info->last_focused_app_screen = app_screen;
+
+       g_list_foreach(user_info->screen_viewer_list,
+                       __send_app_screen_focused, app_screen);
+       LOGD("focus pid(%d), appid(%s), surf(%d), uid(%d)", pid, appid, surf, uid);
+
+       return 0;
+}
+
 static int __screen_connector_remove_app_screen_v2(int pid, uid_t uid)
 {
        struct user_info_s *user_info;
@@ -853,6 +929,8 @@ static int __screen_connector_remove_app_screen_v2(int pid, uid_t uid)
                                        user_info->app_screen_list,
                                        app_screen);
                        __destroy_app_screen(app_screen);
+                       if (user_info->last_focused_app_screen == app_screen)
+                               user_info->last_focused_app_screen = NULL;
                }
        }
 
@@ -1248,6 +1326,36 @@ static int __dispatch_app_get_instance_id_by_surface_id(amd_request_h req)
        return 0;
 }
 
+static int __dispatch_trigger_focused_force(amd_request_h req)
+{
+       uid_t uid = amd_request_get_target_uid(req);
+       int pid = amd_request_get_pid(req);
+       struct user_info_s *user_info;
+       struct viewer_info_s *viewer_info;
+       GList *found;
+
+       user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+       if (user_info == NULL)
+               return -1;
+
+       if (user_info->last_focused_app_screen == NULL) {
+               LOGE("requested bad focused screen");
+               return -1;
+       }
+
+       found = g_list_find_custom(user_info->screen_viewer_list,
+                       GINT_TO_POINTER(pid), __compare_viewer_pid);
+       if (found == NULL)
+               return -1;
+
+       viewer_info = (struct viewer_info_s *)found->data;
+
+       __send_app_screen_event(viewer_info,
+               user_info->last_focused_app_screen, "focus_screen");
+
+       return 0;
+}
+
 static int __dispatch_update_screen_viewer_status(amd_request_h req)
 {
        uid_t uid = amd_request_get_target_uid(req);
@@ -1321,6 +1429,10 @@ static amd_request_cmd_dispatch __dispatch_table[] = {
                .cmd = UPDATE_SCREEN_VIEWER_STATUS,
                .callback = __dispatch_update_screen_viewer_status
        },
+       {
+               .cmd = TRIGGER_APP_SCREEN_FOCUSED_FORCE,
+               .callback = __dispatch_trigger_focused_force
+       },
 };
 
 static amd_cynara_checker __cynara_checkers[] = {
@@ -1339,6 +1451,11 @@ static amd_cynara_checker __cynara_checkers[] = {
                .checker = amd_cynara_simple_checker,
                .data = PRIVILEGE_PLATFORM
        },
+       {
+               .cmd = TRIGGER_APP_SCREEN_FOCUSED_FORCE,
+               .checker = __screen_connector_checker,
+               .data = NULL
+       }
 };
 
 static int __on_launch_status(const char *msg, int arg1, int arg2,
@@ -1355,6 +1472,18 @@ static int __on_launch_status(const char *msg, int arg1, int arg2,
        return 0;
 }
 
+static int __on_focus_status(const char *msg, int arg1, int arg2,
+               void *arg3, bundle *data) {
+       int pid = arg1;
+       uid_t uid = arg2;
+       app_group_node_h node = __find_app_group_node_by_pid(pid);
+       unsigned int surf = _app_group_node_get_window(node);
+
+       __screen_connector_focus_app_screen(pid, surf, uid);
+
+       return 0;
+}
+
 static int __on_app_status_end(const char *msg, int arg1, int arg2,
                void *arg3, bundle *data)
 {
@@ -1460,6 +1589,8 @@ int _screen_connector_init(void)
                        __on_launch_status);
        amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS,
                        __on_launch_status);
+       amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS,
+                       __on_focus_status);
        amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END,
                        __on_app_status_end);
        amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,