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