sync with tizen_2.0
[platform/framework/native/appfw.git] / src / io / FIo_MessagePortProxy.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file        FIo_MessagePortProxy.cpp
20  * @brief       This is the implementation file for the _MessagePortProxy class.
21  *
22  */
23
24 #include <string.h>
25 #include <unique_ptr.h>
26
27 #include <package_manager.h>
28
29 #include <FBaseSysLog.h>
30 #include <FBase_StringConverter.h>
31 #include <FApp_AppInfo.h>
32 #include "FIo_IpcClient.h"
33 #include "FIo_MessagePortProxy.h"
34 #include "FIo_MessagePortMessages.h"
35
36 using namespace std;
37
38 using namespace Tizen::App;
39 using namespace Tizen::Io;
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Collection;
42 using namespace Tizen::Base::Runtime;
43
44 namespace Tizen { namespace Io
45 {
46
47 _MessagePortProxy::_MessagePortProxy(void)
48         : __pIpcClient(null)
49 {
50 }
51
52 _MessagePortProxy::~_MessagePortProxy(void)
53 {
54 }
55
56 result
57 _MessagePortProxy::Construct(void)
58 {
59         SysAssertf(__pIpcClient == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
60
61         result r = E_SUCCESS;
62
63         static _StringHashProvider hashProvider;
64         static _StringComparer stringComparer;
65
66         __listeners.Construct(0, 0, hashProvider, stringComparer);
67         __trustedListeners.Construct(0, 0, hashProvider, stringComparer);
68
69         unique_ptr<_IpcClient> pIpcClient(new (std::nothrow) _IpcClient);
70         SysTryReturnResult(NID_IO, pIpcClient != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
71
72         r = pIpcClient->Construct("osp.io.ipcserver.messageportmanager", this);
73         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Failed to connect to IPC server.", GetErrorMessage(r));
74
75         __pIpcClient = pIpcClient.release();
76
77         const String& appId = _AppInfo::GetAppId();
78         const String& appExecutableName = _AppInfo::GetAppExecutableName();
79
80         __appId.Append(appId);
81         __appId.Append(L'.');
82         __appId.Append(appExecutableName);
83
84         return E_SUCCESS;
85 }
86
87
88 void
89 _MessagePortProxy::OnIpcResponseReceived(_IpcClient& client, const IPC::Message& message)
90 {
91         IPC_BEGIN_MESSAGE_MAP(_MessagePortProxy, message)
92         IPC_MESSAGE_HANDLER_EX(MessagePortService_sendMessageAsync, &client, OnSendMessage)
93         IPC_MESSAGE_HANDLER_EX(MessagePortService_sendBidirMessageAsync, &client, OnSendBidirMessage)
94         IPC_END_MESSAGE_MAP_EX()
95 }
96
97 result
98 _MessagePortProxy::RegisterMessagePort(const String& localPort, bool isTrusted,
99                                                                         const _IMessagePortListener& listener)
100 {
101         SysAssertf(__pIpcClient != null, "Not yet constructed. Construct() should be called before use.\n");
102
103         SysLog(NID_IO, "Register a message port : [%ls:%ls]", __appId.GetPointer(), localPort.GetPointer());
104
105         result r = E_SUCCESS;
106         int ret = 0;
107         bool contain = false;
108         String key = localPort;
109
110         if (!isTrusted)
111         {
112                 __listeners.ContainsKey(key, contain);
113
114                 if (!contain)
115                 {
116                         __listeners.Add(key, const_cast<_IMessagePortListener*>(&listener));
117
118                 }
119                 else
120                 {
121                         __listeners.SetValue(key, const_cast<_IMessagePortListener*>(&listener));
122                 }
123         }
124         else
125         {
126                 __trustedListeners.ContainsKey(key, contain);
127
128                 if (!contain)
129                 {
130                         __trustedListeners.Add(key, const_cast<_IMessagePortListener*>(&listener));
131
132                 }
133                 else
134                 {
135                         __trustedListeners.SetValue(key, const_cast<_IMessagePortListener*>(&listener));
136                 }
137
138         }
139
140         unique_ptr<IPC::Message> pMsg(new (std::nothrow) MessagePortService_register(__appId, localPort, isTrusted, &ret));
141         SysTryReturnResult(NID_IO, pMsg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
142
143         r = __pIpcClient->SendRequest(pMsg.get());
144         SysTryReturnResult(NID_IO, r == E_SUCCESS, r, "Failed to register a message port.", GetErrorMessage(r));
145         SysTryReturnResult(NID_IO, ret == E_SUCCESS,  ret, "Failed to register a message port.", GetErrorMessage(ret));
146
147         return E_SUCCESS;
148 }
149
150 result
151 _MessagePortProxy::RequestRemotePort(const AppId& remoteAppId,
152                                                                         const String& remotePort,
153                                                                         bool isTrusted)
154 {
155         SysAssertf(__pIpcClient != null, "Not yet constructed. Construct() should be called before use.\n");
156
157         SysLog(NID_IO, "Request a remote message port [%ls:%ls]", remoteAppId.GetPointer(), remotePort.GetPointer());
158
159         result r = E_SUCCESS;
160         int ret = 0;
161
162         if (isTrusted)
163         {
164                 package_manager_compare_result_type_e res;
165
166                 unique_ptr<char[]> pLocal(_StringConverter::CopyToCharArrayN(__appId));
167                 unique_ptr<char[]> pRemote(_StringConverter::CopyToCharArrayN(remoteAppId));
168
169                 if (package_manager_compare_app_cert_info(pLocal.get(), pRemote.get(), &res) == 0)
170                 {
171                         if (res != PACAKGE_MANAGER_COMPARE_MATCH)
172                         {
173                                 SysLogException(NID_IO, E_CERTIFICATE_VERIFICATION_FAILED, "[E_CERTIFICATE_VERIFICATION_FAILED] The target application is not signed with the same certificate.");
174                                 return E_CERTIFICATE_VERIFICATION_FAILED;
175                         }
176                 }
177                 else
178                 {
179                         SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to compare the cerificate infomation.");
180                         return E_SYSTEM;
181                 }
182         }
183
184         unique_ptr<IPC::Message> pMsg(new (std::nothrow) MessagePortService_requestRemotePort(remoteAppId, remotePort, isTrusted, &ret));
185         SysTryReturnResult(NID_IO, pMsg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
186
187         r = __pIpcClient->SendRequest(pMsg.get());
188         SysTryReturnResult(NID_IO, r == E_SUCCESS, r, "Failed to request a message port.", GetErrorMessage(r));
189         SysTryReturnResult(NID_IO, ret == E_SUCCESS,  ret, "Failed to request a message port.", GetErrorMessage(ret));
190
191         return E_SUCCESS;
192 }
193
194 result
195 _MessagePortProxy::SendMessage(const AppId& remoteAppId, const String& remotePort, bool isTrusted, const HashMap* pMap)
196 {
197         SysAssertf(__pIpcClient != null, "Not yet constructed. Construct() should be called before use.\n");
198
199         SysLog(NID_IO, "Send a unidirectional message to remote port [%ls:%ls]", remoteAppId.GetPointer(), remotePort.GetPointer());
200
201         result r = E_SUCCESS;
202         int ret = 0;
203
204         if (pMap != null)
205         {
206                 unique_ptr<IPC::Message> pMsg(new (std::nothrow) MessagePortService_sendMessage(remoteAppId, remotePort, isTrusted, *pMap, &ret));
207                 SysTryReturnResult(NID_IO, pMsg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
208                 r = __pIpcClient->SendRequest(pMsg.get() );
209         }
210
211         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Failed to send a message.", GetErrorMessage(r));
212         SysTryReturn(NID_IO, ret == E_SUCCESS, ret, ret, "[%s] Failed to send a message.", GetErrorMessage(ret));
213
214         return E_SUCCESS;
215 }
216
217 result
218 _MessagePortProxy::SendMessage(const String& localPort, bool isTrustedLocal, const AppId& remoteAppId, const String& remotePort, bool isTrustedRemote, const HashMap* pMap)
219 {
220         SysAssertf(__pIpcClient != null, "Not yet constructed. Construct() should be called before use.\n");
221
222         result r = E_SUCCESS;
223         int ret = 0;
224
225         SysLog(NID_IO, "Send a bidirectional message from [%ls:%ls] to [%ls:%ls]", __appId.GetPointer(), localPort.GetPointer(), remoteAppId.GetPointer(), remotePort.GetPointer());
226
227         if (pMap != null)
228         {
229                 if (!isTrustedRemote)
230                 {
231                         unique_ptr<IPC::Message> pMsg(new (std::nothrow) MessagePortService_sendBidirMessage(__appId, localPort, isTrustedLocal, remoteAppId, remotePort, *pMap, &ret));
232                         SysTryReturnResult(NID_IO, pMsg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
233                         r = __pIpcClient->SendRequest(pMsg.get());
234                 }
235                 else
236                 {
237                         unique_ptr<IPC::Message> pMsg(new (std::nothrow) MessagePortService_sendTrustedBidirMessage(__appId, localPort, isTrustedLocal, remoteAppId, remotePort, *pMap, &ret));
238                         SysTryReturnResult(NID_IO, pMsg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
239                         r = __pIpcClient->SendRequest(pMsg.get());
240                 }
241         }
242
243         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Failed to send a message.", GetErrorMessage(r));
244         SysTryReturn(NID_IO, ret == E_SUCCESS, ret, ret, "[%s] Failed to send a message.", GetErrorMessage(ret));
245
246         return E_SUCCESS;
247 }
248
249 bool
250 _MessagePortProxy::OnSendMessage(const String& localPort, bool isTrusted, const HashMap& map)
251 {
252         SysLog(NID_IO, "A message is received to local port [%ls:%ls].", __appId.GetPointer(), localPort.GetPointer());
253
254         _IMessagePortListener* pListener = null;
255
256         String key = localPort;
257
258         if (!isTrusted)
259         {
260                 __listeners.GetValue(key, pListener);
261         }
262         else
263         {
264                 __trustedListeners.GetValue(key, pListener);
265         }
266
267         HashMap* pMap = new (std::nothrow) HashMap(SingleObjectDeleter);
268         SysTryReturn(NID_IO, pMap != null, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
269
270         pMap->Construct(map);
271
272         if (pListener)
273         {
274                 pListener->OnMessageReceivedN(pMap);
275
276                 return true;
277         }
278         else
279         {
280                 delete pMap;
281         }
282
283         return false;
284 }
285
286 bool
287 _MessagePortProxy::OnSendBidirMessage(const String& localPort, bool isTrustedLocal, const AppId& remoteAppId, const String& remotePort, bool isTrustedRemote, const HashMap& map)
288 {
289         SysLog(NID_IO, "A message is received to local port [%ls:%ls], from remote port [%ls:%ls].", __appId.GetPointer(), localPort.GetPointer(), remoteAppId.GetPointer(), remotePort.GetPointer());
290
291         _IMessagePortListener* pListener = null;
292
293         String key = localPort;
294
295         if (!isTrustedLocal)
296         {
297                 __listeners.GetValue(key, pListener);
298         }
299         else
300         {
301                 __trustedListeners.GetValue(key, pListener);
302         }
303
304         HashMap* pMap = new (std::nothrow) HashMap(SingleObjectDeleter);
305         SysTryReturn(NID_IO, pMap != null, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
306
307         pMap->Construct(map);
308
309         if (pListener)
310         {
311                 pListener->OnMessageReceivedN(remoteAppId, remotePort, isTrustedRemote, pMap);
312                 return true;
313         }
314         else
315         {
316                 delete pMap;
317         }
318
319         return false;
320 }
321
322 _MessagePortProxy*
323 _MessagePortProxy::GetProxy(void)
324 {
325         static _MessagePortProxy* pProxy = null;
326
327         if (pProxy == null)
328         {
329                 unique_ptr<_MessagePortProxy> p(new (std::nothrow) _MessagePortProxy);
330                 SysTryReturn(NID_IO, p != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
331
332                 result r = p->Construct();
333                 SysTryReturn(NID_IO, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] Failed to initialize a  message port proxy.");
334
335                 pProxy = p.release();
336         }
337
338         SetLastResult(E_SUCCESS);
339         return pProxy;
340 }
341
342 }}