Merge "Update deprecated libprivilege-control API functions." into tizen
[platform/framework/native/appfw.git] / src / app / FApp_AppImpl.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_AppImpl.cpp
19  * @brief       This is the implementation for the _AppImpl class.
20  */
21
22 #include <unique_ptr.h>
23
24 #include <notification/notification.h>
25 #include <appsvc/appsvc.h>
26 #include <vconf.h>
27 #include <appinfo.h>
28
29 #include <FBaseInteger.h>
30 #include <FBaseColArrayList.h>
31 #include <FBaseColHashMap.h>
32 #include <FBaseRtThread.h>
33 #include <FAppAppRegistry.h>
34 #include <FAppAppControl.h>
35 #include <FAppDataControlProviderManager.h>
36 #include <FAppIAppCheckPointEventListener.h>
37 #include <FAppISqlDataControlProviderEventListener.h>
38 #include <FAppIMapDataControlProviderEventListener.h>
39 #include <FAppIAppControlProviderEventListener.h>
40 #include <FAppIAppLaunchConditionEventListener.h>
41 #include <FIoFile.h>
42 #include <FBaseSysLog.h>
43
44 #include <FBase_StringConverter.h>
45 #include <FIo_RegistryImpl.h>
46 #include <FSys_EnvironmentImpl.h>
47 #include <FSys_PowerManagerImpl.h>
48 #include <FApp_Aul.h>
49 #include <FSys_AlarmManager.h>
50
51 #include "FApp_IAppManager.h"
52 #include "FApp_AppManagerProxy.h"
53 #include "FApp_AppImpl.h"
54 #include "FApp_AppInfo.h"
55 #include "FApp_AppControlManager.h"
56 #include "FApp_AppArg.h"
57 #include "FApp_IAppImpl.h"
58 #include "FApp_AppResourceImpl.h"
59 #include <FSys_SettingInfoImpl.h>
60
61 using namespace Tizen::Base;
62 using namespace Tizen::Base::Collection;
63 using namespace Tizen::Base::Runtime;
64 using namespace Tizen::Io;
65 using namespace Tizen::System;
66
67 namespace
68 {
69
70 const int HEARTBEAT_WAIT_COUNT = 3;
71 const wchar_t SERVICE_APPID[] = L"aospd00043.osp-app-service";
72 const char SELECTOR_RESPONSE_KEY[] = "__APP_SVC_START_INFO__";
73 const wchar_t FILE_SCHEME_WITH_DELIMITER[] = L"file://";
74 #ifndef VCONFKEY_APPSERVICE_STATUS
75 #define VCONFKEY_APPSERVICE_STATUS  "memory/appservice/status"
76 #endif
77
78 }
79
80 namespace Tizen { namespace App
81 {
82
83 _AppImpl* _AppImpl::__pAppImpl = null;
84 bool _AppImpl::__isTerminationRequested = false;
85
86 static const char TIZEN_APPCONTROL_DATA_MULTI_WINDOW[] = "http://tizen.org/appcontrol/data/multiwindow";
87
88 #if 0
89 static const int _DATACONTROL_PACKET_INDEX_APPID = 0;
90 static const int _DATACONTROL_PACKET_INDEX_REQUESTTYPE = 1;
91 static const int _DATACONTROL_PACKET_INDEX_REQID = 2;
92 static const int _DATACONTROL_PACKET_INDEX_PROVIDERID = 3;
93 #endif
94 static const int _DATACONTROL_PACKET_INDEX_DATAID = 0;
95 static const int _DATACONTROL_PACKET_INDEX_COLUMNCOUNT = 1;
96 static const int _DATACONTROL_PACKET_INDEX_DELETEWHERE = 1;
97 static const int _DATACONTROL_PACKET_INDEX_MAPKEY = 1;
98 static const int _DATACONTROL_PACKET_INDEX_COLUMNLIST = 2;
99 static const int _DATACONTROL_PACKET_INDEX_INSERTMAP = 2;
100 static const int _DATACONTROL_PACKET_INDEX_UPDATEMAP = 2;
101
102 struct charDeleter
103 {
104         void operator()(char* pValue)
105         {
106                 if(pValue != null)
107                 {
108                         free(pValue);
109                         pValue = null;
110                 }
111         }
112 };
113
114 _AppImpl::_AppImpl(App* pApp)
115         : __pCheckpointEventListener(null)
116         , __pSqlDataControlProviderEventListener(null)
117         , __pMapDataControlProviderEventListener(null)
118         , __pAppControlProviderEventListener(null)
119         , __pAppControlProviderInternalEventListener(null)
120         , __pAppLaunchConditionEventListener(null)
121         , __pApp(pApp)
122         , __pIAppImpl(null)
123         , __pRequestHandler(&_AppImpl::HandleAppRequest)
124         , __pLegacyRequestHandler(&_AppImpl::HandleDummyAppRequest)
125         , __forcedTermination(false)
126 {
127         __pAppImpl = this;
128 }
129
130
131 result
132 _AppImpl::Construct(const IList* pArgs)
133 {
134         SysTryReturnResult(NID_APP, pArgs != null, E_INVALID_ARG, "pArguments must not be null.");
135         SysAssertf(__pApp != null, "Getting App instance failed.");
136
137         result r = __appUserEvent.Construct();
138         SysTryLog(NID_APP, !IsFailed(r), "[%s] User event handler failure.", GetErrorMessage(r));
139
140         __appUserEvent.AddListener(*this);
141
142         _AppInfo::SetAppState(INITIALIZING);
143
144         r = _SettingInfoImpl::AddSettingEventListenerForInternal(*this);
145         SysTryLog(NID_APP, !IsFailed(r), "[%s] failed to add setting event listener.", GetErrorMessage(r));
146
147         return E_SUCCESS;
148 }
149
150 result
151 _AppImpl::Execute(_IAppImpl* pIAppImpl)
152 {
153         SysLogTag(NID_APP, "LAUNCH","[%ls:<Initialize Application>:start]", _AppInfo::GetAppExecutableName().GetPointer());
154         result r = E_SUCCESS;
155         int eflResult = APP_ERROR_NONE;
156         int argc = 0;
157         char** pArgv = NULL;
158         _IAppManager* pAppManager = null;
159
160         _AppImpl* pAppImpl = _AppImpl::GetInstance();
161         SysTryReturnResult(NID_APP, pAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
162         pAppImpl->__pIAppImpl = pIAppImpl;
163
164         // handle legacy version handling
165         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
166         {
167                 pAppImpl->SetLegacyRequestHandler();
168         }
169
170         app_event_callback_s state_handler;
171         memset(&state_handler, 0, sizeof(app_event_callback_s));
172
173         state_handler.create = &OnCreate;
174         state_handler.service = &OnService;
175         state_handler.terminate = &OnTerminate;
176         state_handler.pause = &OnPause;
177         state_handler.resume = &OnResume;
178         state_handler.device_orientation = NULL;
179
180         state_handler.low_memory = &OnLowMemory;
181         state_handler.low_battery = NULL;
182         state_handler.language_changed = NULL;
183         state_handler.region_format_changed = NULL;
184
185         _Aul::SetPowerOffNotiListener(OnPowerOffNotiReceived, this);
186 //      if (pAppManager != null)
187 //      {
188 //              r = pAppManager->RegisterApplication(_AppInfo::GetPackageId(), _AppInfo::GetAppExecutableName(), _AppInfo::GetAppType() , _AppInfo::GetProcessId());
189 //              SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Application registration failed.", GetErrorMessage(r));
190 //      }
191
192         appinfo_get_argv(&argc, &pArgv);
193         eflResult = app_efl_main(&argc, &pArgv, &state_handler, this);
194         SysTryLog(NID_APP, eflResult == APP_ERROR_NONE, "app_efl_main failed with error (%d): Unknown", eflResult);
195
196         pAppManager = _AppManagerProxy::GetService();
197
198         if (pAppManager != null)
199         {
200                 pAppManager->UnregisterApplication(_AppInfo::GetProcessId());
201         }
202
203         // clear outstanding ongoing notification
204         notification_delete_all_by_type(appinfo_get_appid(), NOTIFICATION_TYPE_ONGOING);
205
206         return r;
207 }
208
209
210 bool
211 _AppImpl::OnCreate(void* user_data)
212 {
213         SysLog(NID_APP, "Platform creation event.");
214
215         _AppImpl* pAppImpl = static_cast<_AppImpl*>(user_data);
216         if (pAppImpl == null)
217         {
218                 _AppInfo::SetAppState(TERMINATED);
219                 SysLogException(NID_APP, E_INIT_FAILED, "[E_INIT_FAILED] Invalid platform state.");
220                 return false;
221         }
222
223         _AppInfo::SetAppState(INITIALIZING);
224
225         if (!ConfirmAppService())
226         {
227                 _AppInfo::SetAppState(TERMINATED);
228                 SysLogException(NID_APP, E_INIT_FAILED, "[E_INIT_FAILED] Osp AppService is not running.");
229                 return false;
230         }
231
232         SysLogTag(NID_APP, "LAUNCH","[%ls:<OnAppInitializing>:start]", _AppInfo::GetAppExecutableName().GetPointer());
233         if (!pAppImpl->__pIAppImpl->OnAppInitializing())
234         {
235                 _AppInfo::SetAppState(TERMINATED);
236                 SysLogException(NID_APP, E_INIT_FAILED, "[E_INIT_FAILED] The initialization of your application failed.");
237                 return false;
238         }
239         SysLogTag(NID_APP, "LAUNCH","[%ls:<OnAppInitializing>:done]", _AppInfo::GetAppExecutableName().GetPointer());
240
241         SysLogTag(NID_APP, "LAUNCH","[%ls:<RegisterApplication>:start]", _AppInfo::GetAppExecutableName().GetPointer());
242         _IAppManager* pAppManager = _AppManagerProxy::GetService();
243
244         if (pAppManager != null)
245         {
246                 result r = pAppManager->RegisterApplication(_AppInfo::GetApplicationId(), static_cast<_AppType>(_AppInfo::GetAppType()), _AppInfo::GetProcessId());
247                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Application registration failed.", GetErrorMessage(r));
248         }
249         SysLogTag(NID_APP, "LAUNCH","[%ls:<RegisterApplication>:done]", _AppInfo::GetAppExecutableName().GetPointer());
250         // hide splash window
251
252         _PowerManagerImpl::InitBatteryEvent();
253
254         return true;
255 }
256
257
258 void
259 _AppImpl::OnService(service_s* service, void* user_data)
260 {
261         _AppImpl* pAppImpl = _AppImpl::GetInstance();
262         SysTryReturnVoidResult(NID_APP, pAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
263         SysTryReturnVoidResult(NID_APP, pAppImpl->__pIAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
264
265         // ugly code for app selector event handling
266         bundle* pBundle = _AppArg::GetBundleFromSvc(service);
267         if (pBundle)
268         {
269                 const char* pValue = appsvc_get_data(pBundle, SELECTOR_RESPONSE_KEY);
270                 if (pValue)
271                 {
272                         const int req = _AppArg::GetRequestIdFromBundle(pBundle);
273
274                         const char* pOperation = appsvc_get_operation(pBundle);
275
276                         SysLog(NID_APP, "App selector response [%s, %s], req(%d).", pValue, pOperation, req);
277
278                         //_AppArg::Print(pBundle);
279                         _AppControlManager::GetInstance()->SendAppControlStartResponse(req, pValue, pOperation);
280                         return;
281                 }
282         }
283
284         //_AppArg::Print(pBundle);
285         int req = -1;
286         _AppHandler handler = _APP_HANDLER_NONE;
287         pAppImpl->RegisterAppRequest(service, req, handler);
288
289         bool initialLaunch = false;
290
291         // initial launch
292         // (1) AppControl / DataControl provider listener
293         // (2) OnAppInitialized()
294         // (3) OnResume() (OnForeground()) (UiApp only)
295         // (4) OnUserEventReceivedN()
296
297         // already launched
298         // (1) AppControl / DataControl provider listener
299         // (2) OnResume() (OnForeground()) (UiApp only)
300         // (3) OnUserEventReceivedN()
301
302         if (_AppInfo::GetAppState() == INITIALIZING)
303         {
304                 initialLaunch = true;
305
306                 unsigned int winId = 0;
307                 service_get_window(service, &winId);
308                 if (winId > 0)
309                 {
310                         _AppInfo::SetParentWindowHandle(winId);
311                         SysLog(NID_APP, "Saving window handle 0x%x.", winId);
312                 }
313
314                 // set an appinfo value for multi-window mode
315                 char* pBuf = null;
316                 int errVal = service_get_extra_data(service, TIZEN_APPCONTROL_DATA_MULTI_WINDOW, &pBuf);
317                 if (errVal == SERVICE_ERROR_NONE)
318                 {
319                         if (!strcmp(pBuf, "on"))
320                         {
321                                 _AppInfo::SetMultiWindow(true);
322                         }
323                         free(pBuf);
324                 }
325
326                 // call for callbacks
327                 // ptr to member function
328                 SysLogTag(NID_APP, "LAUNCH","[%ls:<RequestHandler and OnAppInitialized>:start]", _AppInfo::GetAppExecutableName().GetPointer());
329                 (pAppImpl->*pAppImpl->__pRequestHandler)(service, req, handler);
330
331                 if (!pAppImpl->__pIAppImpl->OnAppInitialized())
332                 {
333                         _AppInfo::SetAppState(TERMINATING);
334                         SysLog(NID_APP, "[E_INIT_FAILED] The Initialization of your application failed.");
335                         app_efl_exit();
336                         return;
337                 }
338                 SysLogTag(NID_APP, "LAUNCH","[%ls:<RequestHandler and OnAppInitialized>:done]", _AppInfo::GetAppExecutableName().GetPointer());
339
340                 _AppInfo::SetAppState(RUNNING);
341
342                 SysLogTag(NID_APP, "LAUNCH","[%ls:<Initialize Application>:done]", _AppInfo::GetAppExecutableName().GetPointer());
343         }
344         else
345         {
346                 // already running
347
348                 // call for callbacks
349                 // ptr to member function
350                 (pAppImpl->*pAppImpl->__pRequestHandler)(service, req, handler);
351
352                 std::unique_ptr<char[], charDeleter> pOperation(null);
353                 char* pBuf = null;
354
355                 int errVal = service_get_operation(service, &pBuf);
356                 pOperation.reset(pBuf);
357
358                 if((errVal == SERVICE_ERROR_NONE) && (!strcmp((const char*)pOperation.get(), "osp.operation.ALARM")))
359                 {
360                         std::unique_ptr<char[], charDeleter> pAlarmId(null);
361                         char* pBuf = null;
362
363                         errVal = service_get_extra_data(service, SERVICE_DATA_ALARM_ID, &pBuf);
364                         pAlarmId.reset(pBuf);
365                         SysTryReturnVoidResult(NID_SYS, errVal == SERVICE_ERROR_NONE, E_SYSTEM, "It is failed to get reserved alarm id.");
366                         int alarmId = atoi((const char*)pAlarmId.get());
367
368                         _AlarmManager* pAlarmManager = _AlarmManager::GetInstance();
369                         pAlarmManager->OnAlarmExpired(alarmId);
370
371                         return;
372                 }
373         }
374
375         pAppImpl->__pIAppImpl->OnService(service, initialLaunch);
376
377         // ptr to member function
378         (pAppImpl->*pAppImpl->__pLegacyRequestHandler)(service, req, handler);
379 }
380
381
382 void
383 _AppImpl::OnTerminate(void* user_data)
384 {
385         SysLog(NID_APP, "Termination event 0x%x state", _AppInfo::GetAppState());
386
387         _AppImpl* pAppImpl = _AppImpl::GetInstance();
388         SysTryReturnVoidResult(NID_APP, pAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
389         SysTryReturnVoidResult(NID_APP, pAppImpl->__pIAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
390
391         result r = _SettingInfoImpl::RemoveSettingEventListenerForInternal(*pAppImpl);
392         SysTryLog(NID_APP, !IsFailed(r), "[%s] failed to remove setting event listener.", GetErrorMessage(r));
393
394         __isTerminationRequested = true;
395         pAppImpl->__pIAppImpl->OnTerminate();
396 }
397
398
399 void
400 _AppImpl::OnResume(void* user_data)
401 {
402         SysLog(NID_APP, "System resume event on 0x%x state", _AppInfo::GetAppState());
403         SysLogTag(NID_APP, "LAUNCH","[%ls:<OnResume>:start]", _AppInfo::GetAppExecutableName().GetPointer());
404
405         _AppImpl* pAppImpl = _AppImpl::GetInstance();
406         SysTryReturnVoidResult(NID_APP, pAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
407         SysTryReturnVoidResult(NID_APP, pAppImpl->__pIAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
408         pAppImpl->__pIAppImpl->OnResume();
409         SysLogTag(NID_APP, "LAUNCH","[%ls:<OnResume>:done]", _AppInfo::GetAppExecutableName().GetPointer());
410 }
411
412
413 void
414 _AppImpl::OnPause(void* user_data)
415 {
416         SysLog(NID_APP, "System pause event on 0x%x state", _AppInfo::GetAppState());
417         SysLogTag(NID_APP, "LAUNCH","[%ls:<OnPause>:start]", _AppInfo::GetAppExecutableName().GetPointer());
418
419         _AppImpl* pAppImpl = _AppImpl::GetInstance();
420         SysTryReturnVoidResult(NID_APP, pAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
421         SysTryReturnVoidResult(NID_APP, pAppImpl->__pIAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
422         pAppImpl->__pIAppImpl->OnPause();
423         pAppImpl->OnAppCheckpoint();
424         SysLogTag(NID_APP, "LAUNCH","[%ls:<OnPause>:done]", _AppInfo::GetAppExecutableName().GetPointer());
425 }
426
427
428 _AppImpl::~_AppImpl(void)
429 {
430         __pAppImpl = null;
431 }
432
433
434 _AppImpl*
435 _AppImpl::GetInstance(void)
436 {
437         return __pAppImpl;
438 }
439
440
441 App*
442 _AppImpl::GetAppInstance(void)
443 {
444         return __pApp;
445 }
446
447
448 IList*
449 _AppImpl::GetAppArgumentListN(void) const
450 {
451         ArrayList* pList = null;
452         const _AppArg* pArg = _AppControlManager::GetInstance()->FindResultRequest(0);
453
454         if (pArg)
455         {
456                 pList = pArg->GetArgListN(0);
457         }
458         else
459         {
460                 // fallback
461                 pList = new (std::nothrow) ArrayList();
462                 SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
463                 String* pData = new (std::nothrow) String(LEGACY_LAUNCH_REASON_NORMAL);
464                 SysTryReturn(NID_APP, pData != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
465                 String* pData2 = new (std::nothrow) String(LEGACY_OPERATION_MAIN);
466                 SysTryReturn(NID_APP, pData2 != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
467
468                 pList->Construct();
469                 pList->Add(*pData);
470                 pList->Add(*pData2);
471         }
472
473         return pList;
474 }
475
476
477 result
478 _AppImpl::Terminate(void)
479 {
480         result r = E_SUCCESS;
481
482         SysLog(NID_APP, "Terminate() is called by application itself");
483
484         __isTerminationRequested = true;
485
486         app_efl_exit();
487         return r;
488 }
489
490
491 bool
492 _AppImpl::OnAppInitializing(void)
493 {
494         return false;
495 }
496
497
498 bool
499 _AppImpl::OnAppWillTerminate(void)
500 {
501         SysTryReturn(NID_APP, __pApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting internal instance failed.");
502
503         return __pApp->OnAppWillTerminate();
504 }
505
506
507 result
508 _AppImpl::RegisterAppRequest(service_s* service, int& req, _AppHandler& handler)
509 {
510         _AppControlManager* pManager = _AppControlManager::GetInstance();
511         SysTryReturnResult(NID_APP, pManager != null, E_SYSTEM, "Wrong system state.");
512
513         result r = pManager->RegisterRequest(service, req, handler);
514         if (IsFailed(r))
515         {
516                 SysPropagate(NID_APP, r);
517                 return r;
518         }
519
520         int providerType = _AppInfo::GetAppHandlerType();
521         providerType |= (_APP_HANDLER_LAUNCH_NORMAL | _APP_HANDLER_LAUNCH_COND);
522
523         SysTryLog(NID_APP, (handler & providerType) != 0, "Request 0x%x received for 0x%x.", handler,
524                         _AppInfo::GetAppHandlerType());
525         return E_SUCCESS;
526 }
527
528
529 result
530 _AppImpl::HandleAppRequest(service_s* service, int req, _AppHandler handler)
531 {
532         const _AppArg* pArg = _AppControlManager::GetInstance()->FindResultRequest(req);
533         SysTryReturnResult(NID_APP, pArg != null, E_SYSTEM, "No argument found for %d.", req);
534
535         pArg->Print();
536
537         switch (handler)
538         {
539         case _APP_HANDLER_DATACONTROL:
540                 SysLog(NID_APP, "Handling DataControl request");
541
542                 OnDataControlRequestReceived(*pArg, static_cast< RequestId >(req));
543
544                 //_AppControlManager::GetInstance()->RemoveResultRequest(req);
545                 break;
546
547         case _APP_HANDLER_LAUNCH_COND:
548                 SysLog(NID_APP, "Handling conditional launch request");
549
550                 OnConditionRequestReceived(*pArg, static_cast< RequestId >(req));
551                 break;
552
553         default:
554                 SysLog(NID_APP, "Handling AppControl request");
555
556                 OnAppControlRequestReceived(*pArg, static_cast< RequestId >(req));
557                 break;
558         }
559
560         return E_SUCCESS;
561 }
562
563
564 result
565 _AppImpl::HandleLegacyAppRequest(service_s* service, int req, _AppHandler handler)
566 {
567         const _AppArg* pArg = _AppControlManager::GetInstance()->FindResultRequest(0);
568         SysTryReturnResult(NID_APP, pArg != null, E_SYSTEM, "No argument found for %d.", req);
569
570         //pArg->Print();
571
572         switch (handler)
573         {
574         case _APP_HANDLER_LAUNCH_NORMAL:
575                 SysLog(NID_APP, "Handling normal launch request");
576                 OnUserEventReceivedN(AppLaunchRequestId, pArg->GetArgListN(req), true);
577
578                 // [TODO] request handle memory cleanup confirm
579                 _AppControlManager::GetInstance()->RemoveResultRequest(req);
580                 break;
581
582         case _APP_HANDLER_LAUNCH_COND:
583                 SysLog(NID_APP, "Handling conditional launch request");
584
585                 OnUserEventReceivedN(AppLaunchRequestId, pArg->GetArgListN(req), true);
586
587                 // [TODO] request handle memory cleanup confirm
588                 _AppControlManager::GetInstance()->RemoveResultRequest(req);
589                 break;
590
591         default:
592                 break;
593         }
594
595         return E_SUCCESS;
596 }
597
598
599 result
600 _AppImpl::HandleDummyAppRequest(service_s* service, int req, _AppHandler handler)
601 {
602         SysLog(NID_APP, "Dummy handler");
603
604         return E_SUCCESS;
605 }
606
607
608 result
609 _AppImpl::SetLegacyRequestHandler(void)
610 {
611         SysLog(NID_APP, "Setting request handler for legacy application.");
612
613         __pRequestHandler = &_AppImpl::HandleDummyAppRequest;
614         __pLegacyRequestHandler = &_AppImpl::HandleLegacyAppRequest;
615
616         return E_SUCCESS;
617 }
618
619
620 void
621 _AppImpl::OnLowMemory(void* user_data)
622 {
623         _AppImpl* pAppImpl = _AppImpl::GetInstance();
624
625         SysTryReturnVoidResult(NID_APP, pAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting internal instance failed.");
626         SysTryReturnVoidResult(NID_APP, pAppImpl->__pApp != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting internal instance failed.");
627
628         if (_AppInfo::GetAppState() == RUNNING)
629         {
630                 pAppImpl->__pApp->OnLowMemory();
631         }
632 }
633
634
635 void
636 _AppImpl::OnBatteryLevelChanged(BatteryLevel batteryLevel)
637 {
638         SysTryReturnVoidResult(NID_APP, __pApp != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting internal instance failed.");
639
640         __pApp->OnBatteryLevelChanged(batteryLevel);
641 }
642
643 result
644 _AppImpl::SendUserEvent(RequestId requestId, const IList* pArgs, bool isPublic)
645 {
646         _AppUserEventArg* pArg = new (std::nothrow) _AppUserEventArg(requestId, pArgs, isPublic);
647         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "User event creation failure for %d.", requestId);
648
649         result r = __appUserEvent.FireAsync(*pArg);
650
651         return r;
652 }
653
654
655 void
656 _AppImpl::OnUserEventReceivedN(RequestId requestId, IList* pArgs, bool isPublic)
657 {
658         SysTryReturnVoidResult(NID_APP, __pApp != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting internal instance failed.");
659
660         if (isPublic)
661         {
662                 __pApp->OnUserEventReceivedN(requestId, pArgs);
663         }
664         else
665         {
666                 switch (requestId)
667                 {
668                 case _APP_EVENT_TERMINATE:
669                         SysLog(NID_APP, "App terminate is requested.");
670                         Terminate();
671                         break;
672                 case _APP_EVENT_RAISE:
673                         SysLog(NID_APP, "App raise is requested.");
674                         RaiseWindow();
675                         break;
676                 default:
677                         SysLog(NID_APP, "Unknown event : 0x%x.", requestId);
678                         break;
679                 }
680         }
681 }
682
683
684 void
685 _AppImpl::OnAppControlRequestReceived(const _AppArg& arg, RequestId reqId)
686 {
687         IAppControlProviderEventListener* pAppControlProviderEventListener = null;
688
689         const String internalOperation = arg.GetValue(OSP_K_APPCONTROL_INTERNAL_OPERATION);
690         if( !internalOperation.IsEmpty() )
691         {
692                 SysLog(NID_APP, "internalOperation:%ls", internalOperation.GetPointer() );
693                 pAppControlProviderEventListener = __pAppControlProviderInternalEventListener;
694         }
695         else
696         {
697                 pAppControlProviderEventListener = __pAppControlProviderEventListener;
698         }
699
700         if( pAppControlProviderEventListener == null)
701         {
702                 SysLog(NID_APP, "No AppControl provider event listener set for request %d.", reqId);
703                 return;
704         }
705
706         const char* pAppId = appinfo_get_appid();
707
708         const char* p = appsvc_get_operation(arg.GetBundle());
709         String operationId = (p) ? String(p) : TIZEN_OPERATION_MAIN;
710         if (operationId == L"http://tizen.org/appcontrol/operation/default")
711         {
712                 operationId = TIZEN_OPERATION_MAIN;
713         }
714
715         SysLog(NID_APP, "AppControl (%s, %ls).", pAppId, operationId.GetPointer());
716
717         String uri;
718         String mime;
719         const String* pUri = null;
720         const String* pMime = null;
721         p = appsvc_get_uri(arg.GetBundle());
722         if (p)
723         {
724                 uri = p;
725                 if (uri[0] == L'/')
726                 {
727                         // SLP deals with the URI as plain /opt/.../a.jpg.
728                         uri.Insert(FILE_SCHEME_WITH_DELIMITER, 0);
729                 }
730                 pUri = &uri;
731
732                 SysLog(NID_APP, "Delivered uri is [%ls].", pUri->GetPointer());
733         }
734
735         p = appsvc_get_mime(arg.GetBundle());
736         if (p)
737         {
738                 mime = p;
739                 pMime = &mime;
740         }
741
742         std::unique_ptr<HashMap> pMap(arg.GetArgMapN());
743
744         pAppControlProviderEventListener->OnAppControlRequestReceived(reqId, operationId, pUri, pMime, pMap.get());
745
746         SysLog(NID_APP, "AppControl (%s, %ls) invocation finished.", pAppId, operationId.GetPointer());
747 }
748
749
750 void
751 _AppImpl::OnDataControlRequestReceived(const _AppArg& arg, RequestId reqId)
752 {
753         String tempFilePath;
754         ISqlDataControlProviderEventListener* pSqlListener = null;
755         IMapDataControlProviderEventListener* pMapListener = null;
756         ArrayList* pColumnList = null;
757         HashMap* pInsertMap = null;
758         HashMap* pUpdateMap = null;
759         String appId;
760         String reqType;
761         String providerId;
762         String version;
763         String* pDataId = null;
764         String callerReqId;
765         String* pColumnCount = null;
766         String* pColumn = null;
767         String* pValue = null;
768         String* pWhere = null;
769         String* pOrder = null;
770         String* pErrorMsg = null;
771         String* pNo = null;
772         String* pCount = null;
773         String* pTmpPath = null;
774         String empty(L"NULL");
775         _AppArg resultArg;
776         int type = 0;
777         _DataControlRequestType requestType = _DATACONTROL_REQUEST_TYPE_UNDEFINED;
778         int columnCount = 0;
779         int pageNo = 0;
780         int countPerPage = 0;
781         int i = 0;
782         int index = 0;
783         result r = E_SUCCESS;
784         result res = E_SUCCESS;
785         ArrayList* pList = null;
786         String* pKey = null;
787         String* pNewValue = null;
788         String* pOldValue = null;
789
790         SysLog(NID_APP, "[DC_PROV_RECV] Data control request is received.");
791         //arg.Print(); // request info
792
793         // key-based request
794         appId = arg.GetCallerAppId();
795
796         reqType = arg.GetValue(OSP_K_DATACONTROL_REQUEST_TYPE);
797         Integer::Parse(reqType, type);
798         requestType = static_cast< _DataControlRequestType >(type);
799
800         version = arg.GetValue(OSP_K_DATACONTROL_PROTOCOL_VERSION);
801         callerReqId = arg.GetValue(OSP_K_REQUEST_ID);
802         providerId = arg.GetValue(OSP_K_DATACONTROL_PROVIDER);
803
804         // list-based request
805         pList = _AppArg::GetListN(arg.GetBundle(), OSP_K_ARG);
806         SysTryCatch(NID_APP, pList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result object");
807
808         pDataId = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_DATAID));// request list[0]: data ID
809         SysTryCatch(NID_APP, pDataId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
810
811         if (requestType >= _DATACONTROL_REQUEST_TYPE_SQL_QUERY && requestType <= _DATACONTROL_REQUEST_TYPE_SQL_DELETE)
812         {
813                 pSqlListener = __pSqlDataControlProviderEventListener;
814                 SysTryCatch(NID_APP, pSqlListener != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
815         }
816         else if (requestType >= _DATACONTROL_REQUEST_TYPE_MAP_QUERY && requestType <= _DATACONTROL_REQUEST_TYPE_MAP_DELETE)
817         {
818                 pKey = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_MAPKEY)); // request list[1]
819                 SysTryCatch(NID_APP, pKey, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
820
821                 pMapListener = __pMapDataControlProviderEventListener;
822                 SysTryCatch(NID_APP, pMapListener != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
823         }
824         else
825         {
826                 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] invalid request");
827                 r = E_SYSTEM;
828         }
829
830         switch (requestType)
831         {
832         case _DATACONTROL_REQUEST_TYPE_SQL_QUERY:
833                 SysLog(NID_APP, "[DC_PROV_RECV] SqlDataControl SELECT");
834
835                 // request list[1]: selected column count
836                 pColumnCount = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_COLUMNCOUNT));
837                 SysTryCatch(NID_APP, pColumnCount, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
838
839                 if (pColumnCount->Equals(empty) == true)
840                 {
841                         pColumnList = null;
842                 }
843                 else
844                 {
845                         Integer::Parse(*pColumnCount, columnCount);
846                         pColumnList = new (std::nothrow) ArrayList();
847                         SysTryReturnVoidResult(NID_APP, pColumnList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
848                         pColumnList->Construct();
849                         SysLog(NID_APP, "[DC_PROV_RECV] selected column count: %d", columnCount);
850
851                         i = 0;
852                         while (i < columnCount) // request list[2]: column list
853                         {
854                                 pColumn = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_COLUMNLIST + i));
855                                 SysTryCatch(NID_APP, pColumn != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
856
857                                 pColumnList->Add(*(new String(*pColumn)));
858                                 SysLog(NID_APP, "[DC_PROV_RECV] column[%d]: %ls", i, pColumn->GetPointer());
859                                 i++;
860                         }
861                 }
862
863                 i += _DATACONTROL_PACKET_INDEX_COLUMNLIST;
864                 pWhere = dynamic_cast< String* >(pList->GetAt(i)); // request list: where clause
865                 SysTryCatch(NID_APP, pWhere, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
866
867                 if (pWhere->Equals(empty) == true)
868                 {
869                         pWhere = null;
870                 }
871                 else
872                 {
873                         SysLog(NID_APP, "[DC_PROV_RECV] pWhere: %ls", pWhere->GetPointer());
874                 }
875
876                 i++;
877                 pOrder = dynamic_cast< String* >(pList->GetAt(i)); // request list: order clause
878                 SysTryCatch(NID_APP, pOrder, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
879
880                 if (pOrder->Equals(empty) == true)
881                 {
882                         pOrder = null;
883                 }
884                 else
885                 {
886                         SysLog(NID_APP, "[DC_PROV_RECV] pOrder: %ls", pOrder->GetPointer());
887                 }
888
889                 i++;
890                 pNo = dynamic_cast <String*>(pList->GetAt(i)); // request list: page number
891                 SysTryCatch(NID_APP, pNo, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
892                 Integer::Parse(*pNo, pageNo);
893
894                 i++;
895                 pCount = dynamic_cast <String*>(pList->GetAt(i)); // request list: count per page
896                 SysTryCatch(NID_APP, pCount, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
897                 Integer::Parse(*pCount, countPerPage);
898
899                 pSqlListener->OnSqlDataControlSelectRequestReceived(reqId, providerId, *pDataId, pColumnList,
900                                 pWhere, pOrder);
901
902                 SysSecureLog(NID_APP, "[DC_PROV_RECV] caller app: %ls, requestType: %d, caller req: %ls, provider: %ls, data: %ls, pColumnList: 0x%0x, pWhere: 0x%x, pOrder: 0x%x, pageNo: %d, countPerPage: %d",
903                                 appId.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(),
904                                 pDataId->GetPointer(), pColumnList, pWhere, pOrder, pageNo, countPerPage);
905                 break;
906         case _DATACONTROL_REQUEST_TYPE_SQL_INSERT:
907                 SysLog(NID_APP, "[DC_PROV_RECV] SqlDataControl INSERT");
908
909                 // request list[1]: inserted column count
910                 pColumnCount = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_COLUMNCOUNT));
911                 SysTryCatch(NID_APP, pColumnCount, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
912
913                 Integer::Parse(*pColumnCount, columnCount);
914                 SysLog(NID_APP, "[DC_PROV_RECV] inserted column count: %d", columnCount);
915
916                 pInsertMap = new (std::nothrow) HashMap();
917                 SysTryReturnVoidResult(NID_APP, pInsertMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
918                 pInsertMap->Construct();
919
920                 SysLog(NID_APP, "[DC_PROV_RECV] version: %ls", version.GetPointer());
921                 if (version == L"ver_2.1.0.2" || version == L"ver_2.1.0.3")
922                 {
923                         pTmpPath = dynamic_cast< String* >(pList->GetAt(2)); // request list[2]: path
924                         SysTryCatch(NID_APP, pTmpPath != null, , E_SYSTEM, "[E_SYSTEM] invalid request");
925                         SysLog(NID_APP, "[DC_PROV_RECV] request: %ls", pTmpPath->GetPointer());
926
927                         File request;
928                         r = request.Construct(*pTmpPath, "r");
929                         SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to open request (%ls).",
930                                         GetErrorMessage(r), pTmpPath->GetPointer());
931
932                         for (i = 0; i < columnCount; ++i) // column-value pairs
933                         {
934                                 int length = -1;
935                                 int ret = request.Read(&length, sizeof(int));
936                                 SysTryCatch(NID_APP, ret > 0, , E_SYSTEM, "[%s] Failed to receive request.",
937                                                 GetErrorMessage(GetLastResult()));
938
939                                 char* pColumn = new (std::nothrow) char[length + 1];
940                                 ret = request.Read(pColumn, length);
941                                 SysTryCatch(NID_APP, ret > 0, delete pColumn, E_SYSTEM, "[%s] Failed to receive request.",
942                                                 GetErrorMessage(GetLastResult()));
943                                 pColumn[length] = '\0';
944                                 SysLog(NID_APP, "[DC_PROV_RECV] column[%d]: %s", i, pColumn);
945
946                                 ret = request.Read(&length, sizeof(int));
947                                 SysTryCatch(NID_APP, ret > 0, delete pColumn, E_SYSTEM, "[%s] Failed to receive request.",
948                                                 GetErrorMessage(GetLastResult()));
949
950                                 char* pValue = new (std::nothrow) char[length + 1];
951                                 ret = request.Read(pValue, length);
952                                 if (ret == 0)
953                                 {
954                                         SysLogException(NID_APP, E_SYSTEM, "[%s] Failed to receive request.", GetErrorMessage(GetLastResult()));
955                                         delete pColumn;
956                                         delete pValue;
957                                 }
958                                 pValue[length] = '\0';
959                                 SysLog(NID_APP, "[DC_PROV_RECV] value[%d]: %s", i, pValue);
960
961                                 pInsertMap->Add(new (std::nothrow) String(pColumn), new (std::nothrow) String(pValue));
962                                 delete pColumn;
963                                 delete pValue;
964                         }
965                 }
966                 else
967                 {
968                         i = 0;
969                         index = 0;
970                         while (i < columnCount * 2) // request list: column-value pairs
971                         {
972                                 pColumn = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_INSERTMAP + i++));
973                                 SysTryCatch(NID_APP, pColumn != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
974                                 SysLog(NID_APP, "[DC_PROV_RECV] column[%d]: %ls", index, pColumn->GetPointer());
975
976                                 pValue = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_INSERTMAP + i++));
977                                 SysTryCatch(NID_APP, pValue != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
978                                 SysLog(NID_APP, "[DC_PROV_RECV] value[%d]: %ls", index, pValue->GetPointer());
979
980                                 pInsertMap->Add(new (std::nothrow) String(*pColumn), new (std::nothrow) String(*pValue));
981                                 index++;
982                         }
983                 }
984
985                 if (pTmpPath)
986                 {
987                         r = File::Remove(*pTmpPath);
988                         SysTryLog(NID_APP, !IsFailed(r), "Failed to remove result: %ls", pTmpPath->GetPointer());
989                 }
990
991                 pSqlListener->OnSqlDataControlInsertRequestReceived(reqId, providerId, *pDataId, *pInsertMap);
992
993                 SysLog(NID_APP, "[DC_PROV_RECV] caller app: %ls, requestType: %d, caller req: %ls, provider: %ls, data: %ls, pInsertMap: 0x%x",
994                                 appId.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(),
995                                 pDataId->GetPointer(), pInsertMap);
996                 break;
997         case _DATACONTROL_REQUEST_TYPE_SQL_UPDATE:
998                 SysLog(NID_APP, "[DC_PROV_RECV] SqlDataControl UPDATE");
999
1000                 // request list[1]: updated column count
1001                 pColumnCount = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_COLUMNCOUNT));
1002                 SysTryCatch(NID_APP, pColumnCount, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1003
1004                 Integer::Parse(*pColumnCount, columnCount);
1005                 SysLog(NID_APP, "[DC_PROV_RECV] updated column count: %d", columnCount);
1006
1007                 pUpdateMap = new (std::nothrow) HashMap();
1008                 SysTryReturnVoidResult(NID_APP, pUpdateMap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
1009                 pUpdateMap->Construct();
1010
1011                 SysLog(NID_APP, "[DC_PROV_RECV] version: %ls", version.GetPointer());
1012                 if (version == L"ver_2.1.0.2" || version == L"ver_2.1.0.3")
1013                 {
1014                         pTmpPath = dynamic_cast< String* >(pList->GetAt(2)); // request list[2]: path
1015                         SysTryCatch(NID_APP, pTmpPath != null, , E_SYSTEM, "[E_SYSTEM] invalid request");
1016                         SysLog(NID_APP, "[DC_PROV_RECV] request: %ls", pTmpPath->GetPointer());
1017
1018                         File request;
1019                         r = request.Construct(*pTmpPath, "r");
1020                         SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to open request (%ls).",
1021                                         GetErrorMessage(r), pTmpPath->GetPointer());
1022
1023                         for (i = 0; i < columnCount; ++i) // column-value pairs
1024                         {
1025                                 int length = -1;
1026                                 int ret = request.Read(&length, sizeof(int));
1027                                 SysTryCatch(NID_APP, ret > 0, , E_SYSTEM, "[%s] Failed to receive request.",
1028                                                 GetErrorMessage(GetLastResult()));
1029
1030                                 char* pColumn = new (std::nothrow) char[length + 1];
1031                                 ret = request.Read(pColumn, length);
1032                                 SysTryCatch(NID_APP, ret > 0, delete pColumn, E_SYSTEM, "[%s] Failed to receive request.",
1033                                                 GetErrorMessage(GetLastResult()));
1034                                 pColumn[length] = '\0';
1035                                 SysLog(NID_APP, "[DC_PROV_RECV] column[%d]: %s", i, pColumn);
1036
1037                                 ret = request.Read(&length, sizeof(int));
1038                                 SysTryCatch(NID_APP, ret > 0, delete pColumn, E_SYSTEM, "[%s] Failed to receive request.",
1039                                                 GetErrorMessage(GetLastResult()));
1040
1041                                 char* pValue = new (std::nothrow) char[length + 1];
1042                                 ret = request.Read(pValue, length);
1043                                 if (ret == 0)
1044                                 {
1045                                         SysLogException(NID_APP, E_SYSTEM, "[%s] Failed to receive request.", GetErrorMessage(GetLastResult()));
1046                                         delete pColumn;
1047                                         delete pValue;
1048                                 }
1049                                 pValue[length] = '\0';
1050                                 SysLog(NID_APP, "[DC_PROV_RECV] value[%d]: %s", i, pValue);
1051
1052                                 pUpdateMap->Add(new (std::nothrow) String(pColumn), new (std::nothrow) String(pValue));
1053                                 delete pColumn;
1054                                 delete pValue;
1055                         }
1056
1057                         // request list: where clause
1058                         pWhere = dynamic_cast< String* >(pList->GetAt(3));
1059                         SysTryCatch(NID_APP, pWhere != null, , E_SYSTEM, "[E_SYSTEM] invalid request");
1060                 }
1061                 else
1062                 {
1063                         i = 0;
1064                         index = 0;
1065                         while (i < columnCount * 2) // request list: column-value pairs
1066                         {
1067                                 pColumn = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_UPDATEMAP + i++));
1068                                 SysTryCatch(NID_APP, pColumn != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1069                                 SysLog(NID_APP, "[DC_PROV_RECV] column[%d]: %ls", index, pColumn->GetPointer());
1070
1071                                 pValue = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_UPDATEMAP + i++));
1072                                 SysTryCatch(NID_APP, pValue != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1073                                 SysLog(NID_APP, "[DC_PROV_RECV] value[%d]: %ls", index, pValue->GetPointer());
1074
1075                                 pUpdateMap->Add(new (std::nothrow) String(*pColumn), new (std::nothrow) String(*pValue));
1076                                 index++;
1077                         }
1078
1079                         // request list: where clause
1080                         pWhere = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_UPDATEMAP + i));
1081                         SysTryCatch(NID_APP, pWhere, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1082                 }
1083
1084                 if (pWhere->Equals(empty) == true)
1085                 {
1086                         pWhere = null;
1087                 }
1088                 else
1089                 {
1090                         SysLog(NID_APP, "[DC_PROV_RECV] pWhere: %ls", pWhere->GetPointer());
1091                 }
1092
1093                 if (pTmpPath)
1094                 {
1095                         r = File::Remove(*pTmpPath);
1096                         SysTryLog(NID_APP, !IsFailed(r), "Failed to remove result: %ls", pTmpPath->GetPointer());
1097                 }
1098
1099                 pSqlListener->OnSqlDataControlUpdateRequestReceived(reqId, providerId, *pDataId, *pUpdateMap, pWhere);
1100
1101                 SysLog(NID_APP, "[DC_PROV_RECV] caller app: %ls, requestType: %d, caller req: %ls, provider: %ls, data: %ls, pUpdateMap: 0x%x, pWhere: 0x%x",
1102                                 appId.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(),
1103                                 pDataId->GetPointer(), pUpdateMap, pWhere);
1104                 break;
1105         case _DATACONTROL_REQUEST_TYPE_SQL_DELETE:
1106                 SysLog(NID_APP, "[DC_PROV_RECV] SqlDataControl DELETE");
1107
1108                 // request list[1]: where clause
1109                 pWhere = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_DELETEWHERE));
1110                 SysTryCatch(NID_APP, pWhere, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1111
1112                 if (pWhere->Equals(empty) == true)
1113                 {
1114                         pWhere = null;
1115                 }
1116                 else
1117                 {
1118                         SysLog(NID_APP, "[DC_PROV_RECV] pWhere: %ls", pWhere->GetPointer());
1119                 }
1120
1121                 pSqlListener->OnSqlDataControlDeleteRequestReceived(reqId, providerId, *pDataId, pWhere);
1122
1123                 SysLog(NID_APP, "[DC_PROV_RECV] caller app: %ls, requestType: %d, caller req: %ls, provider: %ls, data: %ls, pWhere: 0x%x",
1124                                 appId.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(),
1125                                 pDataId->GetPointer(), pWhere);
1126                 break;
1127         case _DATACONTROL_REQUEST_TYPE_MAP_QUERY:
1128                 SysLog(NID_APP, "[DC_PROV_RECV] MapDataControl GetValue");
1129
1130                 pNo = dynamic_cast <String*>(pList->GetAt(2)); // request list[2]
1131                 SysTryCatch(NID_APP, pNo, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1132                 Integer::Parse(*pNo, pageNo);
1133
1134                 pCount = dynamic_cast <String*>(pList->GetAt(3)); // request list[3]
1135                 SysTryCatch(NID_APP, pCount, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1136                 Integer::Parse(*pCount, countPerPage);
1137
1138                 pMapListener->OnMapDataControlGetValueRequestReceived(reqId, providerId, *pDataId, *pKey);
1139
1140                 SysLog(NID_APP, "[DC_PROV_RECV] caller app: %ls, requestType: %d, caller req: %ls, provider: %ls, data: %ls, key: %ls, pageNo: %d, countPerPage: %d",
1141                                 appId.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(),
1142                                 pDataId->GetPointer(), pKey->GetPointer(), pageNo, countPerPage);
1143                 break;
1144         case _DATACONTROL_REQUEST_TYPE_MAP_INSERT:
1145                 SysLog(NID_APP, "[DC_PROV_RECV] MapDataControl AddValue");
1146
1147                 pValue = dynamic_cast <String*>(pList->GetAt(2)); // request list[2]
1148                 SysTryCatch(NID_APP, pValue, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1149
1150                 pMapListener->OnMapDataControlAddValueRequestReceived(reqId, providerId, *pDataId, *pKey, *pValue);
1151
1152                 SysLog(NID_APP, "[DC_PROV_RECV] caller app: %ls, requestType: %d, caller req: %ls, provider: %ls, data: %ls, key: %ls, value: %ls",
1153                                 appId.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(),
1154                                 pDataId->GetPointer(), pKey->GetPointer(), pValue->GetPointer());
1155                 break;
1156         case _DATACONTROL_REQUEST_TYPE_MAP_UPDATE:
1157                 SysLog(NID_APP, "[DC_PROV_RECV] MapDataControl SetValue");
1158
1159                 pOldValue = dynamic_cast <String*>(pList->GetAt(2)); // request list[2]
1160                 SysTryCatch(NID_APP, pOldValue, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1161
1162                 pNewValue = dynamic_cast <String*>(pList->GetAt(3)); // request list[3]
1163                 SysTryCatch(NID_APP, pNewValue, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1164
1165                 pMapListener->OnMapDataControlSetValueRequestReceived(reqId, providerId, *pDataId, *pKey, *pOldValue, *pNewValue);
1166
1167                 SysLog(NID_APP, "[DC_PROV_RECV] caller app: %ls, requestType: %d, caller req: %ls, provider: %ls, data: %ls, key: %ls, oldValue: %ls, newValue: %ls",
1168                                 appId.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(),
1169                                 pDataId->GetPointer(), pKey->GetPointer(), pOldValue->GetPointer(), pNewValue->GetPointer());
1170                 break;
1171         case _DATACONTROL_REQUEST_TYPE_MAP_DELETE:
1172                 SysLog(NID_APP, "[DC_PROV_RECV] MapDataControl RemoveValue");
1173
1174                 pValue = dynamic_cast <String*>(pList->GetAt(2)); // request list[2]
1175                 SysTryCatch(NID_APP, pValue, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1176
1177                 pMapListener->OnMapDataControlRemoveValueRequestReceived(reqId, providerId, *pDataId, *pKey, *pValue);
1178
1179                 SysLog(NID_APP, "[DC_PROV_RECV] caller app: %ls, requestType: %d, caller req: %ls, provider: %ls, data: %ls, key: %ls, value: %ls",
1180                                 appId.GetPointer(), requestType, callerReqId.GetPointer(), providerId.GetPointer(),
1181                                 pDataId->GetPointer(), pKey->GetPointer(), pValue->GetPointer());
1182                 break;
1183         default:
1184                 SysTryCatch(NID_APP, false, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request");
1185                 break;
1186         }
1187
1188         if (pColumnList)
1189         {
1190                 pColumnList->RemoveAll(true);
1191                 delete pColumnList;
1192         }
1193
1194         if (pInsertMap)
1195         {
1196                 pInsertMap->RemoveAll(true);
1197                 delete pInsertMap;
1198         }
1199
1200         if (pUpdateMap)
1201         {
1202                 pUpdateMap->RemoveAll(true);
1203                 delete pUpdateMap;
1204         }
1205
1206         return;
1207
1208 CATCH:
1209         if (pColumnList)
1210         {
1211                 pColumnList->RemoveAll(true);
1212                 delete pColumnList;
1213         }
1214
1215         if (pInsertMap)
1216         {
1217                 pInsertMap->RemoveAll(true);
1218                 delete pInsertMap;
1219         }
1220
1221         if (pUpdateMap)
1222         {
1223                 pUpdateMap->RemoveAll(true);
1224                 delete pUpdateMap;
1225         }
1226
1227         if (r == E_SYSTEM)
1228         {
1229                 pErrorMsg = new (std::nothrow) String("[E_SYSTEM] A system error has occurred.");
1230         }
1231         else if (r == E_OUT_OF_MEMORY)
1232         {
1233                 pErrorMsg = new (std::nothrow) String("[E_OUT_OF_MEMORY] The memory was insufficient.");
1234         }
1235         SysTryReturnVoidResult(NID_APP, pErrorMsg, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory was insufficient.");
1236
1237         res = DataControlProviderManager::GetInstance()->SendDataControlError(reqId, *pErrorMsg);
1238
1239         delete pErrorMsg;
1240
1241         return;
1242 }
1243
1244
1245 void
1246 _AppImpl::OnConditionRequestReceived(const _AppArg& arg, RequestId reqId)
1247 {
1248         if (__pAppLaunchConditionEventListener == null)
1249         {
1250                 SysLog(NID_APP, "No App launch condition event listener");
1251                 return;
1252         }
1253
1254         String condition = arg.GetValue(OSP_K_COND);
1255         //Object* pExtraData = null;//TODO: retrieve NFC extra data.
1256     HashMap* pExtraData = arg.GetArgMapN();
1257         ArrayList* pList = arg.GetArgListN();
1258
1259         __pAppLaunchConditionEventListener->OnAppLaunchConditionMetN(condition, pExtraData, pList);
1260 }
1261
1262
1263 long
1264 _AppImpl::GetWindowHandle(void) const
1265 {
1266         SysTryReturn(NID_APP, __pIAppImpl != null, -1, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
1267
1268         return __pIAppImpl->OnWindowHandleRequest();
1269 }
1270
1271
1272 void
1273 _AppImpl::RaiseWindow(void)
1274 {
1275         SysTryReturnVoidResult(NID_APP, __pIAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting App instance failed.");
1276
1277         __pIAppImpl->OnFrameRaiseRequested();
1278 }
1279
1280
1281 void
1282 _AppImpl::OnAppCheckpoint(void)
1283 {
1284         if (__pCheckpointEventListener)
1285         {
1286                 __pCheckpointEventListener->OnAppCheckpointing(*(AppRegistry::GetInstance()));
1287         }
1288 }
1289
1290
1291 bool
1292 _AppImpl::ConfirmAppService(void)
1293 {
1294         if (_AppInfo::GetApplicationId() == SERVICE_APPID)
1295         {
1296                 return true;
1297         }
1298
1299         int value = -1;
1300         int count = 0;
1301         long interval = 100;
1302
1303         while (true)
1304         {
1305                 int res = vconf_get_int(VCONFKEY_APPSERVICE_STATUS, &value);
1306                 if (value > 0)
1307                 {
1308                         return true;
1309                 }
1310
1311                 if (count >= HEARTBEAT_WAIT_COUNT)
1312                 {
1313                         return false;
1314                 }
1315
1316                 SysLog(NID_APP, "Waiting for app service %dth time(%d msec).", count, interval);
1317                 count++;
1318                 Thread::Sleep(interval);
1319                 interval += 100;
1320         }
1321
1322         return false;
1323 }
1324
1325 result
1326 _AppImpl::SetListener(_AppEvent appEvent, IEventListener* pListener)
1327 {
1328         switch (appEvent)
1329         {
1330         case _APP_EVENT_CHECKPOINT:
1331                 SysTryReturnResult(NID_APP, __pCheckpointEventListener == null, E_OBJ_ALREADY_EXIST, "Checkpoint listener is already set.");
1332
1333                 // fall through
1334         case _APP_EVENT_CLEAR_LISTENER:
1335                 __pCheckpointEventListener = dynamic_cast <IAppCheckpointEventListener*>(pListener);
1336                 break;
1337
1338         default:
1339                 break;
1340         }
1341
1342         return E_SUCCESS;
1343 }
1344
1345
1346 result
1347 _AppImpl::SetSqlDataControlProviderEventListener(ISqlDataControlProviderEventListener* pListener)
1348 {
1349         __pSqlDataControlProviderEventListener = pListener;
1350         int tmpAppHandlerType = _AppInfo::GetAppHandlerType();
1351         tmpAppHandlerType |= _APP_HANDLER_DATACONTROL;
1352         _AppInfo::SetAppHandlerType(tmpAppHandlerType);
1353         return E_SUCCESS;
1354 }
1355
1356
1357 result
1358 _AppImpl::SetMapDataControlProviderEventListener(IMapDataControlProviderEventListener* pListener)
1359 {
1360         __pMapDataControlProviderEventListener = pListener;
1361         int tmpAppHandlerType = _AppInfo::GetAppHandlerType();
1362         tmpAppHandlerType |= _APP_HANDLER_DATACONTROL;
1363         _AppInfo::SetAppHandlerType(tmpAppHandlerType);
1364         return E_SUCCESS;
1365 }
1366
1367
1368 result
1369 _AppImpl::SetAppControlProviderEventListener(IAppControlProviderEventListener* pListener)
1370 {
1371         __pAppControlProviderEventListener = pListener;
1372         int tmpAppHandlerType = _AppInfo::GetAppHandlerType();
1373         tmpAppHandlerType |= _APP_HANDLER_APPCONTROL;
1374         _AppInfo::SetAppHandlerType(tmpAppHandlerType);
1375         return E_SUCCESS;
1376 }
1377
1378 result
1379 _AppImpl::SetAppControlProviderInternalEventListener(IAppControlProviderEventListener* pListener)
1380 {
1381         __pAppControlProviderInternalEventListener = pListener;
1382         int tmpAppHandlerType = _AppInfo::GetAppHandlerType();
1383         tmpAppHandlerType |= _APP_HANDLER_APPCONTROL;
1384         _AppInfo::SetAppHandlerType(tmpAppHandlerType);
1385         return E_SUCCESS;
1386 }
1387
1388
1389 result
1390 _AppImpl::SetAppLaunchConditionEventListener(IAppLaunchConditionEventListener* pListener)
1391 {
1392         __pAppLaunchConditionEventListener = pListener;
1393         int tmpAppHandlerType = _AppInfo::GetAppHandlerType();
1394         tmpAppHandlerType |= _APP_HANDLER_LAUNCH_COND;
1395         _AppInfo::SetAppHandlerType(tmpAppHandlerType);
1396
1397         return E_SUCCESS;
1398 }
1399
1400
1401 bool
1402 _AppImpl::IsTerminationRequested(void)
1403 {
1404         return __isTerminationRequested;
1405 }
1406
1407 typedef void (*cbForVconf)(keynode_t* node, void *pData);
1408
1409 void
1410 _AppImpl::OnPowerOffNotiReceived(void* node, void* user_data)
1411 {
1412         int value = -1;
1413         if (!vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &value))
1414         {
1415                 if (value == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || value == VCONFKEY_SYSMAN_POWER_OFF_RESTART)
1416                 {
1417                         SysLog(NID_APP, "Application is being terminated by power off.");
1418
1419                         if (vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (cbForVconf)_AppImpl::OnPowerOffNotiReceived))
1420                         {
1421                                 SysLog(NID_APP, "Fail to ignore vconf for key(%s)", VCONFKEY_SYSMAN_POWER_OFF_STATUS);
1422                         }
1423
1424                         _AppImpl* pAppImpl = _AppImpl::GetInstance();
1425                         if (pAppImpl != null)
1426                         {
1427                                 pAppImpl->__forcedTermination = true;
1428                         }
1429
1430                         app_efl_exit();
1431                 }
1432         }
1433 }
1434
1435 void
1436 _AppImpl::OnSettingChanged(String& key)
1437 {
1438         if (key == L"http://tizen.org/setting/locale.language")
1439         {
1440                 _AppInfo::UpdatePackageInfo(true);
1441                 _AppResourceImpl::Reinitialize();
1442                 SysLog(NID_APP, "Reinitialized resources due to locale change.");
1443         }
1444 }
1445
1446 bool
1447 _AppImpl::IsForcedTermination(void)
1448 {
1449         return __forcedTermination;
1450 }
1451
1452 }} //Tizen::App
1453