Add the logic to support the virtual root
authorHyunbin Lee <hyunbin.lee@samsung.com>
Thu, 27 Jun 2013 12:21:09 +0000 (21:21 +0900)
committerHyunbin Lee <hyunbin.lee@samsung.com>
Fri, 28 Jun 2013 04:18:50 +0000 (13:18 +0900)
Change-Id: I807c13bc97d781963638bf84883516e775f93540
Signed-off-by: Hyunbin Lee <hyunbin.lee@samsung.com>
inc/FIo_MmcStorageManagerService.h
src/FApp_ContextManager.cpp
src/FIo_MmcStorageManagerService.cpp

index 8efaae4..cddcc4b 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <FBaseObject.h>
 #include <FBaseString.h>
+#include <FBaseColLinkedList.h>
 #include <FAppTypes.h>
 
 #include <FApp_ContextManager.h>
@@ -51,8 +52,8 @@ class _IMmcStorageServiceEventListener;
 class _MmcStorageManagerService
        : public Tizen::Base::Object
 {
-    typedef std::map< std::string, Tizen::Base::String* > _AppList;
-    typedef std::pair< std::string, Tizen::Base::String* > _AppListPair;
+       typedef std::map< std::string, Tizen::Base::String* > _AppList;
+       typedef std::pair< std::string, Tizen::Base::String* > _AppListPair;
 
 public:
        result Construct(_IMmcStorageServiceEventListener* pStub);
@@ -80,8 +81,9 @@ private:
 
        static _MmcStorageManagerService* __pMmcStorageManagerService;
        _IMmcStorageServiceEventListener* __pStub;
-    _AppList __appList;
-    friend class Tizen::App::_ContextManager;
+       _AppList __appList;
+       Tizen::Base::Collection::LinkedList* __pVirtualRootList;
+       friend class Tizen::App::_ContextManager;
 };
 
 }} // Tizen::Io
index 1806b09..6770242 100755 (executable)
@@ -191,6 +191,17 @@ _ContextManager::Register(const PackageId& pkgId, const String& executableName,
                SysLog(NID_APP, "OSP compatible application (%ls) is registered.", pkgId.GetPointer());
        }
 
+       String virtualRootFile(appRoot);
+       virtualRootFile.Append(L"/info/virtualroot.info");
+
+       bool virtualRoot = File::IsFileExist(virtualRootFile);
+       if (GetLastResult() == E_SUCCESS && virtualRoot == true)
+       {
+               _MmcStorageManagerService* pMmcMgr = _MmcStorageManagerService::GetInstance();
+               pMmcMgr->__pVirtualRootList->Add(new (std::nothrow) String(appRoot));
+               SysLog(NID_APP, "Virtual root application (%ls) is registered.", pkgId.GetPointer());
+       }
+
        // ==== set oom policy for ServiceApp
        result r = E_SUCCESS;
        switch (GetOomAppType(pkgId, pid))
index 7b7ac24..be0176e 100644 (file)
@@ -63,8 +63,8 @@ _MmcStorageManagerService::ConvertNativeErrorToResult(int errNo)
        SysLog(NID_IO, "ConvertNativeErrorToResult received : %d\n", errNo);
        result r = E_SUCCESS;
        //Covert the SLP response to Osp response
-        switch(errNo)
-        {
+               switch(errNo)
+               {
                case 0:
                        r = E_SUCCESS;
                        break;
@@ -81,7 +81,7 @@ _MmcStorageManagerService::ConvertNativeErrorToResult(int errNo)
 
                default:
                        r = E_SYSTEM;
-        }
+               }
        return r;
 }
 
@@ -121,12 +121,15 @@ MmcFormatCb(int response, void* data)
 
 _MmcStorageManagerService::_MmcStorageManagerService(void)
        : __pStub(null)
+       , __pVirtualRootList(null)
 {
+       __pVirtualRootList = new (std::nothrow) LinkedList(SingleObjectDeleter);
 }
 
 _MmcStorageManagerService::~_MmcStorageManagerService(void)
 {
        int ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, MmcEventVconfCallback);
+       delete __pVirtualRootList;
 }
 
 _MmcStorageManagerService*
@@ -146,6 +149,7 @@ _MmcStorageManagerService::Construct(_IMmcStorageServiceEventListener* pStub)
 
        int ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, MmcEventVconfCallback, this);
        SysTryReturnResult(NID_IO, ret == 0, E_SYSTEM, "Failed to register MMC event vconf callback.");
+       SysLog(NID_IO, "MMC callback is successfully registered.");
 
        return E_SUCCESS;
 }
@@ -197,6 +201,7 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
 {
        char srcPath[_MAX_EXT_SRC_DIR_COUNT][_MAX_PATH_LENGTH];
        char destPath[_MAX_EXT_DEST_DIR_COUNT][_MAX_PATH_LENGTH];
+       bool compat = false;
 
        SysLog(NID_IO, "MMC event occurs.");
 
@@ -210,11 +215,11 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                _AppList::const_iterator iter;
                for (iter = pMmcMgr->__appList.begin(); iter != pMmcMgr->__appList.end(); ++iter)
                {
+                       compat = true;
                        const String* pAppRoot = iter->second;
                        if (pAppRoot != null)
                        {
                                /*
-                               /opt/storage/sdcard                                      -> {app-root}/opt/storage/sdcard: It is mounted by system.
                                /opt/storage/sdcard/osp/apps/pkgId       -> {app-root}/HomeExt
                                /opt/storage/sdcard/osp/share            -> {app-root}/ShareExt
                                /opt/storage/sdcard/osp/share2           -> {app-root}/Share2Ext
@@ -326,19 +331,110 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                                                SysLog(NID_IO, "OSP compatible application is unregistered.");
                                        }
                                        SysLog(NID_IO, "unmount() succeeded, mount flag: %s", mountFlag);
-                }
-            }
-        }
+                               }
+                       }
+               }
+
+               // Checks virtual root application
+               IEnumerator* pEnum = pMmcMgr->__pVirtualRootList->GetEnumeratorN();
+               while (pEnum->MoveNext() == E_SUCCESS)
+               {
+                       compat = false;
+                       const String* pAppRoot = static_cast< String* >(pEnum->GetCurrent());
+                       if (pAppRoot != null)
+                       {
+                               std::unique_ptr< char[] > pAppRootPath(_StringConverter::CopyToCharArrayN(*pAppRoot));
+                               SysTryReturnVoidResult(NID_IO, pAppRootPath != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
+
+                               String destPath(*pAppRoot);
+                               destPath.Append(L"/virtual-root/opt/storage/sdcard");
+
+                               std::unique_ptr< char[] > pDestPath(_StringConverter::CopyToCharArrayN(destPath));
+                               SysTryReturnVoidResult(NID_IO, pDestPath != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
+
+                               char* pPkgId = strrchr(pAppRootPath.get(), '/');
+                               char mountFlag[_MAX_PATH_LENGTH] = { 0, };
+                               sprintf(mountFlag, "%s/%s", _EXTERNAL_MOUNT_FLAG, ++pPkgId);
+
+                               if (value == 1)
+                               {
+                                       SysLog(NID_IO, "MMC mount event for virtual root application.");
+
+                                       res = access(mountFlag, F_OK);
+                                       if (res == -1 && errno == ENOENT)
+                                       {
+                                               if (access(pAppRootPath.get(), F_OK) == 0)
+                                               {
+                                                       // /opt/storage/sdcard -> {app-root}/virtual-root/opt/storage/sdcard
+#ifdef _OSP_EMUL_
+                                                       res = mount("/dev/mmcblk0", pDestPath.get(), "ext4", 0, "");
+#else
+                                                       res = mount("/dev/mmcblk1p1", pDestPath.get(), "vfat", 0,
+                                                                       "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed,smackfsroot=*,smackfsdef=*");
+#endif
+
+                                                       SysTryReturnVoidResult(NID_IO, res == 0, E_SYSTEM, "[E_SYSTEM] Failed to mount (%s), errno: %d (%s)",
+                                                                       pDestPath.get(), errno, strerror(errno));
+
+                                                       r = _MmcStorageManagerService::CreateFlag(mountFlag);
+                                                       if (IsFailed(r))
+                                                       {
+                                                               SysLogException(NID_IO, E_SYSTEM, "[%s] Failed to create mount flag (%s)",
+                                                                               GetErrorMessage(r), mountFlag);
+                                                               res = umount2(pDestPath.get(), MNT_DETACH);
+                                                       }
+                                                       SysLog(NID_IO, "mount() succeeded, mount flag: %s", mountFlag);
+                                               }
+                                       }
+                                       else if (res == -1)
+                                       {
+                                               SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to access mount flag (%s), errno: %d (%s)",
+                                                               mountFlag, errno, strerror(errno));
+                                               return;
+                                       }
+                                       else
+                                       {
+                                               SysLog(NID_IO, "mount() was already done.");
+                                       }
+                               }
+                               else
+                               {
+                                       SysLog(NID_IO, "MMC unmount event for virtual root application.");
+
+                                       res = umount2(pDestPath.get(), MNT_DETACH);
+                                       SysTryLog(NID_IO, res == 0 || errno == EINVAL || errno == ENOENT,
+                                                       "[E_SYSTEM] Failed to unmount (%s), errno: %d (%s)", pDestPath.get(), errno, strerror(errno));
+
+                                       if (access(mountFlag, F_OK) == 0)
+                                       {
+                                               res = unlink(mountFlag);
+                                               SysTryReturnVoidResult(NID_IO, res == 0, E_SYSTEM, "[E_SYSTEM] Failed to remove mount flag (%s), errno: %d (%s)",
+                                                               mountFlag, errno, strerror(errno));
+                                       }
+
+                                       if (access(pAppRootPath.get(), F_OK) != 0 && errno == ENOENT)
+                                       {
+                                               pMmcMgr->__pVirtualRootList->Remove(*pAppRoot);
+                                               SysLog(NID_IO, "Virtual root application is unregistered.");
+                                       }
+                                       SysLog(NID_IO, "unmount() succeeded, mount flag: %s", mountFlag);
+                               }
+                       }
+               }
+
                res = vconf_set_int(VCONFKEY_APPSERVICE_MMC_STATUS, value);
        }
        return;
 
 CATCH:
-       for (int i = _MAX_EXT_DIR_MOUNT_COUNT; i >= 0; --i)
+       if (compat == true)
        {
-               int res = umount2(destPath[i], MNT_DETACH);
-               SysTryLog(NID_IO, res == 0 || errno == EINVAL || errno == ENOENT,
-                               "[E_SYSTEM] Failed to unmount (%s), errno: %d (%s)", destPath[i], errno, strerror(errno));
+               for (int i = _MAX_EXT_DIR_MOUNT_COUNT; i >= 0; --i)
+               {
+                       int res = umount2(destPath[i], MNT_DETACH);
+                       SysTryLog(NID_IO, res == 0 || errno == EINVAL || errno == ENOENT,
+                                       "[E_SYSTEM] Failed to unmount (%s), errno: %d (%s)", destPath[i], errno, strerror(errno));
+               }
        }
        return;
 }