add storage class specifier(static)
[platform/core/connectivity/stc-manager.git] / plugin / appstatus / stcplugin-appstatus.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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 #include <errno.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <syspopup_caller.h>
22 #include <bundle.h>
23 #include <bundle_internal.h>
24 #include <dlog.h>
25 #include <gio/gio.h>
26
27 #include "stc-plugin-iface-appstatus.h"
28
29 //LCOV_EXCL_START
30 #define AUL_APP_STATUS_DBUS_PATH                   "/Org/Tizen/Aul/AppStatus"
31 #define AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE       "org.tizen.aul.AppStatus"
32 #define AUL_APP_STATUS_BUS_NAME                    AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE
33
34 #define AUL_APP_STATUS_DBUS_LAUNCH_REQUEST         "AppLaunch"
35 #define AUL_APP_STATUS_DBUS_LAUNCH_REQUEST_TYPE    "(isss)"
36 #define AUL_APP_STATUS_DBUS_TERMINATE_REQUEST      "AppTerminate"
37 #define AUL_APP_STATUS_DBUS_TERMINATE_REQUEST_TYPE "(isss)"
38 #define AUL_APP_STATUS_DBUS_STATUS_CHANGE          "AppStatusChange"
39 #define AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE     "(issss)"
40
41 typedef struct {
42         guint sub_id;
43         const gchar *path;
44         const gchar *interface;
45         const gchar *member;
46         const gchar *param_type;
47         GDBusSignalCallback callback;
48         gpointer user_data;
49 } signal_map_s;
50
51 stc_error_e(*state_changed_cb)(stc_cmd_type_e cmd, pid_t pid,
52                                const gchar *app_id, const gchar *pkg_id,
53                                stc_app_type_e app_type);
54
55 static void __stc_gdbus_handle_aul_changestate(GDBusConnection *connection,
56                                                const gchar *sender_name,
57                                                const gchar *object_path,
58                                                const gchar *interface_name,
59                                                const gchar *signal_name,
60                                                GVariant *parameters,
61                                                gpointer user_data)
62 {
63         pid_t pid;
64         stc_cmd_type_e status;
65         stc_app_type_e apptype;
66         gchar *appid = NULL;
67         gchar *pkgid = NULL;
68         gchar *statstr = NULL;
69         gchar *pkgtype = NULL;
70
71         if (g_strcmp0(signal_name, AUL_APP_STATUS_DBUS_LAUNCH_REQUEST) == 0) {
72                 if (g_strcmp0(g_variant_get_type_string(parameters),
73                               AUL_APP_STATUS_DBUS_LAUNCH_REQUEST_TYPE)) {
74                         STC_LOGE("Dbus type not matching, do not process");
75                         return;
76                 }
77
78                 g_variant_get(parameters, AUL_APP_STATUS_DBUS_LAUNCH_REQUEST_TYPE,
79                         &pid, &appid, &pkgid, &pkgtype);
80
81                 status = STC_CMD_SET_APP_LAUNCHED;
82
83                 if (!strncmp(pkgtype, "svc", 3))
84                         apptype = STC_APP_TYPE_SERVICE;
85                 else if (!strncmp(pkgtype, "widget", 6))
86                         apptype = STC_APP_TYPE_WIDGET;
87                 else if (!strncmp(pkgtype, "watch", 5))
88                         apptype = STC_APP_TYPE_WATCH;
89                 else
90                         apptype = STC_APP_TYPE_GUI;
91
92                 if (STC_STAT_LOG) {
93                         STC_LOGD("APP STATUS[\033[1;34mlaunch\033[0;m] PkgID[\033[0;34m%s\033[0;m] "
94                                 "AppID[\033[0;32m%s\033[0;m] PID[\033[1;33m%d\033[0;m] Type[%s]",
95                                 pkgid, appid, pid, pkgtype);
96                 }
97
98                 if (state_changed_cb)
99                         state_changed_cb(status, pid, appid, pkgid, apptype);
100         } else if (g_strcmp0(signal_name, AUL_APP_STATUS_DBUS_TERMINATE_REQUEST) == 0) {
101                 if (g_strcmp0(g_variant_get_type_string(parameters),
102                               AUL_APP_STATUS_DBUS_TERMINATE_REQUEST_TYPE)) {
103                         STC_LOGE("Dbus type not matching, do not process");
104                         return;
105                 }
106
107                 g_variant_get(parameters, AUL_APP_STATUS_DBUS_TERMINATE_REQUEST_TYPE,
108                         &pid, &appid, &pkgid, &pkgtype);
109
110                 status = STC_CMD_SET_TERMINATED;
111
112                 if (!strncmp(pkgtype, "svc", 3))
113                         apptype = STC_APP_TYPE_SERVICE;
114                 else if (!strncmp(pkgtype, "widget", 6))
115                         apptype = STC_APP_TYPE_WIDGET;
116                 else if (!strncmp(pkgtype, "watch", 5))
117                         apptype = STC_APP_TYPE_WATCH;
118                 else
119                         apptype = STC_APP_TYPE_GUI;
120
121                 if (STC_STAT_LOG) {
122                         STC_LOGD("APP STATUS[\033[1;34mterminate\033[0;m] PkgID[\033[0;34m%s\033[0;m] "
123                                 "AppID[\033[0;32m%s\033[0;m] PID[\033[1;33m%d\033[0;m] Type[%s]",
124                                 pkgid, appid, pid, pkgtype);
125                 }
126
127                 if (state_changed_cb)
128                         state_changed_cb(status, pid, appid, pkgid, apptype);
129         } else if (g_strcmp0(signal_name, AUL_APP_STATUS_DBUS_STATUS_CHANGE) == 0) {
130                 if (g_strcmp0(g_variant_get_type_string(parameters),
131                               AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE)) {
132                         STC_LOGE("Dbus type not matching, do not process");
133                         return;
134                 }
135
136                 g_variant_get(parameters, AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE,
137                       &pid, &appid, &pkgid, &statstr, &pkgtype);
138
139                 if (!strncmp(statstr, "fg", 2)) {
140                         status = STC_CMD_SET_FOREGRD;
141                 } else if (!strncmp(statstr, "bg", 2)) {
142                         status = STC_CMD_SET_BACKGRD;
143                 } else {
144                         goto out;
145                 }
146
147                 if (!strncmp(pkgtype, "svc", 3))
148                         apptype = STC_APP_TYPE_SERVICE;
149                 else if (!strncmp(pkgtype, "widget", 6))
150                         apptype = STC_APP_TYPE_WIDGET;
151                 else if (!strncmp(pkgtype, "watch", 5))
152                         apptype = STC_APP_TYPE_WATCH;
153                 else
154                         apptype = STC_APP_TYPE_GUI;
155
156                 if (STC_STAT_LOG) {
157                         STC_LOGD("APP STATUS[\033[1;34m%s\033[0;m] PkgID[\033[0;34m%s\033[0;m] "
158                                 "AppID[\033[0;32m%s\033[0;m] PID[\033[1;33m%d\033[0;m] Type[%s]",
159                                 (status == STC_CMD_SET_FOREGRD) ? "Foregrd" : "Backgrd", pkgid, appid, pid, pkgtype);
160                 }
161
162                 if (state_changed_cb)
163                         state_changed_cb(status, pid, appid, pkgid, apptype);
164         }
165
166 out:
167         FREE(appid);
168         FREE(pkgid);
169         FREE(statstr);
170         FREE(pkgtype);
171 }
172
173 static signal_map_s signal_map[] = {
174
175         /* AMD DBUS */
176         {
177                 0,
178                 AUL_APP_STATUS_DBUS_PATH,
179                 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
180                 AUL_APP_STATUS_DBUS_LAUNCH_REQUEST,
181                 AUL_APP_STATUS_DBUS_LAUNCH_REQUEST_TYPE,
182                 __stc_gdbus_handle_aul_changestate,
183                 NULL
184         },
185         {
186                 0,
187                 AUL_APP_STATUS_DBUS_PATH,
188                 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
189                 AUL_APP_STATUS_DBUS_TERMINATE_REQUEST,
190                 AUL_APP_STATUS_DBUS_TERMINATE_REQUEST_TYPE,
191                 __stc_gdbus_handle_aul_changestate,
192                 NULL
193         },
194         {
195                 0,
196                 AUL_APP_STATUS_DBUS_PATH,
197                 AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE,
198                 AUL_APP_STATUS_DBUS_STATUS_CHANGE,
199                 AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE,
200                 __stc_gdbus_handle_aul_changestate,
201                 NULL
202         },
203         {
204                 0,
205                 NULL,
206                 NULL,
207                 NULL,
208                 NULL
209         }
210 };
211
212 static stc_error_e __ground_status_monitor_init(stc_s *stc)
213 {
214         guint i = 0;
215         guint size = 0;
216
217         ret_value_msg_if(stc == NULL, STC_ERROR_INVALID_PARAMETER, "failed to get stc data");
218
219         size = sizeof(signal_map) / sizeof(signal_map[0]);
220
221         for (i = 0; i < size && signal_map[i].member != NULL; i++) {
222                 signal_map[i].sub_id =
223                         g_dbus_connection_signal_subscribe(stc->connection,
224                                                            NULL,
225                                                            signal_map[i].interface,
226                                                            signal_map[i].member,
227                                                            signal_map[i].path,
228                                                            NULL,
229                                                            G_DBUS_SIGNAL_FLAGS_NONE,
230                                                            signal_map[i].callback,
231                                                            signal_map[i].user_data,
232                                                            NULL);
233                 STC_LOGI("Successfully subscribed [%s] signal",
234                          signal_map[i].member);
235         }
236
237         return STC_ERROR_NONE;
238 }
239
240 static stc_error_e __ground_status_monitor_deinit(stc_s *stc)
241 {
242         guint i = 0;
243         guint size = 0;
244
245         ret_value_msg_if(stc == NULL, STC_ERROR_INVALID_PARAMETER, "failed to get stc data");
246
247         size = sizeof(signal_map) / sizeof(signal_map[0]);
248
249         for (i = 0; i < size && signal_map[i].member != NULL; i++) {
250                 g_dbus_connection_signal_unsubscribe(stc->connection,
251                                                      signal_map[i].sub_id);
252                 signal_map[i].sub_id = 0;
253                 STC_LOGD("Successfully unsubscribed [%s] signal",
254                          signal_map[i].member);
255         }
256
257         return STC_ERROR_NONE;
258 }
259
260 int stc_plugin_appstatus_register_changed_cb(stc_s *stc,
261                                        stc_plugin_app_state_changed_cb cb,
262                                        void *data)
263 {
264         state_changed_cb = cb;
265         __ground_status_monitor_init(stc);
266
267         return 0;
268 }
269
270 int stc_plugin_appstatus_deregister_changed_cb(stc_s *stc)
271 {
272         state_changed_cb = NULL;
273         __ground_status_monitor_deinit(stc);
274         return 0;
275 }
276
277 int stc_plugin_popup_send_message(const char *content,
278                 const char *type, const char *app_id, const char *iftype, const char *limit)
279 {
280         int ret = 0;
281         bundle *b = bundle_create();
282
283         bundle_add(b, "_SYSPOPUP_CONTENT_", content);
284         bundle_add(b, "_SYSPOPUP_TYPE_", type);
285         bundle_add(b, "_APP_ID_", app_id);
286         bundle_add(b, "_IF_TYPE_", iftype);
287
288         if (g_strcmp0(type, "warning_noti") == 0) {
289                 bundle_add(b, "_WARN_LIMIT_", limit);
290                 STC_LOGD("Warn message : content[%s] type[%s] app_id[%s] limit[%s]",
291                         content, type, app_id, limit);
292         } else {
293                 bundle_add(b, "_RESTRICTION_LIMIT_", limit);
294                 STC_LOGD("Restriction message : content[%s] type[%s] app_id[%s] limit[%s]",
295                         content, type, app_id, limit);
296         }
297
298         ret = syspopup_launch("net-popup", b);
299
300         bundle_free(b);
301
302         return ret;
303 }
304
305 API stc_plugin_appstatus_s stc_plugin_appstatus = {
306         .send_message_to_net_popup =
307                 stc_plugin_popup_send_message,
308         .register_state_changed_cb =
309                 stc_plugin_appstatus_register_changed_cb,
310         .deregister_state_changed_cb =
311                 stc_plugin_appstatus_deregister_changed_cb
312 };
313 //LCOV_EXCL_STOP