header depdency correction
[platform/framework/native/appfw.git] / src / app / FApp_AppArg.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     FApp_AppArg.cpp
19 * @brief        This is the implementation for the _AppArg.cpp class.
20 */
21
22 #include <cstdio>
23 #include <cstdlib>
24 #include <new>
25 #include <typeinfo>
26 #include <unique_ptr.h>
27
28 #include <aul.h>
29 #include <app.h>
30 #include <bundle.h>
31 #include <appsvc/appsvc.h>
32 #include <Ecore_X.h>
33
34 #include <FBaseInteger.h>
35 #include <FBaseColArrayList.h>
36 #include <FBaseColHashMap.h>
37 #include <FBaseByteBuffer.h>
38 #include <FBaseUtilStringTokenizer.h>
39 #include <FBaseSysLog.h>
40
41 #include <FBase_StringConverter.h>
42
43 #include "FApp_MapDataControlImpl.h"
44 #include "FApp_AppControlImpl.h"
45 #include "FApp_SqlDataControlImpl.h"
46 #include "FApp_AppControlEventArg.h"
47 #include "FApp_AppArg.h"
48 #include "FApp_AppMessageImpl.h"
49 #include "FApp_Aul.h"
50
51 using namespace Tizen::Base;
52 using namespace Tizen::Base::Collection;
53 using namespace Tizen::Base::Utility;
54
55
56 extern "C" int appsvc_allow_transient_app(bundle*, Ecore_X_Window);
57
58 namespace Tizen { namespace App
59 {
60
61 static const char OSP_V_LAUNCH_TYPE_LAUNCH[] = "launch";
62 static const char OSP_V_LAUNCH_TYPE_APPCONTROL[] = "appcontrol";
63 static const char OSP_V_LAUNCH_TYPE_DATACONTROL[] = "datacontrol";
64 static const char OSP_V_LAUNCH_TYPE_CONDTION[] = "condition";
65 static const char OSP_V_REQUEST_TYPE_SQL_QUERY[] = "sql_query";
66 static const char OSP_V_REQUEST_TYPE_SQL_INSERT[] = "sql_insert";
67 static const char OSP_V_REQUEST_TYPE_SQL_UPDATE[] = "sql_update";
68 static const char OSP_V_REQUEST_TYPE_SQL_DELETE[] = "sql_delete";
69 static const char OSP_V_REQUEST_TYPE_MAP_QEURY[] = "map_query";
70 static const char OSP_V_REQUEST_TYPE_MAP_INSERT[] = "map_insert";
71 static const char OSP_V_REQUEST_TYPE_MAP_UPDATE[] = "map_update";
72 static const char OSP_V_REQUEST_TYPE_MAP_DELETE[] = "map_delete";
73 static const char OSP_V_VERSION_2_1_0_3[] = "ver_2.1.0.3";
74 static const char BUNDLE_KEY_PREFIX_AUL[] = "__AUL_";
75 static const char BUNDLE_KEY_PREFIX_SERVICE[] = "__APP_SVC_";
76 static const char BUNDLE_KEY_PREFIX_OSP[] = "__OSP_";
77 static const char BUNDLE_KEY_PREFIX_UG[] = "__UG_";
78 const char TIZEN_NOTIFICATION_DATA[] = "http://tizen.org/appcontrol/data/notification";
79 const wchar_t LEGACY_OPERATION_MAIN[] = L"osp.operation.MAIN";
80
81
82 _AppArg::_AppArg(void)
83         : __pBundle(null)
84 {
85 }
86
87
88 _AppArg::~_AppArg(void)
89 {
90         if (__pBundle)
91         {
92                 bundle_free(__pBundle);
93         }
94 }
95
96
97 result
98 _AppArg::Construct(const String& argText)
99 {
100         __pBundle = bundle_create();
101         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
102
103         return CreateNotificationArg(__pBundle, argText);
104 }
105
106
107 result
108 _AppArg::Construct(const IList* pList)
109 {
110         __pBundle = bundle_create();
111         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
112
113         return CreateLaunchArg(__pBundle, pList);
114 }
115
116
117 result
118 _AppArg::Construct(const _AppControlImpl& ac, const IList* pList)
119 {
120         __pBundle = bundle_create();
121         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
122
123         return CreateAppControlArg(__pBundle, ac, pList);
124 }
125
126
127 result
128 _AppArg::Construct(const _AppControlImpl& ac, const String* pUri, const String* pMime, const IMap* pList)
129 {
130         __pBundle = bundle_create();
131         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
132
133         return CreateAppControlArg(__pBundle, ac, pUri, pMime, pList);
134 }
135
136
137 result
138 _AppArg::Construct(const _AppMessageImpl& msg, const String& oId, const String* pUri, const String* pMime)
139 {
140         __pBundle = bundle_dup(const_cast<bundle*>(msg.GetBundle()));
141         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
142
143         return CreateAppControlArg(__pBundle, oId, pUri, pMime, null);
144 }
145
146
147 result
148 _AppArg::Construct(const _SqlDataControlImpl& dc, _DataControlRequestType requestType, const IList* pList)
149 {
150         __pBundle = bundle_create();
151         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
152
153         return CreateSqlDataControlArg(__pBundle, dc, requestType, pList);
154 }
155
156
157 result
158 _AppArg::Construct(const _MapDataControlImpl& dc, _DataControlRequestType requestType, const IList* pList)
159 {
160         __pBundle = bundle_create();
161         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
162
163         return CreateMapDataControlArg(__pBundle, dc, requestType, pList);
164 }
165
166
167 result
168 _AppArg::ConstructResult(const _AppArg& arg, const IList* pList)
169 {
170         int ret = aul_create_result_bundle(arg.GetBundle(), &__pBundle);
171         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure : %d.", ret);
172
173         return CreateResultArg(__pBundle, pList);
174 }
175
176
177 result
178 _AppArg::ConstructResult(const _AppArg& arg, const IMap* pMap)
179 {
180         int ret = aul_create_result_bundle(arg.GetBundle(), &__pBundle);
181         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure : %d.", ret);
182
183         return CreateResultArg(__pBundle, pMap);
184 }
185
186
187 result
188 _AppArg::Construct(bundle* b)
189 {
190         __pBundle = bundle_dup(b);
191         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure.");
192
193         return E_SUCCESS;
194 }
195
196
197 result
198 _AppArg::ConstructForAppLaunchCondition(const String& condition, const IList* pList)
199 {
200         __pBundle = bundle_create();
201         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
202
203         return CreateAppLaunchConditionArg(__pBundle, condition, pList);
204 }
205
206 result
207 _AppArg::ConstructForAppLaunchCondition(const String& condition, const IList* pList, const IMap* pMap)
208 {
209         __pBundle = bundle_create();
210         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
211
212         CreateAppLaunchConditionArg(__pBundle, condition, pList);
213
214         return CreateResultArg(__pBundle, pMap);
215 }
216
217 ArrayList*
218 _AppArg::GetArgListN(int num) const
219 {
220         bundle* pBundle = __pBundle;
221         SysTryReturn(NID_APP, pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
222
223         ArrayList* pList = new (std::nothrow) ArrayList();
224         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
225
226         pList->Construct();
227
228         const char* p = NULL;
229         _AppHandler launch_type = GetHandler(pBundle);
230
231         switch (launch_type)
232         {
233         case _APP_HANDLER_APPCONTROL:
234                 // request Id
235                 // [FIXME] proper request Id required
236                 pList->Add(*new (std::nothrow) String(GetRequestId(num)));
237
238                 // category
239                 p = appsvc_get_category(pBundle);
240                 if (p)
241                 {
242                         pList->Add(*new (std::nothrow) String(p));
243                 }
244                 else
245                 {
246                         pList->Add(*new (std::nothrow) String(L""));
247                 }
248
249                 // MIME type
250                 p = appsvc_get_mime(pBundle);
251                 if (p)
252                 {
253                         pList->Add(*new (std::nothrow) String(p));
254                 }
255                 else
256                 {
257                         pList->Add(*new (std::nothrow) String(L""));
258                 }
259
260                 // URI scheme
261                 p = appsvc_get_uri(pBundle);
262                 if (p)
263                 {
264                         pList->Add(*new (std::nothrow) String(p));
265                 }
266                 else
267                 {
268                         pList->Add(*new (std::nothrow) String(L""));
269                 }
270
271                 break;
272
273         case _APP_HANDLER_DATACONTROL:
274                 // appId
275                 AddListFromBundle(pList, pBundle, OSP_K_APPID);
276                 // request type
277                 AddListFromBundle(pList, pBundle, OSP_K_DATACONTROL_REQUEST_TYPE);
278                 // reqId
279                 AddListFromBundle(pList, pBundle, OSP_K_REQUEST_ID);
280                 // providerId
281                 AddListFromBundle(pList, pBundle, OSP_K_DATACONTROL_PROVIDER);
282                 break;
283
284         case _APP_HANDLER_LAUNCH_COND:
285                 pList->Add(*new (std::nothrow) String(LEGACY_LAUNCH_REASON_CONDITIONAL));
286                 AddListFromBundle(pList, pBundle, OSP_K_COND);
287                 break;
288
289         case _APP_HANDLER_LAUNCH_NORMAL:
290                 pList->Add(*new (std::nothrow) String(LEGACY_LAUNCH_REASON_NORMAL));
291                 pList->Add(*new (std::nothrow) String(LEGACY_OPERATION_MAIN));
292                 break;
293
294         default:
295                 SysLog(NID_APP, "Invalid handler type");
296                 break;
297         }
298
299         SetArgList(__pBundle, pList);
300
301         return pList;
302 }
303
304
305 ArrayList*
306 _AppArg::GetArgListN(void) const
307 {
308         SysTryReturn(NID_APP, __pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
309
310         ArrayList* pList = new (std::nothrow) ArrayList();
311         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
312
313         pList->Construct();
314
315         SetArgList(__pBundle, pList);
316
317         return pList;
318 }
319
320 // the returned map is allocated using SingleObjectDeleter
321 HashMap*
322 _AppArg::GetArgMapN(void) const
323 {
324         SysTryReturn(NID_APP, __pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
325
326         //Print();
327
328         HashMap* pHashMap = new (std::nothrow) HashMap(SingleObjectDeleter);
329         SysTryReturn(NID_APP, pHashMap != null, null, E_OUT_OF_MEMORY, "HashMap creation failure.");
330
331         pHashMap->Construct();
332
333         SetArgMap(__pBundle, pHashMap);
334
335         if (pHashMap->GetCount() == 0)
336         {
337                 delete pHashMap;
338                 return null;
339         }
340
341         return pHashMap;
342 }
343
344 static bool
345 IsInternalKey(const char* pKey)
346 {
347         if (strncmp(BUNDLE_KEY_PREFIX_AUL, pKey, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
348         {
349                 return true;
350         }
351
352         if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, pKey, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
353         {
354                 return true;
355         }
356
357         if (strncmp(BUNDLE_KEY_PREFIX_OSP, pKey, strlen(BUNDLE_KEY_PREFIX_OSP)) == 0)
358         {
359                 return true;
360         }
361
362         if (strncmp(BUNDLE_KEY_PREFIX_UG, pKey, strlen(BUNDLE_KEY_PREFIX_UG)) == 0)
363         {
364                 return true;
365         }
366
367         return false;
368 }
369
370 static void
371 BundleIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
372 {
373         HashMap* pMap = static_cast<HashMap*>(pData);
374
375         if (pKey && pVal && pMap)
376         {
377                 if (IsInternalKey(pKey))
378                 {
379                         //SysLog(NID_APP, "(%s)", pKey);
380                         return;
381                 }
382
383                 size_t size = 0;
384                 char* pStr = NULL;
385                 switch (type)
386                 {
387                 case BUNDLE_TYPE_STR:
388                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
389                         if (pStr)
390                         {
391                                 pMap->Add(new (std::nothrow) String(pKey), new (std::nothrow) String(pStr));
392                         }
393                         break;
394                 case BUNDLE_TYPE_STR_ARRAY:
395                         {
396                                 void** pArr = NULL;
397                                 bundle_keyval_get_array_val(const_cast<bundle_keyval_t*>(pVal), &pArr, &size, NULL);
398                                 if (pArr && size > 0)
399                                 {
400                                         ArrayList* pList = new (std::nothrow) ArrayList(SingleObjectDeleter);
401                                         if (pList)
402                                         {
403                                                 pList->Construct();
404
405                                                 for (size_t i = 0; i < size; i++)
406                                                 {
407                                                         // type unsafe ugly static casting required
408                                                         pList->Add(new (std::nothrow) String(static_cast<char*>(*(pArr + i))));
409                                                 }
410
411                                                 const int count = pList->GetCount();
412                                                 if (count != 0)
413                                                 {
414                                                         SysLog(NID_APP, "Adding %d elements for %s", count, pKey);
415                                                         pMap->Add(new (std::nothrow) String(pKey), pList);
416                                                 }
417                                                 else
418                                                 {
419                                                         SysLog(NID_APP, "No object for %s", pKey);
420                                                         delete pList;
421                                                 }
422                                         }
423                                 }
424                                 else
425                                 {
426                                         SysLog(NID_APP, "No entry for str array %s(%d)", pKey, size);
427                                 }
428                         }
429                         break;
430                 case BUNDLE_TYPE_BYTE:
431                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
432
433                         SysLog(NID_IO, "Bundle byte value = %s, size = %d", pStr, size);
434
435                         if (pStr)
436                         {
437                                 ByteBuffer* pBuffer = new (std::nothrow) ByteBuffer();
438                                 SysTryLog(NID_IO, pBuffer != null, "The memory is insufficient.");
439                                 result r = pBuffer->Construct(size);
440                                 SysTryLog(NID_IO, r == E_SUCCESS, "Constructing pBuffer is failed.");
441
442                                 r = pBuffer->SetArray((const byte*)pStr, 0, size);
443                                 SysTryLog(NID_IO, r == E_SUCCESS, "SetArray()for ByteBuffer is failed.");
444
445                                 pBuffer->Flip();
446
447                                 pMap->Add(new (std::nothrow) String(pKey), pBuffer);
448                         }
449                         break;
450                 default:
451                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
452                         break;
453                 }
454         }
455 }
456
457 result
458 _AppArg::SetArgMap(bundle* pBundle, HashMap* pMap)
459 {
460         bundle_foreach(pBundle, BundleIterFnCb, reinterpret_cast<void*>(pMap));
461
462         return E_SUCCESS;
463 }
464
465 result
466 _AppArg::SetArgList(bundle* pBundle, ArrayList* pList)
467 {
468         // actual argument below
469         int len = 0;
470         const char** pa = appsvc_get_data_array(pBundle, OSP_K_ARG, &len);
471         if (pa)
472         {
473                 for (int i = 0; i < len; i++)
474                 {
475                         if (pa[i])
476                         {
477                                 //SysLog(NID_APP, "%d/%dth arg [%s]", i, len, pa[i]);
478                                 pList->Add(*new (std::nothrow) String(pa[i]));
479                         }
480                 }
481         }
482
483         const char* p = appsvc_get_uri(pBundle);
484         if (p)
485         {
486                 pList->Add(*new (std::nothrow) String(p));
487                 SysLog(NID_APP, "argument is %s", p);
488         }
489
490         return E_SUCCESS;
491 }
492
493
494 String
495 _AppArg::GetValue(const char* key) const
496 {
497         const char* p = appsvc_get_data(__pBundle, key);
498         return String(p);
499 }
500
501
502 _AppHandler
503 _AppArg::GetHandler(bundle* b)
504 {
505         SysTryReturn(NID_APP, b != null, _APP_HANDLER_NONE, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
506
507         const char* p = null;
508
509         p = appsvc_get_data(b, OSP_K_LAUNCH_TYPE);
510
511         if (p)
512         {
513                 if (strcmp(p, OSP_V_LAUNCH_TYPE_DATACONTROL) == 0)
514                 {
515                         return _APP_HANDLER_DATACONTROL;
516                 }
517
518                 if (strcmp(p, OSP_V_LAUNCH_TYPE_APPCONTROL) == 0)
519                 {
520                         SysLog(NID_APP, "Building AppControl arguments.");
521
522                         return _APP_HANDLER_APPCONTROL;
523                 }
524                 else
525                 {
526                         // not appcontrol nor datacontrol => normal launch or condlaunch
527                         p = appsvc_get_data(b, OSP_K_COND);
528                         if (p)
529                         {
530                                 SysLog(NID_APP, "Building Conditional AppLaunch arguments.");
531                                 return _APP_HANDLER_LAUNCH_COND;
532                         }
533                         else
534                         {
535                                 SysLog(NID_APP, "Building Normal AppLaunch arguments.");
536                                 return _APP_HANDLER_LAUNCH_NORMAL;
537                         }
538                 }
539         }
540
541         // fallback
542         return _APP_HANDLER_APPCONTROL;
543 }
544
545
546 int
547 _AppArg::GetCallerPid(bundle* pBundle)
548 {
549         const char* pBundleValue = bundle_get_val(pBundle, AUL_K_ORG_CALLER_PID);
550         if (pBundleValue == NULL)
551         {
552                 pBundleValue = bundle_get_val(pBundle, AUL_K_CALLER_PID);
553         }
554
555         SysTryReturn(NID_APP, pBundleValue != null, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found.");
556
557         return atoi(pBundleValue);
558 }
559
560
561 AppId
562 _AppArg::GetCallerAppId(void) const
563 {
564         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLER_APPID);
565
566         return String(pBundleValue);
567 }
568
569
570 AppId
571 _AppArg::GetCalleeAppId(void) const
572 {
573         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLEE_APPID);
574
575         const AppId retVal = pBundleValue;
576
577         return _Aul::GetRealAppId(retVal);
578 }
579
580
581 void
582 _AppArg::AddListFromBundle(ArrayList* pList, bundle* bk, const char* key)
583 {
584         bundle* pBundle = bk;
585
586         const char* p = appsvc_get_data(pBundle, key);
587         if (p)
588         {
589                 pList->Add(*new (std::nothrow) String(p));
590         }
591         else
592         {
593                 pList->Add(*new (std::nothrow) String(L""));
594         }
595 }
596
597
598 result
599 _AppArg::AddStrArray(bundle* b, const String& key, const IList* pList)
600 {
601         std::unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(key));
602
603         return AddStrArray(b, pKey.get(), pList);
604 }
605
606
607 result
608 _AppArg::AddStrArray(bundle* pb, const char* key, const IList* pList)
609 {
610         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
611
612         if (pList == null || pList->GetCount() == 0)
613         {
614                 SysLog(NID_APP, "No element added for bundle.");
615                 return E_SUCCESS;
616         }
617
618         _AppMessageImpl::AddValueArray(pb, key, pList);
619
620         _AppMessageImpl::AddData(pb, pList);
621
622         return E_SUCCESS;
623 }
624
625
626 result
627 _AppArg::AddStrMap(bundle* b, const IMap* pMap)
628 {
629         bundle* pb = b;
630         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
631
632         if (pMap == null || pMap->GetCount() == 0)
633         {
634                 SysLog(NID_APP, "No element added for bundle.");
635                 return E_SUCCESS;
636         }
637
638         std::unique_ptr<IMapEnumerator> pEnum (pMap->GetMapEnumeratorN());
639         while(pEnum->MoveNext() == E_SUCCESS)
640         {
641                 const String* pKey = static_cast<const String*>(pEnum->GetKey());
642                 const Object* pObj = pEnum->GetValue();
643
644                 if (pKey && pObj)
645                 {
646                         if (typeid(*pObj) == typeid(const String))
647                         {
648                                 const String* pVal = static_cast<const String*>(pEnum->GetValue());
649                                 if (pVal)
650                                 {
651                                         _AppMessageImpl::AddData(pb, *pKey, *pVal);
652                                 }
653                         }
654                         else if (typeid(*pObj) == typeid(const ArrayList))
655                         {
656                                 const ArrayList* pList = static_cast<const ArrayList*>(pEnum->GetValue());
657                                 if (pList)
658                                 {
659                                         SysLog(NID_APP, "ArrayList type");
660
661                                         _AppMessageImpl::AddValueArray(pb, *pKey, pList);
662                                 }
663                         }
664                         else if (typeid(*pObj) == typeid(const ByteBuffer))
665                         {
666                                 SysLog(NID_APP, "ByteBuffer type");
667                                 const ByteBuffer* pBuffer = static_cast<const ByteBuffer*>(pObj);
668
669                                 std::unique_ptr<char[]> pBundleKey(_StringConverter::CopyToCharArrayN(*pKey));
670                                 bundle_add_byte(b, pBundleKey.get(), pBuffer->GetPointer(), pBuffer->GetLimit());
671                         }
672                 }
673         }
674
675         return E_SUCCESS;
676 }
677
678
679 result
680 _AppArg::FillMapFromList(IMap* pMap, const IList* pList)
681 {
682         if (pMap == null || pList == null)
683         {
684                 return E_SUCCESS;
685         }
686
687         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
688         SysTryReturnResult(NID_APP, pEnum != null, E_OUT_OF_MEMORY, "Getting enumerator failed.");
689
690         String key;
691         String value;
692         while (pEnum->MoveNext() == E_SUCCESS)
693         {
694                 String* pStr = dynamic_cast<String*>(pEnum->GetCurrent());
695
696                 int index = -1;
697                 if (pStr == null || pStr->IndexOf(L':', 0, index) != E_SUCCESS)
698                 {
699                         continue;
700                 }
701                 pStr->SubString(0, index, key);
702                 if (key.IsEmpty())
703                 {
704                         continue;
705                 }
706
707                 pStr->SubString(index + 1, value);
708
709                 pMap->Add(new String(key), new String(value));
710
711                 SysLog(NID_APP, "Added (%ls, %ls).", key.GetPointer(), value.GetPointer());
712         }
713
714         return E_SUCCESS;
715 }
716
717
718 result
719 _AppArg::FillLegacyAppControlResult(IList& list, int res, const IMap* pArgs, const Tizen::Base::String& aId)
720 {
721         switch (res)
722         {
723         case APP_CTRL_RESULT_SUCCEEDED:
724                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_SUCCEEDED));
725                 break;
726         case APP_CTRL_RESULT_CANCELED:
727                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_CANCELED));
728                 return E_SUCCESS;
729         case APP_CTRL_RESULT_TERMINATED:
730                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_TERMINATED));
731                 return E_SUCCESS;
732         case APP_CTRL_RESULT_ABORTED:
733                 list.Add(* new (std::nothrow) String("aborted"));
734                 return E_SUCCESS;
735                 //case APP_CTRL_RESULT_FAILED:
736         default:
737                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_FAILED));
738                 return E_SUCCESS;
739         }
740
741         if (pArgs == null)
742         {
743                 return E_SUCCESS;
744         }
745
746         bool isPathRegistered = false;
747         // handle APP_CTRL_RESULT_SUCCEEDED only
748         std::unique_ptr<IMapEnumerator> pMapEnum(pArgs->GetMapEnumeratorN());
749
750         while(pMapEnum->MoveNext() == E_SUCCESS)
751         {
752                 String* pKey = static_cast<String*>(pMapEnum->GetKey());
753                 if (pKey == null)
754                 {
755                         SysLog(NID_APP, "Invalid entry.");
756                         continue;
757                 }
758
759                 if (*pKey == L"path" || *pKey == L"http://tizen.org/appcontrol/data/selected")
760                 {
761                         if (!isPathRegistered)
762                         {
763                                 isPathRegistered = true;
764                         }
765                         else
766                         {
767                                 SysLog(NID_APP, "Selected path key is already registered.");
768                                 continue;
769                         }
770                 }
771
772                 String* pVal = dynamic_cast<String*>(pMapEnum->GetValue());
773                 if (pVal)
774                 {
775                         SysLog(NID_APP, "Adding value (%ls).", pVal->GetPointer());
776
777                         StringTokenizer strTok(*pVal, L';');
778                         if (strTok.GetTokenCount() == 0)
779                         {
780                                 list.Add(* new (std::nothrow) String(*pVal));
781                         }
782                         else
783                         {
784                                 String token;
785                                 while(strTok.HasMoreTokens())
786                                 {
787                                         strTok.GetNextToken(token);
788                                         list.Add(* new (std::nothrow) String(token));
789                                         SysLog(NID_APP, "Adding tokenized value (%ls).", token.GetPointer());
790                                 }
791                         }
792                 }
793         }
794
795         return E_SUCCESS;
796 }
797
798
799 ArrayList*
800 _AppArg::GetListN(bundle* b, const char* key)
801 {
802         bundle* pb = b;
803         if (pb == null)
804         {
805                 return null;
806         }
807
808         const char** pValArray = null;
809         int len = 0;
810
811         pValArray = appsvc_get_data_array(b, key, &len);
812         if (len == 0 || pValArray == null)
813         {
814                 return null;
815         }
816
817         ArrayList* pList = new (std::nothrow) ArrayList;
818         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
819
820         pList->Construct();
821
822         for (int i = 0; i < len; i++)
823         {
824                 pList->Add(*new (std::nothrow) String(pValArray[i]));
825         }
826
827         return pList;
828 }
829
830
831 result
832 _AppArg::CreateNotificationArg(bundle* b, const String& arg)
833 {
834         SysAssertf(b != null, "Valid bundle should be supplied");
835
836         bundle* pb = b;
837
838         if (!arg.IsEmpty())
839         {
840                 std::unique_ptr<char[]> pStr(_StringConverter::CopyToCharArrayN(arg));
841                 bundle_add(pb, TIZEN_NOTIFICATION_DATA, pStr.get());
842         }
843
844         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
845
846         return E_SUCCESS;
847 }
848
849
850 result
851 _AppArg::CreateLaunchArg(bundle* b, const IList* pList)
852 {
853         SysAssertf(b != null, "Valid bundle should be supplied");
854
855         bundle* pb = b;
856
857         AddStrArray(pb, OSP_K_ARG, pList);
858
859         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
860
861         return E_SUCCESS;
862 }
863
864
865 result
866 _AppArg::CreateAppLaunchConditionArg(bundle* b, const String& condition, const IList* pList)
867 {
868         SysAssertf(b != null, "Valid bundle should be supplied");
869         SysLog(NID_APP, "");
870
871         bundle* pb = b;
872
873         AddStrArray(pb, OSP_K_ARG, pList);
874
875         std::unique_ptr<char[]> p(_StringConverter::CopyToCharArrayN(condition));
876         if (p)
877         {
878                 bundle_add(pb, OSP_K_COND, p.get());
879         }
880
881         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_CONDTION);
882
883         return E_SUCCESS;
884 }
885
886
887 result
888 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const IList* pList)
889 {
890         SysAssertf(b != null, "Valid bundle should be supplied");
891
892         bundle* pb = b;
893
894         AddStrArray(pb, OSP_K_ARG, pList);
895
896         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(ac._opId));
897         if (pOperation)
898         {
899                 appsvc_set_operation(pb, pOperation.get());
900         }
901
902         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
903
904         return E_SUCCESS;
905 }
906
907
908 result
909 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const String* pUriData, const String* pMimeType, const IMap* pMap)
910 {
911         return CreateAppControlArg(b, ac._opId, pUriData, pMimeType, pMap);
912 }
913
914
915 result
916 _AppArg::CreateAppControlArg(bundle* b, const String& oId, const String* pUriData, const String* pMimeType, const IMap* pMap)
917 {
918         SysAssertf(b != null, "Valid bundle should be supplied");
919
920         bundle* pb = b;
921
922         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(oId));
923         if (pOperation.get())
924         {
925                 appsvc_set_operation(pb, pOperation.get());
926         }
927
928         if (pUriData)
929         {
930                 std::unique_ptr<char[]> pUri(_StringConverter::CopyToCharArrayN(*pUriData));
931                 if (pUri.get())
932                 {
933                         appsvc_set_uri(pb, pUri.get());
934                 }
935         }
936
937         if (pMimeType)
938         {
939                 std::unique_ptr<char[]> pMime(_StringConverter::CopyToCharArrayN(*pMimeType));
940                 if (pMime.get())
941                 {
942                         appsvc_set_mime(pb, pMime.get());
943                 }
944         }
945
946         AddStrMap(pb, pMap);
947
948         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
949
950         return E_SUCCESS;
951 }
952
953
954 namespace
955 {
956 const int MAX_LEN_DATA_CONTROL_REQ_TYPE = 8;
957 }
958 result
959 _AppArg::CreateSqlDataControlArg(bundle* b, const _SqlDataControlImpl& dc, _DataControlRequestType requestType,
960                                                                  const IList* pArgList)
961 {
962         SysAssertf(b != null, "Valid bundle should be supplied");
963
964         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
965
966         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
967         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast<int>(requestType));
968         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
969         bundle_add(b, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
970         bundle_add(b, AUL_K_NO_CANCEL, "1");
971
972         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
973         if (pProvider)
974         {
975                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
976         }
977
978         AddStrArray(b, OSP_K_ARG, pArgList);
979
980         return E_SUCCESS;
981 }
982
983
984 result
985 _AppArg::CreateMapDataControlArg(bundle* b, const _MapDataControlImpl& dc, _DataControlRequestType requestType,
986                                                                  const IList* pArgList)
987 {
988         SysAssertf(b != null, "Valid bundle should be supplied");
989
990         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
991
992         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
993         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast < int >(requestType));
994         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
995         bundle_add(b, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
996         bundle_add(b, AUL_K_NO_CANCEL, "1");
997
998         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
999         if (pProvider)
1000         {
1001                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1002         }
1003
1004         AddStrArray(b, OSP_K_ARG, pArgList);
1005
1006         return E_SUCCESS;
1007 }
1008
1009
1010 result
1011 _AppArg::CreateResultArg(bundle* b, const IList* pList)
1012 {
1013         SysAssertf(b != null, "Valid bundle should be supplied");
1014
1015         bundle* pb = b;
1016
1017         AddStrArray(pb, OSP_K_ARG, pList);
1018
1019         _AppMessageImpl::AddData(pb, pList);
1020
1021         return E_SUCCESS;
1022 }
1023
1024
1025 result
1026 _AppArg::CreateResultArg(bundle* b, const IMap* pMap)
1027 {
1028         SysAssertf(b != null, "Valid bundle should be supplied");
1029
1030         bundle* pb = b;
1031
1032         AddStrMap(pb, pMap);
1033
1034         return E_SUCCESS;
1035 }
1036
1037
1038 bundle*
1039 _AppArg::CreateBundleFromSvc(void* svc)
1040 {
1041         bundle* pBundle = GetBundleFromSvc(svc);
1042         if (pBundle)
1043         {
1044                 return bundle_dup(pBundle);
1045         }
1046
1047         return null;
1048 }
1049
1050
1051 bundle*
1052 _AppArg::GetBundleFromSvc(void* svc)
1053 {
1054         struct DummyS
1055         {
1056                 int dummy1;
1057                 int dummy2;
1058                 bundle* pData;
1059         };
1060
1061         DummyS* pDummy = static_cast<DummyS*>(svc);
1062
1063         if (pDummy && pDummy->pData)
1064         {
1065                 return pDummy->pData;
1066         }
1067
1068         return NULL;
1069 }
1070
1071
1072 String
1073 _AppArg::GetRequestId(int num)
1074 {
1075         String str;
1076         str.Format(10, L"req%05d", num);
1077         return str;
1078 }
1079
1080
1081 int
1082 _AppArg::GetRequestId(const String& str)
1083 {
1084         int i = 0;
1085         String sub;
1086
1087         result r = str.SubString(3, sub);
1088         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1089
1090         r = Integer::Parse(sub, i);
1091         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1092
1093         return i;
1094 }
1095
1096
1097 void
1098 _AppArg::UpdateAppId(bundle* b, const AppId& appId)
1099 {
1100         SysTryReturnVoidResult(NID_APP, b != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1101
1102         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
1103         SysTryReturnVoidResult(NID_APP, pId != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Converting %ls failed.", appId.GetPointer());
1104
1105         int res = bundle_add(b, OSP_K_APPID, pId.get());
1106         if (res < 0 && errno == EPERM) // key exists
1107         {
1108                 bundle_del(b, OSP_K_APPID);
1109                 bundle_add(b, OSP_K_APPID, pId.get());
1110         }
1111
1112         appsvc_set_appid(b, pId.get());
1113 }
1114
1115
1116 void
1117 _AppArg::UpdateRequestId(bundle* pBundle, int reqId)
1118 {
1119         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1120
1121         if (reqId < 0)
1122         {
1123                 //SysLog(NID_APP, "Requested ID is %d", reqId);
1124                 return;
1125         }
1126
1127         char buffer[32] = {0, };
1128         snprintf(buffer, 32, "%d", reqId);
1129         int res = bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1130         if (res < 0 && errno == EPERM) // key exists
1131         {
1132                 bundle_del(pBundle, OSP_K_REQUEST_ID);
1133                 bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1134         }
1135 }
1136
1137 void
1138 _AppArg::UpdateKeyValue(bundle* pBundle, const char* pKey, const String& value)
1139 {
1140         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1141
1142         char pBuffer[128] = {0, };
1143         snprintf(pBuffer, 128, "%ls", value.GetPointer());
1144         int res = bundle_add(pBundle, pKey, pBuffer);
1145         if (res < 0 && errno == EPERM) // key exists
1146         {
1147                 bundle_del(pBundle, pKey);
1148                 bundle_add(pBundle, pKey, pBuffer);
1149         }
1150 }
1151
1152
1153 void
1154 _AppArg::UpdateSubMode(bundle* pBundle)
1155 {
1156         appsvc_add_data(pBundle, OSP_K_SUBMODE_CALLEE, "1");
1157 }
1158
1159
1160 bool
1161 _AppArg::IsSubMode(bundle* pBundle)
1162 {
1163         const char* p = appsvc_get_data(pBundle, OSP_K_SUBMODE_CALLEE);
1164         if (p && (strncmp(p, "1", sizeof(char)) == 0))
1165         {
1166                 return true;
1167         }
1168
1169         return false;
1170 }
1171
1172
1173 int
1174 _AppArg::GetRequestIdFromBundle(bundle* pBundle)
1175 {
1176         const char* p = appsvc_get_data(pBundle, OSP_K_REQUEST_ID);
1177         if (p == NULL)
1178         {
1179                 return -1;
1180         }
1181
1182         int i = atoi(p);
1183         return (i < 0) ? -1 : i;
1184 }
1185
1186
1187 result
1188 _AppArg::UpdateWindowHandle(bundle* pBundle, long handle)
1189 {
1190         appsvc_allow_transient_app(pBundle, handle);
1191
1192         SysLog(NID_APP, "Window Handle 0x%x added.", handle);
1193
1194         return E_SUCCESS;
1195 }
1196
1197
1198 void
1199 _AppArg::PrintSvcHandle(void* svc)
1200 {
1201         service_h service = static_cast<service_h>(svc);
1202
1203         if (service == null)
1204         {
1205                 return;
1206         }
1207
1208         Print(GetBundleFromSvc(service));
1209 }
1210
1211
1212 static void
1213 BundlePrintIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
1214 {
1215         if (pKey && pVal)
1216         {
1217                 size_t size = 0;
1218                 char* pStr = NULL;
1219                 switch (type)
1220                 {
1221                 case BUNDLE_TYPE_STR:
1222                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
1223                         if (pStr)
1224                         {
1225                                 SysSecureLog(NID_APP, "(%s, %s)", pKey, pStr);
1226                         }
1227                         break;
1228                 default:
1229                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
1230                         break;
1231                 }
1232         }
1233 }
1234
1235 void
1236 _AppArg::Print(bundle* b)
1237 {
1238         if (b == null)
1239         {
1240                 return;
1241         }
1242
1243         bundle_foreach(b, BundlePrintIterFnCb, NULL);
1244
1245         int len = 0;
1246         const char** pa = appsvc_get_data_array(b, OSP_K_ARG, &len);
1247         if (pa)
1248         {
1249                 for (int i = 0; i < len; i++)
1250                 {
1251                         if (pa[i])
1252                         {
1253                                 SysLog(NID_APP, "%dth arg [%s]", i, pa[i]);
1254                         }
1255                 }
1256         }
1257 }
1258
1259 } } // Tizen::App