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 FIo_MessagePortProxy.cpp
20 * @brief This is the implementation file for the _MessagePortProxy class.
26 #include <unique_ptr.h>
28 #include <package_manager.h>
30 #include <message-port.h>
32 #include <FBaseSysLog.h>
33 #include <FBase_StringConverter.h>
34 #include <FApp_AppInfo.h>
36 #include "FIo_MessagePortProxy.h"
40 using namespace Tizen::App;
41 using namespace Tizen::Io;
42 using namespace Tizen::Base;
43 using namespace Tizen::Base::Collection;
44 using namespace Tizen::Base::Runtime;
46 namespace Tizen { namespace Io
50 ConvertBundleToMap(const char *pKey, const int type, const bundle_keyval_t *pVal, void *pData)
52 SysLog(NID_IO, "CB key = %s", pKey);
54 HashMap* pMap = static_cast<HashMap*>(pData);
56 if (pKey && pVal && pMap)
63 bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
66 pMap->Add(new (std::nothrow) String(pKey), new (std::nothrow) String(pStr));
70 case BUNDLE_TYPE_BYTE:
71 bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
73 SysLog(NID_IO, "Bundle byte value = %s, size = %d", pStr, size);
77 ByteBuffer* pBuffer = new (std::nothrow) ByteBuffer();
78 SysTryReturn(NID_IO, pMap != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
79 result r = pBuffer->Construct(size);
80 SysTryReturn(NID_IO, r == E_SUCCESS, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
82 pBuffer->SetArray((const byte*)pStr, 0, size);
85 pMap->Add(new (std::nothrow) String(pKey), pBuffer);
90 SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
97 OnMessageReceived(int id, const char* remote_app_id, const char* remote_port, bool trusted_port, bundle* data)
99 SysLog(NID_IO, "Message received");
101 _MessagePortProxy* p = _MessagePortProxy::GetProxy();
104 char* pLocalPort = null;
106 ret = messageport_get_local_port_name(id, &pLocalPort);
107 if (pLocalPort == null)
109 SysLog(NID_IO, "No local port for id: %d", id);
115 SysLog(NID_IO, "local port name: %s", pLocalPort);
117 _IMessagePortListener* pListener = null;
118 p->__listeners.GetValue(pLocalPort, pListener);
122 if (pListener != null)
124 HashMap* pMap = new (std::nothrow) HashMap(SingleObjectDeleter);
125 SysTryCatch(NID_IO, pMap != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
127 result r = pMap->Construct();
128 SysTryCatch(NID_IO, r == E_SUCCESS, delete pMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
130 SysLog(NID_IO, "bundle to map");
132 bundle_foreach(data, ConvertBundleToMap, pMap);
134 if (remote_app_id == null) // Uni-directional
136 pListener->OnMessageReceivedN(pMap);
138 else // Bi-directional
140 SysLog(NID_IO, "Message received from [%s:%s], trusted: %d", remote_app_id, remote_port, trusted_port);
142 pListener->OnMessageReceivedN(remote_app_id, remote_port, trusted_port, pMap);
151 OnTrustedMessageReceived(int id, const char* remote_app_id, const char* remote_port, bool trusted_port, bundle* data)
153 SysLog(NID_IO, "Trusted message received");
155 _MessagePortProxy* p = _MessagePortProxy::GetProxy();
158 char* pLocalPort = null;
159 ret = messageport_get_local_port_name(id, &pLocalPort);
160 if (pLocalPort == null)
162 SysLog(NID_IO, "No local port for id: %d", id);
168 _IMessagePortListener* pListener = null;
169 p->__trustedListeners.GetValue(pLocalPort, pListener);
173 if (pListener != null)
175 HashMap* pMap = new (std::nothrow) HashMap(SingleObjectDeleter);
176 SysTryCatch(NID_IO, pMap != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
178 result r = pMap->Construct();
179 SysTryCatch(NID_IO, r == E_SUCCESS, delete pMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
181 bundle_foreach(data, ConvertBundleToMap, pMap);
183 if (remote_app_id == null) // Uni-directional
185 pListener->OnMessageReceivedN(pMap);
187 else // Bi-directional
189 SysLog(NID_IO, "Trusted message received from [%s:%s], trusted: %d", remote_app_id, remote_port, trusted_port);
190 pListener->OnMessageReceivedN(remote_app_id, remote_port, trusted_port, pMap);
198 _MessagePortProxy::_MessagePortProxy(void)
202 _MessagePortProxy::~_MessagePortProxy(void)
207 _MessagePortProxy::Construct(void)
209 static _StringHashProvider hashProvider;
210 static _StringComparer stringComparer;
212 __listeners.Construct(0, 0, hashProvider, stringComparer);
213 __trustedListeners.Construct(0, 0, hashProvider, stringComparer);
214 __ids.Construct(0, 0, hashProvider, stringComparer);
215 __trustedIds.Construct(0, 0, hashProvider, stringComparer);
217 __appId = _AppInfo::GetApplicationId();
224 _MessagePortProxy::RegisterMessagePort(const String& localPort, bool isTrusted,
225 const _IMessagePortListener& listener)
227 SysLog(NID_IO, "Register a message port : [%ls:%ls]", __appId.GetPointer(), localPort.GetPointer());
229 result r = E_SUCCESS;
231 bool contain = false;
233 unique_ptr<char[]> pLocal(_StringConverter::CopyToCharArrayN(localPort));
237 ret = messageport_register_local_port(pLocal.get(), OnMessageReceived);
238 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "Failed to register the local message port. %d", ret);
240 __listeners.ContainsKey(localPort, contain);
244 __listeners.Add(localPort, const_cast<_IMessagePortListener*>(&listener));
245 __ids.Add(localPort, ret);
249 __listeners.SetValue(localPort, const_cast<_IMessagePortListener*>(&listener));
250 __ids.SetValue(localPort, ret);
256 ret = messageport_register_trusted_local_port(pLocal.get(), OnTrustedMessageReceived);
257 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "Failed to register the trusted local message port. %d", ret);
259 __trustedListeners.ContainsKey(localPort, contain);
263 __trustedListeners.Add(localPort, const_cast<_IMessagePortListener*>(&listener));
264 __trustedIds.Add(localPort, ret);
268 __trustedListeners.SetValue(localPort, const_cast<_IMessagePortListener*>(&listener));
269 __trustedIds.SetValue(localPort, ret);
278 _MessagePortProxy::RequestRemotePort(const AppId& remoteAppId,
279 const String& remotePort,
282 SysLog(NID_IO, "Request a remote message port [%ls:%ls]", remoteAppId.GetPointer(), remotePort.GetPointer());
284 result r = E_SUCCESS;
288 unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(remoteAppId));
289 unique_ptr<char[]> pPort(_StringConverter::CopyToCharArrayN(remotePort));
293 ret = messageport_check_remote_port(pAppId.get(), pPort.get(), &exist);
297 ret = messageport_check_trusted_remote_port(pAppId.get(), pPort.get(), &exist);
302 r = ConvertToResult(ret);
304 SysTryReturnResult(NID_IO, r != E_CERTIFICATE_VERIFICATION_FAILED, E_CERTIFICATE_VERIFICATION_FAILED, "The target application is not signed with the same certificate.");
306 SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to request the remote message port.");
311 SysTryReturnResult(NID_IO, exist, E_OBJ_NOT_FOUND, "The remote message port is not found.");
317 _MessagePortProxy::SendMessage(const AppId& remoteAppId, const String& remotePort, bool isTrusted, const HashMap* pMap)
319 SysLog(NID_IO, "Send a unidirectional message to remote port [%ls:%ls]", remoteAppId.GetPointer(), remotePort.GetPointer());
323 // Convert Map to bundle
324 bundle* b = ConvertMapToBundleN(pMap);
325 SysTryReturnResult(NID_IO, b != null, E_SYSTEM, "Internal system errors.");
327 unique_ptr<char[]> pRemoteAppId(_StringConverter::CopyToCharArrayN(remoteAppId));
328 unique_ptr<char[]> pRemotePort(_StringConverter::CopyToCharArrayN(remotePort));
332 ret = messageport_send_message(pRemoteAppId.get(), pRemotePort.get(), b);
336 ret = messageport_send_trusted_message(pRemoteAppId.get(), pRemotePort.get(), b);
343 result r = ConvertToResult(ret);
345 SysTryReturnResult(NID_IO, r != E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "The remote message port is not found.");
346 SysTryReturnResult(NID_IO, r != E_CERTIFICATE_VERIFICATION_FAILED, E_CERTIFICATE_VERIFICATION_FAILED, "The target application is not signed with the same certificate.");
347 SysTryReturnResult(NID_IO, r != E_MAX_EXCEEDED, E_MAX_EXCEEDED, "The size of the message has exceeded the maximum limit.");
349 SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to request the remote message port.");
358 _MessagePortProxy::SendMessage(const String& localPort, bool isTrustedLocal, const AppId& remoteAppId, const String& remotePort, bool isTrustedRemote, const HashMap* pMap)
360 SysLog(NID_IO, "Send a bidirectional message from [%ls:%ls] to [%ls:%ls]", __appId.GetPointer(), localPort.GetPointer(), remoteAppId.GetPointer(), remotePort.GetPointer());
362 result r = E_SUCCESS;
367 r = __ids.GetValue(localPort, id);
371 r = __trustedIds.GetValue(localPort, id);
374 SysTryReturnResult(NID_IO, r == E_SUCCESS, E_SYSTEM, "Internal system errors.");
376 // Convert Map to bundle
377 bundle* b = ConvertMapToBundleN(pMap);
378 SysTryReturnResult(NID_IO, b != null, E_SYSTEM, "Internal system errors.");
380 unique_ptr<char[]> pRemoteAppId(_StringConverter::CopyToCharArrayN(remoteAppId));
381 unique_ptr<char[]> pRemotePort(_StringConverter::CopyToCharArrayN(remotePort));
384 if (!isTrustedRemote)
386 ret = messageport_send_bidirectional_message(id, pRemoteAppId.get(), pRemotePort.get(), b);
390 ret = messageport_send_bidirectional_trusted_message(id, pRemoteAppId.get(), pRemotePort.get(), b);
397 result r = ConvertToResult(ret);
399 SysTryReturnResult(NID_IO, r != E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "The remote message port is not found.");
400 SysTryReturnResult(NID_IO, r != E_CERTIFICATE_VERIFICATION_FAILED, E_CERTIFICATE_VERIFICATION_FAILED, "The target application is not signed with the same certificate.");
401 SysTryReturnResult(NID_IO, r != E_MAX_EXCEEDED, E_MAX_EXCEEDED, "The size of the message has exceeded the maximum limit.");
403 SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to request the remote message port.");
412 _MessagePortProxy::GetProxy(void)
414 static _MessagePortProxy* pProxy = null;
418 unique_ptr<_MessagePortProxy> p(new (std::nothrow) _MessagePortProxy);
419 SysTryReturn(NID_IO, p != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
421 result r = p->Construct();
422 SysTryReturn(NID_IO, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] Failed to initialize a message port proxy.");
424 pProxy = p.release();
427 SetLastResult(E_SUCCESS);
432 _MessagePortProxy::ConvertToResult(int error)
434 SysLog(NID_IO, "Native error = %d", error);
438 case MESSAGEPORT_ERROR_IO_ERROR:
441 case MESSAGEPORT_ERROR_OUT_OF_MEMORY:
442 return E_OUT_OF_MEMORY;
444 case MESSAGEPORT_ERROR_INVALID_PARAMETER:
445 return E_INVALID_ARG;
447 case MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND:
448 return E_OBJ_NOT_FOUND;
450 case MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH:
451 return E_CERTIFICATE_VERIFICATION_FAILED;
453 case MESSAGEPORT_ERROR_MAX_EXCEEDED:
454 return E_MAX_EXCEEDED;
464 _MessagePortProxy::ConvertMapToBundleN(const HashMap* pMap)
466 bundle *b = bundle_create();
468 std::unique_ptr<IMapEnumerator> pEnum (pMap->GetMapEnumeratorN());
469 while(pEnum->MoveNext() == E_SUCCESS)
471 const String* pKey = dynamic_cast<const String*>(pEnum->GetKey());
472 const Object* pValue = pEnum->GetValue();
476 unique_ptr<char[]> pKeyData(_StringConverter::CopyToCharArrayN(*pKey));
478 if (typeid(*pValue) == typeid(const String)) // String
480 unique_ptr<char[]> pValueData(_StringConverter::CopyToCharArrayN(*(static_cast<const String*>(pValue))));
482 //SysLog(NID_IO, "key: %s, value: %s", pKeyData.get(), pValueData.get());
484 bundle_add(b, pKeyData.get(), pValueData.get());
488 if (typeid(*pValue) == typeid(const ByteBuffer)) // ByteBuffer
490 const ByteBuffer* pBuffer = static_cast<const ByteBuffer*>(pValue);
492 // Add a byte data to bundle
493 SysLog(NID_IO, "Add a string key: %s, byte value: %s", pKeyData.get(), pBuffer->GetPointer());
495 bundle_add_byte(b, pKeyData.get(), pBuffer->GetPointer(), pBuffer->GetLimit());
499 SysLog(NID_IO, "Not supported");
508 SysLog(NID_IO, "Not supported");