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_AppWidgetManagerService.h"
32 #include "FShell_AppWidgetPopupContext.h"
33 #include "FShell_AppWidgetContext.h"
34 #include "FShell_AppWidgetContextHelper.h"
35 #include "FShell_AppWidgetRemoteBuffer.h"
37 namespace Tizen { namespace Shell { namespace App
41 using namespace Tizen::App;
42 using namespace Tizen::Base;
43 using namespace Tizen::Base::Collection;
44 using namespace Tizen::System;
46 const wchar_t ARG_KEY_INSTANCE_ID[] = L"_InstanceId";
47 const wchar_t ARG_KEY_PROVIDER_NAME[] = L"_ProviderName";
48 const wchar_t ARG_KEY_USER_INFO[] = L"_UserInfo";
49 const wchar_t ARG_KEY_X[] = L"_X";
50 const wchar_t ARG_KEY_Y[] = L"_Y";
51 const wchar_t ARG_KEY_WIDTH[] = L"_Width";
52 const wchar_t ARG_KEY_HEIGHT[] = L"_Height";
53 const wchar_t ARG_KEY_POPUP_WIDTH[] = L"_PopupWidth";
54 const wchar_t ARG_KEY_POPUP_HEIGHT[] = L"_PopupHeight";
55 const wchar_t ARG_KEY_ARGUMENT[] = L"_Argument";
56 const wchar_t ARG_KEY_EVENT_TYPE[] = L"_EventType";
57 const wchar_t ARG_KEY_TIME_STAMP[] = L"_TimeStamp";
59 const wchar_t APPWIDGET_ON_ADD[] = L"http://tizen.org/appcontrol/appwidget/add";
60 const wchar_t APPWIDGET_ON_REMOVE[] = L"http://tizen.org/appcontrol/appwidget/remove";
61 const wchar_t APPWIDGET_ON_UPDATE[] = L"http://tizen.org/appcontrol/appwidget/update";
62 const wchar_t APPWIDGET_ON_RESIZE[] = L"http://tizen.org/appcontrol/appwidget/resize";
63 const wchar_t APPWIDGET_ON_TOUCH[] = L"http://tizen.org/appcontrol/appwidget/touch";
65 const int UPDATE_PERIOD_MSEC_MIN = 1800000; // 30min
68 _AppWidgetContext::_AppWidgetContext(_AppContext* pAppContext, const String& instanceId, const String& providerId, int width, int height, const Tizen::Base::String& userInfo, int period)
69 :__instanceId(instanceId)
70 ,__providerId(providerId)
71 ,__appId(_AppWidgetHelper::ExtractAppId(providerId))
72 ,__providerName(_AppWidgetHelper::ExtractProviderName(providerId))
76 ,__updateMillis( (period > UPDATE_PERIOD_MSEC_MIN) ? period : UPDATE_PERIOD_MSEC_MIN )
79 ,__isRemoteBufferProxyCreated(false)
81 ,__hasPendingRequest(false)
82 ,__pAppContext(pAppContext)
83 ,__pAppWidgetPopup(null)
84 ,__pAppWidgetRemoteBuffer(null)
85 ,__pPendingTouchEventList(null)
87 SysSecureLog(NID_SHELL, "appId(%ls), providerId(%ls), instanceId(%ls), width(%d), height(%d), period(%d)", __appId.GetPointer(), __providerId.GetPointer(), __instanceId.GetPointer(), __width, __height, __updateMillis);
89 // for updating period
90 if (__updateMillis > 0)
92 SystemTime::GetTicks(this->__lastUpdatedTime);
94 result r = __updateTimer.Construct(*this);
95 SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "");
97 r = __updateTimer.StartAsRepeatable(__updateMillis);
98 SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "");
101 __pPendingTouchEventList = new (nothrow) ArrayListT<PendingTouchEvent*>();
102 SysTryReturnVoidResult(NID_SHELL, __pPendingTouchEventList, E_OUT_OF_MEMORY, "");
103 __pPendingTouchEventList->Construct();
105 __pAppWidgetRemoteBuffer = new (nothrow) _AppWidgetRemoteBuffer(providerId, instanceId, TYPE_LB, this);
106 SysTryReturnVoidResult(NID_SHELL, __pAppWidgetRemoteBuffer, E_OUT_OF_MEMORY, "");
109 _AppWidgetContext::~_AppWidgetContext(void)
111 SysSecureLog(NID_SHELL, "appId(%ls), instanceId(%ls), width(%d), height(%d)", GetProviderId().GetPointer(), GetInstanceId().GetPointer(), GetWidth(), GetHeight());
113 __updateTimer.Cancel();
115 if (__pAppWidgetPopup)
117 SysLog(NID_SHELL, "Destroying dangling AppWidgetPopup instance..");
118 delete __pAppWidgetPopup;
121 if (__pPendingTouchEventList)
123 for (int i = 0; i < __pPendingTouchEventList->GetCount(); i++)
125 PendingTouchEvent* pTouchEvent = null;
126 __pPendingTouchEventList->GetAt(i, pTouchEvent);
129 __pPendingTouchEventList->RemoveAll();
130 delete __pPendingTouchEventList;
133 if (__pAppWidgetRemoteBuffer)
135 delete __pAppWidgetRemoteBuffer;
140 _AppWidgetContext::GetAppContext(void) const
142 return __pAppContext;
145 _AppWidgetPopupContext*
146 _AppWidgetContext::GetAppWidgetPopup(void) const
148 return __pAppWidgetPopup;
152 _AppWidgetContext::OnAdded(void)
154 SendAddRequest(GetWidth(), GetHeight());
158 _AppWidgetContext::OnRemoved(bool isTriggeredByViewer)
160 if (isTriggeredByViewer)
162 return SendRemoveRequest();
166 std::unique_ptr<char[]> providerId(_StringConverter::CopyToCharArrayN(GetProviderId()));
167 std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
169 int ret = provider_send_deleted(providerId.get(), id.get());
170 SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "Failed to execute provider_send_deleted.");
176 _AppWidgetContext::OnUpdate(const String& argument)
180 if (this->IsForeground())
182 result r = this->SendUpdateRequest(GetWidth(), GetHeight(), argument);
183 SysTryLog(NID_SHELL, !IsFailed(r), "Failed to execute SendUpdateRequest.");
185 SystemTime::GetTicks(this->__lastUpdatedTime);
186 SysLog(NID_SHELL, "Updated with argument(%ls), The last updated time is %lld.", argument.GetPointer(), this->__lastUpdatedTime);
188 __hasPendingRequest = false;
189 __pendingArgument.Clear();
193 // Queueing the pointer of background context.
194 if (!argument.IsEmpty())
196 __pendingArgument = argument;
199 __hasPendingRequest = true;
200 SysLog(NID_SHELL, "Update pending. The %ls is background. argument(%ls), ", argument.GetPointer(), GetProviderId().GetPointer());
205 _AppWidgetContext::OnUpdateAsync(_AppContext* pAppContext, const String& argument)
207 ArrayList* pArray = new (std::nothrow) ArrayList();
208 SysTryReturnResult(NID_SHELL, pArray, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
211 pArray->Add(pAppContext);
213 pArray->Add(new String(argument));
215 result r = Tizen::App::App::GetInstance()->SendUserEvent(LOCAL_EVENT_REQUEST_UPDATE, pArray);
216 SysTryLog(NID_SHELL, !IsFailed(r), "[%s] Propagated.", GetErrorMessage(r));
217 SysLog(NID_SHELL, "Local event is sent for '%ls.%ls'.", GetAppId().GetPointer(), GetProviderName().GetPointer() );
223 _AppWidgetContext::OnResize(int width, int height)
225 SysSecureLog(NID_SHELL, "appId(%ls), instanceId(%ls), width(%d->%d), height(%d->%d)", GetProviderId().GetPointer(), GetInstanceId().GetPointer(), GetWidth(), width, GetHeight(), height);
230 SendResizeRequest(width, height);
234 _AppWidgetContext::OnForeground(void)
238 SysLog(NID_SHELL, "%ls is already foreground.", (this->GetAppId()).GetPointer());
242 __isForeground = true;
244 if (__hasPendingRequest == true)
246 SysLog(NID_SHELL, "There is pending request.");
247 OnUpdateAsync(__pAppContext, __pendingArgument);
251 if (IsUpdatePeriodExpired() == true)
253 SysLog(NID_SHELL, "The period is expired.");
254 OnUpdateAsync(__pAppContext, L"");
260 _AppWidgetContext::IsUpdatePeriodExpired(void) const
262 if (this->GetPeriod() <= 0)
267 long long currentTicks = 0;
268 SystemTime::GetTicks(currentTicks);
270 SysLog(NID_SHELL, "current[%lld] - last updated time[%lld] = [%lld], period[%d]",
271 currentTicks, this->GetLastUpdatedTime(), currentTicks - this->GetLastUpdatedTime(), this->GetPeriod());
273 bool isPeriodExpired = (currentTicks - this->GetLastUpdatedTime()) >= (this->GetPeriod());
274 return isPeriodExpired;
278 _AppWidgetContext::OnBackground(void)
282 SysLog(NID_SHELL, "%ls is already background.", (this->GetAppId()).GetPointer());
286 SysLog(NID_SHELL, "OnBackground");
287 __isForeground = false;
291 _AppWidgetContext::OnPopupCreated(double x, double y, int width, int height)
293 __pAppWidgetPopup = new (nothrow) _AppWidgetPopupContext(this);
294 SysTryReturnVoidResult(NID_SHELL, __pAppWidgetPopup, E_OUT_OF_MEMORY, "");
296 __pAppWidgetPopup->OnPopupCreated(x, y, width, height);
300 _AppWidgetContext::OnPopupDestoyed(void)
302 SysLog(NID_SHELL, "");
304 if (__pAppWidgetPopup)
306 delete __pAppWidgetPopup;
307 __pAppWidgetPopup = null;
312 _AppWidgetContext::SendAddRequest(int width, int height) const
314 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
315 _AppContext::Request* pRequest = new _AppContext::Request(APPWIDGET_ON_ADD, pArgs.release());
316 return __pAppContext->SendRequestToApp(GetAppId(), pRequest);
320 _AppWidgetContext::SendUpdateRequest(int width, int height, const String& argument) const
322 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
323 pArgs->Add(new (nothrow) String(ARG_KEY_ARGUMENT), new (nothrow) String(argument));
324 _AppContext::Request* pRequest = new _AppContext::Request(APPWIDGET_ON_UPDATE, pArgs.release());
325 return __pAppContext->SendRequestToApp(GetAppId(), pRequest);
329 _AppWidgetContext::SendResizeRequest(int width, int height) const
331 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN() );
332 _AppContext::Request* pRequest = new _AppContext::Request(APPWIDGET_ON_RESIZE, pArgs.release());
333 return __pAppContext->SendRequestToApp(GetAppId(), pRequest);
337 _AppWidgetContext::SendRemoveRequest(void) const
339 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
340 _AppContext::Request* pRequest = new _AppContext::Request(APPWIDGET_ON_REMOVE, pArgs.release());
341 return __pAppContext->SendRequestToApp(GetAppId(), pRequest);
345 _AppWidgetContext::SendPendingTouchEvent(void)
347 for (int i =0; i< __pPendingTouchEventList->GetCount(); i++)
349 PendingTouchEvent* pTouchEvent = null;
350 __pPendingTouchEventList->GetAt(i, pTouchEvent);
351 AppWidgetManagerService::GetInstance()->SendTouchEvent(GetClientId(), GetInstanceId(), pTouchEvent->eventType, pTouchEvent->timeStamp, pTouchEvent->x, pTouchEvent->y);
354 __pPendingTouchEventList->RemoveAll();
358 _AppWidgetContext::OnTouchEventReceived(buffer_event event, double timestamp, double x, double y)
360 if (__pAppContext->GetConnectionState() == CONNECTION_STATE_CONNECTED && __isRemoteBufferProxyCreated)
362 SysLog(NID_SHELL, "%d, %f, %f", event, x, y);
363 AppWidgetManagerService::GetInstance()->SendTouchEvent(GetClientId(), GetInstanceId(), event, timestamp, x, y);
367 __pPendingTouchEventList->Add(new (nothrow) PendingTouchEvent(event, timestamp, x, y));
369 if( _AppManagerImpl::GetInstance()->IsRunning(this->GetAppId() ) == false ||
370 ( __pAppContext->GetConnectionState() == CONNECTION_STATE_CONNECTED && __isRemoteBufferProxyCreated == false))
372 SysLog(NID_SHELL, "request to start AppControl");
373 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN() );
375 // TODO: consider to remove these unused args.
376 pArgs->Add(new (nothrow) String(ARG_KEY_EVENT_TYPE), new (nothrow) String(Integer::ToString(event)));
377 pArgs->Add(new (nothrow) String(ARG_KEY_TIME_STAMP), new (nothrow) String(Double::ToString(timestamp)));
378 pArgs->Add(new (nothrow) String(ARG_KEY_X), new (nothrow) String(Double::ToString(x)));
379 pArgs->Add(new (nothrow) String(ARG_KEY_Y), new (nothrow) String(Double::ToString(y)));
381 _AppWidgetRequestHelper::SendAppControlRequest(GetAppId(), APPWIDGET_ON_TOUCH, pArgs.get());
387 _AppWidgetContext::SyncRemoteBuffer(int width, int height)
389 result r = __pAppWidgetRemoteBuffer->Sync(width, height, GetUserInfo());
390 SysSecureTryReturnResult(NID_SHELL, !IsFailed(r) , r, "Failed to sync (%ls)", GetProviderId().GetPointer());
392 SendPendingTouchEvent();
397 _AppWidgetContext::SyncRemoteBufferForPD(void) const
399 _AppWidgetPopupContext* pPopupContext = GetAppWidgetPopup();
400 SysSecureTryReturnResult(NID_SHELL, pPopupContext , E_SYSTEM, "pPopupContext is null for (%ls)", GetProviderId().GetPointer());
402 return pPopupContext->SyncRemoteBuffer();
406 _AppWidgetContext::SendAccessStatus(int accessStatus) const
408 return __pAppWidgetRemoteBuffer->SendAccessStatus(accessStatus);
411 Tizen::Base::Collection::HashMap*
412 _AppWidgetContext::CreateRequestArgsN(void) const
414 HashMap* pArgs = new (nothrow) HashMap(SingleObjectDeleter);
417 pArgs->Add(new (nothrow) String(ARG_KEY_INSTANCE_ID), new (nothrow) String(GetInstanceId()));
418 pArgs->Add(new (nothrow) String(ARG_KEY_PROVIDER_NAME), new (nothrow) String(GetProviderName()));
419 pArgs->Add(new (nothrow) String(ARG_KEY_USER_INFO), new (nothrow) String(GetUserInfo()));
420 pArgs->Add(new (nothrow) String(ARG_KEY_WIDTH), new (nothrow) String(Integer::ToString(GetWidth())));
421 pArgs->Add(new (nothrow) String(ARG_KEY_HEIGHT), new (nothrow) String(Integer::ToString(GetHeight())));
427 _AppWidgetContext::GetPeriod(void) const
429 return __updateMillis;
433 _AppWidgetContext::GetLastUpdatedTime(void) const
435 return __lastUpdatedTime;
439 _AppWidgetContext::GetClientId(void) const
441 return GetAppContext()->GetClientId();
445 _AppWidgetContext::GetWidth(void) const
451 _AppWidgetContext::SetWidth(int width)
457 _AppWidgetContext::GetHeight(void) const
463 _AppWidgetContext::SetHeight(int height)
469 _AppWidgetContext::GetProviderId(void) const
475 _AppWidgetContext::SetProviderId(const String& providerId)
477 __providerId = providerId;
481 _AppWidgetContext::GetAppId(void) const
487 _AppWidgetContext::GetProviderName(void) const
489 return __providerName;
493 _AppWidgetContext::IsForeground(void) const
495 return __isForeground;
499 _AppWidgetContext::GetUserInfo(void) const
505 _AppWidgetContext::SetUserInfo(const String& userInfo)
507 __userInfo = userInfo;
511 _AppWidgetContext::GetInstanceId(void) const
517 _AppWidgetContext::IsActive(void) const
519 return __isRemoteBufferProxyCreated;
523 _AppWidgetContext::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
525 if (&timer == &__updateTimer)
527 SysLog(NID_SHELL, "update timer is expired for appWidget app(%ls).", GetProviderId().GetPointer());
533 _AppWidgetContext::OnDisconnected(void)
535 SysSecureLog(NID_SHELL, "%ls, %ls", GetInstanceId().GetPointer(), GetProviderId().GetPointer());
537 __isRemoteBufferProxyCreated = false;
538 if (GetAppWidgetPopup())
545 _AppWidgetContext::AcquireRemoteBuffer(int w, int h) const
547 int id = __pAppWidgetRemoteBuffer->Acquire(w, h);
550 __isRemoteBufferProxyCreated = true;
556 _AppWidgetContext::AcquireRemoteBufferForPD(int w, int h) const
558 _AppWidgetPopupContext* pPopupContext = GetAppWidgetPopup();
559 SysSecureTryReturnResult(NID_SHELL, pPopupContext , E_SYSTEM, "pPopupContext is null for (%ls)", GetProviderId().GetPointer());
561 int bufferId = pPopupContext->AcquireRemoteBuffer(w, h);
562 SysSecureTryReturnResult(NID_SHELL, bufferId != -1, E_SYSTEM, "Failed to AcquireRemoteBuffer for (%ls)", GetProviderId().GetPointer());
567 }}} // Tizen::Shell::App