Tizen 2.1 base
[platform/framework/native/app-service.git] / src / FApp_ConditionHandler.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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         FApp_ConditionHandler.cpp
20  * @brief       This is the implementation for the _ConditionHandler class.
21  */
22
23 #include <unistd.h>
24 #include <cstdio>
25
26 #include <FBaseRtLibrary.h>
27 #include <FAppApp.h>
28 #include <FBaseSysLog.h>
29 #include <FBase_StringConverter.h>
30 #include <FIo_DirectoryImpl.h>
31 #include <FApp_AppManagerImpl.h>
32 #include <FApp_AppControlManager.h>
33
34 #include "FApp_ConditionHandler.h"
35
36 namespace Tizen { namespace App {
37
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::Io;
41
42 _ConditionHandler::_ConditionHandler(const String& fileName, const String& types)
43 : __typesString(types)
44 , __pluginFileName(fileName)
45 , __pPluginInstance(null)
46 , __pLib(null)
47 , __pfDestroyPlugin(null)
48 {
49         SysLog(NID_APP, "%ls, %ls", fileName.GetPointer(), types.GetPointer() );
50 }
51
52 _ConditionHandler::~_ConditionHandler()
53 {
54         SysLog(NID_APP, "Enter");
55         if (__pfDestroyPlugin != null && __pPluginInstance != null)
56         {
57                 __pfDestroyPlugin(__pPluginInstance);
58                 __pfDestroyPlugin = null;
59                 __pPluginInstance = null;
60         }
61
62         delete __pLib;
63
64         SysLog(NID_APP, "Exit");
65 }
66 //#define FILENAME_MAX 2048
67
68 result
69 _ConditionHandler::Construct()
70 {
71         SysLog(NID_APP, "Enter");
72
73         result r = LoadPlugin();
74     __conditionalOperations.Construct( 16, 0.75f, __strHashMapProvider, __strComparer);
75
76     SysLog(NID_APP, "Exit");
77     return r;
78 }
79
80 result
81 _ConditionHandler::LoadPlugin(void)
82 {
83         char filePath[FILENAME_MAX];
84         char* pFileName = _StringConverter::CopyToCharArrayN(__pluginFileName);
85         create_plugin pfCreatePlugin = null;
86         result r = E_SUCCESS;
87
88         String dataPath = App::GetInstance()->GetAppRootPath() + L"lib";
89         snprintf(filePath, FILENAME_MAX, "%ls/%s", dataPath.GetPointer(), pFileName);
90         delete[] pFileName;
91
92         if (access(filePath, F_OK) != 0) // for uts-app
93         {
94                 dataPath.Clear();
95                 pFileName = _StringConverter::CopyToCharArrayN(__pluginFileName);
96                 r = _AppManagerImpl::GetAppRootPath(L"aospd00043", dataPath);
97                 snprintf(filePath, FILENAME_MAX, "%ls/%s", dataPath.GetPointer(), pFileName);
98                 delete[] pFileName;
99                 SysTryCatch(NID_APP, !IsFailed(r), r = E_SYSTEM, E_SYSTEM,
100                                 "[E_SYSTEM] osp-app-service should be installed.");
101
102                 dataPath.Append(L"data");
103         }
104
105         __pLib = new (std::nothrow) Runtime::Library();
106         r = __pLib->Construct(filePath);
107         SysTryCatch(NID_APP, !IsFailed(r), , r, "dlopen fails (%s)", GetErrorMessage(r) );
108
109         pfCreatePlugin = (create_plugin)__pLib->GetProcAddress(L"CreatePlugin");
110         __pfDestroyPlugin = (destroy_plugin)__pLib->GetProcAddress(L"DestroyPlugin");
111         SysTryCatch(NID_APP, pfCreatePlugin != null && __pfDestroyPlugin != null, r = E_FAILURE, E_FAILURE, "failed to get symbols," );
112
113         __pPluginInstance = pfCreatePlugin();
114         SysTryCatch(NID_APP, __pPluginInstance != null, r = E_FAILURE, E_FAILURE, "pfCreatePlugin fails" );
115
116         __pPluginInstance->SetEventListener(*this);
117
118         return E_SUCCESS;
119
120 CATCH:
121         SysLog(NID_APP, "CATCH:");
122         delete __pLib;
123         __pLib = null;
124         __pfDestroyPlugin = null;
125         return r;
126 }
127
128 result
129 _ConditionHandler::CreateUniqueId(String& uniqueId)
130 {
131         int index = 0;//TODO: improve algorithm
132         String candidateSectionName(__pluginFileName);
133         while( index < Integer::VALUE_MAX)
134         {
135                 candidateSectionName.Format(1024, L"%ls_%d",__pluginFileName.GetPointer(), index );
136                 if (FindItemBySectionName(candidateSectionName) == null)
137                 {
138                         uniqueId.Clear();
139                         uniqueId.Append(candidateSectionName);
140                         return E_SUCCESS;
141                 }
142                 index++;
143         }
144
145         return E_OVERFLOW;
146 }
147
148 result
149 _ConditionHandler::AddCondition( _AppLaunchCondition& operation)
150 {
151         SysTryReturnResult(NID_APP, __pPluginInstance != null, E_INVALID_STATE, "" );
152
153         //TODO
154         String condition = operation.GetConditionString();
155         if (HasCondition(operation.GetAppId(), operation.GetExecutableName(), &condition))
156                 return E_OBJ_ALREADY_EXIST;
157
158         result r = __pPluginInstance->Register(operation);
159         SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] failed to register", GetErrorMessage(r) );
160
161         String uniqueId;
162         if (operation.__regSectionName.IsEmpty())
163         {
164                 CreateUniqueId(uniqueId);
165                 operation.__regSectionName = uniqueId;
166                 _ConditionRegistryHelper::AddToRegistry(uniqueId, operation.GetAppId(), operation.GetExecutableName(), operation.GetConditionString(), operation.__pArguments );
167         }
168         else
169         {
170                 // from registry conditional-operations.ini
171                 uniqueId = operation.__regSectionName;
172         }
173
174         __conditionalOperations.Add(operation.GetConditionString(), &operation);
175         SysLog(NID_APP, "AppLaunchCondition item count (%d)", __conditionalOperations.GetCount());
176
177         return E_SUCCESS;
178 }
179
180 result
181 _ConditionHandler::RemoveCondition(const AppId& appId, const String* pExecutableName, const String* pCondition)
182 {
183         SysLog(NID_APP,"Trying to unregister appId(%ls)", appId.GetPointer() );
184         SysTryReturnResult(NID_APP, __pPluginInstance != null, E_INVALID_STATE, "" );
185
186         bool found = false;
187
188         IListT<_AppLaunchCondition*>* pValues = __conditionalOperations.GetValuesN();
189         SysTryReturn(NID_APP, pValues != null, GetLastResult(), GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
190
191         result r = E_SUCCESS;
192         for (int i = 0; i< pValues->GetCount(); i++)
193         {
194                 String uniqueId;
195
196                 _AppLaunchCondition *pOperation = null;
197                 r = pValues->GetAt(i, pOperation);
198                 SysTryCatch(NID_APP, pOperation != null, , r, "[%s] Propagated.", GetErrorMessage(r) );
199                 SysLog(NID_APP,"Trying to unregister appId(%ls), pExecutableName(%ls), condition(%ls)", appId.GetPointer(), pOperation->GetExecutableName().GetPointer(), pOperation->GetConditionString().GetPointer() );
200
201                 if ( pOperation->GetAppId() == appId
202                                 && ( pExecutableName == null || pOperation->GetExecutableName() == *pExecutableName )
203                                 && ( pCondition == null || pOperation->GetConditionString() == *pCondition ) )
204                 {
205                         r = __pPluginInstance->Unregister(*pOperation);
206                         SysTryCatch(NID_APP, !IsFailed(r), delete pOperation, r, "[%s] failed to Unregister(%ls, %ls)", GetErrorMessage(r), appId.GetPointer(), pOperation->GetConditionString().GetPointer() );//TBC
207                         _ConditionRegistryHelper::RemoveFromRegistry(pOperation->__regSectionName);
208
209                         r = __conditionalOperations.Remove(pOperation->GetConditionString(), pOperation);
210                         SysTryLog(NID_APP, !IsFailed(r), "[%s]", GetErrorMessage(r));
211
212                         SysLog(NID_APP,"Unregistered appId(%ls), pExecutableName(%ls), condition(%ls)", appId.GetPointer(), pOperation->GetExecutableName().GetPointer(), pOperation->GetConditionString().GetPointer() );
213
214                         delete pOperation;
215                         if ( pCondition != null)
216                         {
217                                 pValues->RemoveAll();
218                                 delete pValues;
219                                 return E_SUCCESS;
220                         }
221                         else
222                         {
223                                 found = true;
224                                 // loop next
225                         }
226                 }
227         }
228
229         return (found) ? E_SUCCESS : E_OBJ_NOT_FOUND;
230
231 CATCH:
232         pValues->RemoveAll();
233         delete pValues;
234         return r;
235 }
236
237
238 //TODO: argument?
239 bool
240 _ConditionHandler::HasCondition(const AppId& appId, const String& executableName, const String *pCondition) const
241 {
242         IListT<_AppLaunchCondition*>* pList = __conditionalOperations.GetValuesN();
243         SysTryReturn(NID_APP, pList != null, false, GetLastResult(), "[%s] Propagated. ", GetLastResult());
244
245         result r = E_SUCCESS;
246         for (int i = 0; i < pList->GetCount(); i++)
247         {
248                 _AppLaunchCondition *pOperation = null;
249                 r = pList->GetAt(i, pOperation);
250                 SysTryCatch(NID_APP, pOperation != null, , r, "[%s] Propagated.", GetErrorMessage(r));
251
252                 if (pOperation->GetAppId() == appId && pOperation->GetExecutableName() == executableName
253                                 && ( pCondition == null || pOperation->GetConditionString() == *pCondition) )
254                 {
255                         return true;
256                 }
257         }
258
259 CATCH:
260         delete pList;
261         return false;
262 }
263
264 bool
265 _ConditionHandler::CanHandleType(const String& type ) const
266 {
267         return __typesString.Contains(type);
268 }
269
270 _AppLaunchCondition*
271 _ConditionHandler::FindItemBySectionName(const String& sectionName) const
272 {
273         IListT<_AppLaunchCondition*>* pValues = __conditionalOperations.GetValuesN();
274         SysTryReturn(NID_APP, pValues != null, null, GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
275
276         result r = E_SUCCESS;
277         for (int i = 0; i< pValues->GetCount(); i++)
278         {
279                 _AppLaunchCondition *pOperation = null;
280                 r = pValues->GetAt(i, pOperation);
281                 if ( !IsFailed(r) && pOperation->__regSectionName == sectionName)
282                 {
283                         return pOperation;
284                 }
285         }
286         return null;
287 }
288
289 void
290 _ConditionHandler::OnAppLaunchConditionMet(const _AppLaunchCondition& operation)
291 {
292         SysLog(NID_APP, "Enter");
293
294         result r  = _AppControlManager::GetInstance()->LaunchAppWithCondition(operation.GetAppId(), operation.GetExecutableName(), operation.GetConditionString(), operation.__pArguments );
295         SysTryLog(NID_APP, !IsFailed(r), "[%ls] LaunchApplication failed.", GetErrorMessage(r));
296
297         SysLog(NID_APP, "Exit");
298 }
299
300 void
301 _ConditionHandler::Dump(void) const
302 {
303         SysLog(NID_APP, "[%ls]", this->__pluginFileName.GetPointer() );
304
305 //      result r = E_SUCCESS;
306 //      _AppLaunchConditionEnumerator* pEnum =__conditionalOperations.GetMapEnumeratorN();
307 //      SysTryReturnVoidResult(NID_APP, pEnum != null, GetLastResult(), "[%s]", GetErrorMessage(GetLastResult()));
308 //
309 //      while( pEnum->MoveNext() == E_SUCCESS )
310 //      {
311 //              _AppLaunchCondition *pOperation = null;
312 //              r = pEnum->GetValue(pOperation);
313 //              SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
314 //              SysTryCatch(NID_APP, pOperation != null, , r, "[%s] Propagated.", GetErrorMessage(r));
315 //
316 //              SysLog(NID_APP, "appId:%ls, condition:%ls, uniqueId:%ls", pOperation->__appId.GetPointer(), pOperation->GetConditionString().GetPointer(), pOperation->__regSectionName.GetPointer() );
317 //      }
318 //
319 //CATCH:
320 //      delete pEnum;
321 }
322
323
324 }} // Tizen::App