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