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