2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FSys_RuntimeInfoStub.cpp
20 * @brief This is the implementation for the _RuntimeInfoStub class.
27 #include <FBaseSysLog.h>
28 #include <FBase_StringConverter.h>
29 #include <FIo_IpcServer.h>
30 #include <FIo_AppServiceIpcMessages.h>
33 #include "FSys_RuntimeInfo.h"
34 #include "FSys_RuntimeInfoStub.h"
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Collection;
38 using namespace Tizen::Io;
39 using namespace Tizen::System;
40 using namespace Tizen::App;
43 static const wchar_t* RUNTIME_INFO_STUB_MUTEX_ID = L"osp.sys.ipcserver.runtimeinfo";
44 static const int _RUNTIME_GET_PARAM_TYPE = 1;
45 static const wchar_t* _RUNTIME_SERVICE_ID = L"osp.sys.ipcserver.runtimeinfo";
46 static const wchar_t* _RUNTIME_GET_SIZE = L"osp.system.command.runtime.get.size";
47 static const wchar_t* _RUNTIME_RESULT_SUCCESS = L"osp.system.result.success";
48 static const wchar_t* _RUNTIME_RESULT_SYSTEM = L"osp.system.result.system";
51 _RuntimeInfoStub* _RuntimeInfoStub::__pRuntimeInfoStub = null;
53 static pthread_mutex_t send_msg_lock;
54 class _DirectorySizeObject
57 _DirectorySizeObject()
63 ~_DirectorySizeObject()
76 _RuntimeInfoStub::_RuntimeInfoStub(void)
78 , __pIpcEventForAsync(null)
81 r = __Mutex.Create(RUNTIME_INFO_STUB_MUTEX_ID);
82 SysTryReturn(NID_SYS, r == E_SUCCESS, , r, "It is failed to create mutex. [%s] Propaged.", GetErrorMessage(r));
84 if(pthread_mutex_init(&send_msg_lock, null))
86 SysLogException(NID_SYS, E_SYSTEM, "It is failed to init mutex.");
90 _RuntimeInfoStub::~_RuntimeInfoStub(void)
97 result r = __Mutex.Release();
98 SysTryReturn(NID_SYS, r == E_SUCCESS, , r, "It is failed to release mutex. [%s] Propaged.", GetErrorMessage(r));
100 if(pthread_mutex_destroy(&send_msg_lock))
102 SysLogException(NID_SYS, E_SYSTEM, "It is failed to term mutex.");
107 _RuntimeInfoStub::GetInstance(void)
109 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
111 if (__pRuntimeInfoStub == null)
113 pthread_once(&onceBlock, InitSingleton);
115 return __pRuntimeInfoStub;
119 _RuntimeInfoStub::InitSingleton(void)
121 std::unique_ptr< _RuntimeInfoStub > pRuntimeInfoStub(new (std::nothrow) _RuntimeInfoStub());
122 SysTryReturn(NID_SYS, pRuntimeInfoStub, , E_OUT_OF_MEMORY, "It is not enough memory.");
124 result r = pRuntimeInfoStub->Construct();
125 SysTryReturn(NID_SYS, !IsFailed(r), , r, "[%s] It is failed to get RuntimeInfoCommunicationStub.", GetErrorMessage(r));
126 __pRuntimeInfoStub = pRuntimeInfoStub.release();
127 atexit(DestroySingleton);
131 _RuntimeInfoStub::DestroySingleton(void)
133 delete __pRuntimeInfoStub;
137 _RuntimeInfoStub::Construct(void)
139 std::unique_ptr<_IpcServer> pIpcServer(new (std::nothrow) _IpcServer());
140 SysTryReturnResult(NID_SYS, pIpcServer, E_OUT_OF_MEMORY, "Memory is insufficient.");
142 result r = pIpcServer->Construct(String(_RUNTIME_SERVICE_ID), *this, true);
143 SysTryReturnResult(NID_SYS, r == E_SUCCESS, r, "It is failed to construct.");
145 r = pIpcServer->Start();
146 SysTryReturnResult(NID_SYS, r == E_SUCCESS, r, "It is failed to start.");
148 __pIpcServer = move(pIpcServer);
153 _RuntimeInfoStub::OnIpcRequestReceived(_IpcServer& server, const IPC::Message& message)
155 __currentPid = server.GetClientId();
156 IPC_BEGIN_MESSAGE_MAP(_RuntimeInfoStub, message)
157 IPC_MESSAGE_HANDLER_EX(IoService_Request, &server, OnRequestOccured)
158 IPC_END_MESSAGE_MAP_EX()
162 _RuntimeInfoStub::OnRequestOccured(const ArrayList& request, ArrayList* response)
164 bool isSuccess = false;
165 result r = E_SUCCESS;
167 __serviceId = _RUNTIME_SERVICE_ID;
168 __command = *((String*)request.GetAt(_RUNTIME_GET_PARAM_TYPE));
171 if(__command == _RUNTIME_GET_SIZE)
174 String* path = (String*)request.GetAt(_RUNTIME_GET_PARAM_TYPE+1);
175 String* messageId = (String*)request.GetAt(_RUNTIME_GET_PARAM_TYPE+2);
176 SysTryCatch(NID_SYS, path != null, r = E_SYSTEM, E_SYSTEM, "There is no path information.");
178 std::unique_ptr< char > directoryPath(_StringConverter::CopyToCharArrayN(*path));
179 Integer::Parse(*messageId, mid);
180 _DirectorySizeObject* dso = new (std::nothrow) _DirectorySizeObject();
181 dso->pid = __currentPid;
182 dso->path = directoryPath.release();
186 int thr_id = pthread_create(&p_thread, null, _RuntimeInfoStub::GetDirectorySizeAsync, dso);
189 __result = _RUNTIME_RESULT_SYSTEM;
193 pthread_detach(p_thread);
194 __result = _RUNTIME_RESULT_SUCCESS;
199 __result = _RUNTIME_RESULT_SYSTEM;
204 response->Add(__serviceId);
205 response->Add(__command);
206 if (isSuccess == true)
208 response->Add(__result);
211 ArrayList* temp = const_cast<ArrayList*>(&request);
212 temp->RemoveAll(true);
217 _RuntimeInfoStub::GetDirectorySizeAsync(void* data)
222 _DirectorySizeObject* dso = (_DirectorySizeObject*) data;
223 SysTryCatch(NID_SYS, dso != null, r = E_SYSTEM, r, "There is no _DirectorySizeObject.");
224 size = _RuntimeInfo::GetDirectorySize(dso->path);
227 _RuntimeInfoStub::SendResponse(dso->pid, dso->msg_id, size, r);
233 _RuntimeInfoStub::SendResponse(int pid, int msg_id, long long size, result rcode)
235 result r = E_SUCCESS;
236 pthread_mutex_lock(&send_msg_lock);
238 ArrayList* data = null;
239 String* pValue = null;
240 String* pMessageId = null;
242 SysLog(NID_SYS, "It sends asynchronous result to pid [%d].", pid);
244 data = new (std::nothrow) ArrayList(SingleObjectDeleter);
247 pMessageId = new (std::nothrow) String();
248 pMessageId->Append(msg_id);
250 data->Add(new (std::nothrow) String(_RUNTIME_SERVICE_ID));
251 data->Add(new (std::nothrow) String(_RUNTIME_GET_SIZE));
252 data->Add(pMessageId);
254 pValue = new (std::nothrow) String();
255 pValue->Append(size);
258 if(rcode == E_SUCCESS)
260 data->Add(new (std::nothrow) String(_RUNTIME_RESULT_SUCCESS));
264 data->Add(new (std::nothrow) String(_RUNTIME_RESULT_SYSTEM));
267 _RuntimeInfoStub* pRuntimeInfoStub = null;
268 pRuntimeInfoStub = _RuntimeInfoStub::GetInstance();
269 SysTryReturn(NID_SYS, pRuntimeInfoStub, , E_SYSTEM, "RuntimeInfoStub is not created.");
271 pRuntimeInfoStub->SendDataAsync(pid, data);
273 pthread_mutex_unlock(&send_msg_lock);
278 _RuntimeInfoStub::SendDataAsync(const int pid, Tizen::Base::Collection::ArrayList* data)
281 result r = E_SUCCESS;
283 SysTryCatch(NID_SYS, __pIpcServer != null, r = E_SYSTEM, E_SYSTEM, "IPC server is not ready.");
284 SysTryCatch(NID_SYS, data != null, r = E_SYSTEM, E_SYSTEM, "There is no data.");
286 if(__pIpcEventForAsync == null)
288 __pIpcEventForAsync.reset(new (std::nothrow) _SystemServiceIpcEventForAsync(__pIpcServer.get()));
289 SysTryCatch(NID_SYS, __pIpcEventForAsync != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "It is not enough memory.");
290 __pIpcEventForAsync->Construct(1048576, Tizen::Base::Runtime::THREAD_PRIORITY_MID);
291 __pIpcEventForAsync->Start();
294 r = __pIpcEventForAsync->SendUserEvent((RequestId)pid, (IList*)data);
295 SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "Message is failed to add on event thread.");