2 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
18 * @file FShell_AppWidgetContext.cpp
19 * @brief This is the implementation for the _AppWidgetContext class.
23 #include <unique_ptr.h>
26 #include <FBaseSysLog.h>
27 #include <FSysSystemTime.h>
29 #include <FBase_StringConverter.h>
30 #include <FApp_AppManagerImpl.h>
31 #include "FShell_AppWidgetManagerImpl.h"
32 #include "FShell_AppWidgetManagerService.h"
33 #include "FShell_AppWidgetPopupContext.h"
34 #include "FShell_AppWidgetContext.h"
35 #include "FShell_AppWidgetContextHelper.h"
36 #include "FShell_AppWidgetRemoteBuffer.h"
38 namespace Tizen { namespace Shell { namespace App
42 using namespace Tizen::App;
43 using namespace Tizen::Base;
44 using namespace Tizen::Base::Collection;
45 using namespace Tizen::System;
47 const wchar_t ARG_KEY_INSTANCE_ID[] = L"_InstanceId";
48 const wchar_t ARG_KEY_PROVIDER_NAME[] = L"_ProviderName";
49 const wchar_t ARG_KEY_USER_INFO[] = L"_UserInfo";
50 const wchar_t ARG_KEY_X[] = L"_X";
51 const wchar_t ARG_KEY_Y[] = L"_Y";
52 const wchar_t ARG_KEY_WIDTH[] = L"_Width";
53 const wchar_t ARG_KEY_HEIGHT[] = L"_Height";
54 const wchar_t ARG_KEY_POPUP_WIDTH[] = L"_PopupWidth";
55 const wchar_t ARG_KEY_POPUP_HEIGHT[] = L"_PopupHeight";
56 const wchar_t ARG_KEY_ARGUMENT[] = L"_Argument";
57 const wchar_t ARG_KEY_EVENT_TYPE[] = L"_EventType";
58 const wchar_t ARG_KEY_TIME_STAMP[] = L"_TimeStamp";
60 const wchar_t APPWIDGET_ON_ADD[] = L"http://tizen.org/appcontrol/appwidget/add";
61 const wchar_t APPWIDGET_ON_REMOVE[] = L"http://tizen.org/appcontrol/appwidget/remove";
62 const wchar_t APPWIDGET_ON_UPDATE[] = L"http://tizen.org/appcontrol/appwidget/update";
63 const wchar_t APPWIDGET_ON_RESIZE[] = L"http://tizen.org/appcontrol/appwidget/resize";
64 const wchar_t APPWIDGET_ON_TOUCH[] = L"http://tizen.org/appcontrol/appwidget/touch";
66 const int UPDATE_PERIOD_MSEC_MIN = 1800000; // 30min
69 _AppWidgetContext::_AppWidgetContext(_AppContext* pAppContext, const String& instanceId, const String& providerId, int width, int height, const Tizen::Base::String& userInfo, int period, int priority)
70 :__instanceId(instanceId)
71 ,__providerId(providerId)
72 ,__appId(_AppWidgetHelper::ExtractAppId(providerId))
73 ,__providerName(_AppWidgetHelper::ExtractProviderName(providerId))
78 ,__updateMillis( (period > UPDATE_PERIOD_MSEC_MIN) ? period : UPDATE_PERIOD_MSEC_MIN )
81 ,__isRemoteBufferProxyCreated(false)
83 ,__hasPendingRequest(false)
84 ,__pAppContext(pAppContext)
85 ,__pAppWidgetPopup(null)
86 ,__pAppWidgetRemoteBuffer(null)
87 ,__pPendingTouchEventList(null)
89 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);
91 // for updating period
92 if (__updateMillis > 0)
94 SystemTime::GetTicks(this->__lastUpdatedTime);
96 result r = __updateTimer.Construct(*this);
97 SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "");
99 r = __updateTimer.StartAsRepeatable(__updateMillis);
100 SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "");
103 __pPendingTouchEventList = new (nothrow) ArrayListT<PendingTouchEvent*>();
104 SysTryReturnVoidResult(NID_SHELL, __pPendingTouchEventList, E_OUT_OF_MEMORY, "");
105 __pPendingTouchEventList->Construct();
107 __pAppWidgetRemoteBuffer = new (nothrow) _AppWidgetRemoteBuffer(providerId, instanceId, TYPE_LB, this);
108 SysTryReturnVoidResult(NID_SHELL, __pAppWidgetRemoteBuffer, E_OUT_OF_MEMORY, "");
111 _AppWidgetContext::~_AppWidgetContext(void)
113 SysSecureLog(NID_SHELL, "appId(%ls), instanceId(%ls), width(%d), height(%d), priority(%d)", GetProviderId().GetPointer(), GetInstanceId().GetPointer(), GetWidth(), GetHeight(), GetPriority());
115 __updateTimer.Cancel();
117 if (__pAppWidgetPopup)
119 SysLog(NID_SHELL, "Destroying dangling AppWidgetPopup instance..");
120 delete __pAppWidgetPopup;
123 if (__pPendingTouchEventList)
125 for (int i = 0; i < __pPendingTouchEventList->GetCount(); i++)
127 PendingTouchEvent* pTouchEvent = null;
128 __pPendingTouchEventList->GetAt(i, pTouchEvent);
131 __pPendingTouchEventList->RemoveAll();
132 delete __pPendingTouchEventList;
135 if (__pAppWidgetRemoteBuffer)
137 delete __pAppWidgetRemoteBuffer;
142 _AppWidgetContext::GetAppContext(void) const
144 return __pAppContext;
147 _AppWidgetPopupContext*
148 _AppWidgetContext::GetAppWidgetPopup(void) const
150 return __pAppWidgetPopup;
154 _AppWidgetContext::OnAdded(void)
156 SendAddRequest(GetWidth(), GetHeight());
160 _AppWidgetContext::OnRemoved(bool isTriggeredByViewer)
162 if (isTriggeredByViewer)
164 return SendRemoveRequest();
168 std::unique_ptr<char[]> providerId(_StringConverter::CopyToCharArrayN(GetProviderId()));
169 std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
171 int ret = provider_send_deleted(providerId.get(), id.get());
172 SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "Failed to execute provider_send_deleted.");
178 _AppWidgetContext::OnUpdate(const String& argument)
180 SysLog(NID_SHELL, "argument(%ls)", argument.GetPointer());
183 if (this->IsForeground())
185 result r = this->SendUpdateRequest(GetWidth(), GetHeight(), argument);
186 SysTryLog(NID_SHELL, !IsFailed(r), "Failed to execute SendUpdateRequest.");
188 SystemTime::GetTicks(this->__lastUpdatedTime);
189 SysLog(NID_SHELL, "The last updated time is %lld.", this->__lastUpdatedTime);
191 __hasPendingRequest = false;
192 __pendingArgument.Clear();
196 // Queueing the pointer of background context.
197 if (!argument.IsEmpty())
199 __pendingArgument = argument;
202 __hasPendingRequest = true;
203 SysLog(NID_SHELL, "Update is requested but the %ls is background.", (this->GetProviderId()).GetPointer());
208 _AppWidgetContext::OnUpdateAsync(_AppContext* pAppContext, const String& argument)
210 ArrayList* pArray = new (std::nothrow) ArrayList();
211 SysTryReturnResult(NID_SHELL, pArray, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
214 pArray->Add(pAppContext);
216 pArray->Add(new String(argument));
218 result r = Tizen::App::App::GetInstance()->SendUserEvent(LOCAL_EVENT_REQUEST_UPDATE, pArray);
219 SysTryLog(NID_SHELL, !IsFailed(r), "[%s] Propagated.", GetErrorMessage(r));
220 SysLog(NID_SHELL, "UserEvent(%d) is sent for '%ls.%ls'.", LOCAL_EVENT_REQUEST_UPDATE, GetAppId().GetPointer(), GetProviderName().GetPointer() );
226 _AppWidgetContext::OnResize(int width, int height)
228 SysSecureLog(NID_SHELL, "appId(%ls), instanceId(%ls), width(%d->%d), height(%d->%d)", GetProviderId().GetPointer(), GetInstanceId().GetPointer(), GetWidth(), width, GetHeight(), height);
233 SendResizeRequest(width, height);
237 _AppWidgetContext::OnForeground(void)
241 SysLog(NID_SHELL, "%ls is already foreground.", (this->GetAppId()).GetPointer());
245 __isForeground = true;
247 if (__hasPendingRequest == true)
249 SysLog(NID_SHELL, "There is pending request.");
250 OnUpdateAsync(__pAppContext, __pendingArgument);
254 if (IsUpdatePeriodExpired() == true)
256 SysLog(NID_SHELL, "The period is expired.");
257 OnUpdateAsync(__pAppContext, L"");
263 _AppWidgetContext::IsUpdatePeriodExpired(void) const
265 if (this->GetPeriod() <= 0)
270 long long currentTicks = 0;
271 SystemTime::GetTicks(currentTicks);
273 SysLog(NID_SHELL, "current[%lld] - last updated time[%lld] = [%lld], period[%d]",
274 currentTicks, this->GetLastUpdatedTime(), currentTicks - this->GetLastUpdatedTime(), this->GetPeriod());
276 bool isPeriodExpired = (currentTicks - this->GetLastUpdatedTime()) >= (this->GetPeriod());
277 return isPeriodExpired;
281 _AppWidgetContext::OnBackground(void)
285 SysLog(NID_SHELL, "%ls is already background.", (this->GetAppId()).GetPointer());
289 SysLog(NID_SHELL, "OnBackground");
290 __isForeground = false;
294 _AppWidgetContext::OnPopupCreated(double x, double y, int width, int height)
296 __pAppWidgetPopup = new (nothrow) _AppWidgetPopupContext(this);
297 SysTryReturnVoidResult(NID_SHELL, __pAppWidgetPopup, E_OUT_OF_MEMORY, "");
299 __pAppWidgetPopup->OnPopupCreated(x, y, width, height);
303 _AppWidgetContext::OnPopupDestoyed(void)
305 SysLog(NID_SHELL, "");
307 if (__pAppWidgetPopup)
309 delete __pAppWidgetPopup;
310 __pAppWidgetPopup = null;
315 _AppWidgetContext::SendAddRequest(int width, int height) const
317 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
319 return __pAppContext->SendRequestToApp(GetAppId(), APPWIDGET_ON_ADD, pArgs.release());
323 _AppWidgetContext::SendUpdateRequest(int width, int height, const String& argument) const
325 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
327 pArgs->Add(new (nothrow) String(ARG_KEY_ARGUMENT), new (nothrow) String(argument));
329 return __pAppContext->SendRequestToApp(GetAppId(), APPWIDGET_ON_UPDATE, pArgs.release());
333 _AppWidgetContext::SendResizeRequest(int width, int height) const
335 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN() );
337 return __pAppContext->SendRequestToApp(GetAppId(), APPWIDGET_ON_RESIZE, pArgs.release());
341 _AppWidgetContext::SendRemoveRequest(void) const
343 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
345 return __pAppContext->SendRequestToApp(GetAppId(), APPWIDGET_ON_REMOVE, pArgs.release());
349 _AppWidgetContext::SendPendingTouchEvent(void)
351 for (int i =0; i< __pPendingTouchEventList->GetCount(); i++)
353 PendingTouchEvent* pTouchEvent = null;
354 __pPendingTouchEventList->GetAt(i, pTouchEvent);
355 AppWidgetManagerService::GetInstance()->SendTouchEvent(GetClientId(), GetInstanceId(), pTouchEvent->eventType, pTouchEvent->timeStamp, pTouchEvent->x, pTouchEvent->y);
358 __pPendingTouchEventList->RemoveAll();
362 _AppWidgetContext::OnTouchEventReceived(buffer_event event, double timestamp, double x, double y)
364 if (__pAppContext->GetConnectionState() == CONNECTION_STATE_CONNECTED && __isRemoteBufferProxyCreated)
366 SysLog(NID_SHELL, "%d, %f, %f", event, x, y);
367 AppWidgetManagerService::GetInstance()->SendTouchEvent(GetClientId(), GetInstanceId(), event, timestamp, x, y);
371 __pPendingTouchEventList->Add(new (nothrow) PendingTouchEvent(event, timestamp, x, y));
373 if( _AppManagerImpl::GetInstance()->IsRunning(this->GetAppId() ) == false ||
374 ( __pAppContext->GetConnectionState() == CONNECTION_STATE_CONNECTED && __isRemoteBufferProxyCreated == false))
376 SysLog(NID_SHELL, "request to start AppControl");
377 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN() );
379 // TODO: consider to remove these unused args.
380 pArgs->Add(new (nothrow) String(ARG_KEY_EVENT_TYPE), new (nothrow) String(Integer::ToString(event)));
381 pArgs->Add(new (nothrow) String(ARG_KEY_TIME_STAMP), new (nothrow) String(Double::ToString(timestamp)));
382 pArgs->Add(new (nothrow) String(ARG_KEY_X), new (nothrow) String(Double::ToString(x)));
383 pArgs->Add(new (nothrow) String(ARG_KEY_Y), new (nothrow) String(Double::ToString(y)));
385 _AppWidgetRequestHelper::SendAppControlRequest(GetAppId(), APPWIDGET_ON_TOUCH, pArgs.get());
391 _AppWidgetContext::SyncRemoteBuffer(int width, int height)
393 std::unique_ptr<char[]> providerId(_StringConverter::CopyToCharArrayN(GetProviderId()));
394 std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
395 std::unique_ptr<char[]> content_info(_StringConverter::CopyToCharArrayN(GetUserInfo()));
397 int ret = provider_send_updated(providerId.get(), id.get(), width, height, GetPriority(), content_info.get(), null);
398 SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "[E_SYSTEM] failed to provider_send_updated");
400 SendPendingTouchEvent();
401 SysLog(NID_SHELL, "Done");
406 _AppWidgetContext::SyncRemoteBufferForPD(void) const
408 _AppWidgetPopupContext* pPopupContext = GetAppWidgetPopup();
409 SysSecureTryReturnResult(NID_SHELL, pPopupContext , E_SYSTEM, "pPopupContext is null for (%ls)", GetProviderId().GetPointer());
411 return pPopupContext->SyncRemoteBuffer();
415 _AppWidgetContext::SendAccessStatus(int accessStatus) const
417 std::unique_ptr<char[]> providerId(_StringConverter::CopyToCharArrayN(GetProviderId()));
418 std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
420 int ret = provider_send_access_status(providerId.get(), id.get(), accessStatus);
421 SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "[E_SYSTEM] failed to provider_send_access_status");
426 Tizen::Base::Collection::HashMap*
427 _AppWidgetContext::CreateRequestArgsN(void) const
429 HashMap* pArgs = new (nothrow) HashMap(SingleObjectDeleter);
432 pArgs->Add(new (nothrow) String(ARG_KEY_INSTANCE_ID), new (nothrow) String(GetInstanceId()));
433 pArgs->Add(new (nothrow) String(ARG_KEY_PROVIDER_NAME), new (nothrow) String(GetProviderName()));
434 pArgs->Add(new (nothrow) String(ARG_KEY_USER_INFO), new (nothrow) String(GetUserInfo()));
435 pArgs->Add(new (nothrow) String(ARG_KEY_WIDTH), new (nothrow) String(Integer::ToString(GetWidth())));
436 pArgs->Add(new (nothrow) String(ARG_KEY_HEIGHT), new (nothrow) String(Integer::ToString(GetHeight())));
442 _AppWidgetContext::GetPeriod(void) const
444 return __updateMillis;
448 _AppWidgetContext::GetLastUpdatedTime(void) const
450 return __lastUpdatedTime;
454 _AppWidgetContext::GetClientId(void) const
456 return GetAppContext()->GetClientId();
460 _AppWidgetContext::GetWidth(void) const
466 _AppWidgetContext::SetWidth(int width)
472 _AppWidgetContext::GetHeight(void) const
478 _AppWidgetContext::SetHeight(int height)
484 _AppWidgetContext::GetProviderId(void) const
490 _AppWidgetContext::SetProviderId(const String& providerId)
492 __providerId = providerId;
496 _AppWidgetContext::GetAppId(void) const
502 _AppWidgetContext::GetPriority(void) const
508 _AppWidgetContext::SetPriority(int priority)
510 __priority = priority;
514 _AppWidgetContext::GetProviderName(void) const
516 return __providerName;
520 _AppWidgetContext::IsForeground(void) const
522 return __isForeground;
526 _AppWidgetContext::GetUserInfo(void) const
532 _AppWidgetContext::SetUserInfo(const String& userInfo)
534 __userInfo = userInfo;
538 _AppWidgetContext::GetInstanceId(void) const
544 _AppWidgetContext::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
546 if (&timer == &__updateTimer)
548 SysLog(NID_SHELL, "update timer is expired for appWidget app(%ls).", GetProviderId().GetPointer());
554 _AppWidgetContext::OnDisconnected(void)
556 SysSecureLog(NID_SHELL, "%ls, %ls", GetInstanceId().GetPointer(), GetProviderId().GetPointer());
558 __isRemoteBufferProxyCreated = false;
559 if (GetAppWidgetPopup())
566 _AppWidgetContext::AcquireRemoteBuffer(int w, int h) const
568 int id = __pAppWidgetRemoteBuffer->Acquire(w, h);
571 __isRemoteBufferProxyCreated = true;
577 _AppWidgetContext::AcquireRemoteBufferForPD(int w, int h) const
579 _AppWidgetPopupContext* pPopupContext = GetAppWidgetPopup();
580 SysSecureTryReturnResult(NID_SHELL, pPopupContext , E_SYSTEM, "pPopupContext is null for (%ls)", GetProviderId().GetPointer());
582 int bufferId = pPopupContext->AcquireRemoteBuffer(w, h);
583 SysSecureTryReturnResult(NID_SHELL, bufferId != -1, E_SYSTEM, "Failed to AcquireRemoteBuffer for (%ls)", GetProviderId().GetPointer());
588 }}} // Tizen::Shell::App