--- /dev/null
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file FSys_RuntimeInfoStub.h
+ * @brief This is the header file of the _RuntimeInfoStub class.
+ *
+ * This header file contains the declarations of the _RuntimeInfoStub class.
+ */
+
+#ifndef _FSYS_RUNTIME_INFO_STUB_H_
+#define _FSYS_RUNTIME_INFO_STUB_H_
+
+#include <unique_ptr.h>
+#include <FBase.h>
+#include <FSystem.h>
+#include <FIo_IIpcServerEventListener.h>
+
+#include "FSys_SystemServiceIpcEventForAsync.h"
+
+namespace Tizen { namespace System
+{
+class _OSP_EXPORT_ _RuntimeInfoStub
+ : public Tizen::Base::Object
+ , public Tizen::Io::_IIpcServerEventListener
+{
+public:
+ static _RuntimeInfoStub* GetInstance(void);
+ virtual ~_RuntimeInfoStub(void);
+
+private:
+ static void InitSingleton(void);
+ static void DestroySingleton(void);
+
+ _RuntimeInfoStub(void);
+ result Construct(void);
+
+ bool OnRequestOccured(const Tizen::Base::Collection::ArrayList& request, Tizen::Base::Collection::ArrayList* response);
+ virtual void OnIpcRequestReceived(Tizen::Io::_IpcServer& server, const IPC::Message& message);
+ result SendDataAsync(const int pid, Tizen::Base::Collection::ArrayList* data);
+
+ static void SendResponse(int pid, int msg_id, long long size, result rcode);
+ static void* GetDirectorySizeAsync(void* data);
+
+ virtual void OnIpcServerStarted(const Tizen::Io::_IpcServer& server) {}
+ virtual void OnIpcServerStopped(const Tizen::Io::_IpcServer& server) {}
+ virtual void OnIpcClientConnected(const Tizen::Io::_IpcServer& server, int clientId) {}
+ virtual void OnIpcClientDisconnected(const Tizen::Io::_IpcServer&server, int clientId) {}
+
+private:
+ int __currentPid;
+ Tizen::Base::String __serviceId;
+ Tizen::Base::String __command;
+ Tizen::Base::String __result;
+
+ std::unique_ptr< Tizen::Io::_IpcServer > __pIpcServer;
+ std::unique_ptr< _SystemServiceIpcEventForAsync > __pIpcEventForAsync;
+
+ static _RuntimeInfoStub* __pRuntimeInfoStub;
+ Tizen::Base::Runtime::Mutex __Mutex;
+}; // _RuntimeInfoStub
+
+}} // Tizen::System
+
+#endif // _FSYS_RUNTIME_INFO_STUB_H_
--- /dev/null
+//
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file FSys_SystemServiceIpcEventForAsync.cpp
+ * @brief This is the header file for the %_SystemServiceIpcEventForAsync class.
+ *
+ * This header file contains the declarations of the %_SystemServiceIpcEventForAsync class.
+ */
+
+#include <FIo_AppServiceIpcMessages.h>
+#include "FSys_SystemServiceIpcEventForAsync.h"
+
+using namespace Tizen::Base;
+using namespace Tizen::Base::Collection;
+using namespace Tizen::Base::Runtime;
+using namespace Tizen::Io;
+
+namespace Tizen{ namespace System {
+
+_SystemServiceIpcEventForAsync::_SystemServiceIpcEventForAsync(_IpcServer *pIpcServer)
+{
+ __pIpcServer = pIpcServer;
+}
+
+result
+_SystemServiceIpcEventForAsync::Construct(long stackSize, ThreadPriority priority)
+{
+ return EventDrivenThread::Construct(stackSize, priority);
+}
+
+void
+_SystemServiceIpcEventForAsync::OnUserEventReceivedN(RequestId requestId, IList *pArgs)
+{
+ if(pArgs != null)
+ {
+ ArrayList* data = (ArrayList*)pArgs;
+ result r = __pIpcServer->SendResponse((int)requestId, new (std::nothrow) IoService_Data(*data));
+ delete pArgs;
+ SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM,
+ "It is failed to send IPC message to %d. [%s]", (int)requestId, GetErrorMessage(r));
+ }
+}
+
+}}
--- /dev/null
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file FSys_RuntimeInfoStub.cpp
+ * @brief This is the implementation for the _RuntimeInfoStub class.
+ */
+#include <pthread.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <FBaseSysLog.h>
+#include <FBase_StringConverter.h>
+#include <FIo_IpcServer.h>
+#include <FIo_AppServiceIpcMessages.h>
+#include <FSystem.h>
+
+#include "FSys_RuntimeInfo.h"
+#include "FSys_RuntimeInfoStub.h"
+
+using namespace Tizen::Base;
+using namespace Tizen::Base::Collection;
+using namespace Tizen::Io;
+using namespace Tizen::System;
+using namespace Tizen::App;
+
+namespace {
+ static const wchar_t* RUNTIME_INFO_STUB_MUTEX_ID = L"osp.sys.ipcserver.runtimeinfo";
+ static const int _RUNTIME_GET_PARAM_TYPE = 1;
+ static const wchar_t* _RUNTIME_SERVICE_ID = L"osp.sys.ipcserver.runtimeinfo";
+ static const wchar_t* _RUNTIME_GET_SIZE = L"osp.system.command.runtime.get.size";
+ static const wchar_t* _RUNTIME_RESULT_SUCCESS = L"osp.system.result.success";
+ static const wchar_t* _RUNTIME_RESULT_SYSTEM = L"osp.system.result.system";
+}
+
+_RuntimeInfoStub* _RuntimeInfoStub::__pRuntimeInfoStub = null;
+
+static pthread_mutex_t send_msg_lock;
+class _DirectorySizeObject
+{
+public:
+ _DirectorySizeObject()
+ : path(null)
+ , pid(0)
+ , msg_id(0)
+ {
+ }
+ ~_DirectorySizeObject()
+ {
+ if(path != null)
+ {
+ delete [] path;
+ }
+ }
+
+ char* path;
+ int pid;
+ int msg_id;
+};
+
+_RuntimeInfoStub::_RuntimeInfoStub(void)
+ : __pIpcServer(null)
+ , __pIpcEventForAsync(null)
+{
+ result r = E_SUCCESS;
+ r = __Mutex.Create(RUNTIME_INFO_STUB_MUTEX_ID);
+ SysTryReturn(NID_SYS, r == E_SUCCESS, , r, "It is failed to create mutex. [%s] Propaged.", GetErrorMessage(r));
+
+ if(pthread_mutex_init(&send_msg_lock, null))
+ {
+ SysLogException(NID_SYS, E_SYSTEM, "It is failed to init mutex.");
+ }
+}
+
+_RuntimeInfoStub::~_RuntimeInfoStub(void)
+{
+ if (__pIpcServer)
+ {
+ __pIpcServer->Stop();
+ }
+
+ result r = __Mutex.Release();
+ SysTryReturn(NID_SYS, r == E_SUCCESS, , r, "It is failed to release mutex. [%s] Propaged.", GetErrorMessage(r));
+
+ if(pthread_mutex_destroy(&send_msg_lock))
+ {
+ SysLogException(NID_SYS, E_SYSTEM, "It is failed to term mutex.");
+ }
+}
+
+_RuntimeInfoStub*
+_RuntimeInfoStub::GetInstance(void)
+{
+ static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
+
+ if (__pRuntimeInfoStub == null)
+ {
+ pthread_once(&onceBlock, InitSingleton);
+ }
+ return __pRuntimeInfoStub;
+}
+
+void
+_RuntimeInfoStub::InitSingleton(void)
+{
+ std::unique_ptr< _RuntimeInfoStub > pRuntimeInfoStub(new (std::nothrow) _RuntimeInfoStub());
+ SysTryReturn(NID_SYS, pRuntimeInfoStub, , E_OUT_OF_MEMORY, "It is not enough memory.");
+
+ result r = pRuntimeInfoStub->Construct();
+ SysTryReturn(NID_SYS, !IsFailed(r), , r, "[%s] It is failed to get RuntimeInfoCommunicationStub.", GetErrorMessage(r));
+ __pRuntimeInfoStub = pRuntimeInfoStub.release();
+ atexit(DestroySingleton);
+}
+
+void
+_RuntimeInfoStub::DestroySingleton(void)
+{
+ delete __pRuntimeInfoStub;
+}
+
+result
+_RuntimeInfoStub::Construct(void)
+{
+ std::unique_ptr<_IpcServer> pIpcServer(new (std::nothrow) _IpcServer());
+ SysTryReturnResult(NID_SYS, pIpcServer, E_OUT_OF_MEMORY, "Memory is insufficient.");
+
+ result r = pIpcServer->Construct(String(_RUNTIME_SERVICE_ID), *this, true);
+ SysTryReturnResult(NID_SYS, r == E_SUCCESS, r, "It is failed to construct.");
+
+ r = pIpcServer->Start();
+ SysTryReturnResult(NID_SYS, r == E_SUCCESS, r, "It is failed to start.");
+
+ __pIpcServer = move(pIpcServer);
+ return E_SUCCESS;
+}
+
+void
+_RuntimeInfoStub::OnIpcRequestReceived(_IpcServer& server, const IPC::Message& message)
+{
+ __currentPid = server.GetClientId();
+ IPC_BEGIN_MESSAGE_MAP(_RuntimeInfoStub, message)
+ IPC_MESSAGE_HANDLER_EX(IoService_Request, &server, OnRequestOccured)
+ IPC_END_MESSAGE_MAP_EX()
+}
+
+bool
+_RuntimeInfoStub::OnRequestOccured(const ArrayList& request, ArrayList* response)
+{
+ bool isSuccess = false;
+ result r = E_SUCCESS;
+
+ __serviceId = _RUNTIME_SERVICE_ID;
+ __command = *((String*)request.GetAt(_RUNTIME_GET_PARAM_TYPE));
+ __result = L"";
+
+ if(__command == _RUNTIME_GET_SIZE)
+ {
+ int mid = 0;
+ String* path = (String*)request.GetAt(_RUNTIME_GET_PARAM_TYPE+1);
+ String* messageId = (String*)request.GetAt(_RUNTIME_GET_PARAM_TYPE+2);
+ SysTryCatch(NID_SYS, path != null, r = E_SYSTEM, E_SYSTEM, "There is no path information.");
+
+ std::unique_ptr< char > directoryPath(_StringConverter::CopyToCharArrayN(*path));
+ Integer::Parse(*messageId, mid);
+ _DirectorySizeObject* dso = new (std::nothrow) _DirectorySizeObject();
+ dso->pid = __currentPid;
+ dso->path = directoryPath.release();
+ dso->msg_id = mid;
+
+ pthread_t p_thread;
+ int thr_id = pthread_create(&p_thread, null, _RuntimeInfoStub::GetDirectorySizeAsync, dso);
+ if(thr_id < 0)
+ {
+ __result = _RUNTIME_RESULT_SYSTEM;
+ }
+ else
+ {
+ pthread_detach(p_thread);
+ __result = _RUNTIME_RESULT_SUCCESS;
+ }
+ }
+ else
+ {
+ __result = _RUNTIME_RESULT_SYSTEM;
+ }
+
+ isSuccess = true;
+CATCH:
+ response->Add(__serviceId);
+ response->Add(__command);
+ if (isSuccess == true)
+ {
+ response->Add(__result);
+ }
+
+ ArrayList* temp = const_cast<ArrayList*>(&request);
+ temp->RemoveAll(true);
+ return isSuccess;
+}
+
+void*
+_RuntimeInfoStub::GetDirectorySizeAsync(void* data)
+{
+ result r= E_SUCCESS;
+ long long size = 0;
+
+ _DirectorySizeObject* dso = (_DirectorySizeObject*) data;
+ SysTryCatch(NID_SYS, dso != null, r = E_SYSTEM, r, "There is no _DirectorySizeObject.");
+ size = _RuntimeInfo::GetDirectorySize(dso->path);
+
+CATCH:
+ _RuntimeInfoStub::SendResponse(dso->pid, dso->msg_id, size, r);
+ delete dso;
+ return null;
+}
+
+void
+_RuntimeInfoStub::SendResponse(int pid, int msg_id, long long size, result rcode)
+{
+ result r = E_SUCCESS;
+ pthread_mutex_lock(&send_msg_lock);
+
+ ArrayList* data = null;
+ String* pValue = null;
+ String* pMessageId = null;
+
+ SysLog(NID_SYS, "It sends asynchronous result to pid [%d].", pid);
+
+ data = new (std::nothrow) ArrayList(SingleObjectDeleter);
+ data->Construct();
+
+ pMessageId = new (std::nothrow) String();
+ pMessageId->Append(msg_id);
+
+ data->Add(new (std::nothrow) String(_RUNTIME_SERVICE_ID));
+ data->Add(new (std::nothrow) String(_RUNTIME_GET_SIZE));
+ data->Add(pMessageId);
+
+ pValue = new (std::nothrow) String();
+ pValue->Append(size);
+ data->Add(pValue);
+
+ if(rcode == E_SUCCESS)
+ {
+ data->Add(new (std::nothrow) String(_RUNTIME_RESULT_SUCCESS));
+ }
+ else
+ {
+ data->Add(new (std::nothrow) String(_RUNTIME_RESULT_SYSTEM));
+ }
+
+ _RuntimeInfoStub* pRuntimeInfoStub = null;
+ pRuntimeInfoStub = _RuntimeInfoStub::GetInstance();
+ SysTryReturn(NID_SYS, pRuntimeInfoStub, , E_SYSTEM, "RuntimeInfoStub is not created.");
+
+ pRuntimeInfoStub->SendDataAsync(pid, data);
+CATCH:
+ pthread_mutex_unlock(&send_msg_lock);
+
+}
+
+result
+_RuntimeInfoStub::SendDataAsync(const int pid, Tizen::Base::Collection::ArrayList* data)
+{
+ __Mutex.Acquire();
+ result r = E_SUCCESS;
+
+ SysTryCatch(NID_SYS, __pIpcServer != null, r = E_SYSTEM, E_SYSTEM, "IPC server is not ready.");
+ SysTryCatch(NID_SYS, data != null, r = E_SYSTEM, E_SYSTEM, "There is no data.");
+
+ if(__pIpcEventForAsync == null)
+ {
+ __pIpcEventForAsync.reset(new (std::nothrow) _SystemServiceIpcEventForAsync(__pIpcServer.get()));
+ SysTryCatch(NID_SYS, __pIpcEventForAsync != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "It is not enough memory.");
+ __pIpcEventForAsync->Construct(1048576, Tizen::Base::Runtime::THREAD_PRIORITY_MID);
+ __pIpcEventForAsync->Start();
+ }
+
+ r = __pIpcEventForAsync->SendUserEvent((RequestId)pid, (IList*)data);
+ SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "Message is failed to add on event thread.");
+
+CATCH:
+ if(r != E_SUCCESS)
+ {
+ delete data;
+ }
+ __Mutex.Release();
+ return r;
+}