2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "stc-application-lifecycle.h"
22 #define AUL_APP_STATUS_DBUS_PATH "/Org/Tizen/Aul/AppStatus"
23 #define AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE "org.tizen.aul.AppStatus"
24 #define AUL_APP_STATUS_BUS_NAME AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE
26 #define AUL_APP_STATUS_DBUS_LAUNCH_REQUEST "AppLaunch"
27 #define AUL_APP_STATUS_DBUS_LAUNCH_REQUEST_TYPE "(isss)"
29 #define AUL_APP_STATUS_DBUS_STATUS_CHANGE "AppStatusChange"
30 #define AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE "(issss)"
32 #define AUL_APP_STATUS_DBUS_GROUP "AppGroup"
33 #define AUL_APP_STATUS_DBUS_GROUP_TYPE "(iis)"
35 #define AUL_APP_STATUS_DBUS_TERMINATED "AppTerminated"
36 #define AUL_APP_STATUS_DBUS_TERMINATED_TYPE "(i)"
42 STC_CMD_SET_APP_LAUNCHED,
43 STC_CMD_SET_SERVICE_LAUNCHED,
44 STC_CMD_SET_TERMINATED,
51 const gchar *interface;
53 const gchar *param_type;
54 GDBusSignalCallback callback;
58 static stc_error_e __stc_manager_app_status_changed(stc_cmd_type_e cmd,
62 stc_app_type_e app_type)
64 __STC_LOG_FUNC_ENTER__;
65 stc_error_e ret = STC_ERROR_NONE;
68 case STC_CMD_SET_FOREGRD:
70 stc_app_key_s app_key;
71 stc_app_value_s app_value;
72 stc_process_key_s proc_key;
73 stc_process_value_s proc_value;
75 memset(&app_key, 0, sizeof(stc_app_key_s));
76 memset(&app_value, 0, sizeof(stc_app_value_s));
77 memset(&proc_key, 0, sizeof(stc_process_key_s));
78 memset(&proc_value, 0, sizeof(stc_process_value_s));
80 app_key.pkg_id = g_strdup(pkg_id);
81 app_key.app_id = g_strdup(app_id);
83 app_value.type = app_type;
84 app_value.processes = NULL;
88 proc_value.ground = STC_APP_STATE_FOREGROUND;
90 stc_monitor_application_add(app_key, app_value);
91 stc_monitor_process_add(app_key, proc_key, proc_value);
92 stc_monitor_process_update_ground(app_key, proc_key,
93 STC_APP_STATE_FOREGROUND);
99 case STC_CMD_SET_BACKGRD:
101 stc_app_key_s app_key;
102 stc_app_value_s app_value;
103 stc_process_key_s proc_key;
104 stc_process_value_s proc_value;
106 memset(&app_key, 0, sizeof(stc_app_key_s));
107 memset(&app_value, 0, sizeof(stc_app_value_s));
108 memset(&proc_key, 0, sizeof(stc_process_key_s));
109 memset(&proc_value, 0, sizeof(stc_process_value_s));
111 app_key.pkg_id = g_strdup(pkg_id);
112 app_key.app_id = g_strconcat(app_id, STC_BACKGROUND_APP_SUFFIX,
115 app_value.type = app_type;
116 app_value.processes = NULL;
120 proc_value.ground = STC_APP_STATE_BACKGROUND;
122 stc_monitor_application_add(app_key, app_value);
123 stc_monitor_process_add(app_key, proc_key, proc_value);
124 stc_monitor_process_update_ground(app_key, proc_key,
125 STC_APP_STATE_BACKGROUND);
127 FREE(app_key.pkg_id);
128 FREE(app_key.app_id);
131 case STC_CMD_SET_APP_LAUNCHED:
133 stc_app_key_s app_key;
134 stc_app_value_s app_value;
135 stc_process_key_s proc_key;
136 stc_process_value_s proc_value;
138 memset(&app_key, 0, sizeof(stc_app_key_s));
139 memset(&app_value, 0, sizeof(stc_app_value_s));
140 memset(&proc_key, 0, sizeof(stc_process_key_s));
141 memset(&proc_value, 0, sizeof(stc_process_value_s));
143 app_key.pkg_id = g_strdup(pkg_id);
144 app_key.app_id = g_strdup(app_id);
146 app_value.type = app_type;
147 app_value.processes = NULL;
151 proc_value.ground = STC_APP_STATE_UNKNOWN;
153 /* create foreground cgroup */
154 stc_monitor_application_add(app_key, app_value);
155 stc_monitor_process_add(app_key, proc_key, proc_value);
157 /* create background cgroup */
158 FREE(app_key.app_id);
160 app_key.app_id = g_strconcat(app_id, STC_BACKGROUND_APP_SUFFIX,
162 stc_monitor_application_add(app_key, app_value);
164 FREE(app_key.pkg_id);
165 g_free(app_key.app_id);
168 case STC_CMD_SET_SERVICE_LAUNCHED:
170 stc_app_key_s app_key;
171 stc_app_value_s app_value;
172 stc_process_key_s proc_key;
173 stc_process_value_s proc_value;
175 memset(&app_key, 0, sizeof(stc_app_key_s));
176 memset(&app_value, 0, sizeof(stc_app_value_s));
177 memset(&proc_key, 0, sizeof(stc_process_key_s));
178 memset(&proc_value, 0, sizeof(stc_process_value_s));
180 app_key.pkg_id = g_strdup(pkg_id);
181 app_key.app_id = g_strconcat(app_id, STC_BACKGROUND_APP_SUFFIX,
184 app_value.type = app_type;
185 app_value.processes = NULL;
189 /* services will run always in background. */
190 proc_value.ground = STC_APP_STATE_BACKGROUND;
192 stc_monitor_application_add(app_key, app_value);
193 stc_monitor_process_add(app_key, proc_key, proc_value);
195 FREE(app_key.pkg_id);
196 g_free(app_key.app_id);
199 case STC_CMD_SET_TERMINATED:
201 stc_monitor_process_remove(pid);
205 STC_LOGE("Unhandled command");
206 ret = STC_ERROR_INVALID_PARAMETER;
209 __STC_LOG_FUNC_EXIT__;
213 static void __stc_gdbus_handle_aul_launch(GDBusConnection *connection,
214 const gchar *sender_name,
215 const gchar *object_path,
216 const gchar *interface_name,
217 const gchar *signal_name,
218 GVariant *parameters,
221 __STC_LOG_FUNC_ENTER__;
223 stc_cmd_type_e status;
224 stc_app_type_e apptype;
225 gchar *appid, *pkgid, *pkgtype;
227 RETURN_IF_DBUS_TYPE_MISMATCH(parameters,
228 AUL_APP_STATUS_DBUS_LAUNCH_REQUEST_TYPE);
230 g_variant_get(parameters, AUL_APP_STATUS_DBUS_LAUNCH_REQUEST_TYPE,
231 &pid, &appid, &pkgid, &pkgtype);
233 if (!strncmp(pkgtype, "svc", 3)) {
234 apptype = STC_APP_TYPE_SERVICE;
235 status = STC_CMD_SET_SERVICE_LAUNCHED;
237 } else if (!strncmp(pkgtype, "ui", 2)) {
238 apptype = STC_APP_TYPE_GUI;
239 status = STC_CMD_SET_APP_LAUNCHED;
241 } else if (!strncmp(pkgtype, "widget", 6)) {
242 apptype = STC_APP_TYPE_WIDGET;
243 status = STC_CMD_SET_APP_LAUNCHED;
245 } else if (!strncmp(pkgtype, "watch", 5)) {
246 apptype = STC_APP_TYPE_WATCH;
247 status = STC_CMD_SET_APP_LAUNCHED;
250 __STC_LOG_FUNC_EXIT__;
254 __stc_manager_app_status_changed(status, pid, appid, pkgid, apptype);
256 __STC_LOG_FUNC_EXIT__;
263 static void __stc_gdbus_handle_aul_changestate(GDBusConnection *connection,
264 const gchar *sender_name,
265 const gchar *object_path,
266 const gchar *interface_name,
267 const gchar *signal_name,
268 GVariant *parameters,
271 __STC_LOG_FUNC_ENTER__;
273 stc_cmd_type_e status;
274 stc_app_type_e apptype;
275 gchar *appid, *pkgid, *statstr, *pkgtype;
277 RETURN_IF_DBUS_TYPE_MISMATCH(parameters,
278 AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE);
280 g_variant_get(parameters, AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE,
281 &pid, &appid, &pkgid, &statstr, &pkgtype);
283 if (!strncmp(statstr, "fg", 2)) {
284 status = STC_CMD_SET_FOREGRD;
285 } else if (!strncmp(statstr, "bg", 2)) {
286 status = STC_CMD_SET_BACKGRD;
288 __STC_LOG_FUNC_EXIT__;
292 if (!strncmp(pkgtype, "svc", 3))
293 apptype = STC_APP_TYPE_SERVICE;
294 else if (!strncmp(pkgtype, "widget", 6))
295 apptype = STC_APP_TYPE_WIDGET;
296 else if (!strncmp(pkgtype, "watch", 5))
297 apptype = STC_APP_TYPE_WATCH;
299 apptype = STC_APP_TYPE_GUI;
301 __stc_manager_app_status_changed(status, pid, appid, pkgid, apptype);
303 __STC_LOG_FUNC_EXIT__;
311 static void __stc_gdbus_handle_aul_group(GDBusConnection *connection,
312 const gchar *sender_name,
313 const gchar *object_path,
314 const gchar *interface_name,
315 const gchar *signal_name,
316 GVariant *parameters,
319 __STC_LOG_FUNC_ENTER__;
320 pid_t ownerpid, childpid;
323 RETURN_IF_DBUS_TYPE_MISMATCH(parameters,
324 AUL_APP_STATUS_DBUS_GROUP_TYPE);
326 g_variant_get(parameters, AUL_APP_STATUS_DBUS_GROUP_TYPE,
327 &ownerpid, &childpid, &appid);
329 if (ownerpid == childpid) {
330 STC_LOGD("Skip merge, when one app %d makes multiple window.",
332 __STC_LOG_FUNC_EXIT__;
336 STC_LOGD("received process grouping : owner %d, child %d, previous appid %s",
337 ownerpid, childpid, appid);
340 * TODO: app_set_group(ownerpid, childpid, appid)
343 __STC_LOG_FUNC_EXIT__;
348 static void __stc_gdbus_handle_aul_terminated(GDBusConnection *connection,
349 const gchar *sender_name,
350 const gchar *object_path,
351 const gchar *interface_name,
352 const gchar *signal_name,
353 GVariant *parameters,
356 __STC_LOG_FUNC_ENTER__;
358 stc_cmd_type_e status = STC_CMD_SET_TERMINATED;
360 RETURN_IF_DBUS_TYPE_MISMATCH(parameters,
361 AUL_APP_STATUS_DBUS_TERMINATED_TYPE);
363 g_variant_get(parameters, AUL_APP_STATUS_DBUS_TERMINATED_TYPE,
366 __stc_manager_app_status_changed(status, pid, NULL, NULL,
369 __STC_LOG_FUNC_EXIT__;
372 signal_map_s signal_map[] = {
377 AUL_APP_STATUS_DBUS_PATH,
378 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
379 AUL_APP_STATUS_DBUS_LAUNCH_REQUEST,
380 AUL_APP_STATUS_DBUS_LAUNCH_REQUEST_TYPE,
381 __stc_gdbus_handle_aul_launch,
386 AUL_APP_STATUS_DBUS_PATH,
387 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
388 AUL_APP_STATUS_DBUS_STATUS_CHANGE,
389 AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE,
390 __stc_gdbus_handle_aul_changestate,
395 AUL_APP_STATUS_DBUS_PATH,
396 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
397 AUL_APP_STATUS_DBUS_GROUP,
398 AUL_APP_STATUS_DBUS_GROUP_TYPE,
399 __stc_gdbus_handle_aul_group,
404 AUL_APP_STATUS_DBUS_PATH,
405 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
406 AUL_APP_STATUS_DBUS_TERMINATED,
407 AUL_APP_STATUS_DBUS_TERMINATED_TYPE,
408 __stc_gdbus_handle_aul_terminated,
420 stc_error_e stc_application_lifecycle_monitor_init(stc_s *stc)
423 ret_value_msg_if(stc == NULL, STC_ERROR_INVALID_PARAMETER, "failed to get stc data");
425 for (i = 0; signal_map[i].member != NULL; i++) {
426 signal_map[i].sub_id =
427 stc_manager_gdbus_subscribe_signal(stc->connection,
429 signal_map[i].interface,
430 signal_map[i].member,
433 G_DBUS_SIGNAL_FLAGS_NONE,
434 signal_map[i].callback,
435 signal_map[i].user_data,
437 STC_LOGI("Successfully subscribed [%s] signal",
438 signal_map[i].member);
441 return STC_ERROR_NONE;
444 stc_error_e stc_application_lifecycle_monitor_deinit(stc_s *stc)
447 ret_value_msg_if(stc == NULL, STC_ERROR_INVALID_PARAMETER, "failed to get stc data");
449 for (i = 0; signal_map[i].member != NULL; i++) {
450 stc_manager_gdbus_unsubscribe_signal(stc->connection,
451 signal_map[i].sub_id);
452 signal_map[i].sub_id = 0;
453 STC_LOGD("Successfully unsubscribed [%s] signal",
454 signal_map[i].member);
457 return STC_ERROR_NONE;