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_DataControlProviderManagerImpl.cpp
19 * @brief This is the implementation for the %_DataControlProviderManagerImpl class.
23 #include <unique_ptr.h>
24 #include <security-server.h>
26 #include <FBaseDataType.h>
27 #include <FBaseInteger.h>
28 #include <FBaseString.h>
29 #include <FBaseLongLong.h>
30 #include <FBaseColArrayList.h>
31 #include <FBaseColIList.h>
32 #include <FBaseSysLog.h>
33 #include <FBaseErrors.h>
34 #include <FAppAppManager.h>
35 #include <FAppSqlDataControl.h>
36 #include <FAppMapDataControl.h>
37 #include <FAppDataControlProviderManager.h>
40 #include <FBase_StringConverter.h>
41 #include <FIo_DataControlResultSetImpl.h>
44 #include "FApp_AppArg.h"
45 #include "FApp_AppInfo.h"
46 #include "FApp_AppImpl.h"
47 #include "FApp_AppControlManager.h"
48 #include "FApp_SqlDataControlImpl.h"
49 #include "FApp_MapDataControlImpl.h"
50 #include "FApp_DataControlProviderManagerImpl.h"
51 #include "FApp_DataControlManager.h"
54 using namespace Tizen::Base;
55 using namespace Tizen::Base::Collection;
56 using namespace Tizen::Io;
58 extern const char* _DATACONTROL_RESULT_DIR;
59 extern const char* _DATACONTROL_RESULT_COMPAT_DIR;
61 namespace Tizen { namespace App
64 static const int _MAX_ARGUMENT_SIZE = 16384; // 16KB
67 _DataControlProviderManagerImpl::SetSqlDataControlProviderEventListener(ISqlDataControlProviderEventListener* pListener)
69 _AppImpl* pAppImpl = _AppImpl::GetInstance();
70 SysTryReturn(NID_APP, pAppImpl, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting _AppImpl instance failed.");
72 return pAppImpl->SetSqlDataControlProviderEventListener(pListener);
76 _DataControlProviderManagerImpl::SetMapDataControlProviderEventListener(IMapDataControlProviderEventListener* pListener)
78 _AppImpl* pAppImpl = _AppImpl::GetInstance();
79 SysTryReturn(NID_APP, pAppImpl, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting _AppImpl instance failed.");
81 return pAppImpl->SetMapDataControlProviderEventListener(pListener);
85 _DataControlProviderManagerImpl::SendDataControlResult(RequestId reqId, _DataControlRequestType apiType,
86 IDbEnumerator* pDbEnum, IList* pResultValueList, long long insertRowId, bool providerResult, const String* pErrorMsg)
88 ArrayList* pList = null;
94 _DataControlRequestType requestType = _DATACONTROL_REQUEST_TYPE_UNDEFINED;
97 ArrayList* pResultArgList = null;
98 String* pResult = null;
99 String* pErrorMessage = null;
100 String* pTempFilePath = null;
103 String* pCount = null;
104 int countPerPage = 0;
105 String* pResultCount = null;
106 String* pResultValue = null;
108 String* pDataId = null;
109 result r = E_SUCCESS;
112 _AppControlManager* pAppMgr = _AppControlManager::GetInstance();
113 SysTryReturnResult(NID_APP, pAppMgr, E_SYSTEM, "Failed to get instance.");
115 _ResultInfo* pResultInfo = pAppMgr->__resultManager.FindItem(static_cast< int >(reqId)); // provider reqId
116 SysTryReturnResult(NID_APP, pResultInfo, E_OBJ_NOT_FOUND,
117 "The data control request specified with the req (%ld) did not exist.", reqId);
119 const _AppArg& arg = pResultInfo->arg; // request info
122 reqType = arg.GetValue(OSP_K_DATACONTROL_REQUEST_TYPE);
123 Integer::Parse(reqType, type);
124 requestType = static_cast< _DataControlRequestType >(type);
125 if (providerResult == true && apiType != requestType)
127 if ((apiType == _DATACONTROL_REQUEST_TYPE_SQL_UPDATE /*UpdateDelete*/ && requestType == _DATACONTROL_REQUEST_TYPE_SQL_DELETE) ||
128 apiType == _DATACONTROL_REQUEST_TYPE_UNDEFINED /*MAP*/)
135 SysLog(NID_APP, "[E_INVALID_ARG] This method cannot send the result set for the specified reqId.");
140 callerAppId = arg.GetCallerAppId();
141 callerPid = arg.GetCallerPid();
142 version = arg.GetValue(OSP_K_DATACONTROL_PROTOCOL_VERSION);
143 callerReqId = arg.GetValue(OSP_K_REQUEST_ID);
144 providerId = arg.GetValue(OSP_K_DATACONTROL_PROVIDER);
146 // list-based request
147 pList = _AppArg::GetListN(arg.GetBundle(), OSP_K_ARG);
148 SysTryCatch(NID_APP, pList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
150 pDataId = dynamic_cast< String* >(pList->GetAt(0)); // request list[0]
151 SysTryCatch(NID_APP, pDataId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
153 SysSecureLog(NID_APP, "[DC_PROV_SEND] > caller app: %ls, caller proc: %d, version: %ls requestType: %d, callerReq: %ls, provider: %ls, data: %ls",
154 callerAppId.GetPointer(), callerPid, version.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(), pDataId->GetPointer());
157 pResultArgList = new (std::nothrow) ArrayList();
158 SysTryCatch(NID_APP, pResultArgList, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
159 "[E_OUT_OF_MEMORY] The memory was insufficient.");
160 pResultArgList->Construct();
162 pResult = new (std::nothrow) String();
163 SysTryCatch(NID_APP, pResult, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
164 "[E_OUT_OF_MEMORY] The memory was insufficient.");
165 pResult->Append(static_cast< int >(providerResult));
166 pResultArgList->Add(*pResult); // result list[0]
168 if (pErrorMsg == null)
170 pErrorMessage = new (std::nothrow) String();
174 pErrorMessage = new (std::nothrow) String(*pErrorMsg);
176 SysTryCatch(NID_APP, pErrorMessage, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
177 "[E_OUT_OF_MEMORY] The memory was insufficient.");
178 SysTryCatch(NID_APP, pErrorMessage->GetLength() <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
179 "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", pErrorMessage->GetLength());
180 pResultArgList->Add(*pErrorMessage); // result list[1]
184 case _DATACONTROL_REQUEST_TYPE_SQL_QUERY:
188 unique_ptr<_DataControlResultSetImpl> pResultSet(new (std::nothrow) _DataControlResultSetImpl(reqId));
189 SysTryCatch(NID_APP, pResultSet, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
190 "[E_OUT_OF_MEMORY] The memory is insufficient.");
192 r = pResultSet->FillWith(pDbEnum, version);
193 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM,
194 "[E_SYSTEM] The method cannot proceed due to a severe system error.");
197 if (version == L"ver_2.1.0.3")
199 tempFilePath.Append(_DATACONTROL_RESULT_DIR);
201 DataControlProviderManager* pDcMgr = DataControlProviderManager::GetInstance();
202 SysTryCatch(NID_APP, pDcMgr != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get DataControlProviderManager instance.");
203 r = pDcMgr->__pDataControlProviderManagerImpl->AllowAccess(callerAppId);
204 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
208 tempFilePath.Append(_DATACONTROL_RESULT_COMPAT_DIR);
210 tempFilePath.Append(callerAppId);
211 tempFilePath.Append(callerReqId);
212 pTempFilePath = new (std::nothrow) String(tempFilePath);
216 pTempFilePath = new (std::nothrow) String(L"NoResultSet");
218 SysTryCatch(NID_APP, pTempFilePath, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
219 "[E_OUT_OF_MEMORY] The memory is insufficient.");
221 pResultArgList->Add(*pTempFilePath); // result list[2]
224 case _DATACONTROL_REQUEST_TYPE_SQL_INSERT:
225 pResultArgList->Add(*(new String(LongLong::ToString(insertRowId)))); // result list[2]
228 case _DATACONTROL_REQUEST_TYPE_SQL_UPDATE:
230 case _DATACONTROL_REQUEST_TYPE_SQL_DELETE:
233 case _DATACONTROL_REQUEST_TYPE_MAP_QUERY:
235 SysTryCatch(NID_APP, !(providerResult == true && pResultValueList == null), r = E_INVALID_ARG, E_INVALID_ARG,
236 "[E_INVALID_ARG] The specified pResultValueList should not be null if the request is GetValue query.");
238 if (pResultValueList)
240 // list-based request
241 pNo = dynamic_cast< String* >(pList->GetAt(2)); // request list[2]
242 SysTryCatch(NID_APP, pNo, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
243 Integer::Parse(*pNo, pageNo);
245 pCount = dynamic_cast< String* >(pList->GetAt(3)); // request list[3]
246 SysTryCatch(NID_APP, pCount, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
247 Integer::Parse(*pCount, countPerPage);
248 SysLog(NID_APP, "[DC_PROV_SEND] pageNo: %d, countPerPage: %d", pageNo, countPerPage);
251 int num = pResultValueList->GetCount();
252 int currentoffset = (pageNo - 1) * countPerPage;
253 int remainingNum = num - currentoffset;
254 remainingNum = (remainingNum > 0) ? remainingNum : 0; // round off to zero if negative num is found
255 int addItemCount = (countPerPage > remainingNum) ? remainingNum : countPerPage;
256 resultCount.Append(addItemCount);
258 pResultCount = new (std::nothrow) String(resultCount);
259 SysTryCatch(NID_APP, pResultCount, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
260 "[E_OUT_OF_MEMORY] The memory was insufficient.");
261 pResultArgList->Add(*pResultCount); // result list[2]
262 SysLog(NID_APP, "[DC_PROV_SEND] result count: %ls", resultCount.GetPointer());
264 long long argSize = 0;
265 if (addItemCount > 0)
267 if (version == L"ver_2.1.0.1" || version == L"ver_2.1.0.2" || version == L"ver_2.1.0.3")
270 if (version == L"ver_2.1.0.3")
272 tempFilePath.Append(_DATACONTROL_RESULT_DIR);
276 tempFilePath.Append(_DATACONTROL_RESULT_COMPAT_DIR);
278 tempFilePath.Append(callerAppId);
279 tempFilePath.Append(callerReqId);
280 pTempFilePath = new (std::nothrow) String(tempFilePath);
281 pResultArgList->Add(*pTempFilePath); // result list[3]
282 SysLog(NID_APP, "[DC_PROV_SEND] protocol version: %ls, path: %ls", version.GetPointer(), pTempFilePath->GetPointer());
284 unique_ptr< File > pFile(new (std::nothrow) File());
285 SysTryCatch(NID_APP, pFile != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
287 r = pFile->Construct(*pTempFilePath, L"w+", true);
288 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to create temp file (%ls) for result set.",
289 GetErrorMessage(r), pTempFilePath->GetPointer());
291 for (int i = currentoffset; i < num; ++i)
293 String* pValue = dynamic_cast< String* >(pResultValueList->GetAt(i));
294 SysTryCatch(NID_APP, pValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
295 "[E_INVALID_ARG] The specified pResultValueList parameter should be String class.");
297 unique_ptr< char[] > pData(_StringConverter::CopyToCharArrayN(*pValue));
298 SysTryCatch(NID_APP, pData != null, , GetLastResult(), "[%s] Invalid result value",
299 GetErrorMessage(GetLastResult()));
301 int length = strlen(pData.get());
302 r = pFile->Write(&length, sizeof(int)); // data length
303 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send result.", GetErrorMessage(r));
305 r = pFile->Write(pData.get(), length); // data
306 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send result.", GetErrorMessage(r));
310 if (version == L"ver_2.1.0.3")
312 DataControlProviderManager* pDcMgr = DataControlProviderManager::GetInstance();
313 SysTryCatch(NID_APP, pDcMgr != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get DataControlProviderManager instance.");
314 r = pDcMgr->__pDataControlProviderManagerImpl->AllowAccess(callerAppId);
315 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
320 SysLog(NID_APP, "[DC_PROV_SEND] protocol version: none");
321 for (int i = currentoffset; i < num; ++i)
323 String* pValue = dynamic_cast< String* >(pResultValueList->GetAt(i));
324 SysTryCatch(NID_APP, pValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
325 "[E_INVALID_ARG] The specified pResultValueList parameter should be String class.");
327 pResultValue = new (std::nothrow) String(*pValue);
328 SysTryCatch(NID_APP, pResultValue, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
329 "[E_OUT_OF_MEMORY] The memory was insufficient.");
330 pResultArgList->Add(*pResultValue); // list[3] ~
331 argSize += pValue->GetLength() * sizeof(wchar_t);
333 SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
334 "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
340 case _DATACONTROL_REQUEST_TYPE_MAP_INSERT:
342 case _DATACONTROL_REQUEST_TYPE_MAP_UPDATE:
344 case _DATACONTROL_REQUEST_TYPE_MAP_DELETE:
345 SysTryCatch(NID_APP, !(providerResult == true && pResultValueList != null), r = E_INVALID_ARG, E_INVALID_ARG,
346 "[E_INVALID_ARG] The specified pResultValueList should be null if the request is \
347 one of AddValue, SetValue, RemoveValue queries.");
351 SysTryCatch(NID_APP, false, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
355 r = resultArg.ConstructResult(arg, pResultArgList);
356 SysTryCatch(NID_APP, !IsFailed(r), r = E_SYSTEM, r, "[%s] Propagating.", GetErrorMessage(r));
357 resultArg.UpdateKeyValue(OSP_K_REQUEST_ID, callerReqId);
358 resultArg.UpdateKeyValue(OSP_K_DATACONTROL_REQUEST_TYPE, reqType);
359 resultArg.UpdateKeyValue(OSP_K_DATACONTROL_PROVIDER, providerId);
360 resultArg.UpdateKeyValue(OSP_K_DATACONTROL_DATA, *pDataId);
361 resultArg.UpdateKeyValue(OSP_K_DATACONTROL_PROTOCOL_VERSION, version);
364 r = _Aul::SendResult(resultArg.GetBundle(), static_cast< appsvc_result_val >(0));
365 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to send result.", GetErrorMessage(r));
367 // Erases _AppArg after sending the result back to the caller
368 pAppMgr->__resultManager.RemoveItem(static_cast< int >(reqId));
373 pList->RemoveAll(true);
379 pResultArgList->RemoveAll(true);
381 delete pResultArgList;
387 _DataControlProviderManagerImpl::SendSqlDataControlSelectResult(RequestId reqId, IDbEnumerator* pDbEnum)
389 return _DataControlProviderManagerImpl::SendDataControlResult(reqId, _DATACONTROL_REQUEST_TYPE_SQL_QUERY,
390 pDbEnum, null, -1, true, null);
394 _DataControlProviderManagerImpl::SendSqlDataControlInsertResult(RequestId reqId, long long insertRowId)
396 return _DataControlProviderManagerImpl::SendDataControlResult(reqId, _DATACONTROL_REQUEST_TYPE_SQL_INSERT,
397 null, null, insertRowId, true, null);
401 _DataControlProviderManagerImpl::SendSqlDataControlUpdateDeleteResult(RequestId reqId)
403 return _DataControlProviderManagerImpl::SendDataControlResult(reqId, _DATACONTROL_REQUEST_TYPE_SQL_UPDATE,
404 null, null, -1, true, null);
408 _DataControlProviderManagerImpl::SendMapDataControlResult(RequestId reqId, IList* pResultValueList)
410 return _DataControlProviderManagerImpl::SendDataControlResult(reqId, _DATACONTROL_REQUEST_TYPE_UNDEFINED,
411 null, pResultValueList, -1, true, null);
415 _DataControlProviderManagerImpl::SendDataControlError(RequestId reqId, const String& errorMsg)
417 return _DataControlProviderManagerImpl::SendDataControlResult(reqId, _DATACONTROL_REQUEST_TYPE_UNDEFINED,
418 null, null, -1, false, &errorMsg);
421 DataControlProviderManager*
422 _DataControlProviderManagerImpl::GetInstance(void)
424 static DataControlProviderManager* pDcMgr = null;
428 pDcMgr = new (std::nothrow) DataControlProviderManager();
429 SysTryReturn(NID_APP, pDcMgr, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory was insufficient.");
436 _DataControlProviderManagerImpl::Cache(String& appId)
438 __pProviderList->Add(new (std::nothrow) String(appId));
442 _DataControlProviderManagerImpl::IsCached(String& appId)
444 unique_ptr< IEnumerator > pEnum(__pProviderList->GetEnumeratorN());
445 while (pEnum->MoveNext() == E_SUCCESS)
447 String* pCachedAppId = dynamic_cast< String* >(pEnum->GetCurrent());
448 if (pCachedAppId != null && pCachedAppId->Equals(appId) == true)
457 _DataControlProviderManagerImpl::AllowAccess(String& appId)
459 if (IsCached(appId) == false)
461 unique_ptr< char[] > pPkgId(_StringConverter::CopyToCharArrayN(appId));
462 SysTryReturnResult(NID_APP, pPkgId != null, E_SYSTEM, "The method cannot proceed due to a severe system error.");
463 pPkgId.get()[10] = '\0';
465 int ret = security_server_app_give_access(pPkgId.get(), -1);
466 SysTryReturnResult(NID_APP, ret == 0, E_SYSTEM,
467 "Failed to call security_server_app_give_access(), provider: %s, ret: %d", pPkgId.get(), ret);
472 SysLog(NID_APP, "[DC_PROV_SEND] Allow %ls to access", appId.GetPointer());
476 _DataControlProviderManagerImpl::_DataControlProviderManagerImpl(void)
477 : __pProviderList(null)
479 __pProviderList = new (std::nothrow) LinkedList(SingleObjectDeleter);
480 SysTryReturnVoidResult(NID_APP, __pProviderList != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
483 _DataControlProviderManagerImpl::~_DataControlProviderManagerImpl(void)
485 delete __pProviderList;