Merge "Update for handling bytebuffer" 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                                 pBuffer->SetArray((const byte*)pStr, 0, size);
447                                 pBuffer->Flip();
448
449                                 pMap->Add(new (std::nothrow) String(pKey), pBuffer);
450                         }
451                         break;
452                 default:
453                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
454                         break;
455                 }
456         }
457 }
458
459 result
460 _AppArg::SetArgMap(bundle* pBundle, HashMap* pMap)
461 {
462         bundle_foreach(pBundle, BundleIterFnCb, reinterpret_cast<void*>(pMap));
463
464         return E_SUCCESS;
465 }
466
467 result
468 _AppArg::SetArgList(bundle* pBundle, ArrayList* pList)
469 {
470         // actual argument below
471         int len = 0;
472         const char** pa = appsvc_get_data_array(pBundle, OSP_K_ARG, &len);
473         if (pa)
474         {
475                 for (int i = 0; i < len; i++)
476                 {
477                         if (pa[i])
478                         {
479                                 //SysLog(NID_APP, "%d/%dth arg [%s]", i, len, pa[i]);
480                                 pList->Add(*new (std::nothrow) String(pa[i]));
481                         }
482                 }
483         }
484
485         const char* p = appsvc_get_uri(pBundle);
486         if (p)
487         {
488                 pList->Add(*new (std::nothrow) String(p));
489                 SysLog(NID_APP, "argument is %s", p);
490         }
491
492         String tmp;
493         p = appsvc_get_data(pBundle, SMS_KEY_SERVICE_CALLER);
494         if (p)
495         {
496                 tmp.Format(60, L"%s:%s", SMS_KEY_SERVICE_CALLER, p);
497                 pList->Add(*new (std::nothrow) String(tmp));
498                 SysLog(NID_APP, "service_caller is %s", p);
499         }
500         
501         p = appsvc_get_data(pBundle, SMS_KEY_SERVICE_DATA);
502         if (p)
503         {
504                 tmp.Format(60, L"%s:%s", SMS_KEY_SERVICE_DATA, p);
505                 pList->Add(*new (std::nothrow) String(tmp));
506                 SysLog(NID_APP, "service_data is set");
507         }
508         
509         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_CLIENT_ID);
510         if (p)
511         {
512                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_CLIENT_ID, p);
513                 pList->Add(*new (std::nothrow) String(tmp));
514                 SysLog(NID_APP, "client_id is %s", p);
515         }
516         
517         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET);
518         if (p)
519         {
520                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET, p);
521                 pList->Add(*new (std::nothrow) String(tmp));
522                 SysLog(NID_APP, "client_secret is %s", p);
523         }
524
525         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY);
526         if (p)
527         {
528                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY, p);
529                 pList->Add(*new (std::nothrow) String(tmp));
530                 SysLog(NID_APP, "service_category is %s", p);
531         }
532
533         return E_SUCCESS;
534 }
535
536
537 String
538 _AppArg::GetValue(const char* key) const
539 {
540         const char* p = appsvc_get_data(__pBundle, key);
541         return String(p);
542 }
543
544
545 _AppHandler
546 _AppArg::GetHandler(bundle* b)
547 {
548         SysTryReturn(NID_APP, b != null, _APP_HANDLER_NONE, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
549
550         const char* p = null;
551
552         p = appsvc_get_data(b, OSP_K_LAUNCH_TYPE);
553
554         if (p)
555         {
556                 if (strcmp(p, OSP_V_LAUNCH_TYPE_DATACONTROL) == 0)
557                 {
558                         return _APP_HANDLER_DATACONTROL;
559                 }
560
561                 if (strcmp(p, OSP_V_LAUNCH_TYPE_APPCONTROL) == 0)
562                 {
563                         SysLog(NID_APP, "Building AppControl arguments.");
564
565                         return _APP_HANDLER_APPCONTROL;
566                 }
567                 else
568                 {
569                         // not appcontrol nor datacontrol => normal launch or condlaunch
570                         p = appsvc_get_data(b, OSP_K_COND);
571                         if (p)
572                         {
573                                 SysLog(NID_APP, "Building Conditional AppLaunch arguments.");
574                                 return _APP_HANDLER_LAUNCH_COND;
575                         }
576                         else
577                         {
578                                 SysLog(NID_APP, "Building Normal AppLaunch arguments.");
579                                 return _APP_HANDLER_LAUNCH_NORMAL;
580                         }
581                 }
582         }
583
584         // fallback
585         return _APP_HANDLER_APPCONTROL;
586 }
587
588
589 int
590 _AppArg::GetCallerPid(bundle* pBundle)
591 {
592         const char* pBundleValue = bundle_get_val(pBundle, AUL_K_ORG_CALLER_PID);
593         if (pBundleValue == NULL)
594         {
595                 pBundleValue = bundle_get_val(pBundle, AUL_K_CALLER_PID);
596         }
597
598         SysTryReturn(NID_APP, pBundleValue != null, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found.");
599
600         return atoi(pBundleValue);
601 }
602
603
604 AppId
605 _AppArg::GetCallerAppId(void) const
606 {
607         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLER_APPID);
608
609         return String(pBundleValue);
610 }
611
612
613 AppId
614 _AppArg::GetCalleeAppId(void) const
615 {
616         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLEE_APPID);
617
618         String retVal = pBundleValue;
619
620         String temp;
621         // [INFO] ugly code for submode callee
622         retVal.SubString(11, temp);
623         if (temp == L"_AppControl")
624         {
625                 String id;
626                 retVal.SubString(0, 10, id);
627                 const String& name = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(id);
628
629                 retVal = id + L'.' + name;
630                 SysLog(NID_APP, "Converted caller Id is %ls", retVal.GetPointer());
631         }
632
633         return retVal;
634 }
635
636
637 void
638 _AppArg::AddListFromBundle(ArrayList* pList, bundle* bk, const char* key)
639 {
640         bundle* pBundle = bk;
641
642         const char* p = appsvc_get_data(pBundle, key);
643         if (p)
644         {
645                 pList->Add(*new (std::nothrow) String(p));
646         }
647         else
648         {
649                 pList->Add(*new (std::nothrow) String(L""));
650         }
651 }
652
653
654 result
655 _AppArg::AddStrArray(bundle* b, const String& key, const IList* pList)
656 {
657         std::unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(key));
658
659         return AddStrArray(b, pKey.get(), pList);
660 }
661
662
663 result
664 _AppArg::AddStrArray(bundle* pb, const char* key, const IList* pList)
665 {
666         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
667
668         if (pList == null || pList->GetCount() == 0)
669         {
670                 SysLog(NID_APP, "No element added for bundle.");
671                 return E_SUCCESS;
672         }
673
674         _AppMessageImpl::AddValueArray(pb, key, pList);
675
676         _AppMessageImpl::AddData(pb, pList);
677
678         return E_SUCCESS;
679 }
680
681
682 result
683 _AppArg::AddStrMap(bundle* b, const IMap* pMap)
684 {
685         bundle* pb = b;
686         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
687
688         if (pMap == null || pMap->GetCount() == 0)
689         {
690                 SysLog(NID_APP, "No element added for bundle.");
691                 return E_SUCCESS;
692         }
693
694         std::unique_ptr<IMapEnumerator> pEnum (pMap->GetMapEnumeratorN());
695         while(pEnum->MoveNext() == E_SUCCESS)
696         {
697                 const String* pKey = static_cast<const String*>(pEnum->GetKey());
698                 const Object* pObj = pEnum->GetValue();
699
700                 if (pKey && pObj)
701                 {
702                         if (typeid(*pObj) == typeid(const String))
703                         {
704                                 const String* pVal = static_cast<const String*>(pEnum->GetValue());
705                                 if (pVal)
706                                 {
707                                         _AppMessageImpl::AddData(pb, *pKey, *pVal);
708                                 }
709                         }
710                         else if (typeid(*pObj) == typeid(const ArrayList))
711                         {
712                                 const ArrayList* pList = static_cast<const ArrayList*>(pEnum->GetValue());
713                                 if (pList)
714                                 {
715                                         SysLog(NID_APP, "ArrayList type");
716
717                                         _AppMessageImpl::AddValueArray(pb, *pKey, pList);
718                                 }
719                         }
720                         else if (typeid(*pObj) == typeid(const ByteBuffer))
721                         {
722                                 SysLog(NID_APP, "ByteBuffer type");
723                                 const ByteBuffer* pBuffer = static_cast<const ByteBuffer*>(pObj);
724
725                                 std::unique_ptr<char[]> pBundleKey(_StringConverter::CopyToCharArrayN(*pKey));
726                                 bundle_add_byte(b, pBundleKey.get(), pBuffer->GetPointer(), pBuffer->GetLimit());
727                         }
728                 }
729         }
730
731         return E_SUCCESS;
732 }
733
734
735 result
736 _AppArg::FillMapFromList(IMap* pMap, const IList* pList)
737 {
738         if (pMap == null || pList == null)
739         {
740                 return E_SUCCESS;
741         }
742
743         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
744         SysTryReturnResult(NID_APP, pEnum != null, E_OUT_OF_MEMORY, "Getting enumerator failed.");
745
746         String key;
747         String value;
748         while (pEnum->MoveNext() == E_SUCCESS)
749         {
750                 String* pStr = dynamic_cast<String*>(pEnum->GetCurrent());
751
752                 int index = -1;
753                 if (pStr == null || pStr->IndexOf(L':', 0, index) != E_SUCCESS)
754                 {
755                         continue;
756                 }
757                 pStr->SubString(0, index, key);
758                 if (key.IsEmpty())
759                 {
760                         continue;
761                 }
762
763                 pStr->SubString(index + 1, value);
764
765                 pMap->Add(new String(key), new String(value));
766
767                 SysLog(NID_APP, "Added (%ls, %ls).", key.GetPointer(), value.GetPointer());
768         }
769
770         return E_SUCCESS;
771 }
772
773
774 result
775 _AppArg::FillLegacyAppControlResult(IList& list, int res, const IMap* pArgs, const Tizen::Base::String& aId)
776 {
777         switch (res)
778         {
779         case APP_CTRL_RESULT_SUCCEEDED:
780                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_SUCCEEDED));
781                 break;
782         case APP_CTRL_RESULT_CANCELED:
783                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_CANCELED));
784                 return E_SUCCESS;
785         case APP_CTRL_RESULT_TERMINATED:
786                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_TERMINATED));
787                 return E_SUCCESS;
788         case APP_CTRL_RESULT_ABORTED:
789                 list.Add(* new (std::nothrow) String("aborted"));
790                 return E_SUCCESS;
791                 //case APP_CTRL_RESULT_FAILED:
792         default:
793                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_FAILED));
794                 return E_SUCCESS;
795         }
796
797         if (pArgs == null)
798         {
799                 return E_SUCCESS;
800         }
801
802         bool isPathRegistered = false;
803         // handle APP_CTRL_RESULT_SUCCEEDED only
804         std::unique_ptr<IMapEnumerator> pMapEnum(pArgs->GetMapEnumeratorN());
805
806         while(pMapEnum->MoveNext() == E_SUCCESS)
807         {
808                 String* pKey = static_cast<String*>(pMapEnum->GetKey());
809                 if (pKey == null)
810                 {
811                         SysLog(NID_APP, "Invalid entry.");
812                         continue;
813                 }
814
815                 if (*pKey == L"path" || *pKey == L"http://tizen.org/appcontrol/data/selected")
816                 {
817                         if (!isPathRegistered)
818                         {
819                                 isPathRegistered = true;
820                         }
821                         else
822                         {
823                                 SysLog(NID_APP, "Selected path key is already registered.");
824                                 continue;
825                         }
826                 }
827
828                 String* pVal = dynamic_cast<String*>(pMapEnum->GetValue());
829                 if (pVal)
830                 {
831                         SysLog(NID_APP, "Adding value (%ls).", pVal->GetPointer());
832
833                         StringTokenizer strTok(*pVal, L';');
834                         if (strTok.GetTokenCount() == 0)
835                         {
836                                 list.Add(* new (std::nothrow) String(*pVal));
837                         }
838                         else
839                         {
840                                 String token;
841                                 while(strTok.HasMoreTokens())
842                                 {
843                                         strTok.GetNextToken(token);
844                                         list.Add(* new (std::nothrow) String(token));
845                                         SysLog(NID_APP, "Adding tokenized value (%ls).", token.GetPointer());
846                                 }
847                         }
848                 }
849         }
850
851         return E_SUCCESS;
852 }
853
854
855 ArrayList*
856 _AppArg::GetListN(bundle* b, const char* key)
857 {
858         bundle* pb = b;
859         if (pb == null)
860         {
861                 return null;
862         }
863
864         const char** pValArray = null;
865         int len = 0;
866
867         pValArray = appsvc_get_data_array(b, key, &len);
868         if (len == 0 || pValArray == null)
869         {
870                 return null;
871         }
872
873         ArrayList* pList = new (std::nothrow) ArrayList;
874         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
875
876         pList->Construct();
877
878         for (int i = 0; i < len; i++)
879         {
880                 pList->Add(*new (std::nothrow) String(pValArray[i]));
881         }
882
883         return pList;
884 }
885
886
887 result
888 _AppArg::CreateLaunchArg(bundle* b, const String& arg)
889 {
890         SysAssertf(b != null, "Valid bundle should be supplied");
891
892         bundle* pb = b;
893
894         if (!arg.IsEmpty())
895         {
896                 const char** pSa = new (std::nothrow) const char*[1];
897                 SysTryReturnResult(NID_APP, pSa != null, E_OUT_OF_MEMORY, "Insufficient memory.");
898                 pSa[0] = _StringConverter::CopyToCharArrayN(arg);
899                 bundle_add_str_array(pb, OSP_K_ARG, pSa, 1);
900
901                 bundle_add(pb, TIZEN_NOTIFICATION_DATA, pSa[0]);
902
903                 delete[] pSa[0];
904                 delete[] pSa;
905         }
906
907         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
908
909         return E_SUCCESS;
910 }
911
912
913 result
914 _AppArg::CreateLaunchArg(bundle* b, const IList* pList)
915 {
916         SysAssertf(b != null, "Valid bundle should be supplied");
917
918         bundle* pb = b;
919
920         AddStrArray(pb, OSP_K_ARG, pList);
921
922         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
923
924         return E_SUCCESS;
925 }
926
927
928 result
929 _AppArg::CreateAppLaunchConditionArg(bundle* b, const String& condition, const IList* pList)
930 {
931         SysAssertf(b != null, "Valid bundle should be supplied");
932         SysLog(NID_APP, "");
933
934         bundle* pb = b;
935
936         AddStrArray(pb, OSP_K_ARG, pList);
937
938         std::unique_ptr<char[]> p(_StringConverter::CopyToCharArrayN(condition));
939         if (p)
940         {
941                 bundle_add(pb, OSP_K_COND, p.get());
942         }
943
944         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_CONDTION);
945
946         return E_SUCCESS;
947 }
948
949
950 result
951 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const IList* pList)
952 {
953         SysAssertf(b != null, "Valid bundle should be supplied");
954
955         bundle* pb = b;
956
957         AddStrArray(pb, OSP_K_ARG, pList);
958
959         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(ac._opId));
960         if (pOperation)
961         {
962                 appsvc_set_operation(pb, pOperation.get());
963         }
964
965         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
966
967         return E_SUCCESS;
968 }
969
970
971 result
972 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const String* pUriData, const String* pMimeType, const IMap* pMap)
973 {
974         return CreateAppControlArg(b, ac._opId, pUriData, pMimeType, pMap);
975 }
976
977
978 result
979 _AppArg::CreateAppControlArg(bundle* b, const String& oId, const String* pUriData, const String* pMimeType, const IMap* pMap)
980 {
981         SysAssertf(b != null, "Valid bundle should be supplied");
982
983         bundle* pb = b;
984
985         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(oId));
986         if (pOperation.get())
987         {
988                 appsvc_set_operation(pb, pOperation.get());
989         }
990
991         if (pUriData)
992         {
993                 std::unique_ptr<char[]> pUri(_StringConverter::CopyToCharArrayN(*pUriData));
994                 if (pUri.get())
995                 {
996                         appsvc_set_uri(pb, pUri.get());
997                 }
998         }
999
1000         if (pMimeType)
1001         {
1002                 std::unique_ptr<char[]> pMime(_StringConverter::CopyToCharArrayN(*pMimeType));
1003                 if (pMime.get())
1004                 {
1005                         appsvc_set_mime(pb, pMime.get());
1006                 }
1007         }
1008
1009         AddStrMap(pb, pMap);
1010
1011         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
1012
1013         return E_SUCCESS;
1014 }
1015
1016
1017 namespace
1018 {
1019 const int MAX_LEN_DATA_CONTROL_REQ_TYPE = 8;
1020 }
1021 result
1022 _AppArg::CreateSqlDataControlArg(bundle* b, const _SqlDataControlImpl& dc, _DataControlRequestType requestType,
1023                                                                  const IList* pArgList)
1024 {
1025         SysAssertf(b != null, "Valid bundle should be supplied");
1026
1027         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1028
1029         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1030         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast<int>(requestType));
1031         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1032         bundle_add(b, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_2);
1033
1034         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1035         if (pProvider)
1036         {
1037                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1038         }
1039
1040         AddStrArray(b, OSP_K_ARG, pArgList);
1041
1042         return E_SUCCESS;
1043 }
1044
1045
1046 result
1047 _AppArg::CreateMapDataControlArg(bundle* b, const _MapDataControlImpl& dc, _DataControlRequestType requestType,
1048                                                                  const IList* pArgList)
1049 {
1050         SysAssertf(b != null, "Valid bundle should be supplied");
1051
1052         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1053
1054         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1055         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast < int >(requestType));
1056         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1057         bundle_add(b, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_2);
1058
1059         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1060         if (pProvider)
1061         {
1062                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1063         }
1064
1065         AddStrArray(b, OSP_K_ARG, pArgList);
1066
1067         return E_SUCCESS;
1068 }
1069
1070
1071 result
1072 _AppArg::CreateResultArg(bundle* b, const IList* pList)
1073 {
1074         SysAssertf(b != null, "Valid bundle should be supplied");
1075
1076         bundle* pb = b;
1077
1078         AddStrArray(pb, OSP_K_ARG, pList);
1079
1080         _AppMessageImpl::AddData(pb, pList);
1081
1082         return E_SUCCESS;
1083 }
1084
1085
1086 result
1087 _AppArg::CreateResultArg(bundle* b, const IMap* pMap)
1088 {
1089         SysAssertf(b != null, "Valid bundle should be supplied");
1090
1091         bundle* pb = b;
1092
1093         AddStrMap(pb, pMap);
1094
1095         return E_SUCCESS;
1096 }
1097
1098
1099 bundle*
1100 _AppArg::CreateBundleFromSvc(void* svc)
1101 {
1102         bundle* pBundle = GetBundleFromSvc(svc);
1103         if (pBundle)
1104         {
1105                 return bundle_dup(pBundle);
1106         }
1107
1108         return null;
1109 }
1110
1111
1112 bundle*
1113 _AppArg::GetBundleFromSvc(void* svc)
1114 {
1115         struct DummyS
1116         {
1117                 int dummy1;
1118                 int dummy2;
1119                 bundle* pData;
1120         };
1121
1122         DummyS* pDummy = static_cast<DummyS*>(svc);
1123
1124         if (pDummy && pDummy->pData)
1125         {
1126                 return pDummy->pData;
1127         }
1128
1129         return NULL;
1130 }
1131
1132
1133 String
1134 _AppArg::GetRequestId(int num)
1135 {
1136         String str;
1137         str.Format(10, L"req%05d", num);
1138         return str;
1139 }
1140
1141
1142 int
1143 _AppArg::GetRequestId(const String& str)
1144 {
1145         int i = 0;
1146         String sub;
1147
1148         result r = str.SubString(3, sub);
1149         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1150
1151         r = Integer::Parse(sub, i);
1152         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1153
1154         return i;
1155 }
1156
1157
1158 void
1159 _AppArg::UpdateAppId(bundle* b, const AppId& appId)
1160 {
1161         SysTryReturnVoidResult(NID_APP, b != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1162
1163         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
1164         SysTryReturnVoidResult(NID_APP, pId != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Converting %ls failed.", appId.GetPointer());
1165
1166         int res = bundle_add(b, OSP_K_APPID, pId.get());
1167         if (res < 0 && errno == EPERM) // key exists
1168         {
1169                 bundle_del(b, OSP_K_APPID);
1170                 bundle_add(b, OSP_K_APPID, pId.get());
1171         }
1172
1173         appsvc_set_appid(b, pId.get());
1174 }
1175
1176
1177 void
1178 _AppArg::UpdateRequestId(bundle* pBundle, int reqId)
1179 {
1180         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1181
1182         if (reqId < 0)
1183         {
1184                 //SysLog(NID_APP, "Requested ID is %d", reqId);
1185                 return;
1186         }
1187
1188         char buffer[32] = {0, };
1189         snprintf(buffer, 32, "%d", reqId);
1190         int res = bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1191         if (res < 0 && errno == EPERM) // key exists
1192         {
1193                 bundle_del(pBundle, OSP_K_REQUEST_ID);
1194                 bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1195         }
1196 }
1197
1198 void
1199 _AppArg::UpdateKeyValue(bundle* pBundle, const char* pKey, const String& value)
1200 {
1201         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1202
1203         char pBuffer[128] = {0, };
1204         snprintf(pBuffer, 128, "%ls", value.GetPointer());
1205         int res = bundle_add(pBundle, pKey, pBuffer);
1206         if (res < 0 && errno == EPERM) // key exists
1207         {
1208                 bundle_del(pBundle, pKey);
1209                 bundle_add(pBundle, pKey, pBuffer);
1210         }
1211 }
1212
1213 int
1214 _AppArg::GetRequestIdFromBundle(bundle* pBundle)
1215 {
1216         const char* p = appsvc_get_data(pBundle, OSP_K_REQUEST_ID);
1217         if (p == NULL)
1218         {
1219                 return -1;
1220         }
1221
1222         int i = atoi(p);
1223         return (i < 0) ? -1 : i;
1224 }
1225
1226
1227 result
1228 _AppArg::UpdateWindowHandle(bundle* pBundle, long handle)
1229 {
1230         appsvc_allow_transient_app(pBundle, handle);
1231
1232         SysLog(NID_APP, "Window Handle 0x%x added.", handle);
1233
1234         return E_SUCCESS;
1235 }
1236
1237
1238 void
1239 _AppArg::PrintSvcHandle(void* svc)
1240 {
1241         service_h service = static_cast<service_h>(svc);
1242
1243         if (service == null)
1244         {
1245                 return;
1246         }
1247
1248         Print(GetBundleFromSvc(service));
1249 }
1250
1251
1252 static void
1253 BundlePrintIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
1254 {
1255         if (pKey && pVal)
1256         {
1257                 size_t size = 0;
1258                 char* pStr = NULL;
1259                 switch (type)
1260                 {
1261                 case BUNDLE_TYPE_STR:
1262                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
1263                         if (pStr)
1264                         {
1265                                 SysSecureLog(NID_APP, "(%s, %s)", pKey, pStr);
1266                         }
1267                         break;
1268                 default:
1269                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
1270                         break;
1271                 }
1272         }
1273 }
1274
1275 void
1276 _AppArg::Print(bundle* b)
1277 {
1278         if (b == null)
1279         {
1280                 return;
1281         }
1282
1283         const char* p = null;
1284         p = appsvc_get_data(b, AUL_K_CALLER_PID);
1285         if (p)
1286         {
1287                 SysLog(NID_APP, "CallerPId[%s]", p);
1288         }
1289
1290         p = appsvc_get_data(b, AUL_K_WAIT_RESULT);
1291         if (p)
1292         {
1293                 SysLog(NID_APP, "WaitResult[%s]", p);
1294         }
1295
1296         p = appsvc_get_data(b, OSP_K_COND);
1297         if (p)
1298         {
1299                 SysLog(NID_APP, "Condition[%s]", p);
1300         }
1301
1302         p = appsvc_get_operation(b);
1303         if (p)
1304         {
1305                 SysLog(NID_APP, "operation[%s]", p);
1306         }
1307
1308         p = appsvc_get_uri(b);
1309         if (p)
1310         {
1311                 SysLog(NID_APP, "uri[%s]", p);
1312         }
1313
1314         p = appsvc_get_mime(b);
1315         if (p)
1316         {
1317                 SysLog(NID_APP, "mime[%s]", p);
1318         }
1319
1320         p = appsvc_get_category(b);
1321         if (p)
1322         {
1323                 SysLog(NID_APP, "Category[%s]", p);
1324         }
1325
1326         bundle_foreach(b, BundlePrintIterFnCb, NULL);
1327
1328         int len = 0;
1329         const char** pa = appsvc_get_data_array(b, OSP_K_ARG, &len);
1330         if (pa)
1331         {
1332                 for (int i = 0; i < len; i++)
1333                 {
1334                         if (pa[i])
1335                         {
1336                                 SysLog(NID_APP, "%dth arg [%s]", i, pa[i]);
1337                         }
1338                 }
1339         }
1340 }
1341
1342 } } // Tizen::App