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