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