//
-// Open Service Platform
// Copyright (c) 2012 Samsung Electronics Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the License);
*/
#include <typeinfo>
-#include <new>
#include <unique_ptr.h>
#include <appsvc/appsvc.h>
#include <FBaseInteger.h>
#include <FBaseString.h>
+#include <FBaseColLinkedList.h>
#include <FBaseRtIEventArg.h>
+#include <FIoFile.h>
#include <FAppMapDataControl.h>
#include <FAppIMapDataControlResponseListener.h>
{
static const int MAX_REQUEST_COUNT = 128;
+static const int REQUEST_THRESHOLD = 100;
static const int _MAX_ARGUMENT_SIZE = 16384; // 16KB
class _MapDataControlEventArg
: public Event
{
protected:
- virtual void FireImpl(IEventListener& listener, const IEventArg& arg);
+ virtual void FireImpl(IEventListener& listener, const IEventArg& arg);
};
void
// private
_MapDataControlImpl::_MapDataControlImpl(void)
- : __appId(L"")
- , __providerId(L"")
- , __access(_DATACONTROL_ACCESS_UNDEFINED)
+ : __access(_DATACONTROL_ACCESS_UNDEFINED)
, __pPreviousListener(null)
, __pMapDataControlEvent(null)
{
_MapDataControlImpl::~_MapDataControlImpl(void)
{
delete __pMapDataControlEvent;
+
+ _DataControlManager* pDcMgr = _DataControlManager::GetInstance();
+
+ IEnumerator* pEnum = __pRequestList->GetEnumeratorN();
+ while (pEnum->MoveNext() == E_SUCCESS)
+ {
+ Integer* pReqId = dynamic_cast< Integer* >(pEnum->GetCurrent());
+ if (pReqId != null)
+ {
+ pDcMgr->RemoveRequestInfo(*pReqId);
+ }
+ }
+ delete __pRequestList;
}
_MapDataControlImpl*
result r = E_SUCCESS;
int req = -1;
- _AppControlManager* pAppManagerImpl = _AppControlManager::GetInstance();
+ _DataControlManager* pDcMgr = _DataControlManager::GetInstance();
// Check the request count of DataControl operation
- int count = pAppManagerImpl->GetLaunchRequestCount();
+ int count = pDcMgr->GetRequestCount();
SysLog(NID_APP, "Current launch request count: %d", count);
+ if (count > REQUEST_THRESHOLD)
+ {
+ _AppManagerImpl* pImpl = _AppManagerImpl::GetInstance();
+
+ // Clear the request queue if the provider is terminated
+ if (!pImpl->IsRunning(__appId))
+ {
+ SysLog(NID_APP, "The request queue is cleared due to the invalid provider.");
+
+ pDcMgr->RemoveAllRequests();
+ }
+ }
+
SysTryReturnResult(NID_APP, count < MAX_REQUEST_COUNT, E_MAX_EXCEEDED, "The number of requests has exceeded the maximum limit.");
_AppArg* pArg = new(std::nothrow) _AppArg; // XXX: pArg will be released in _AppManagerImpl::LaunchApp().
pArg->Construct(*this, static_cast <_DataControlRequestType>(type), pDataList);
+ _AppControlManager* pAppManagerImpl = _AppControlManager::GetInstance();
+
if (__pMapDataControlEvent)
{
// reqId is system-wide id because the bundle is system-wide.
"[E_OUT_OF_MEMORY] The memory is insufficient");
pReqInfo = new (std::nothrow) _DataControlRequestInfo(__pMapDataControlEvent);
- SysTryCatch(NID_APP, pReqId != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ SysTryCatch(NID_APP, pReqInfo != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
"[E_OUT_OF_MEMORY] The memory is insufficient");
+ pReqInfo->SetMapDataControlImpl(this);
r = pDcMgr->AddRequestInfo(pReqId, pReqInfo);
SysTryCatch(NID_APP, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] Failed to add request info", GetErrorMessage(r));
SysPropagate(NID_APP, r);
reqObj.Invalidate();
pDcMgr->RemoveRequestInfo(*pReqId);
- delete pArg;
return r;
}
+ __pRequestList->Add(new (std::nothrow) Integer(req));
+
if (pReq)
{
*pReq = req;
long long argSize = dataId.GetLength() * sizeof(wchar_t);
argSize += key.GetLength() * sizeof(wchar_t);
SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
- "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
+ "[E_MAX_EXCEEDED] The size of sending argument (%lld) exceeds the maximum limit.", argSize);
pPageNo = new (std::nothrow) String();
pPageNo->Append(pageNo);
reqId = static_cast< RequestId >(id);
- SysLog(NID_APP, "[DC_CALLER_SEND] dataId: %ls, key: %ls, reqId: %d, pageNo: %d, countPerPage: %d",
+ SysLog(NID_APP, "[DC_CALLER_SEND] data: %ls, key: %ls, req: %d, pageNo: %d, countPerPage: %d",
dataId.GetPointer(), key.GetPointer(), reqId, pageNo, countPerPage);
// fall through
}
result
-_MapDataControlImpl::MapDataControlCallback(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop)
+_MapDataControlImpl::MapDataControlCallback(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop, int option)
{
ArrayList* pResultList = null;
+ String version;
String* pResult = null;
String* pProviderId = null;
String* pDataId = null;
String* pErrorMessage = null;
String* pErrorMsg = null;
String* pResultCount = null;
- String* pValue = null;
+ String* pPath = null;
ArrayList* pResultValueList = null;
int resultCount = 0;
int requestType = 0;
int reqId = 0;
+ int launchReqId = 0;
int providerRes = 0;
bool providerResult = true;
//bundle* origBundle = null;
bundle* resBundle = null;
_MapDataControlEventArg* pEventArg = null;
+ const char* p = null;
result r = E_SUCCESS;
SysTryReturnResult(NID_APP, pResArg != null, E_INVALID_ARG, "Empty result callback.");
resBundle = pResArg->GetBundle();
if (resBundle)
{
- const char* p = appsvc_get_data(resBundle, OSP_K_REQUEST_ID);
+ p = appsvc_get_data(resBundle, OSP_K_REQUEST_ID);
SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
reqId = atoi(p);
Integer key(reqId);
_DataControlManager* pDcMgr = static_cast< _DataControlManager* >(data);
_DataControlRequestInfo* pReqInfo = pDcMgr->GetRequestInfo(key);
- SysTryCatch(NID_APP, pReqInfo != null, r = E_SYSTEM, E_SYSTEM,
- "[E_SYSTEM] Failed to get request info");
+ if (pReqInfo == null)
+ {
+ SysLog(NID_APP, "No request info of reqId %d", reqId);
+ return E_SUCCESS;
+ }
_MapDataControlEvent* pMapDataControlEvent = dynamic_cast< _MapDataControlEvent* >(pReqInfo->GetEvent());
- SysTryCatch(NID_APP, pMapDataControlEvent != null, r = E_SYSTEM, E_SYSTEM,
- "[E_SYSTEM] invalid request info");
+ SysTryCatch(NID_APP, pMapDataControlEvent != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request info");
pDcMgr->RemoveRequestInfo(key);
+ _MapDataControlImpl* pDcImpl = pReqInfo->GetMapDataControlImpl();
+ SysTryCatch(NID_APP, pDcImpl != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request info");
+ pDcImpl->__pRequestList->Remove(key);
+
+ // Remove the request from the queue
+ SysLog(NID_APP, "Remove the request, req: %d", reqId);
+
if (pMapDataControlEvent != null && typeid(pMapDataControlEvent) == typeid(_MapDataControlEvent*))
{
SysTryCatch(NID_APP, pDataId, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
"[E_OUT_OF_MEMORY] The memory is insufficient.");
- SysLog(NID_APP, "[DC_CALLER_RECV] provider result: %ld, requestType: %d, reqId: %d, providerId: %ls, dataId: %ls, errorMsg: %ls ",
- providerRes, requestType, reqId, pProviderId->GetPointer(), pDataId->GetPointer(), pErrorMsg->GetPointer());
+ version = pResArg->GetValue(OSP_K_DATACONTROL_PROTOCOL_VERSION);
+
+ SysSecureLog(NID_APP, "[DC_CALLER_RECV] version: %ls, provider result: %ld, requestType: %d, req: %d, provider: %ls, data: %ls, errorMsg: %ls",
+ version.GetPointer(), providerRes, requestType, reqId, pProviderId->GetPointer(), pDataId->GetPointer(), pErrorMsg->GetPointer());
switch (static_cast< _DataControlRequestType >(requestType))
{
case _DATACONTROL_REQUEST_TYPE_MAP_QUERY:
{
- pResultValueList = new (std::nothrow) ArrayList();
+ pResultValueList = new (std::nothrow) ArrayList(SingleObjectDeleter);
SysTryCatch(NID_APP, pResultValueList, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
"[E_OUT_OF_MEMORY] The memory is insufficient.");
if (providerResult == true)
{
pResultCount = dynamic_cast< String* >(pResultList->GetAt(2)); // result list[2]
- if (pResultCount == null)
- {
- SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] invalid result");
- pResultValueList->RemoveAll(true);
- delete pResultValueList;
- goto CATCH;
- }
+ SysTryCatch(NID_APP, pResultCount, delete pResultValueList, E_SYSTEM, "[E_SYSTEM] invalid result");
Integer::Parse(*pResultCount, resultCount);
+ SysLog(NID_APP, "[DC_CALLER_RECV] result count: %d", resultCount);
- int index = 3;
- while (resultCount)
+ if (resultCount > 0)
{
- pValue = dynamic_cast< String* >(pResultList->GetAt(index));
- if (pValue == null)
+ if (version == L"ver_2.1.0.1" || version == L"ver_2.1.0.2" || version == L"ver_2.1.0.3")
{
- SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] invalid result");
- pResultValueList->RemoveAll(true);
- delete pResultValueList;
- goto CATCH;
+ pPath = dynamic_cast< String* >(pResultList->GetAt(3)); // result list[3]
+ SysTryCatch(NID_APP, pPath, delete pResultValueList, E_SYSTEM, "[E_SYSTEM] invalid result");
+ SysLog(NID_APP, "[DC_CALLER_RECV] path: %ls", pPath->GetPointer());
+
+ unique_ptr< File > pFile(new (std::nothrow) File());
+ SysTryCatch(NID_APP, pFile, delete pResultValueList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
+
+ r = pFile->Construct(*pPath, "r");
+ SysTryCatch(NID_APP, !IsFailed(r), delete pResultValueList, r, "[%s] Failed to open result set (%ls)",
+ GetErrorMessage(r), pPath->GetPointer());
+
+ while (resultCount)
+ {
+ int length = 0;
+ int ret = pFile->Read(&length, sizeof(int));
+ SysTryCatch(NID_APP, ret, delete pResultValueList, E_SYSTEM,
+ "[E_SYSTEM] Failed to read data from the result set of data control provider.");
+
+ char* pValue = new (std::nothrow) char[length + 1];
+ SysTryCatch(NID_APP, pValue, delete pResultValueList, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] The memory is insufficient.");
+
+ ret = pFile->Read(pValue, length);
+ if (ret == 0)
+ {
+ SysLogException(NID_APP, E_SYSTEM,
+ "[E_SYSTEM] Failed to read data from the result set of data control provider.");
+ delete pResultValueList;
+ delete[] pValue;
+ goto CATCH;
+ }
+ pValue[length] = '\0';
+
+ pResultValueList->Add(new (std::nothrow) String(pValue));
+ delete[] pValue;
+ --resultCount;
+ }
}
+ else
+ {
+ int index = 3;
+ while (resultCount)
+ {
+ String* pValue = dynamic_cast< String* >(pResultList->GetAt(index)); // result list[3] ~
+ SysTryCatch(NID_APP, pValue, delete pResultValueList, E_SYSTEM, "[E_SYSTEM] invalid result");
+
+ pResultValueList->Add((new (std::nothrow) String(*pValue)));
+ --resultCount;
+ ++index;
+ }
+ }
+ }
- pResultValueList->Add(*(new (std::nothrow) String(*pValue)));
- resultCount--;
- index++;
+ if (pPath)
+ {
+ r = File::Remove(*pPath);
+ SysTryLog(NID_APP, !IsFailed(r), "Failed to remove result: %ls", pPath->GetPointer());
}
}
}
}
- // Remove the request count
- SysLog(NID_APP, "Remove a launch request: reqId: %d", reqId);
- _AppControlManager::GetInstance()->RemoveLaunchRequest(reqId);
+ p = appsvc_get_data(pArg->GetBundle(), OSP_K_REQUEST_ID);
+ SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
+ launchReqId = atoi(p);
return E_SUCCESS;
argSize += key.GetLength() * sizeof(wchar_t);
argSize += value.GetLength() * sizeof(wchar_t);
SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
- "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
+ "[E_MAX_EXCEEDED] The size of sending argument (%lld) exceeds the maximum limit.", argSize);
r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_INSERT, pArgList, &id);
SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
reqId = static_cast< RequestId >(id);
- SysLog(NID_APP, "[DC_CALLER_SEND] dataId: %ls, key: %ls, value: %ls, reqId: %d",
+ SysLog(NID_APP, "[DC_CALLER_SEND] data: %ls, key: %ls, value: %ls, req: %d",
dataId.GetPointer(), key.GetPointer(), value.GetPointer(), reqId);
// fall through
argSize += oldValue.GetLength() * sizeof(wchar_t);
argSize += newValue.GetLength() * sizeof(wchar_t);
SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
- "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
+ "[E_MAX_EXCEEDED] The size of sending argument (%lld) exceeds the maximum limit.", argSize);
r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_UPDATE, pArgList, &id);
SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
reqId = static_cast< RequestId >(id);
- SysLog(NID_APP, "[DC_CALLER_SEND] dataId: %ls, key: %ls, oldValue: %ls, newValue: %ls, reqId: %d",
+ SysLog(NID_APP, "[DC_CALLER_SEND] data: %ls, key: %ls, oldValue: %ls, newValue: %ls, req: %d",
dataId.GetPointer(), key.GetPointer(), oldValue.GetPointer(), newValue.GetPointer(), reqId);
// fall through
argSize += key.GetLength() * sizeof(wchar_t);
argSize += value.GetLength() * sizeof(wchar_t);
SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
- "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
+ "[E_MAX_EXCEEDED] The size of sending argument (%lld) exceeds the maximum limit.", argSize);
r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_DELETE, pArgList, &id);
SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
reqId = static_cast< RequestId >(id);
- SysLog(NID_APP, "[DC_CALLER_SEND] dataId: %ls, key: %ls, value: %ls, reqId: %d",
+ SysLog(NID_APP, "[DC_CALLER_SEND] data: %ls, key: %ls, value: %ls, req: %d",
dataId.GetPointer(), key.GetPointer(), value.GetPointer(), reqId);
// fall through
SysTryReturn(NID_APP, pDc != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient");
_MapDataControlImpl* pDcImpl = _MapDataControlImpl::GetInstance(*pDc);
+ pDcImpl->__appId = appId;
+ pDcImpl->__providerId = providerId;
unique_ptr<_MapDataControlEvent> pMapDataControlEvent(new (std::nothrow) _MapDataControlEvent);
SysTryReturn(NID_IO, pMapDataControlEvent != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
+ pDcImpl->__pRequestList = new (std::nothrow) LinkedList(SingleObjectDeleter);
+ SysTryReturn(NID_IO, pDcImpl->__pRequestList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
+
pDcImpl->__pMapDataControlEvent = pMapDataControlEvent.release();
- pDcImpl->__appId = appId;
- pDcImpl->__providerId = providerId;
if (access == L"readonly")
{