2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FApp_AppInfo.cpp
19 * @brief This is the implementation for the _AppInfo.cpp class.
28 #include <unique_ptr.h>
32 #include <FBaseErrors.h>
33 #include <FAppPkgPackageInfo.h>
34 #include <FBaseSysLog.h>
36 #include <FBaseRt_Process.h>
37 #include <FBase_StringConverter.h>
39 #include "FAppPkg_PackageInfoImpl.h"
41 #include "FApp_AppInfo.h"
43 using namespace Tizen::App::Package;
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Runtime;
52 result r = Tizen::App::_AppInfo::GetInstance()->Construct();
55 SysLogException(NID_APP, E_SYSTEM, "Application initialization failure.");
56 fprintf(stderr, "Application initialization failure.\n");
63 InitAppInfo(const char* packageId, const char* svcId, int argc, char* pArgv[], int fd)
69 InitWebAppInfo(const char* appId, const char* rootPath)
71 result r = Tizen::App::_AppInfo::GetInstance()->Construct(appId, rootPath, Tizen::App::_APP_TYPE_WEB_APP);
74 SysLogException(NID_APP, E_SYSTEM, "Application initialization failure for %s.", appId);
75 fprintf(stderr, "Application initialization failure for %s.\n", appId);
81 extern void FBase_Initialize(void);
85 namespace Tizen { namespace App
88 const int MAX_APIVERSION = 8;
89 const int MAX_APPID = 10;
90 const char PACKAGE_PATH_FORMAT[] = "/opt/usr/apps/0000000000/";
91 const char PATH_ROOT[] = "/opt/usr/apps/";
92 const char APPINFO_FILE_PATH[] = "info/version.info";
93 const char COMPAT_FILE_PATH[] = "info/compat.info";
94 const char VIRTUAL_ROOT_FILE_PATH[] = "info/virtual.info";
95 const char TYPE_FILE_PATH[] = "info/type.info";
96 const char SUBMODE_NAME[] = "_AppControl";
99 _AppInfo::_AppInfo(void)
100 : __appState(TERMINATED)
101 , __appType(_APP_TYPE_NONE)
104 , __appHandlerType(_APP_HANDLER_NONE)
105 , __parentWindowHandle(-1)
107 , __pAppVersion(null)
108 , __isPackageInfoInitialized(false)
110 , __isVirtualRoot(false)
111 , __isMultiWindow(false)
113 SysStaticAssert(sizeof(pid_t) == sizeof(int));
115 //FBase_Initialize();
118 _AppInfo::~_AppInfo(void)
121 delete __pAppVersion;
123 // closing may or may not succeed
124 close(__appRootDirFd);
129 _AppInfo::GetInstance(void)
131 static _AppInfo info;
138 _AppInfo::Construct(void)
140 SysAssertf(appinfo_is_initialized() == 1, "appinfo is not initialized.");
144 const char* pPackageId = appinfo_get_packageid();
145 const char* pExecName = appinfo_get_execname();
147 if (strncmp(pExecName, SUBMODE_NAME, strlen(SUBMODE_NAME)) == 0)
149 SysLog(NID_APP, "Handling for submode.");
151 const char* pAppId = appinfo_get_appid();
152 const String& mainId = _Aul::GetMainAppId(pAppId);
153 if (!mainId.IsEmpty())
155 std::unique_ptr<char[]> pMainId(_StringConverter::CopyToCharArrayN(mainId));
156 appinfo_update_submode_appid(pMainId.get());
160 SysLog(NID_APP, "Executable name is changed to %s.", pMainId.get());
164 result r = E_SUCCESS;
168 char appInfoPath[PATH_MAX] = {0, };
170 int len = strlen(PACKAGE_PATH_FORMAT);
171 strncpy(appInfoPath, PACKAGE_PATH_FORMAT, len);
172 appInfoPath[len] = '\0';
173 strncpy(appInfoPath + strlen(PATH_ROOT), pPackageId, MAX_APPID);
175 // app root directory file descriptor
176 __appRootDirFd = open(appInfoPath, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
177 __appRootPath = appInfoPath;
179 SysLog(NID_APP, "App root directory (%s:%d) open.", appInfoPath, __appRootDirFd);
181 int fd = openat(__appRootDirFd, APPINFO_FILE_PATH, O_RDONLY);
182 SysAssertf(fd != -1, "Failed to open info file, errno: %d (%s)", errno, strerror(errno));
184 pFile = fdopen(fd, "r");
185 SysTryCatch(NID_APP, pFile != NULL, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Opening appinfo file (%s) failed : %s.", appInfoPath, strerror(errno));
188 char sdInfoPath[PATH_MAX] = {0, };
189 strncpy(sdInfoPath, "/opt/storage/sdcard/app2sd/", strlen("/opt/storage/sdcard/app2sd/"));
190 strncat(sdInfoPath, pPackageId, MAX_APPID);
192 __appSdDirFd = open(sdInfoPath, O_RDONLY);
193 SysLog(NID_APP, "sd root directory (%s:%d) open.", sdInfoPath, __appSdDirFd);
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));
200 // fd is closed when the stream is closed by fclose();
202 appinfo_set_api_version(appinfo_get_api_version_from_str(apiVersion));
204 // to reduce package manager overhead, libc API is used
205 if (faccessat(__appRootDirFd, COMPAT_FILE_PATH, F_OK, 0) == 0)
207 SysLog(NID_APP, "OSP compatibility mode on.");
208 appinfo_set_compat(1);
211 if (faccessat(__appRootDirFd, VIRTUAL_ROOT_FILE_PATH, F_OK, 0) == 0)
213 SysLog(NID_APP, "virtual root mode on.");
214 __isVirtualRoot = true;
217 // type file may does not exist
218 fd = openat(__appRootDirFd, TYPE_FILE_PATH, O_RDONLY);
221 pFile = fdopen(fd, "r");
225 int line = fscanf(pFile, "%d", &i);
228 // fd is closed when the stream is closed by fclose();
230 __appType = _APP_TYPE_UI_APP | i;
231 SysLog(NID_APP, "Reading app type %d -> %d", i, __appType);
235 SysLog(NID_APP, "AppInfo [%s][%s.%s][%d].", appinfo_get_appid(), appinfo_get_packageid(), appinfo_get_execname(), appinfo_get_api_version());
250 // initialize app context only
252 _AppInfo::Construct(const char* appId, const char* appRoot, _AppType type)
254 SysAssertf(appId != null, "Valid appId required to launch application.");
258 if (appinfo_is_initialized() == 0)
260 appinfo_init(appId, 0);
263 __appRootDirFd = open(appRoot, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
264 appinfo_set_api_version(APP_INFO_VERSION_2_2);
267 __appRootPath = appRoot;
268 if (__appRootPath[__appRootPath.GetLength()] != L'/')
270 __appRootPath.Append(L'/');
273 SysLog(NID_APP, "AppInfo [%s][%s.%s][%ls][%d].", appinfo_get_appid(), appinfo_get_packageid(), appinfo_get_execname()), __appRootPath.GetPointer(), appinfo_get_api_version();
280 _AppInfo::UpdateAppInfoFromPackageInfo(const PackageId& packageId)
282 _PackageManagerImpl* pPkg = _PackageManagerImpl::GetInstance();
283 SysTryReturnResult(NID_APP, pPkg != null, E_INVALID_STATE, "Invalid PackageManager instance.");
285 result r = E_SUCCESS;
286 std::unique_ptr<PackageInfo> pInfo(pPkg->GetPackageInfoN(packageId));
287 if (pInfo.get() == null)
290 SysPropagate(NID_APP, r);
294 const _PackageInfoImpl* pPkgInfo = _PackageInfoImpl::GetInstance(pInfo.get());
295 SysTryReturnResult(NID_APP, pPkgInfo != null, E_INVALID_STATE, "Invalid PackageInfo instance.");
298 __pAppName = new (std::nothrow) String(pPkgInfo->GetName());
299 SysTryCatch(NID_APP, __pAppName != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] AppName allocation failure.");
301 delete __pAppVersion;
302 __pAppVersion = new (std::nothrow) String(pPkgInfo->GetVersion());
303 SysTryCatch(NID_APP, __pAppVersion != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] AppVersion allocation failure.");
305 __isPackageInfoInitialized = true;
307 SysLog(NID_APP, "AppInfo updated [%ls][%ls].", __pAppName->GetPointer(), __pAppVersion->GetPointer());
315 delete __pAppVersion;
316 __pAppVersion = null;
323 _AppInfo::GetApiVersion(void)
325 return static_cast<_ApiVersion>(appinfo_get_api_version());
330 _AppInfo::IsOspCompat(void)
332 return (appinfo_is_compat() == 1);
336 _AppInfo::IsVirtualRoot(void)
338 return GetInstance()->__isVirtualRoot;
342 _AppInfo::SetApiVersion(_ApiVersion v)
344 appinfo_set_api_version(static_cast<app_info_version_e>(v));
350 _AppInfo::GetProcessId(void)
352 static int processId = static_cast<int>(getpid());
358 _AppInfo::GetAppRootDirFd(void)
360 return GetInstance()->__appRootDirFd;
365 _AppInfo::GetApplicationId(void)
367 return String(appinfo_get_appid());
372 _AppInfo::GetPackageId(void)
374 return String(appinfo_get_packageid());
379 _AppInfo::GetAppExecutableName(void)
381 return String(appinfo_get_execname());
386 _AppInfo::IsSubMode(void)
388 return GetInstance()->__isSubMode;
393 _AppInfo::GetAppName(void)
395 if (!GetInstance()->__isPackageInfoInitialized)
397 const String& packageId = GetInstance()->GetPackageId();
399 SysAssertf(!packageId.IsEmpty(), "PackageId is not initialized properly.");
401 result r = GetInstance()->UpdateAppInfoFromPackageInfo(packageId);
402 SysAssertf(r == E_SUCCESS, "AppInfo update failure due to package problem.");
405 return *(GetInstance()->__pAppName);
410 _AppInfo::GetAppRootPath(void)
412 return GetInstance()->__appRootPath;
416 _AppInfo::GetAppVersion(void)
418 if (!GetInstance()->__isPackageInfoInitialized)
420 const String& packageId = GetInstance()->GetPackageId();
422 SysAssertf(!packageId.IsEmpty(), "PackageId is not initialized properly.");
424 result r = GetInstance()->UpdateAppInfoFromPackageInfo(packageId);
425 SysAssertf(r == E_SUCCESS, "AppInfo update failure due to package problem.");
428 return *(GetInstance()->__pAppVersion);
433 _AppInfo::GetAppState(void)
435 return GetInstance()->__appState;
440 _AppInfo::SetAppState(AppState appState)
442 GetInstance()->__appState = appState;
447 _AppInfo::GetAppType(void)
449 return GetInstance()->__appType;
454 _AppInfo::SetAppType(_AppType appType)
456 GetInstance()->__appType |= appType;
461 _AppInfo::GetAppHandlerType(void)
463 return GetInstance()->__appHandlerType;
468 _AppInfo::SetAppHandlerType(int appHandlerType)
470 GetInstance()->__appHandlerType = appHandlerType;
475 _AppInfo::GetParentWindowHandle(void)
477 return GetInstance()->__parentWindowHandle;
482 _AppInfo::SetParentWindowHandle(unsigned int handle)
484 GetInstance()->__parentWindowHandle = handle;
489 _AppInfo::UpdatePackageInfo(bool update)
491 GetInstance()->__isPackageInfoInitialized = !update;
495 _AppInfo::IsMultiWindow(void)
497 return GetInstance()->__isMultiWindow;
501 _AppInfo::SetMultiWindow(bool enable)
503 GetInstance()->__isMultiWindow = enable;