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