Merge "Remove fallback routines and memory leak." into tizen_2.1
[platform/framework/native/appfw.git] / src / io / FIo_ServerChannelImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 /**
18  * @file        FIo_ServerChannelImpl.cpp
19  * @brief       This is the implementation file for the _ServerChannelImpl class.
20  *
21  */
22
23 #include <unique_ptr.h>
24
25 #include <FApp_AppInfo.h>
26 #include <FBaseSysLog.h>
27 #include <FIoChannelTypes.h>
28 #include <FIoServerChannel.h>
29 #include <FAppPkg_PackageManagerImpl.h>
30 #include "FIo_ServerChannelImpl.h"
31 #include "FIo_Channel.h"
32 #include "FIo_ChannelManager.h"
33
34 using namespace std;
35 using namespace Tizen::App;
36 using namespace Tizen::App::Package;
37 using namespace Tizen::Base;
38 using namespace Tizen::Base::Collection;
39
40 namespace Tizen { namespace Io
41 {
42
43 _ServerChannelImpl::_ServerChannelImpl(void)
44         : __pServerChannel(null)
45         , __pRequestListener(null)
46         , __pChannel(null)
47 {
48 }
49
50 _ServerChannelImpl::~_ServerChannelImpl(void)
51 {
52 }
53
54 result
55 _ServerChannelImpl::Construct(ServerChannel* pServerChannel, const Tizen::Base::String& channelName)
56 {
57         String channelId(_AppInfo::GetApplicationId());
58
59         if (!channelName.IsEmpty())
60         {
61                 channelId.Append(L'.');
62                 channelId.Append(channelName);
63         }
64
65         // Create a channel
66         _ChannelManager* pManager = _ChannelManager::GetInstance();
67         SysTryReturnResult(NID_IO, pManager != null, E_SYSTEM, "Failed to create a channel manager");
68
69         _Channel* pChannel = pManager->GetChannel(channelId);
70         SysTryReturnResult(NID_IO, pChannel != null, E_SYSTEM, "Failed to create a channel: [%ls]", channelId.GetPointer());
71
72         pChannel->SetChannelRequestEventListener(*this);
73
74         __pServerChannel = pServerChannel;
75         __pChannel = pChannel;
76
77         return E_SUCCESS;
78 }
79
80 void
81 _ServerChannelImpl::SetChannelRequestEventListener(IChannelRequestEventListener* pRequestListener)
82 {
83         __pRequestListener = (IChannelRequestEventListener*) pRequestListener;
84 }
85
86 result
87 _ServerChannelImpl::SendResponse(const String& clientChannelId, const IList* pArgs, RequestId reqId)
88 {
89         const int APP_ID_LEN = 10;
90
91         String channelId = clientChannelId;
92         String execName;
93
94         if (clientChannelId.GetLength() <= APP_ID_LEN)
95         {
96                 execName = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(clientChannelId);
97                 channelId.Append(L'.');
98                 channelId.Append(execName);
99         }
100
101         if (pArgs == null)
102         {
103                 return __pChannel->SendNullResponse(channelId, reqId);
104         }
105
106         const ArrayList* pList = dynamic_cast<const ArrayList*>(pArgs);
107         if (pList == null)
108         {
109                 unique_ptr<ArrayList> pArrayList(new (std::nothrow) ArrayList());
110                 pArrayList->Construct(*pArgs);
111
112                 return __pChannel->SendResponse(channelId, *pArrayList, reqId);
113         }
114
115         return __pChannel->SendResponse(channelId, *pList, reqId);
116 }
117
118 void
119 _ServerChannelImpl::OnChannelRequestReceivedN(RequestId reqId, const String& channelId, IList* pArgs)
120 {
121         SysLog(NID_IO, "Received from [%ls]", channelId.GetPointer());
122
123         if (__pRequestListener != null)
124         {
125                 if (_AppInfo::IsOspCompat() == false)
126                 {
127                         __pRequestListener->OnChannelRequestReceivedN(reqId, *__pServerChannel, channelId, pArgs);
128                 }
129                 else
130                 {
131                         String appId;
132                         channelId.SubString(0, 10, appId);
133
134                         __pRequestListener->OnChannelRequestReceivedN(reqId, *__pServerChannel, appId, pArgs);
135                 }
136         }
137         else
138         {
139                 pArgs->RemoveAll(true);
140                 delete pArgs;
141         }
142 }
143
144
145 _ServerChannelImpl* 
146  _ServerChannelImpl::GetInstance(ServerChannel* pChannel)
147 {
148
149         result r = E_SUCCESS;
150         static _ServerChannelImpl* pImpl = null;
151         if (pImpl == null)
152         {
153                 unique_ptr<_ServerChannelImpl> p(new (std::nothrow) _ServerChannelImpl);
154                 SysTryReturn(NID_IO, p != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
155
156                 r = p->Construct(pChannel);
157                 SysTryReturn(NID_IO, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] Failed to initialize channel.");
158
159                 pImpl = p.release();
160         }
161
162         return pImpl;
163 }
164
165 ServerChannel*
166 _ServerChannelImpl::GetServerChannel(const Tizen::Base::String& channelName)
167 {
168         _ChannelManager* pManager = _ChannelManager::GetInstance();
169         SysTryReturn(NID_IO, pManager != null, null, E_SYSTEM, "[E_SYSTEM] Failed to create a _ChannelManager.");
170
171         ServerChannel* pChannel = pManager->GetServerChannel(channelName);
172         if (pChannel == null)
173         {
174                 // unique_ptr cannot be used because Dtor is private
175                 pChannel = new (std::nothrow) ServerChannel;
176                 SysTryReturn(NID_IO, pChannel != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
177
178                 unique_ptr<_ServerChannelImpl> pImpl(new (std::nothrow) _ServerChannelImpl);
179                 SysTryCatch(NID_IO, pImpl != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
180
181                 result r = pImpl->Construct(pChannel, channelName);
182                 SysTryCatch(NID_IO, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to initialize channel.");
183
184                 pChannel->__pServerChannelImpl = pImpl.release();
185
186                 pManager->AddServerChannel(channelName, pChannel);
187         }
188
189         return pChannel;
190
191 CATCH:
192         delete pChannel;
193
194         return null;
195 }
196
197 } } // Tizen::Io