16242173f521c49b3f0d889202dc030b1cb5925f
[apps/native/starter.git] / src / process_mgr.c
1 /*
2  * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
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 <vconf.h>
18 #include <aul.h>
19 #include <Ecore.h>
20 #include <syspopup_caller.h>
21 #include <sys/time.h>
22 #include <sys/resource.h>
23 #include <bundle_internal.h>
24
25 #include "process_mgr.h"
26 #include "util.h"
27 #include "dbus_util.h"
28
29 #define LOCKD_VOICE_CALL_PKG_NAME "org.tizen.call-ui"
30 #define LOCKD_VIDEO_CALL_PKG_NAME "org.tizen.vtmain"
31
32 #define NICE_VALUE_PWLOCK -5
33 #define NICE_VALUE_LOCKSCREEN -20
34
35
36
37 typedef struct _launch_info_s {
38         char *appid;
39         char *key;
40         char *value;
41         after_func afn;
42         change_func cfn;
43 } launch_info_s;
44
45
46
47 static int _try_to_launch(const char *appid, const char *key, const char *value, after_func afn)
48 {
49         int pid = -1;
50         bundle *b = NULL;
51
52         retv_if(!appid, -1);
53
54         if (key) {
55                 b = bundle_create();
56                 if (!b) {
57                         _E("Failed to create a bundle");
58                         return -1;
59                 }
60                 bundle_add(b, key, value);
61         }
62
63         pid = aul_launch_app(appid, b);
64         if (b) bundle_free(b);
65         if (pid > 0) {
66                 _D("Succeed to launch %s", appid);
67                 if (afn) afn(pid);
68         }
69
70         return pid;
71 }
72
73
74
75 static Eina_Bool _must_launch_cb(void *data)
76 {
77         launch_info_s *launch_info = data;
78         int pid;
79
80         retv_if(!launch_info, ECORE_CALLBACK_CANCEL);
81
82         pid = _try_to_launch(launch_info->appid, launch_info->key, launch_info->value, launch_info->afn);
83         if (pid > 0) {
84                 goto OUT;
85         }
86
87         retv_if(pid == AUL_R_ECOMM, ECORE_CALLBACK_RENEW);
88         retv_if(pid == AUL_R_ETERMINATING, ECORE_CALLBACK_RENEW);
89         if (pid == AUL_R_ERROR) {
90                 if (launch_info->cfn
91                         && 0 == launch_info->cfn(launch_info->appid, launch_info->key, launch_info->value, (void *) launch_info->cfn, (void *) launch_info->afn))
92                 {
93                         _D("change func has set the next appid");
94                 } else {
95                         _E("change func has returned error");
96                 }
97                 goto OUT;
98         }
99
100         return ECORE_CALLBACK_RENEW;
101
102 OUT:
103         free(launch_info->appid);
104         free(launch_info->key);
105         free(launch_info->value);
106         free(launch_info);
107         return ECORE_CALLBACK_CANCEL;
108 }
109
110
111
112 void process_mgr_must_launch(const char *appid, const char *key, const char *value, change_func cfn, after_func afn)
113 {
114         Ecore_Timer *timer = NULL;
115         launch_info_s *launch_info = NULL;
116         int pid = -1;
117
118         _D("Must launch %s", appid);
119
120         pid = _try_to_launch(appid, key, value, afn);
121         if (pid > 0) return;
122
123         _E("Failed the first try to launch %s", appid);
124
125         launch_info = calloc(1, sizeof(launch_info_s));
126         ret_if(!launch_info);
127
128         if (appid) launch_info->appid = strdup(appid);
129         if (key) launch_info->key = strdup(key);
130         if (value) launch_info->value = strdup(value);
131         launch_info->cfn = cfn;
132         launch_info->afn = afn;
133
134         timer = ecore_timer_add(0.1f, _must_launch_cb, launch_info);
135         if (!timer) {
136                 _E("cannot add a timer for must_launch");
137                 free(launch_info->appid);
138                 free(launch_info->key);
139                 free(launch_info->value);
140                 free(launch_info);
141         }
142 }
143
144
145
146 static int _try_to_open(const char *appid, after_func afn)
147 {
148         int pid = -1;
149
150         retv_if(!appid, -1);
151
152         pid = aul_open_app(appid);
153         if (pid > 0) {
154                 _D("Succeed to open %s", appid);
155                 if (afn) afn(pid);
156         }
157
158         return pid;
159 }
160
161
162
163 static Eina_Bool _must_open_cb(void *data)
164 {
165         launch_info_s *launch_info = data;
166         int pid;
167
168         retv_if(!launch_info, ECORE_CALLBACK_CANCEL);
169
170         pid = _try_to_open(launch_info->appid, launch_info->afn);
171         if (pid > 0) {
172                 goto OUT;
173         }
174
175         retv_if(pid == AUL_R_ECOMM, ECORE_CALLBACK_RENEW);
176         retv_if(pid == AUL_R_ETERMINATING, ECORE_CALLBACK_RENEW);
177         if (pid == AUL_R_ERROR) {
178                 if (launch_info->cfn && 0 == launch_info->cfn(launch_info->appid, NULL, NULL, launch_info->cfn, launch_info->afn)) {
179                         _D("change func has set the next appid");
180                 } else {
181                         _E("change func has returned error");
182                 }
183                 goto OUT;
184         }
185
186         return ECORE_CALLBACK_RENEW;
187
188 OUT:
189         free(launch_info->appid);
190         free(launch_info);
191         return ECORE_CALLBACK_CANCEL;
192 }
193
194
195
196 void process_mgr_must_open(const char *appid, change_func cfn, after_func afn)
197 {
198         Ecore_Timer *timer = NULL;
199         launch_info_s *launch_info = NULL;
200         int pid = -1;
201
202         _D("Must open %s", appid);
203
204         pid = _try_to_open(appid, afn);
205         if (pid > 0) return;
206
207         _E("Failed the first try to open %s", appid);
208
209         launch_info = calloc(1, sizeof(launch_info_s));
210         ret_if(!launch_info);
211
212         if (appid) launch_info->appid = strdup(appid);
213         launch_info->cfn = cfn;
214         launch_info->afn = afn;
215
216         timer = ecore_timer_add(0.1f, _must_open_cb, launch_info);
217         if (!timer) {
218                 _E("cannot add a timer for must_launch");
219                 free(launch_info->appid);
220                 free(launch_info);
221         }
222 }
223
224
225
226 static int _try_to_syspopup_launch(const char *appid, const char *key, const char *value, after_func afn)
227 {
228         int pid = -1;
229         bundle *b = NULL;
230
231         retv_if(!appid, -1);
232
233         if (key) {
234                 b = bundle_create();
235                 bundle_add(b, key, value);
236         }
237
238         pid = aul_launch_app("org.tizen.volume", b);
239         if (b) bundle_free(b);
240         if (pid > 0) {
241                 _D("Succeed to launch %s", appid);
242                 if (afn) afn(pid);
243         }
244
245         return pid;
246 }
247
248
249
250 static Eina_Bool _must_syspopup_launch_cb(void *data)
251 {
252         launch_info_s *launch_info = data;
253         int pid;
254
255         retv_if(!launch_info, ECORE_CALLBACK_CANCEL);
256
257         pid = _try_to_syspopup_launch(launch_info->appid, launch_info->key, launch_info->value, launch_info->afn);
258         if (pid > 0) {
259                 goto OUT;
260         }
261
262         retv_if(pid == AUL_R_ECOMM, ECORE_CALLBACK_RENEW);
263         retv_if(pid == AUL_R_ETERMINATING, ECORE_CALLBACK_RENEW);
264         if (pid == AUL_R_ERROR) {
265                 if (launch_info->cfn
266                         && 0 == launch_info->cfn(launch_info->appid, launch_info->key, launch_info->value, launch_info->cfn, launch_info->afn)) {
267                         _D("change func has set the next appid");
268                 } else {
269                         _E("change func has returned error");
270                 }
271                 goto OUT;
272         }
273
274         return ECORE_CALLBACK_RENEW;
275
276 OUT:
277         free(launch_info->appid);
278         free(launch_info->key);
279         free(launch_info->value);
280         free(launch_info);
281         return ECORE_CALLBACK_CANCEL;
282 }
283
284
285
286 void process_mgr_must_syspopup_launch(const char *appid, const char *key, const char *value, change_func cfn, after_func afn)
287 {
288         Ecore_Timer *timer = NULL;
289         launch_info_s *launch_info = NULL;
290         int pid = -1;
291
292         _D("Must launch %s", appid);
293
294         pid = _try_to_syspopup_launch(appid, key, value, afn);
295         if (pid > 0) return;
296
297         _E("Failed the first try to launch %s", appid);
298
299         launch_info = calloc(1, sizeof(launch_info_s));
300         ret_if(!launch_info);
301
302         if (appid) launch_info->appid = strdup(appid);
303         if (key) launch_info->key = strdup(key);
304         if (value) launch_info->value = strdup(value);
305         launch_info->cfn = cfn;
306         launch_info->afn = afn;
307
308         timer = ecore_timer_add(0.1f, _must_syspopup_launch_cb, launch_info);
309         if (!timer) {
310                 _E("cannot add a timer for must_launch");
311                 free(launch_info->appid);
312                 free(launch_info->key);
313                 free(launch_info->value);
314                 free(launch_info);
315         }
316 }
317
318
319
320 static Eina_Bool _set_lock_priority_cb(void *data)
321 {
322         int prio;
323
324         prio = getpriority(PRIO_PROCESS, (pid_t)data);
325         if (prio == NICE_VALUE_LOCKSCREEN) {
326                 _D("%s (%d: %d)\n", "setpriority Success", (pid_t)data, prio);
327                 return ECORE_CALLBACK_CANCEL;
328         }
329
330         if (setpriority(PRIO_PROCESS, (pid_t)data, NICE_VALUE_LOCKSCREEN) < 0 ) {
331                 _D("error : %d", errno);
332                 return ECORE_CALLBACK_CANCEL;
333         }
334
335         return ECORE_CALLBACK_RENEW;
336 }
337
338
339
340 static Eina_Bool _set_pwlock_priority_cb(void *data)
341 {
342         int prio;
343
344         prio = getpriority(PRIO_PROCESS, (pid_t)data);
345         if (prio == NICE_VALUE_PWLOCK) {
346                 _D("%s (%d: %d)\n", "setpriority Success", (pid_t)data, prio);
347                 return ECORE_CALLBACK_CANCEL;
348         }
349
350         if (setpriority(PRIO_PROCESS, (pid_t)data, NICE_VALUE_PWLOCK) < 0 ) {
351                 _D("error : %d", errno);
352                 return ECORE_CALLBACK_CANCEL;
353         }
354
355         return ECORE_CALLBACK_RENEW;
356 }
357
358
359
360 int process_mgr_set_lock_priority(int pid)
361 {
362         return !ecore_timer_add(1.0f, _set_lock_priority_cb, (void *)pid);
363 }
364
365
366
367 int process_mgr_set_pwlock_priority(int pid)
368 {
369         return !ecore_timer_add(1.0f, _set_pwlock_priority_cb, (void *)pid);
370 }
371
372
373
374 void process_mgr_terminate_app(int pid, int state)
375 {
376         _D("process_mgr_terminate_app,  state:%d\n", state);
377
378         if (state == 1) {
379                 if (pid != 0) {
380                         _D("Terminate Lock app(pid : %d)", pid);
381                         aul_terminate_pid(pid);
382                 }
383         }
384 }
385
386
387
388 extern int aul_kill_pid(int pid);
389 void process_mgr_kill_app(int pid)
390 {
391         _D ("process_mgr_kill_app [pid:%d]..", pid);
392         aul_kill_pid(pid);
393 }
394
395
396
397 int process_mgr_validate_app(int pid)
398 {
399         char buf[BUF_SIZE_128] = {0, };
400
401         /* Check pid is invalid. */
402         if (aul_app_get_pkgname_bypid(pid, buf, sizeof(buf)) < 0) {
403                 _D("no such pkg by pid %d\n", pid);
404         } else {
405                 _SECURE_D("appid = %s, pid = %d\n", buf, pid);
406                 if (aul_app_is_running(buf) == TRUE) {
407                         _D("%s [pid = %d] is running\n", buf, pid);
408                         return TRUE;
409                 } else {
410                         _SECURE_D("[pid = %d] is exist but %s is not running\n", pid, buf);
411                 }
412         }
413
414         return FALSE;
415 }
416
417
418
419 int process_mgr_validate_call(int pid)
420 {
421         char buf[BUF_SIZE_128] = {0, };
422
423         /* Check pid is invalid. */
424         if (aul_app_get_pkgname_bypid(pid, buf, sizeof(buf)) < 0) {
425                 _D("no such pkg by pid %d", pid);
426         } else {
427                 _SECURE_D("appid = %s, pid = %d", buf, pid);
428                 if ((!strncmp(buf, LOCKD_VOICE_CALL_PKG_NAME, strlen(buf)))
429                     || (!strncmp(buf, LOCKD_VIDEO_CALL_PKG_NAME, strlen(buf)))) {
430                     return TRUE;
431                 }
432         }
433
434         return FALSE;
435 }
436
437
438