Merge "add prefix [SECURE_LOG] to secure log output" into tizen_2.1
[platform/framework/native/appfw.git] / src / app / FApp_AppInfo.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file         FApp_AppInfo.cpp
20  * @brief       This is the implementation for the _AppInfo.cpp class.
21  */
22
23 #include <cstdio>
24 #include <cstring>
25 #include <unistd.h>
26 #include <limits.h>
27 #include <new>
28 #include <fcntl.h>
29
30 #include <FBaseErrors.h>
31 #include <FAppPkgPackageInfo.h>
32
33 #include <FBaseSysLog.h>
34 #include <FBaseRt_Process.h>
35
36 #include "FAppPkg_PackageInfoImpl.h"
37 #include "FApp_AppInfo.h"
38 #include "FApp_Aul.h"
39 #include "FApp_AppArg.h"
40
41 using namespace Tizen::App::Package;
42 using namespace Tizen::Base;
43 using namespace Tizen::Base::Runtime;
44
45 extern "C"
46 {
47 void _OSP_EXPORT_
48 InitAppInfo(const char* appId, const char* svcId, int argc, char* pArgv[], int fd)
49 {
50         result r = Tizen::App::_AppInfo::GetAppInfo()->Construct(appId, svcId, argc, pArgv);
51         if (IsFailed(r))
52         {
53                 SysLogException(NID_APP, E_SYSTEM, "Application initialization failure for %s.", appId);
54                 fprintf(stderr, "Application initialization failure for %s.\n", appId);
55
56                 _Process::Exit(-1);
57         }
58 }
59
60 void _OSP_EXPORT_
61 InitWebAppInfo(const char* appId, const char* rootPath)
62 {
63         result r = Tizen::App::_AppInfo::GetAppInfo()->Construct(appId, rootPath, Tizen::App::_APP_TYPE_WEB_APP);
64         if (IsFailed(r))
65         {
66                 SysLogException(NID_APP, E_SYSTEM, "Application initialization failure for %s.", appId);
67                 fprintf(stderr, "Application initialization failure for %s.\n", appId);
68
69                 _Process::Exit(-1);
70         }
71 }
72
73 extern void FBase_Initialize(void);
74
75 }
76
77 namespace Tizen { namespace App
78 {
79
80 const int MAX_APIVERSION = 8;
81 const int MAX_APPID = 10;
82 const char PACKAGE_PATH_FORMAT[] = "/opt/usr/apps/0000000000/";
83 const char PACKAGE_PATH_FORMAT2[] = "/opt/apps/0000000000/";
84 const char PATH_ROOT[] = "/opt/usr/apps/";
85 const char PATH_ROOT2[] = "/opt/apps/";
86 const char APPINFO_FILE_PATH[] = "info/version.info";
87 const char COMPAT_FILE_PATH[] = "info/compat.info";
88 const char TYPE_FILE_PATH[] = "info/type.info";
89
90
91 _AppInfo::_AppInfo(void)
92         : __appState(TERMINATED)
93         , __appType(_APP_TYPE_UI_APP)
94         , __appRootDirFd(-1)
95         , __appHandlerType(_APP_HANDLER_NONE)
96         , __parentWindowHandle(-1)
97         , __apiVersion(_API_VERSION_2_1)
98         , __pAppName(null)
99         , __pAppVersion(null)
100         , __argc(0)
101         , __pArgv(null)
102         , __isPackageInfoInitialized(false)
103         , __isOspCompat(false)
104         , __isSubMode(false)
105 {
106         SysStaticAssert(sizeof(pid_t) == sizeof(int));
107
108         //FBase_Initialize();
109 }
110
111 _AppInfo::~_AppInfo(void)
112 {
113         delete __pAppName;
114         delete __pAppVersion;
115 }
116
117 _AppInfo*
118 _AppInfo::GetAppInfo(void)
119 {
120         static _AppInfo info;
121
122         return &info;
123 }
124
125
126 result
127 _AppInfo::Construct(const char* appId, const char* exeName, int argc, char* argv[])
128 {
129         SysAssertf(appId != null, "Valid appId required to launch application.");
130
131      FBase_Initialize();
132
133         __appExecutableName = exeName;
134         __packageId = appId;
135
136         if (__appExecutableName == L"_AppControl")
137         {
138                 SysLog(NID_APP, "Handling for submode.");
139                 const String& name = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(__packageId);
140
141                 __isSubMode = true;
142                 __appExecutableName = name;
143                 SysLog(NID_APP, "Executable name is changed to %ls.", __appExecutableName.GetPointer());
144         }
145
146         __appId = __packageId + L'.' + __appExecutableName;
147
148         result r = E_SUCCESS;
149         FILE* pFile = NULL;
150
151         {
152                 char appInfoPath[PATH_MAX] = {0, };
153 #if 0
154                 const int len = strlen(PACKAGE_PATH_FORMAT2);
155                 strncpy(appInfoPath, PACKAGE_PATH_FORMAT2, len);
156                 appInfoPath[len] = '\0';
157
158                 // due to possible dependency problem, FIoFile is not used
159                 // app root path first
160
161                 strncpy(appInfoPath + strlen(PATH_ROOT2), appId, MAX_APPID);
162 #else
163                 // [FIXME] temporary code for directory location migration
164                 int len = strlen(PACKAGE_PATH_FORMAT2);
165                 strncpy(appInfoPath, PACKAGE_PATH_FORMAT2, len);
166                 appInfoPath[len] = '\0';
167
168                 if (access(appInfoPath, R_OK) != 0)
169                 {
170                         len = strlen(PACKAGE_PATH_FORMAT);
171                         strncpy(appInfoPath, PACKAGE_PATH_FORMAT, len);
172                         appInfoPath[len] = '\0';
173                         
174                         strncpy(appInfoPath + strlen(PATH_ROOT), appId, MAX_APPID);
175                 }
176                 else
177                 {
178                         strncpy(appInfoPath + strlen(PATH_ROOT2), appId, MAX_APPID);
179                 }
180 #endif
181
182                 // app root directory file descriptor
183                 __appRootDirFd = open(appInfoPath, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
184
185                 __appRootPath = appInfoPath;
186                 
187                 SysLog(NID_APP, "App root directory (%s:%d) open.", appInfoPath, __appRootDirFd);
188
189                 int fd = openat(__appRootDirFd, APPINFO_FILE_PATH, O_RDONLY);
190                 SysAssert(fd != -1);
191
192                 pFile = fdopen(fd, "r");
193                 SysTryCatch(NID_APP, pFile != NULL, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Opening appinfo file (%s) failed : %s.", appInfoPath, strerror(errno));
194
195                 char apiVersion[MAX_APIVERSION] = {0, };
196                 char* pRet = fgets(apiVersion, MAX_APIVERSION - 1, pFile);
197                 SysTryCatch(NID_APP, pRet != NULL, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Reading appinfo file (%s) failed : %s.", appInfoPath, strerror(errno));
198
199                 fclose(pFile);
200                 // fd is closed when the stream is closed by fclose();
201
202                 __apiVersion = GetApiVersionFromStr(apiVersion);
203
204                 __argc = argc;
205                 __pArgv = argv;
206
207                 // to reduce package manager overhead, libc API is used
208                 if (faccessat(__appRootDirFd, COMPAT_FILE_PATH, F_OK, 0) == 0)
209                 {
210                         SysLog(NID_APP, "OSP compatibility mode on.");
211                         __isOspCompat = true;
212                 }
213
214                 // type file may does not exist
215                 fd = openat(__appRootDirFd, TYPE_FILE_PATH, O_RDONLY);
216                 if (fd > 0)
217                 {
218                         pFile = fdopen(fd, "r");
219                         if (pFile)
220                         {
221                                 int i;
222                                 int line = fscanf(pFile, "%d", &i);
223
224                                 fclose(pFile);
225                                 // fd is closed when the stream is closed by fclose();
226
227                                 __appType = _APP_TYPE_UI_APP | i;
228                                 SysLog(NID_APP, "Reading app type %d -> %d", i, __appType);
229                         }
230                 }
231
232                 SysLog(NID_APP, "AppInfo initialization finished [%ls][%ls.%ls][%d].",
233                                 __appId.GetPointer(), __packageId.GetPointer(), __appExecutableName.GetPointer(), __apiVersion);
234         }
235
236         return E_SUCCESS;
237
238 CATCH:
239         __appId.Clear();
240         __appExecutableName.Clear();
241
242         delete __pAppName;
243         __pAppName = null;
244
245         delete __pAppVersion;
246         __pAppVersion = null;
247
248         if (pFile != NULL)
249         {
250                 fclose(pFile);
251         }
252
253         return r;
254 }
255
256
257 // initialize app context only
258 result
259 _AppInfo::Construct(const char* appId, const char* appRoot, _AppType type)
260 {
261         SysAssertf(appId != null, "Valid appId required to launch application.");
262
263      FBase_Initialize();
264
265         __appId = appId;
266
267         int index = 0;
268         if (__appId.LastIndexOf(L'.', __appId.GetLength() - 1, index) == E_SUCCESS)
269         {
270                 __appId.SubString(index + 1, __appExecutableName);
271                 __appId.SubString(0, index, __packageId);
272         }
273         else
274         {
275                 __appExecutableName = __appId;
276                 __packageId = __appId;
277         }
278
279         __appRootDirFd = open(appRoot, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
280         __apiVersion = _API_VERSION_2_1;
281         __appType = type;
282
283         __appRootPath = appRoot;
284         if (__appRootPath[__appRootPath.GetLength()] != L'/')
285         {
286                 __appRootPath.Append(L'/');
287         }
288
289         SysLog(NID_APP, "AppInfo initialization finished [%ls][%ls.%ls][%ls][%d].", __appId.GetPointer(), __packageId.GetPointer(), __appExecutableName.GetPointer(), __appRootPath.GetPointer(),  __apiVersion);
290
291         return E_SUCCESS;
292 }
293
294
295 result
296 _AppInfo::UpdateAppInfoFromPackageInfo(const PackageId& packageId)
297 {
298         _PackageManagerImpl* pPkg = null;
299         pPkg = _PackageManagerImpl::GetInstance();
300         SysTryReturnResult(NID_APP, pPkg != null, E_INVALID_STATE, "Invalid PackageManager instance.");
301
302         result r = E_SUCCESS;
303         PackageInfo* pInfo = null;
304         pInfo = pPkg->GetPackageInfoN(packageId);
305         SysTryReturn(NID_APP, pInfo != null, r, r, "[%s] Propagating.", GetErrorMessage(r));
306
307         const _PackageInfoImpl* pPkgInfo = _PackageInfoImpl::GetInstance(pInfo);
308         SysTryReturnResult(NID_APP, pPkgInfo != null, E_INVALID_STATE, "Invalid PackageInfo instance.");
309
310         delete __pAppName;
311         __pAppName = new (std::nothrow) String(pPkgInfo->GetName());
312         SysTryCatch(NID_APP, __pAppName != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] AppName allocation failure.");
313
314         delete __pAppVersion;
315         __pAppVersion = new (std::nothrow) String(pPkgInfo->GetVersion());
316         SysTryCatch(NID_APP, __pAppVersion != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] AppVersion allocation failure.");
317
318         __isPackageInfoInitialized = true;
319
320         delete pInfo;
321
322         SysLog(NID_APP, "AppInfo updated [%ls][%ls].", __pAppName->GetPointer(), __pAppVersion->GetPointer());
323
324         return r;
325
326 CATCH:
327         delete pInfo;
328
329         delete __pAppName;
330         __pAppName = null;
331
332         delete __pAppVersion;
333         __pAppVersion = null;
334
335         return r;
336 }
337
338
339 // [FIXME] refactoring to use hash
340 _ApiVersion
341 _AppInfo::GetApiVersionFromStr(const char* pVer)
342 {
343         String ver(pVer);
344         ver.Trim();
345
346         if (ver == L"3.0")
347         {
348                 return _API_VERSION_2_1;
349         }
350         else if (ver == L"2.0")
351         {
352                 return _API_VERSION_2_0;
353         }
354         else if (ver == L"1.2")
355         {
356                 return _API_VERSION_1_2;
357         }
358         else if (ver == L"1.1")
359         {
360                 return _API_VERSION_1_1;
361         }
362         else if (ver == L"1.0.2")
363         {
364                 return _API_VERSION_1_0_2;
365         }
366         else if (ver == L"1.0")
367         {
368                 return _API_VERSION_1_0;
369         }
370         else
371         {
372                 return _API_VERSION_2_1;
373         }
374 }
375
376
377 _ApiVersion
378 _AppInfo::GetApiVersion(void)
379 {
380         return GetAppInfo()->__apiVersion;
381 }
382
383
384 bool
385 _AppInfo::IsOspCompat(void)
386 {
387         return GetAppInfo()->__isOspCompat;
388 }
389
390
391 result
392 _AppInfo::SetApiVersion(_ApiVersion v)
393 {
394         GetAppInfo()->__apiVersion = v;
395         return E_SUCCESS;
396 }
397
398
399 int
400 _AppInfo::GetProcessId(void)
401 {
402         static int processId = static_cast<int>(getpid());
403
404         return processId;
405 }
406
407 int
408 _AppInfo::GetAppRootDirFd(void)
409 {
410         return GetAppInfo()->__appRootDirFd;
411 }
412
413
414 AppId
415 _AppInfo::GetApplicationId(void)
416 {
417         const String& appId = GetAppInfo()->__appId;
418
419         SysAssertf(!appId.IsEmpty(), "AppId is not initialized properly.");
420
421         return appId;
422 }
423
424
425 PackageId
426 _AppInfo::GetPackageId(void)
427 {
428         const String& packageId = GetAppInfo()->__packageId;
429
430         SysAssertf(!packageId.IsEmpty(), "PackageId is not initialized properly.");
431
432         return packageId;
433 }
434
435
436 String
437 _AppInfo::GetAppExecutableName(void)
438 {
439         return GetAppInfo()->__appExecutableName;
440 }
441
442
443 bool
444 _AppInfo::IsSubMode(void)
445 {
446         return GetAppInfo()->__isSubMode;
447 }
448
449
450 String
451 _AppInfo::GetAppName(void)
452 {
453         if (!GetAppInfo()->__isPackageInfoInitialized)
454         {
455                 const String& packageId = GetAppInfo()->__packageId;
456
457                 SysAssertf(!packageId.IsEmpty(), "PackageId is not initialized properly.");
458
459                 result r = GetAppInfo()->UpdateAppInfoFromPackageInfo(packageId);
460                 SysAssertf(r == E_SUCCESS, "AppInfo update failure due to package problem.");
461         }
462
463         return *(GetAppInfo()->__pAppName);
464 }
465
466
467 String
468 _AppInfo::GetAppRootPath(void)
469 {
470         return GetAppInfo()->__appRootPath;
471 }
472
473 String
474 _AppInfo::GetAppVersion(void)
475 {
476         if (!GetAppInfo()->__isPackageInfoInitialized)
477         {
478                 const String& packageId = GetAppInfo()->__packageId;
479
480                 SysAssertf(!packageId.IsEmpty(), "PackageId is not initialized properly.");
481
482                 result r = GetAppInfo()->UpdateAppInfoFromPackageInfo(packageId);
483                 SysAssertf(r == E_SUCCESS, "AppInfo update failure due to package problem.");
484         }
485
486         return *(GetAppInfo()->__pAppVersion);
487 }
488
489
490 AppState
491 _AppInfo::GetAppState(void)
492 {
493         return GetAppInfo()->__appState;
494 }
495
496
497 void
498 _AppInfo::SetAppState(AppState appState)
499 {
500         GetAppInfo()->__appState = appState;
501 }
502
503
504 int
505 _AppInfo::GetAppType(void)
506 {
507         return GetAppInfo()->__appType;
508 }
509
510
511 void
512 _AppInfo::SetAppType(_AppType appType)
513 {
514         GetAppInfo()->__appType |= appType;
515 }
516
517
518 int
519 _AppInfo::GetArgc(void)
520 {
521         return GetAppInfo()->__argc;
522 }
523
524
525 char**
526 _AppInfo::GetArgv(void)
527 {
528         return GetAppInfo()->__pArgv;
529 }
530
531
532 int
533 _AppInfo::GetAppHandlerType(void)
534 {
535         return GetAppInfo()->__appHandlerType;
536 }
537
538
539 void
540 _AppInfo::SetAppHandlerType(int appHandlerType)
541 {
542         GetAppInfo()->__appHandlerType = appHandlerType;
543 }
544
545
546 unsigned int
547 _AppInfo::GetParentWindowHandle(void)
548 {
549         return GetAppInfo()->__parentWindowHandle;
550 }
551
552
553 void
554 _AppInfo::SetParentWindowHandle(unsigned int handle)
555 {
556         GetAppInfo()->__parentWindowHandle = handle;
557 }
558
559
560 void
561 _AppInfo::UpdatePackageInfo(bool update)
562 {
563         GetAppInfo()->__isPackageInfoInitialized = !update;
564 }
565
566 }} // Tizen::App