Modify DataControl manager for thread-safe
[platform/framework/native/appfw.git] / src / app / FApp_AppResourceImpl.cpp
index 33ad248..94b0a09 100644 (file)
@@ -1,5 +1,4 @@
 //
-// Open Service Platform
 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
 //
 // Licensed under the Apache License, Version 2.0 (the License);
  * @brief      This is the implementation for the _AppResourceImpl class.
  */
 
-#include <FBaseObject.h>
-#include <FBaseString.h>
+#include <unique_ptr.h>
+
 #include <FBaseResult.h>
 #include <FBaseSysLog.h>
-#include <FAppAppResource.h>
-
+#include <FBaseColHashMap.h>
 #include <FBaseRt_LibraryImpl.h>
 
-#include "FApp_AppResourceImpl.h"
-#include "FApp_AppResourceString.h"
+#include <FAppAppResource.h>
 #include "FApp_AppManagerImpl.h"
+#include "FApp_AppResourceString.h"
 #include "FApp_IAppResourceBitmap.h"
 
+#include "FApp_AppResourceImpl.h"
+
+
 using namespace Tizen::Base;
+using namespace Tizen::Base::Collection;
 using namespace Tizen::Base::Runtime;
+using namespace Tizen::Graphics;
 using namespace Tizen::Io;
-using namespace Tizen::Locales;
-using namespace Tizen::System;
 
-using namespace Tizen::Graphics;
 
 namespace Tizen { namespace App
 {
 
 #define BITMAP_PIXEL_FORMAT_INVALID (BITMAP_PIXEL_FORMAT_MIN)
 
-static _IAppResourceBitmap*(* p_Create_AppResourceBitmapInstanceN)(void) = null;
-static _IAppResourceBitmap*(* p_Create_AppResourceBitmapInstanceByAppIdN)(const String& appId) = null;
+
+static _IAppResourceBitmap*(* p_Create_IAppResourceBitmapInstanceN)(int type, const String& value) = null;
+
+Tizen::Base::Collection::HashMap* _AppResourceImpl::__pContainer = null;
+Tizen::Base::Runtime::Mutex* _AppResourceImpl::__pLock = null;
 
 _AppResourceImpl::_AppResourceImpl(void)
-       : __pAppResource(null)
-       , __p_AppResourceString(null)
+       : __p_AppResourceString(null)
        , __p_IAppResourceBitmap(null)
-       , __isByAppId(false)
+       , __type(APP_RESOURCE_DEFAULT)
+       , __value()
 {
 }
 
-
 result
-_AppResourceImpl::Construct(const Locale& locale)
+_AppResourceImpl::ReleaseInstance(const Tizen::Base::String& key)
 {
-       return Construct();
-}
+       result ret = E_SUCCESS;
 
+       if (__pContainer != null)
+       {
+               result r = __pLock->Acquire();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to acquire mutex.");
 
-result
-_AppResourceImpl::Construct(void)
-{
-       return E_SUCCESS;
+               ret = __pContainer->Remove(key);
+
+               r = __pLock->Release();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to release mutex.");
+       }
+
+       return ret;
 }
 
-result
-_AppResourceImpl::Construct(const AppId& appId)
+// Exception: E_OUT_OF_MEMORY, E_SYSTEM, E_INVALID_ARG, E_OBJ_NOT_FOUND, E_APP_NOT_INSTALLED [Get_AppResourceStringN], Get_IAppResourceBitmapN
+AppResource*
+_AppResourceImpl::GetInstanceN(AppResourceBy type, const Tizen::Base::String& value)
 {
        result r = E_SUCCESS;
-       if (__p_AppResourceString == null)
+       static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
+       if (__pContainer == null)
        {
-               __p_AppResourceString = new (std::nothrow) _AppResourceString();
-               SysTryReturnResult(NID_APP, __p_AppResourceString != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]Failed to create String resource");
-
-               r = __p_AppResourceString->Construct(appId);
-               SysTryCatch(NID_APP, !IsFailed(r),  , r, "[%s] Failed to construct String resource", GetErrorMessage(r));
+               ClearLastResult();
+               pthread_once(&onceBlock, InitSingleton);
+               r = GetLastResult();
+               SysTryReturn(NID_APP, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Creating the container is failed [%s].", GetErrorMessage(r));
        }
 
-       if (p_Create_AppResourceBitmapInstanceByAppIdN == null)
-       {
-               _LibraryImpl& lib = _AppManagerImpl::GetInstance()->GetUiLibraryImpl();
-               p_Create_AppResourceBitmapInstanceByAppIdN = reinterpret_cast<_IAppResourceBitmap*(*)(const String& appId)>(lib.GetProcAddress(L"_Create_IAppResourceBitmapInstanceByAppIdN"));
-               SysTryCatch(NID_APP, p_Create_AppResourceBitmapInstanceByAppIdN != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get Bitmap resource [%s].", GetErrorMessage(GetLastResult()));
-       }
+       r = __pLock->Acquire();
+       SysTryLog(NID_APP, !IsFailed(r), "Failed to acquire mutex.");
 
-       if (__p_IAppResourceBitmap == null)
+       bool hasAppResource = false;
+       r = __pContainer->ContainsKey(value, hasAppResource);
+       SysTryCatch(NID_APP, !IsFailed(r), r, r, "[%s] Checking to contain is failed.", GetErrorMessage(r));
+
+       if (hasAppResource)
        {
-               __p_IAppResourceBitmap = p_Create_AppResourceBitmapInstanceByAppIdN(appId);
-               SysTryCatch(NID_APP, __p_IAppResourceBitmap != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get Bitmap resource.");
+               r = __pLock->Release();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to release mutex.");
+
+               return static_cast<AppResource*> (__pContainer->GetValue(value));
        }
+       else
+       {
+               std::unique_ptr< _AppResourceImpl > pAppResourceImpl(new (std::nothrow) _AppResourceImpl());
+               SysTryCatch(NID_APP, pAppResourceImpl != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,"[E_OUT_OF_MEMORY] Unable to allocate memory for AppResourceImpl.");
+
+               std::unique_ptr< _AppResourceString > pAppResourceString(_AppResourceString::Get_AppResourceStringN(type, value));
+               r = GetLastResult();
+               SysTryCatch(NID_APP, !IsFailed(r), r, r, "[%s] Unable to get _AppResourceString.", GetErrorMessage(r));
+
+               std::unique_ptr< _IAppResourceBitmap > pAppResourceBitmap(Get_IAppResourceBitmapN(type, value));
+               r = GetLastResult();
+               SysTryCatch(NID_APP, !IsFailed(r), r, r, "[%s] Unable to get _IAppResourceBitmap.", GetErrorMessage(r));
+
+               pAppResourceImpl->__p_AppResourceString = pAppResourceString.release();
+               pAppResourceImpl->__p_IAppResourceBitmap = pAppResourceBitmap.release();
+               pAppResourceImpl->__type = type;
+               pAppResourceImpl->__value = value;
+
+               std::unique_ptr< String > pStr(new (std::nothrow) String(value));
+               SysTryCatch(NID_APP, pStr != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Creating a key is failed.");
+
+               AppResource* pAppResource = new (std::nothrow) AppResource;
+               SysTryCatch(NID_APP, pAppResource != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to allocate memory for AppResource");
+
+               pAppResource->__pAppResourceImpl = pAppResourceImpl.release();
+               r = __pContainer->Add(*pStr, *pAppResource);
+               if (IsFailed(r))
+               {
+                       delete pAppResource;
+                       SysTryCatch(NID_APP, false, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Adding an element to the container is failed.");
+               }
+
+               pStr.release();
 
-       __isByAppId = true;
-       return E_SUCCESS;
+               r = __pLock->Release();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to release mutex.");
+
+               return pAppResource;
+       }
 
+       // fall thru
 CATCH:
-       delete __p_AppResourceString;
-       __p_AppResourceString = null;
+       SetLastResult(r);
+
+       r = __pLock->Release();
+       SysTryLog(NID_APP, !IsFailed(r), "Failed to release mutex.");
 
-       return r;
+       return null;
+}
+
+_IAppResourceBitmap*
+_AppResourceImpl::Get_IAppResourceBitmapN(AppResourceBy type, const Tizen::Base::String& value)
+{
+       if (p_Create_IAppResourceBitmapInstanceN == null)
+       {
+               _LibraryImpl& lib = _AppManagerImpl::GetInstance()->GetUiLibraryImpl();
+               p_Create_IAppResourceBitmapInstanceN =
+                               reinterpret_cast<_IAppResourceBitmap*(*)(int, const String&)>(lib.GetProcAddress(L"_Create_IAppResourceBitmapInstanceN"));
+               SysTryReturn(NID_APP, p_Create_IAppResourceBitmapInstanceN != null,
+                               null, E_SYSTEM, "[E_SYSTEM] Failed to get Bitmap resource [%s].", GetErrorMessage(E_SYSTEM));
+       }
+
+       std::unique_ptr< _IAppResourceBitmap > pAppResourceBitmap(p_Create_IAppResourceBitmapInstanceN(type, value));
+       SysTryReturn(NID_APP, pAppResourceBitmap != null, null,
+                       E_SYSTEM, "[%s] Unable to get IAppResourceBitmap.", GetErrorMessage(E_SYSTEM));
+
+       return pAppResourceBitmap.release();
 }
 
 _AppResourceImpl::~_AppResourceImpl(void)
@@ -113,88 +182,124 @@ _AppResourceImpl::~_AppResourceImpl(void)
        delete __p_IAppResourceBitmap;
 }
 
-
 result
 _AppResourceImpl::GetString(const String& resourceId, String& loadedString)
 {
-       result r = E_SUCCESS;
-
-       if ((__isByAppId == false) && (__p_AppResourceString == null))
+       if (__p_AppResourceString == null)
        {
-               __p_AppResourceString = new (std::nothrow) _AppResourceString();
-               SysTryReturnResult(NID_APP, __p_AppResourceString != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]Not enough memory.");
-
-               r = __p_AppResourceString->Construct();
-               SysTryCatch(NID_APP, !IsFailed(r), , r = E_SYSTEM, "[E_SYSTEM] Failed to get String resource.");
+               __p_AppResourceString = _AppResourceString::Get_AppResourceStringN(__type, __value);
+               SysTryReturnResult(NID_APP, __p_AppResourceString == null, E_FAILURE, "Failed to get String resource.");
        }
 
-       r = __p_AppResourceString->GetString(resourceId, loadedString);
-
-CATCH:
-       return r;
+       return __p_AppResourceString->GetString(resourceId, loadedString);
 }
 
-
 Bitmap*
 _AppResourceImpl::GetBitmapN(const String& imgFilePath, BitmapPixelFormat pixelFormat)
 {
-       if (__isByAppId == false)
+       if (__p_IAppResourceBitmap == null)
        {
-               if (p_Create_AppResourceBitmapInstanceN == null)
-               {
-                       _LibraryImpl& lib = _AppManagerImpl::GetInstance()->GetUiLibraryImpl();
-                       p_Create_AppResourceBitmapInstanceN = reinterpret_cast<_IAppResourceBitmap*(*)(void)>(lib.GetProcAddress(L"_Create_IAppResourceBitmapInstanceN"));
-                       SysTryCatch(NID_APP, p_Create_AppResourceBitmapInstanceN != null, , E_SYSTEM, "[E_SYSTEM] Failed to get Bitmap resource [%s].", GetErrorMessage(GetLastResult()));
-               }
-
-               if (__p_IAppResourceBitmap == null)
-               {
-                       __p_IAppResourceBitmap = p_Create_AppResourceBitmapInstanceN();
-                       SysTryCatch(NID_APP, __p_IAppResourceBitmap != null, , E_SYSTEM, "[E_SYSTEM] Failed to get Bitmap resource.");
-               }
+               __p_IAppResourceBitmap = Get_IAppResourceBitmapN(__type, __value);
+               SysTryReturn(NID_APP, __p_IAppResourceBitmap == null,
+                               null, E_SYSTEM, "[%s] Failed to get Bitmap resource.", GetErrorMessage(E_SYSTEM));
        }
 
        return __p_IAppResourceBitmap->GetBitmapN(imgFilePath, pixelFormat);
-
-CATCH:
-       return null;
 }
 
-
 Bitmap*
 _AppResourceImpl::GetBitmapN(const String& imgFilePath)
 {
        return GetBitmapN(imgFilePath, BITMAP_PIXEL_FORMAT_INVALID);
 }
 
-
-AppResource*
-_AppResourceImpl::GetAppResource(void)
-{
-       return __pAppResource;
-}
-
 _AppResourceImpl*
 _AppResourceImpl::GetInstance(void)
 {
-//     return __pAppResource->__pAppResourceImpl;
-       return AppResource::GetInstance()->__pAppResourceImpl;
+       AppResource* pAppResource = AppResource::GetInstance();
+       if (pAppResource)
+       {
+               return pAppResource->__pAppResourceImpl;
+       }
+       return null;
 }
 
 void
 _AppResourceImpl::Reinitialize(void)
 {
-       if (__p_AppResourceString != null)
+       _AppResourceImpl* pThis = _AppResourceImpl::GetInstance();
+       if (pThis == null)
        {
+               SysLog(NID_APP, "No _AppResourceImpl instance.");
+               return;
+       }
 
-               __p_AppResourceString->Initialize();
+       if (__pContainer != null)
+       {
+               std::unique_ptr< IMapEnumerator > pMapEnum(__pContainer->GetMapEnumeratorN());
+               if (pMapEnum)
+               {
+                       while(pMapEnum->MoveNext() == E_SUCCESS)
+                       {
+                               AppResource* pAppResource = static_cast<AppResource*> (pMapEnum->GetValue());
+                               if (pAppResource && pAppResource->__pAppResourceImpl)
+                               {
+                                       _AppResourceImpl* pAppResourceImpl = pAppResource->__pAppResourceImpl;
+                                       delete pAppResourceImpl->__p_AppResourceString;
+                                       pAppResourceImpl->__p_AppResourceString =
+                                                       _AppResourceString::Get_AppResourceStringN(pAppResourceImpl->__type, pAppResourceImpl->__value);
+
+                                       // This function will be called on Language change event
+                                       // Need not to re-initialize Bitmap resource as language change does not affect bitmap resource path
+                               }
+                       }
+               }
+       }
+}
+
+Bitmap*
+_AppResourceImpl::GetNonScalingBitmapN(const Tizen::Base::String& imagePath)
+{
+       _IAppResourceBitmap* pAppResourceBitmap = Tizen::App::_AppResourceImpl::Get_IAppResourceBitmapN(APP_RESOURCE_BITMAP);
+
+       if (pAppResourceBitmap != null)
+       {
+               return pAppResourceBitmap->GetBitmapN(imagePath, BITMAP_PIXEL_FORMAT_INVALID, false);
+       }
+       else
+       {
+               SysLog(NID_APP, "Getting pAppResourceBitmap instance is failed");
+               return null;
        }
-       AppResource::Reinitialize();
 }
 
 void
-_AppResourceImpl::Reinitialize(const AppId& appId)
+_AppResourceImpl::InitSingleton(void)
 {
-               __p_AppResourceString->Initialize(appId);
+       std::unique_ptr< HashMap > pContainer(new (std::nothrow) HashMap(SingleObjectDeleter));
+       SysTryReturnVoidResult(NID_APP, pContainer != null, E_OUT_OF_MEMORY, "[%s] Creating the container is failed.");
+
+       result r = pContainer->Construct();
+       SysTryReturnVoidResult(NID_APP, !IsFailed(r), E_SYSTEM, "[E_SYSTEM] Constructing the container is failed.");
+
+       __pContainer = pContainer.release();
+
+       std::unique_ptr< Mutex > pLock(new (std::nothrow) Mutex());
+       SysTryReturnVoidResult(NID_APP, pLock != null, E_OUT_OF_MEMORY, "[%s] Creating the mutex is failed.");
+
+       r = pLock->Create();
+       SysTryReturnVoidResult(NID_APP, !IsFailed(r), E_SYSTEM, "[E_SYSTEM] Constructing the mutex is failed.");
+
+       __pLock = pLock.release();
+
+       //std::atexit(DestroySingleton);
+}
+
+void
+_AppResourceImpl::DestroySingleton(void)
+{
+       delete __pContainer;
+       delete __pLock;
 }
+
 } } // Tizen::App