removed redundant code
[platform/framework/native/appfw.git] / src / app / FApp_Aul.cpp
1 //
2 // Copyright (c) 2012 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 /**
18  * @file         FApp_Aul.cpp
19  * @brief       This is the implementation for the _Aul.cpp class.
20  */
21 #include <cstdio>
22 #include <cstdlib>
23 #include <new>
24 #include <unistd.h>
25 #include <sys/prctl.h>
26 #include <signal.h>
27 #include <unique_ptr.h>
28
29 #include <aul.h>
30 #include <bundle.h>
31 #include <appsvc/appsvc.h>
32 #include <vconf.h>
33 #include <pkgmgr-info.h>
34
35 #include <FBaseObject.h>
36 #include <FBaseString.h>
37 #include <FBaseUtil.h>
38 #include <FBaseSysLog.h>
39 #include <FBaseColHashMapT.h>
40 #include <FAppPkgPackageInfo.h>
41
42 #include <FBaseRt_Process.h>
43 #include <FBase_StringConverter.h>
44 #include "FAppPkg_PackageManagerImpl.h"
45 #include "FApp_Types.h"
46 #include "FApp_Aul.h"
47 #include "FApp_AppArg.h"
48 #include "FApp_TemplateUtil.h"
49
50
51 using namespace Tizen::App::Package;
52 using namespace Tizen::Base;
53 using namespace Tizen::Base::Collection;
54 using namespace Tizen::Base::Runtime;
55 using namespace Tizen::Base::Utility;
56
57 namespace
58 {
59 const int _MAX_CATEGORY = 34;
60
61 // borrowed from app-svc/include/pri_key.h
62 #define APP_SVC_K_RES_VAL       "__APP_SVC_K_RES_VAL__"
63
64 }
65
66 namespace Tizen { namespace App
67 {
68
69 struct _CategoryList
70 {
71         const char category[_MAX_CATEGORY];
72         const _AppType type;
73 };
74
75 static const _CategoryList _CATEGORY_LIST[] =
76 {
77         {"home-screen", _APP_TYPE_HOME_APP},
78         {"lock-screen", _APP_TYPE_LOCK_APP},
79         {"ime", _APP_TYPE_IME_APP},
80         {"http://tizen.org/category/homeapp", _APP_TYPE_HOME_APP},
81         {"http://tizen.org/category/lockapp", _APP_TYPE_LOCK_APP},
82         {"http://tizen.org/category/ime", _APP_TYPE_IME_APP},
83 };
84
85 static const int _NUM_CATEGORY = sizeof(_CATEGORY_LIST) / sizeof(_CategoryList);
86
87 result
88 _Aul::GetConvertedResult(const int aul_ret, const char* pFunctionName)
89 {
90         result r = E_SUCCESS;
91
92         switch (aul_ret)
93         {
94         case AUL_R_EINVAL:
95                 r = E_INVALID_ARG;
96                 SysLogException(NID_APP, r, "%s : Invalid argument.", pFunctionName);
97                 break;
98
99         case AUL_R_ECOMM:
100                 r = E_SYSTEM;
101                 SysLogException(NID_APP, r, "%s : Internal IPC error.", pFunctionName);
102                 break;
103
104         case AUL_R_ERROR:
105                 r = E_SYSTEM;
106                 SysLogException(NID_APP, r, "%s : General error.", pFunctionName);
107                 break;
108
109         default:
110                 SysLog(NID_APP, "%s : successed.", pFunctionName);
111                 break;
112         }
113
114         return r;
115 }
116
117 result
118 _Aul::SendResult(bundle* b, appsvc_result_val res, bool isSubMode, bool isServiceApp)
119 {
120         // to skip error handling, of appsvc_send_result, use aul_send_service_result() directly.
121         //int ret = appsvc_send_result(b, res);
122
123         char tmp[32] = {0, };
124         snprintf(tmp, 32, "%d", static_cast<int>(res));
125         appsvc_add_data(b, APP_SVC_K_RES_VAL, tmp);
126
127         if (isSubMode)
128         {
129                 _AppArg::UpdateSubMode(b);
130         }
131
132         if (isServiceApp)
133         {
134                 _AppArg::UpdateServiceApp(b);
135         }
136
137         const int aul_ret = aul_send_service_result(b);
138
139         result r = GetConvertedResult(aul_ret, "SendResult");
140         if (r == E_INVALID_ARG)
141         {
142                 SysLog(NID_APP, "Converting internal exception to E_MAX_EXCEEDED.");
143                 r = E_MAX_EXCEEDED;
144         }
145         return r;
146 }
147
148
149 bool
150 _Aul::IsRunning(const String& appId)
151 {
152         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(appId));
153
154         const bool isRunning = (aul_app_is_running(pPackageId.get()) > 0);
155
156         SysLog(NID_APP, "'%ls' %s running now.", appId.GetPointer(), (isRunning) ? "is" : "is NOT");
157         return isRunning;
158 }
159
160
161 result
162 _Aul::TerminateApplicationByPid(int pid)
163 {
164         int ret_aul = aul_subapp_terminate_request_pid(pid);
165
166         return GetConvertedResult(ret_aul, "TerminateApplicationByPid");
167 }
168
169 static int
170 TerminateApplicationIterFnCb(const aul_app_info* pAppInfo, void* pData)
171 {
172         const char* pStr = static_cast<const char*>(pData);
173
174         if (pStr && strncmp(pStr, pAppInfo->pkg_name, NATIVE_APP_MAX_APPID_LENGTH) == 0)
175         {
176                 SysLog(NID_APP, "%s(%d) is terminated.", pAppInfo->pkg_name, pAppInfo->pid);
177                 int ret_aul = aul_terminate_pid( pAppInfo->pid );
178                 SetLastResult(_Aul::GetConvertedResult(ret_aul, "TerminateApplication"));
179         }
180         return 0;
181 }
182
183 result
184 _Aul::TerminateApplication(const AppId& appId)
185 {
186         SetLastResult(E_OBJ_NOT_FOUND);
187         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
188         aul_app_get_running_app_info(TerminateApplicationIterFnCb, static_cast<void*>(pAppId.get()));
189
190         SysLog(NID_APP, "%ls terminated.", appId.GetPointer());
191         return GetLastResult();
192 }
193
194 result
195 _Aul::SetOomAdj(int pid, int adj)
196 {
197         // set oom_adj to -17 for system service
198         result r = E_SUCCESS;
199         char buf[FILENAME_MAX];
200         FILE *fP = NULL;
201
202         snprintf(buf, FILENAME_MAX, "/proc/%d/oom_adj", pid);
203         fP = fopen(buf, "w");
204         SysTryReturnResult(NID_APP, fP != NULL, E_SYSTEM, "oom_adj change failed with %s.", strerror(errno));
205
206         fprintf(fP, "%d", adj);
207         fclose(fP);
208
209         return r;
210 }
211
212 typedef void (* cbForVconf)(keynode_t* node, void *pData);
213
214 result
215 _Aul::SetPowerOffNotiListener( void (*powerOffCb)(void* node, void *pData), void *pData)
216 {
217
218 #if 1
219         int ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (cbForVconf)powerOffCb, pData);
220         SysTryReturnResult(NID_SYS, ret == 0, E_SYSTEM, "It failed to set power off");
221 #else
222         int heyFd = heynoti_init();
223         SysTryReturnResult(NID_APP, heyFd >= 0, E_SYSTEM, "heynoti_init failed.");
224
225         int ret = heynoti_subscribe(heyFd, "power_off_start", powerOffCb, pData);
226         SysTryReturnResult(NID_APP, ret >= 0, E_SYSTEM, "heynoti_subscribe failed.");
227
228         ret = heynoti_attach_handler(heyFd);
229         SysTryReturnResult(NID_APP, ret >= 0, E_SYSTEM, "heynoti_attach_handler failed.");
230 #endif
231
232         return E_SUCCESS;
233 }
234
235
236 // _Aul::GetAppType is provided for installer usage
237 int
238 _Aul::GetAppType(const String& category)
239 {
240         int ret = 0;
241
242         HashMapT<String, int> map;
243         map.Construct();
244
245         StringTokenizer strTok(category, L';');
246
247         String token;
248         while (strTok.HasMoreTokens())
249         {
250                 result r = strTok.GetNextToken(token);
251                 if (r == E_SUCCESS)
252                 {
253                         map.Add(token, 0);
254                 }
255         }
256
257         SysLog(NID_APP, "%d category items .", map.GetCount());
258
259         String key;
260
261         for (int i = 0; i < _NUM_CATEGORY; i++)
262         {
263                 bool b = false;
264                 key = _CATEGORY_LIST[i].category;
265                 result r = map.ContainsKey(key, b);
266                 if (r == E_SUCCESS && b)
267                 {
268                         ret |= _CATEGORY_LIST[i].type;
269                 }
270         }
271
272         return ret;
273 }
274
275
276 bool
277 _Aul::IsInstalled(const AppId& appId)
278 {
279         String packageId;
280         packageId = _PackageManagerImpl::GetPackageIdByAppId(appId);
281
282         return _PackageManagerImpl::GetInstance()->IsPackageInstalled(packageId);
283 }
284
285
286 String
287 _Aul::GetMainAppId(const char* appid)
288 {
289         pkgmgrinfo_appinfo_h handle = NULL;
290         int ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
291         if (ret != PMINFO_R_OK)
292         {
293                 return String();
294         }
295
296         char* mainid = NULL;
297         ret = pkgmgrinfo_appinfo_get_submode_mainid(handle, &mainid);
298         SysTryLog(NID_APP, ret == PMINFO_R_OK, "Cannot get main id for %s.", appid);
299
300         const String tmp = String(mainid);
301         pkgmgrinfo_appinfo_destroy_appinfo(handle);
302         return tmp;
303 }
304
305
306 AppId
307 _Aul::GetRealAppId(const AppId& appId)
308 {
309         String temp;
310         appId.SubString(11, temp);
311         if (temp == String(SUBMODE_NAME))
312         {
313                 std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
314                 const String& main = GetMainAppId(pAppId.get());
315                 if (!main.IsEmpty())
316                 {
317                         SysLog(NID_APP, "main Id is %ls", main.GetPointer());
318                         return main;
319                 }
320         }
321
322         return appId;
323 }
324
325 } } // Tizen::App