//
-// 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 %_DataControlProviderManagerImpl class.
*/
+#include <new>
#include <unique_ptr.h>
+#include <security-server.h>
#include <FBaseDataType.h>
#include <FBaseInteger.h>
#include <FBaseLongLong.h>
#include <FBaseColArrayList.h>
#include <FBaseColIList.h>
+#include <FBaseSysLog.h>
#include <FBaseErrors.h>
+#include <FAppTypes.h>
#include <FAppAppManager.h>
#include <FAppSqlDataControl.h>
#include <FAppMapDataControl.h>
#include <FAppDataControlProviderManager.h>
+#include <FIoFile.h>
-#include <FBaseSysLog.h>
+#include <FBase_StringConverter.h>
#include <FIo_DataControlResultSetImpl.h>
+#include <FAppPkg_PackageManagerImpl.h>
#include "FApp_Aul.h"
#include "FApp_AppArg.h"
#include "FApp_SqlDataControlImpl.h"
#include "FApp_MapDataControlImpl.h"
#include "FApp_DataControlProviderManagerImpl.h"
+#include "FApp_DataControlManager.h"
+using namespace std;
using namespace Tizen::Base;
using namespace Tizen::Base::Collection;
using namespace Tizen::Io;
+using namespace Tizen::App::Package;
-extern const char* _DATACONTROL_RESULTSET_DIR;
+extern const char* _DATACONTROL_RESULT_DIR;
+extern const char* _DATACONTROL_RESULT_COMPAT_DIR;
namespace Tizen { namespace App
{
+static const int _MAX_ARGUMENT_SIZE = 16384; // 16KB
+
result
_DataControlProviderManagerImpl::SetSqlDataControlProviderEventListener(ISqlDataControlProviderEventListener* pListener)
{
IDbEnumerator* pDbEnum, IList* pResultValueList, long long insertRowId, bool providerResult, const String* pErrorMsg)
{
ArrayList* pList = null;
- String* pAppId = null;
- String* pRequestType = null;
+ String callerAppId;
+ int callerPid = -1;
+ String version;
+ String reqType;
int type = 0;
_DataControlRequestType requestType = _DATACONTROL_REQUEST_TYPE_UNDEFINED;
- String* pProviderId = null;
- String* pReqId = null;
+ String providerId;
+ String callerReqId;
ArrayList* pResultArgList = null;
String* pResult = null;
String* pErrorMessage = null;
String* pResultCount = null;
String* pResultValue = null;
_AppArg resultArg;
+ String* pDataId = null;
result r = E_SUCCESS;
+ //int ret = -1;
_AppControlManager* pAppMgr = _AppControlManager::GetInstance();
SysTryReturnResult(NID_APP, pAppMgr, E_SYSTEM, "Failed to get instance.");
- _ResultInfo* pResultInfo = pAppMgr->__resultManager.FindItem(static_cast< int >(reqId));
+ _ResultInfo* pResultInfo = pAppMgr->__resultManager.FindItem(static_cast< int >(reqId)); // provider reqId
SysTryReturnResult(NID_APP, pResultInfo, E_OBJ_NOT_FOUND,
- "The data control request specified with the reqId (%ld) did not exist.", reqId);
-
- const _AppArg& arg = pResultInfo->arg;
+ "The data control request specified with the req (%ld) did not exist.", reqId);
- pList = arg.GetArgListN(0);
- SysTryCatch(NID_APP, pList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
+ const _AppArg& arg = pResultInfo->arg; // request info
// key-based request
- pAppId = dynamic_cast< String* >(pList->GetAt(0)); // request key[0]
- SysTryCatch(NID_APP, pAppId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
-
- pRequestType = dynamic_cast< String* >(pList->GetAt(1)); // request key[1]
- SysTryCatch(NID_APP, pRequestType, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
- Integer::Parse(*pRequestType, type);
+ reqType = arg.GetValue(OSP_K_DATACONTROL_REQUEST_TYPE);
+ Integer::Parse(reqType, type);
requestType = static_cast< _DataControlRequestType >(type);
-
if (providerResult == true && apiType != requestType)
{
if ((apiType == _DATACONTROL_REQUEST_TYPE_SQL_UPDATE /*UpdateDelete*/ && requestType == _DATACONTROL_REQUEST_TYPE_SQL_DELETE) ||
}
}
- pReqId = dynamic_cast< String* >(pList->GetAt(2)); // request key[2]
- SysTryCatch(NID_APP, pReqId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
+ callerAppId = arg.GetCallerAppId();
+ callerPid = arg.GetCallerPid();
+ version = arg.GetValue(OSP_K_DATACONTROL_PROTOCOL_VERSION);
+ callerReqId = arg.GetValue(OSP_K_REQUEST_ID);
+ providerId = arg.GetValue(OSP_K_DATACONTROL_PROVIDER);
+
+ // list-based request
+ pList = _AppArg::GetListN(arg.GetBundle(), OSP_K_ARG);
+ SysTryCatch(NID_APP, pList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
+
+ pDataId = dynamic_cast< String* >(pList->GetAt(0)); // request list[0]
+ SysTryCatch(NID_APP, pDataId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
- pProviderId = dynamic_cast< String* >(pList->GetAt(3)); // request key[3]
- SysTryCatch(NID_APP, pProviderId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
+ SysSecureLog(NID_APP, "[DC_PROV_SEND] > caller app: %ls, caller proc: %d, version: %ls requestType: %d, callerReq: %ls, provider: %ls, data: %ls",
+ callerAppId.GetPointer(), callerPid, version.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(), pDataId->GetPointer());
- // Serializes the result
+ // Serializes result
pResultArgList = new (std::nothrow) ArrayList();
SysTryCatch(NID_APP, pResultArgList, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
"[E_OUT_OF_MEMORY] The memory was insufficient.");
}
SysTryCatch(NID_APP, pErrorMessage, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
"[E_OUT_OF_MEMORY] The memory was insufficient.");
+ SysTryCatch(NID_APP, pErrorMessage->GetLength() <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
+ "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", pErrorMessage->GetLength());
pResultArgList->Add(*pErrorMessage); // result list[1]
switch (requestType)
{
if (pDbEnum)
{
- std::unique_ptr<_DataControlResultSetImpl> pResultSet(new (std::nothrow) _DataControlResultSetImpl(reqId));
+ unique_ptr<_DataControlResultSetImpl> pResultSet(new (std::nothrow) _DataControlResultSetImpl(reqId));
SysTryCatch(NID_APP, pResultSet, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
"[E_OUT_OF_MEMORY] The memory is insufficient.");
- r = pResultSet->FillWith(pDbEnum);
+ r = pResultSet->FillWith(pDbEnum, version);
SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM,
"[E_SYSTEM] The method cannot proceed due to a severe system error.");
- String tempFilePath(_DATACONTROL_RESULTSET_DIR);
- tempFilePath.Append(*pAppId);
- tempFilePath.Append(*pReqId);
+ String tempFilePath;
+ if (version == L"ver_2.1.0.3")
+ {
+ tempFilePath.Append(_DATACONTROL_RESULT_DIR);
+
+ DataControlProviderManager* pDcMgr = DataControlProviderManager::GetInstance();
+ SysTryCatch(NID_APP, pDcMgr != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get DataControlProviderManager instance.");
+ r = pDcMgr->__pDataControlProviderManagerImpl->AllowAccess(callerAppId);
+ SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
+ }
+ else
+ {
+ tempFilePath.Append(_DATACONTROL_RESULT_COMPAT_DIR);
+ }
+ tempFilePath.Append(callerAppId);
+ tempFilePath.Append(callerReqId);
pTempFilePath = new (std::nothrow) String(tempFilePath);
}
else
if (pResultValueList)
{
// list-based request
- pNo = dynamic_cast< String* >(pList->GetAt(6)); // request list[2]
+ pNo = dynamic_cast< String* >(pList->GetAt(2)); // request list[2]
SysTryCatch(NID_APP, pNo, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
Integer::Parse(*pNo, pageNo);
- pCount = dynamic_cast< String* >(pList->GetAt(7)); // request list[3]
+ pCount = dynamic_cast< String* >(pList->GetAt(3)); // request list[3]
SysTryCatch(NID_APP, pCount, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
Integer::Parse(*pCount, countPerPage);
+ SysLog(NID_APP, "[DC_PROV_SEND] pageNo: %d, countPerPage: %d", pageNo, countPerPage);
String resultCount;
int num = pResultValueList->GetCount();
SysTryCatch(NID_APP, pResultCount, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
"[E_OUT_OF_MEMORY] The memory was insufficient.");
pResultArgList->Add(*pResultCount); // result list[2]
+ SysLog(NID_APP, "[DC_PROV_SEND] result count: %ls", resultCount.GetPointer());
- for (int i = currentoffset; i < num; i++)
+ long long argSize = 0;
+ if (addItemCount > 0)
{
- String* pTempValue = dynamic_cast< String* >(pResultValueList->GetAt(i));
- SysTryCatch(NID_APP, pTempValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
- "[E_INVALID_ARG] The specified pResultValueList parameter should be String class.");
-
- pResultValue = new (std::nothrow) String(*pTempValue);
- SysTryCatch(NID_APP, pResultValue, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
- "[E_OUT_OF_MEMORY] The memory was insufficient.");
- pResultArgList->Add(*pResultValue); // list[3] ~
+ if (version == L"ver_2.1.0.1" || version == L"ver_2.1.0.2" || version == L"ver_2.1.0.3")
+ {
+ String tempFilePath;
+ if (version == L"ver_2.1.0.3")
+ {
+ tempFilePath.Append(_DATACONTROL_RESULT_DIR);
+ }
+ else
+ {
+ tempFilePath.Append(_DATACONTROL_RESULT_COMPAT_DIR);
+ }
+ tempFilePath.Append(callerAppId);
+ tempFilePath.Append(callerReqId);
+ pTempFilePath = new (std::nothrow) String(tempFilePath);
+ pResultArgList->Add(*pTempFilePath); // result list[3]
+ SysLog(NID_APP, "[DC_PROV_SEND] protocol version: %ls, path: %ls", version.GetPointer(), pTempFilePath->GetPointer());
+
+ unique_ptr< File > pFile(new (std::nothrow) File());
+ SysTryCatch(NID_APP, pFile != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
+
+ r = pFile->Construct(*pTempFilePath, L"w+", true);
+ SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to create temp file (%ls) for result set.",
+ GetErrorMessage(r), pTempFilePath->GetPointer());
+
+ for (int i = currentoffset; i < num; ++i)
+ {
+ String* pValue = dynamic_cast< String* >(pResultValueList->GetAt(i));
+ SysTryCatch(NID_APP, pValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] The specified pResultValueList parameter should be String class.");
+
+ unique_ptr< char[] > pData(_StringConverter::CopyToCharArrayN(*pValue));
+ SysTryCatch(NID_APP, pData != null, , GetLastResult(), "[%s] Invalid result value",
+ GetErrorMessage(GetLastResult()));
+
+ int length = strlen(pData.get());
+ r = pFile->Write(&length, sizeof(int)); // data length
+ SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send result.", GetErrorMessage(r));
+
+ r = pFile->Write(pData.get(), length); // data
+ SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send result.", GetErrorMessage(r));
+ }
+ pFile->Flush();
+
+ if (version == L"ver_2.1.0.3")
+ {
+ DataControlProviderManager* pDcMgr = DataControlProviderManager::GetInstance();
+ SysTryCatch(NID_APP, pDcMgr != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get DataControlProviderManager instance.");
+ r = pDcMgr->__pDataControlProviderManagerImpl->AllowAccess(callerAppId);
+ SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
+ }
+ }
+ else
+ {
+ SysLog(NID_APP, "[DC_PROV_SEND] protocol version: none");
+ for (int i = currentoffset; i < num; ++i)
+ {
+ String* pValue = dynamic_cast< String* >(pResultValueList->GetAt(i));
+ SysTryCatch(NID_APP, pValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] The specified pResultValueList parameter should be String class.");
+
+ pResultValue = new (std::nothrow) String(*pValue);
+ SysTryCatch(NID_APP, pResultValue, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] The memory was insufficient.");
+ pResultArgList->Add(*pResultValue); // list[3] ~
+ argSize += pValue->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);
+ }
}
}
break;
r = resultArg.ConstructResult(arg, pResultArgList);
SysTryCatch(NID_APP, !IsFailed(r), r = E_SYSTEM, r, "[%s] Propagating.", GetErrorMessage(r));
+ resultArg.UpdateKeyValue(OSP_K_REQUEST_ID, callerReqId);
+ resultArg.UpdateKeyValue(OSP_K_DATACONTROL_REQUEST_TYPE, reqType);
+ resultArg.UpdateKeyValue(OSP_K_DATACONTROL_PROVIDER, providerId);
+ resultArg.UpdateKeyValue(OSP_K_DATACONTROL_DATA, *pDataId);
+ resultArg.UpdateKeyValue(OSP_K_DATACONTROL_PROTOCOL_VERSION, version);
//resultArg.Print();
- r = _Aul::SendResult(resultArg.GetBundle(), static_cast< appsvc_result_val >(0));
+ r = _Aul::SendResult(resultArg.GetBundle(), static_cast< appsvc_result_val >(0), false, false);
SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to send result.", GetErrorMessage(r));
// Erases _AppArg after sending the result back to the caller
return pDcMgr;
}
-// private
+void
+_DataControlProviderManagerImpl::Cache(const AppId& appId)
+{
+ __pProviderList->Add(new (std::nothrow) String(appId));
+}
+
+bool
+_DataControlProviderManagerImpl::IsCached(const AppId& appId)
+{
+ unique_ptr< IEnumerator > pEnum(__pProviderList->GetEnumeratorN());
+ while (pEnum->MoveNext() == E_SUCCESS)
+ {
+ String* pCachedAppId = dynamic_cast< String* >(pEnum->GetCurrent());
+ if (pCachedAppId != null && pCachedAppId->Equals(appId) == true)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+result
+_DataControlProviderManagerImpl::AllowAccess(const AppId& appId)
+{
+ //if (IsCached(appId) == false)
+ //{
+ const PackageId& pkgId = _PackageManagerImpl::GetPackageIdByAppId(appId);
+ unique_ptr< char[] > pPkgId(_StringConverter::CopyToCharArrayN(pkgId));
+ SysTryReturnResult(NID_APP, pPkgId != null, E_SYSTEM, "The method cannot proceed due to a severe system error.");
+
+ int ret = security_server_app_give_access(pPkgId.get(), -1);
+ SysTryReturnResult(NID_APP, ret == 0, E_SYSTEM,
+ "Failed to call security_server_app_give_access(), provider: %s, ret: %d", pPkgId.get(), ret);
+
+ // Cache(appId);
+ //}
+
+ SysLog(NID_APP, "[DC_PROV_SEND] Allow %ls to access", appId.GetPointer());
+ return E_SUCCESS;
+}
+
_DataControlProviderManagerImpl::_DataControlProviderManagerImpl(void)
+ : __pProviderList(null)
{
+ __pProviderList = new (std::nothrow) LinkedList(SingleObjectDeleter);
+ SysTryReturnVoidResult(NID_APP, __pProviderList != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
}
_DataControlProviderManagerImpl::~_DataControlProviderManagerImpl(void)
{
+ delete __pProviderList;
}
-} } // Tizen::App
+}} // Tizen::App