refactoring (now _AppContext manages list of _AppWidgetContext, IpcConnection state...
[framework/osp/appwidget-service.git] / src / FShell_AppWidgetContext.cpp
1 //
2 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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        FShell_AppWidgetContext.cpp
19  * @brief       This is the implementation for the _AppWidgetContext class.
20  */
21
22 #include <provider.h>
23 #include <unique_ptr.h>
24
25 #include <FBase.h>
26 //#include <FBaseColIList.h>
27 #include <FBaseSysLog.h>
28 #include <FBaseInteger.h>
29 #include <FBaseDouble.h>
30 #include <FBaseColHashMap.h>
31 #include <FBaseColAllElementsDeleter.h>
32 #include <FSysSystemTime.h>
33 #include <FAppApp.h>
34 #include <FAppAppManager.h>
35 #include <FBaseComparerT.h>
36
37 #include <FBase_StringConverter.h>
38 #include "FShell_AppWidgetManagerImpl.h"
39 #include "FShell_AppWidgetManagerService.h"
40 #include "FShell_AppWidgetPopupContext.h"
41 #include "FShell_AppWidgetContext.h"
42 #include "FShell_AppWidgetContextHelper.h"
43 #include "FShell_AppWidgetRemoteBuffer.h"
44 #include "FShell_TemplateUtil.h"
45
46 namespace Tizen { namespace Shell  { namespace App
47 {
48
49 using namespace std;
50 using namespace Tizen::App;
51 using namespace Tizen::Base;
52 using namespace Tizen::Base::Collection;
53 using namespace Tizen::System;
54
55 const wchar_t ARG_KEY_INSTANCE_ID[] = L"_InstanceId";
56 const wchar_t ARG_KEY_PROVIDER_NAME[] = L"_ProviderName";
57 const wchar_t ARG_KEY_USER_INFO[] = L"_UserInfo";
58 const wchar_t ARG_KEY_X[] = L"_X";
59 const wchar_t ARG_KEY_Y[] = L"_Y";
60 const wchar_t ARG_KEY_WIDTH[] = L"_Width";
61 const wchar_t ARG_KEY_HEIGHT[] = L"_Height";
62 const wchar_t ARG_KEY_POPUP_WIDTH[] = L"_PopupWidth";
63 const wchar_t ARG_KEY_POPUP_HEIGHT[] = L"_PopupHeight";
64 const wchar_t ARG_KEY_ARGUMENT[] = L"_Argument";
65 const wchar_t ARG_KEY_EVENT_TYPE[] = L"_EventType";
66 const wchar_t ARG_KEY_TIME_STAMP[] = L"_TimeStamp";
67
68 const wchar_t APPWIDGET_ON_ADD[] = L"http://tizen.org/appcontrol/appwidget/add";
69 const wchar_t APPWIDGET_ON_REMOVE[] = L"http://tizen.org/appcontrol/appwidget/remove";
70 const wchar_t APPWIDGET_ON_UPDATE[] = L"http://tizen.org/appcontrol/appwidget/update";
71 const wchar_t APPWIDGET_ON_RESIZE[] = L"http://tizen.org/appcontrol/appwidget/resize";
72 const wchar_t APPWIDGET_ON_TOUCH[] = L"http://tizen.org/appcontrol/appwidget/touch";
73
74 const int UPDATE_PERIOD_MSEC_MIN = 1800000;     // 30min
75
76 static const wchar_t INVALID_INSTANCE[] = L"file://invalid instance id";
77
78 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
79 // _AppContext class
80 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 _AppContext::_AppContext(const AppId& appId)
82         :__appId(appId)
83         ,__isWaitingResult(false)
84         ,__ipcClientId(0)
85         ,__connectionState(CONNECTION_STATE_NONE)
86         ,__pPendingEventList(null)
87 {
88
89         __pPendingEventList = new (nothrow) ArrayListT<PendingEvent*>();
90         SysTryReturnVoidResult(NID_SHELL, __pPendingEventList, E_OUT_OF_MEMORY, "");
91
92         result r = __pPendingEventList->Construct();
93         SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "Failed to execute Construct.");
94
95         static __HashMapDefaultProviderT <String> strHashCodeProvider;
96         static ComparerT <String> strComparer;
97         r = __appWidgetContextList.Construct(0, 0, strHashCodeProvider, strComparer);
98         SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "Failed to execute Construct.");
99 }
100
101 _AppContext::~_AppContext(void)
102 {
103         if (__pPendingEventList)
104         {
105                 for (int i = 0; i < __pPendingEventList->GetCount(); i++)
106                 {
107                         PendingEvent* pEvent = null;
108                         __pPendingEventList->GetAt(i, pEvent);
109                         delete pEvent;
110                 }
111                 __pPendingEventList->RemoveAll();
112                 delete __pPendingEventList;
113         }
114 }
115
116 _AppWidgetContext*
117 _AppContext::AddAppWidget(const Tizen::Base::String& userInfo, const Tizen::Base::String& providerId, const Tizen::Base::String& instanceId, int width, int height, int period, int priority)
118 {
119         _AppWidgetContext* pAppWidgetContext = new (std::nothrow)_AppWidgetContext(this, userInfo, providerId, instanceId, width, height, period, priority);
120         SysTryReturn(NID_SHELL, pAppWidgetContext, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
121
122         __appWidgetContextList.Add(pAppWidgetContext->GetInstanceId(), pAppWidgetContext);
123         pAppWidgetContext->OnAdded();
124
125         SysSecureLog(NID_SHELL, "%ls, %ls, count(%d)", pAppWidgetContext->GetProviderId().GetPointer(), pAppWidgetContext->GetInstanceId().GetPointer(), __appWidgetContextList.GetCount());
126         return pAppWidgetContext;
127 }
128
129 result
130 _AppContext::RemoveAppWidget(const Tizen::Base::String& instanceId, bool isTriggeredByViewer)
131 {
132         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
133         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND]");
134
135         __appWidgetContextList.Remove(instanceId);
136
137         result r = pAppWidgetContext->OnRemoved(isTriggeredByViewer);
138         SysTryLog(NID_SHELL, !IsFailed(r), "Failed to execute OnRemoved.");
139
140         delete pAppWidgetContext;
141
142     SysLog(NID_SHELL, "AppWidget(%ls, %ls) is removed. remain count(%d)", pAppWidgetContext->GetProviderId().GetPointer(), instanceId.GetPointer(), __appWidgetContextList.GetCount());
143         return E_SUCCESS;
144 }
145
146 _ConnectionState
147 _AppContext::GetConnectionState(void) const
148 {
149         return __connectionState;
150 }
151
152 void
153 _AppContext::SetConnectionState(_ConnectionState state)
154 {
155         __connectionState = state;
156 }
157
158 Tizen::App::AppId
159 _AppContext::GetAppId(void) const
160 {
161         return __appId;
162 }
163
164 int
165 _AppContext::GetClientId(void) const
166 {
167         return __ipcClientId;
168 }
169
170 void
171 _AppContext::OnIpcConnected(int clientId)
172 {
173         __ipcClientId = clientId;
174         SetConnectionState(CONNECTION_STATE_CONNECTED);
175 }
176
177 void
178 _AppContext::OnIpcDisconnected(void)
179 {
180         __ipcClientId = -1;
181         SetConnectionState(CONNECTION_STATE_DISCONNECTED);
182
183         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
184         SysTryReturnVoidResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "");
185
186         _AppWidgetContext* pAppWidgetContext = null;
187         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
188         {
189                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
190                 if (pAppWidgetContext)
191                 {
192                         pAppWidgetContext->OnDisconnected();
193                 }
194         }
195 }
196
197 void
198 _AppContext::SetWaitingStatus(bool status)
199 {
200         __isWaitingResult = status;
201 }
202
203 bool
204 _AppContext::GetWaitingStatus(void) const
205 {
206         return __isWaitingResult;
207 }
208
209 result
210 _AppContext::SendRequestToApp(const AppId& providerAppId, const String& operation, HashMap* pArgs)
211 {
212         result r = E_SUCCESS;
213
214         if (GetConnectionState() == CONNECTION_STATE_NONE || GetConnectionState() == CONNECTION_STATE_DISCONNECTED)
215         {
216                 SysLog(NID_SHELL, "The application is not running.");
217                 result r = _AppWidgetRequestHelper::SendAppControlRequest(providerAppId, operation, pArgs);
218                 SysTryReturn(NID_SHELL, !IsFailed(r), r, r, "[%s] Failed to SendRequestToApp", GetErrorMessage(r));
219
220                 SetWaitingStatus(true);
221                 SetConnectionState(CONNECTION_STATE_CONNECTING);
222         }
223         else
224         {
225                 if (GetConnectionState() == CONNECTION_STATE_CONNECTING || GetWaitingStatus() == true)
226                 {
227                         SysLog(NID_SHELL, "The application is running but IPC is not connected yet.");
228                         __pPendingEventList->Add(new (nothrow) PendingEvent(operation, pArgs));
229                 }
230                 else
231                 {
232                         SysLog(NID_SHELL, "The application is running and IPC is connected.");
233                         r  = _AppWidgetRequestHelper::SendIpcRequest(GetClientId(), operation, pArgs);
234
235                         pArgs->RemoveAll(true);
236                         delete pArgs;
237                         SetWaitingStatus(true);
238                 }
239         }
240
241         return E_SUCCESS;
242 }
243
244 result
245 _AppContext::SendPendingEvent(void)
246 {
247         SetWaitingStatus(false);
248         TryReturn(__pPendingEventList->GetCount() > 0, E_DATA_NOT_FOUND, "This context has no pending event. Please find next pending event context.");
249
250         PendingEvent* pEvent = null;
251         __pPendingEventList->GetAt(0, pEvent);
252         SysTryReturnResult(NID_SHELL, pEvent != null, E_SYSTEM, "__pPendingEventList has (%d) items, but failed to GetAt(0)", __pPendingEventList->GetCount());
253
254         __pPendingEventList->RemoveAt(0);
255         SysLog(NID_SHELL, "(%d) Remains in __pPendingEventList.", __pPendingEventList->GetCount());
256
257         result r = _AppWidgetRequestHelper::SendIpcRequest(GetClientId(), pEvent->operation, pEvent->pArg);
258         delete pEvent;
259         SysTryReturnResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "SendIpcRequest failed.");
260
261         return E_SUCCESS;
262 }
263
264 _AppWidgetContext*
265 _AppContext::FindAppWidget(const String& instanceId) const
266 {
267         _AppWidgetContext* pAppWidgetContext = null;
268
269         if (instanceId == INVALID_INSTANCE)
270         {
271                 pAppWidgetContext = FindInvalidAppWidget();
272         }
273         else
274         {
275                 result r = __appWidgetContextList.GetValue(instanceId, pAppWidgetContext);
276                 SysTryReturn(NID_SHELL, !IsFailed(r), null, E_OBJ_NOT_FOUND, "instanceId(%ls) is not found", instanceId.GetPointer() );
277         }
278         return pAppWidgetContext;
279 }
280
281 _AppWidgetContext*
282 _AppContext::FindInvalidAppWidget(void) const
283 {
284         SysTryReturn(NID_SHELL, GetConnectionState() == CONNECTION_STATE_NONE, null, E_INVALID_STATE, "[E_INVALID_STATE] connectionState(%d)", GetConnectionState());
285
286         _AppWidgetContext* pAppWidgetContext = null;
287         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
288         SysTryReturn(NID_SHELL, pAppWidgetContextEnum, null, E_SYSTEM, "");
289
290         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
291         {
292                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
293                 if (pAppWidgetContext)
294                 {
295                         //TODO: check whether this app context has only one instance of _AppWidgetContext
296                         return pAppWidgetContext;
297                 }
298         }
299         return null;
300 }
301
302 int
303 _AppContext::GetProviderCount(const String& appId) const
304 {
305         return __appWidgetContextList.GetCount();
306 }
307
308 result
309 _AppContext::RequestUpdate(const Tizen::Base::String& providerName, const Tizen::Base::String& argument) const
310 {
311         bool found = false;
312         bool requestToAll = providerName.IsEmpty();
313
314         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
315         SysTryReturnResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "Failed to invoke __appWidgetContextList.GetMapEnumeratorN()");
316
317         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
318         {
319                 _AppWidgetContext* pAppWidgetContext = null;
320                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
321
322                 if (pAppWidgetContext->GetProviderName() == providerName || requestToAll == true)
323                 {
324                         pAppWidgetContext->RequestUpdate(argument);
325                         found = true;
326                 }
327         }
328
329         SysLog(NID_SHELL, "Exit.");
330         return (found) ? E_SUCCESS : E_OBJ_NOT_FOUND;
331 }
332
333 result
334 _AppContext::OnAppWidgetBackgroundAll(void) const
335 {
336         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
337         SysTryReturnResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "Failed to invoke GetMapEnumeratorN()");
338
339         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
340         {
341                 _AppWidgetContext* pAppWidgetContext = null;
342                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
343                 if (pAppWidgetContext)
344                 {
345                         pAppWidgetContext->OnBackground();
346                 }
347         }
348
349         return E_SUCCESS;
350 }
351
352 result
353 _AppContext::OnAppWidgetForegroundAll(void) const
354 {
355         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
356         SysTryReturnResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "Failed to invoke GetMapEnumeratorN()");
357
358         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
359         {
360                 _AppWidgetContext* pAppWidgetContext = null;
361                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
362                 if (pAppWidgetContext)
363                 {
364                         pAppWidgetContext->OnForeground();
365                 }
366         }
367
368         return E_SUCCESS;
369 }
370
371
372
373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
374 // _AppWidgetContext class
375 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
376 _AppWidgetContext::_AppWidgetContext(_AppContext* pAppContext, const String& userInfo, const String& providerId, const String& instanceId, int width, int height, int period, int priority)
377         :__isRemoteBufferProxyCreated(false)
378         ,__hasPendingRequest(false)
379         ,__isForeground(true)
380         ,__width(width)
381         ,__height(height)
382         ,__priority(priority)
383         ,__ipcClientId(-1)
384         ,__updateMillis( (period > UPDATE_PERIOD_MSEC_MIN) ? period : UPDATE_PERIOD_MSEC_MIN )
385         ,__lastUpdatedTime(0)
386         ,__userInfo(userInfo)
387         ,__providerId(providerId)
388         ,__instanceId(instanceId)
389         ,__pAppContext(pAppContext)
390         ,__pAppWidgetPopup(null)
391         ,__pAppWidgetRemoteBuffer(null)
392         ,__pPendingTouchEventList(null)
393 {
394         _AppWidgetManagerImpl::ExtractAppIdAndProviderName(providerId, __appId, __providerName);//TODO: extract this line to outside
395         SysSecureLog(NID_SHELL, "appId(%ls), providerId(%ls), instanceId(%ls), width(%d), height(%d), priority(%d), period(%d)", __appId.GetPointer(), __providerId.GetPointer(), __instanceId.GetPointer(), __width, __height, __priority, __updateMillis);
396
397         // for updating period
398         if (__updateMillis > 0)
399         {
400                 SystemTime::GetTicks(this->__lastUpdatedTime);
401
402                 result r = __updateTimer.Construct(*this);
403                 SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "");
404
405                 r = __updateTimer.StartAsRepeatable(__updateMillis);
406                 SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "");
407         }
408
409         __pPendingTouchEventList = new (nothrow) ArrayListT<PendingTouchEvent*>();
410         SysTryReturnVoidResult(NID_SHELL, __pPendingTouchEventList, E_OUT_OF_MEMORY, "");
411         __pPendingTouchEventList->Construct();
412
413         __pAppWidgetRemoteBuffer = new (nothrow) _AppWidgetRemoteBuffer(providerId, instanceId, TYPE_LB, this);
414         SysTryReturnVoidResult(NID_SHELL, __pAppWidgetRemoteBuffer, E_OUT_OF_MEMORY, "");
415 }
416
417 _AppWidgetContext::~_AppWidgetContext(void)
418 {
419         SysSecureLog(NID_SHELL, "appId(%ls), instanceId(%ls), width(%d), height(%d), priority(%d)", GetProviderId().GetPointer(), GetInstanceId().GetPointer(), GetWidth(), GetHeight(), GetPriority());
420
421         __updateTimer.Cancel();
422
423         if (__pAppWidgetPopup)
424         {
425                 SysLog(NID_SHELL, "Destroying dangling AppWidgetPopup instance..");
426                 delete __pAppWidgetPopup;
427         }
428
429         if (__pPendingTouchEventList)
430         {
431                 for (int i = 0; i < __pPendingTouchEventList->GetCount(); i++)
432                 {
433                         PendingTouchEvent* pTouchEvent = null;
434                         __pPendingTouchEventList->GetAt(i, pTouchEvent);
435                         delete pTouchEvent;
436                 }
437                 __pPendingTouchEventList->RemoveAll();
438                 delete __pPendingTouchEventList;
439         }
440
441         if (__pAppWidgetRemoteBuffer)
442         {
443                 delete __pAppWidgetRemoteBuffer;
444         }
445 }
446
447 _AppContext*
448 _AppWidgetContext::GetAppContext(void) const
449 {
450         return __pAppContext;
451 }
452
453 _AppWidgetPopupContext*
454 _AppWidgetContext::GetAppWidgetPopup(void) const
455 {
456         return __pAppWidgetPopup;
457 }
458
459 void
460 _AppWidgetContext::OnAdded(void)
461 {
462         SendAddRequest(GetWidth(), GetHeight());
463 }
464
465 result
466 _AppWidgetContext::OnRemoved(bool isTriggeredByViewer)
467 {
468         if (isTriggeredByViewer)
469         {
470                 return SendRemoveRequest();
471         }
472         else
473         {
474                 std::unique_ptr<char[]> providerId(_StringConverter::CopyToCharArrayN(GetProviderId()));
475                 std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
476
477                 int ret = provider_send_deleted(providerId.get(), id.get());
478                 SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "Failed to execute provider_send_deleted.");
479         }
480         return E_SUCCESS;
481 }
482
483 void
484 _AppWidgetContext::OnUpdate(const String& argument)
485 {
486         SysLog(NID_SHELL, "argument(%ls)", argument.GetPointer());
487         ClearLastResult();
488
489         // Queueing the pointer of background context.
490         if (!this->IsForeground())
491         {
492                 // Saving the data
493                 if (!argument.IsEmpty())
494                 {
495                         __pendingArgument = argument;
496                 }
497
498                 __hasPendingRequest = true;
499                 SysLog(NID_SHELL, "Update is requested but the %ls is background.", (this->GetAppId()).GetPointer());
500         }
501         else
502         {
503                 result r = this->SendUpdateRequest(GetWidth(), GetHeight(), argument);
504                 SysTryLog(NID_SHELL, !IsFailed(r), "Failed to execute SendUpdateRequest.");
505
506                 SystemTime::GetTicks(this->__lastUpdatedTime);
507                 SysLog(NID_SHELL, "The last updated time is %lld.", this->__lastUpdatedTime);
508
509                 __hasPendingRequest = false;
510                 __pendingArgument.Clear();
511         }
512 }
513
514 void
515 _AppWidgetContext::OnResize(int width, int height)
516 {
517         SysSecureLog(NID_SHELL, "appId(%ls), instanceId(%ls), width(%d), height(%d), priority(%d)", GetProviderId().GetPointer(), GetInstanceId().GetPointer(), GetWidth(), GetHeight(), GetPriority());
518
519         SetWidth(width);
520         SetHeight(height);
521
522         SendResizeRequest(width, height);
523 }
524
525 result
526 _AppWidgetContext::RequestUpdate(const String& argument)
527 {
528         ArrayList* pArray = new (std::nothrow) ArrayList();
529         SysTryReturnResult(NID_SHELL, pArray, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
530
531         pArray->Construct();
532         pArray->Add(this);
533         pArray->Add(new String(argument));
534
535         result r = Tizen::App::App::GetInstance()->SendUserEvent(LOCAL_EVENT_REQUEST_UPDATE, pArray);
536         SysTryLog(NID_SHELL, !IsFailed(r), "[%s] Propagated.", GetErrorMessage(r));
537         SysLog(NID_SHELL, "UserEvent(%d) is sent for '%ls.%ls'.", LOCAL_EVENT_REQUEST_UPDATE, GetAppId().GetPointer(), GetProviderName().GetPointer() );
538
539         return E_SUCCESS;
540 }
541
542 void
543 _AppWidgetContext::OnForeground(void)
544 {
545         if (IsForeground())
546         {
547                 SysLog(NID_SHELL, "%ls is already foreground.", (this->GetAppId()).GetPointer());
548                 return;
549         }
550
551         this->SetForeground(true);
552
553         if (__hasPendingRequest == true)
554         {
555                 SysLog(NID_SHELL, "There is pending update request.");
556 //              RequestUpdate(__pendingArgument);
557                 OnUpdate(__pendingArgument);
558         }
559         else
560         {
561                 if (IsUpdatePeriodExpired() == true)
562                 {
563                         SysLog(NID_SHELL, "The period is expired.");
564 //                      RequestUpdate(L"");
565                         OnUpdate(L"");
566                 }
567         }
568 }
569
570 bool
571 _AppWidgetContext::IsUpdatePeriodExpired(void) const
572 {
573         if (this->GetPeriod() <= 0)
574         {
575                 return false;
576         }
577
578         long long currentTicks = 0;
579         SystemTime::GetTicks(currentTicks);
580
581         SysLog(NID_SHELL, "current[%lld] - last updated time[%lld] = [%lld], period[%d]",
582                         currentTicks, this->GetLastUpdatedTime(), currentTicks - this->GetLastUpdatedTime(), this->GetPeriod());
583
584         bool isPeriodExpired = (currentTicks - this->GetLastUpdatedTime()) >= (this->GetPeriod());
585         return isPeriodExpired;
586 }
587
588 void
589 _AppWidgetContext::OnBackground(void)
590 {
591         if (!IsForeground())
592         {
593                 SysLog(NID_SHELL, "%ls is already background.", (this->GetAppId()).GetPointer());
594                 return;
595         }
596
597         SysLog(NID_SHELL, "OnBackground");
598         SetForeground(false);
599 }
600
601 void
602 _AppWidgetContext::OnPopupCreated(double x, double y, int width, int height)
603 {
604         __pAppWidgetPopup = new (nothrow) _AppWidgetPopupContext(this);
605         SysTryReturnVoidResult(NID_SHELL, __pAppWidgetPopup, E_OUT_OF_MEMORY, "");
606
607         __pAppWidgetPopup->OnPopupCreated(x, y, width, height);
608 }
609
610 void
611 _AppWidgetContext::OnPopupDestoyed(void)
612 {
613         SysLog(NID_SHELL, "");
614
615         if (__pAppWidgetPopup)
616         {
617 //              __pAppWidgetPopup->OnPopupDestoyed();
618                 delete __pAppWidgetPopup;
619                 __pAppWidgetPopup = null;
620         }
621 }
622
623 result
624 _AppWidgetContext::SendAddRequest(int width, int height) const
625 {
626         std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
627
628         return __pAppContext->SendRequestToApp(GetAppId(), APPWIDGET_ON_ADD, pArgs.release());
629 }
630
631 result
632 _AppWidgetContext::SendUpdateRequest(int width, int height, const String& argument) const
633 {
634         std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
635
636         pArgs->Add(new (nothrow) String(ARG_KEY_ARGUMENT), new (nothrow) String(argument));
637
638         return __pAppContext->SendRequestToApp(GetAppId(), APPWIDGET_ON_UPDATE, pArgs.release());
639 }
640
641 result
642 _AppWidgetContext::SendResizeRequest(int width, int height) const
643 {
644         std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN() );
645
646         return __pAppContext->SendRequestToApp(GetAppId(), APPWIDGET_ON_RESIZE, pArgs.release());
647 }
648
649 result
650 _AppWidgetContext::SendRemoveRequest(void) const
651 {
652         std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
653
654         return __pAppContext->SendRequestToApp(GetAppId(), APPWIDGET_ON_REMOVE, pArgs.release());
655 }
656
657 void
658 _AppWidgetContext::SendPendingTouchEvent(void)
659 {
660         for (int i =0; i< __pPendingTouchEventList->GetCount(); i++)
661         {
662                 PendingTouchEvent* pTouchEvent = null;
663                 __pPendingTouchEventList->GetAt(i, pTouchEvent);
664                 AppWidgetManagerService::GetInstance()->SendTouchEvent(GetClientId(), GetInstanceId(), pTouchEvent->eventType, pTouchEvent->timeStamp, pTouchEvent->x, pTouchEvent->y);
665                 delete pTouchEvent;
666         }
667         __pPendingTouchEventList->RemoveAll();
668 }
669
670 void
671 _AppWidgetContext::OnTouchEventReceived(buffer_event event, double timestamp, double x, double y)
672 {
673         if (__pAppContext->GetConnectionState() == CONNECTION_STATE_CONNECTED && __isRemoteBufferProxyCreated)
674         {
675                 SysLog(NID_SHELL, "%d, %f, %f", event, x, y);
676                 AppWidgetManagerService::GetInstance()->SendTouchEvent(GetClientId(), GetInstanceId(), event, timestamp, x, y);
677         }
678         else
679         {
680                 __pPendingTouchEventList->Add(new (nothrow) PendingTouchEvent(event, timestamp, x, y));
681
682                 if( AppManager::GetInstance()->IsRunning(this->GetAppId() ) == false ||
683                         ( __pAppContext->GetConnectionState() == CONNECTION_STATE_CONNECTED && __isRemoteBufferProxyCreated == false))
684                 {
685                         SysLog(NID_SHELL, "request to start AppControl");
686                         std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN() );
687
688                         // TODO: consider to remove these unused args.
689                         pArgs->Add(new (nothrow) String(ARG_KEY_EVENT_TYPE), new (nothrow) String(Integer::ToString(event)));
690                         pArgs->Add(new (nothrow) String(ARG_KEY_TIME_STAMP), new (nothrow) String(Double::ToString(timestamp)));
691                         pArgs->Add(new (nothrow) String(ARG_KEY_X), new (nothrow) String(Double::ToString(x)));
692                         pArgs->Add(new (nothrow) String(ARG_KEY_Y), new (nothrow) String(Double::ToString(y)));
693
694                         _AppWidgetRequestHelper::SendAppControlRequest(GetAppId(), APPWIDGET_ON_TOUCH, pArgs.get());
695                 }
696         }
697 }
698
699 result
700 _AppWidgetContext::SyncRemoteBuffer(int width, int height)
701 {
702         std::unique_ptr<char[]> providerId(_StringConverter::CopyToCharArrayN(GetProviderId()));
703         std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
704         std::unique_ptr<char[]> content_info(_StringConverter::CopyToCharArrayN(GetUserInfo()));
705
706         int ret = provider_send_updated(providerId.get(), id.get(), width, height, GetPriority(), content_info.get(), null);
707         SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "[E_SYSTEM] failed to provider_send_updated");
708
709         SendPendingTouchEvent();
710         SysLog(NID_SHELL, "Done");
711         return E_SUCCESS;
712 }
713
714 result
715 _AppWidgetContext::SendAccessStatus(int accessStatus) const
716 {
717         std::unique_ptr<char[]> providerId(_StringConverter::CopyToCharArrayN(GetProviderId()));
718         std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
719
720         int ret = provider_send_access_status(providerId.get(), id.get(), accessStatus);
721         SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "[E_SYSTEM] failed to provider_send_access_status");
722
723         return E_SUCCESS;
724 }
725
726 Tizen::Base::Collection::HashMap*
727 _AppWidgetContext::CreateRequestArgsN(void) const
728 {
729         HashMap* pArgs = new (nothrow) HashMap(SingleObjectDeleter);
730         pArgs->Construct();
731
732         pArgs->Add(new (nothrow) String(ARG_KEY_INSTANCE_ID), new (nothrow) String(GetInstanceId()));
733         pArgs->Add(new (nothrow) String(ARG_KEY_PROVIDER_NAME), new (nothrow) String(GetProviderName()));
734         pArgs->Add(new (nothrow) String(ARG_KEY_USER_INFO), new (nothrow) String(GetUserInfo()));
735         pArgs->Add(new (nothrow) String(ARG_KEY_WIDTH), new (nothrow) String(Integer::ToString(GetWidth())));
736         pArgs->Add(new (nothrow) String(ARG_KEY_HEIGHT), new (nothrow) String(Integer::ToString(GetHeight())));
737
738         return pArgs;
739 }
740
741 int
742 _AppWidgetContext::GetPeriod(void) const
743 {
744         return __updateMillis;
745 }
746
747 long long
748 _AppWidgetContext::GetLastUpdatedTime(void) const
749 {
750         return __lastUpdatedTime;
751 }
752
753 int
754 _AppWidgetContext::GetClientId(void) const
755 {
756         return GetAppContext()->GetClientId();
757 }
758
759 int
760 _AppWidgetContext::GetWidth(void) const
761 {
762         return __width;
763 }
764
765 void
766 _AppWidgetContext::SetWidth(int width)
767 {
768         __width = width;
769 }
770
771 int
772 _AppWidgetContext::GetHeight(void) const
773 {
774         return __height;
775 }
776
777 void
778 _AppWidgetContext::SetHeight(int height)
779 {
780         __height = height;
781 }
782
783 String
784 _AppWidgetContext::GetProviderId(void) const
785 {
786         return __providerId;
787 }
788
789 /*void
790 _AppWidgetContext::SetProviderId(const String& providerId)
791 {
792         __providerId = providerId;
793 }*/
794
795 String
796 _AppWidgetContext::GetAppId(void) const
797 {
798         return __appId;
799 }
800
801 int
802 _AppWidgetContext::GetPriority(void) const
803 {
804         return __priority;
805 }
806
807 /*void
808 _AppWidgetContext::SetPriority(int priority)
809 {
810         __priority = priority;
811 }*/
812
813 String
814 _AppWidgetContext::GetProviderName(void) const
815 {
816         return __providerName;
817 }
818
819 void
820 _AppWidgetContext::SetForeground(bool foreground)
821 {
822         __isForeground = foreground;
823 }
824
825 bool
826 _AppWidgetContext::IsForeground(void) const
827 {
828         return __isForeground;
829 }
830
831 String
832 _AppWidgetContext::GetUserInfo(void) const
833 {
834         return __userInfo;
835 }
836
837 /*void
838 _AppWidgetContext::SetUserInfo(const String& userInfo)
839 {
840         __userInfo = userInfo;
841 }*/
842
843 String
844 _AppWidgetContext::GetInstanceId(void) const
845 {
846         return __instanceId;
847 }
848
849 void
850 _AppWidgetContext::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
851 {
852         if (&timer == &__updateTimer)
853         {
854                 SysLog(NID_SHELL, "update timer is expired for appWidget app(%ls).", GetProviderId().GetPointer());
855                 OnUpdate(L"");
856         }
857 }
858
859 void
860 _AppWidgetContext::OnDisconnected(void)
861 {
862         SysSecureLog(NID_SHELL, "%ls, %ls", GetInstanceId().GetPointer(), GetProviderId().GetPointer());
863
864         __isRemoteBufferProxyCreated = false;
865         if (GetAppWidgetPopup())
866         {
867                 OnPopupDestoyed();
868         }
869 }
870
871 int
872 _AppWidgetContext::AcquireRemoteBuffer(int w, int h) const
873 {
874         int id = __pAppWidgetRemoteBuffer->Acquire(w, h);
875         if (id != -1)
876         {
877                 __isRemoteBufferProxyCreated = true;
878         }
879         return id;
880 }
881
882 }}}  // Tizen::Shell::App