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>
25 #include <FBaseSysLog.h>
26 #include <FBaseInteger.h>
27 #include <FBaseDouble.h>
28 #include <FBaseColHashMap.h>
29 #include <FBaseColAllElementsDeleter.h>
30 #include <FSysSystemTime.h>
31 #include <FAppAppManager.h>
33 #include <FBase_StringConverter.h>
34 #include "FShell_AppWidgetManagerService.h"
35 #include "FShell_AppWidgetPopupContext.h"
36 #include "FShell_AppWidgetContext.h"
37 #include "FShell_AppWidgetContextHelper.h"
39 namespace Tizen { namespace Shell { namespace App
43 using namespace Tizen::App;
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::System;
48 const String APPWIDGET_ON_ADD = L"http://tizen.org/appcontrol/appwidget/add";
49 const String APPWIDGET_ON_REMOVE = L"http://tizen.org/appcontrol/appwidget/remove";
50 const String APPWIDGET_ON_UPDATE = L"http://tizen.org/appcontrol/appwidget/update";
51 const String APPWIDGET_ON_RESIZE = L"http://tizen.org/appcontrol/appwidget/resize";
52 const String APPWIDGET_ON_TOUCH = L"http://tizen.org/appcontrol/appwidget/touch";
54 const int UPDATE_PERIOD_MSEC_MIN = 1800000; // 30min
56 _AppWidgetContext::_AppWidgetContext(_AppContext* pAppContext, const String& info, const String& providerId, const String& instanceId, int width, int height, int period, int priority)
57 :_AppWidgetContextBase(TYPE_LB, info, providerId, instanceId, width, height, priority)
58 ,__pAppWidgetPopup(null)
59 ,__updateMillis(period)
61 ,__pPendingTouchEventList(null)
62 ,__hasPendingRequest(false)
63 ,__pAppContext(pAppContext)
64 ,__pPendingEventList(null)
66 // for updating period
67 if (__updateMillis > 0)
69 __updateMillis = (__updateMillis > UPDATE_PERIOD_MSEC_MIN) ? __updateMillis : UPDATE_PERIOD_MSEC_MIN;
70 SysLog(NID_SHELL, "period(%d)", __updateMillis);
72 SystemTime::GetTicks(this->__lastUpdatedTime);
74 __updateTimer.Construct(*this);
75 __updateTimer.StartAsRepeatable(__updateMillis);
78 __pPendingTouchEventList = new (nothrow) ArrayListT<PendingTouchEvent*>();
79 __pPendingTouchEventList->Construct();
81 __pPendingEventList = new (nothrow) ArrayListT<PendingEvent*>();
82 __pPendingEventList->Construct();
85 _AppWidgetContext::~_AppWidgetContext(void)
87 SysSecureLog(NID_SHELL, "appId(%ls), instanceId(%ls), width(%d), height(%d), priority(%d)", GetProviderId().GetPointer(), GetInstanceId().GetPointer(), GetWidth(), GetHeight(), GetPriority());
89 __updateTimer.Cancel();
91 if (__pAppWidgetPopup)
93 SysLog(NID_SHELL, "Destroying dangling AppWidgetPopup instance..");
94 __pAppWidgetPopup->OnPopupDestoyed();
95 delete __pAppWidgetPopup;
98 if (__pPendingTouchEventList)
100 for (int i = 0; i < __pPendingTouchEventList->GetCount(); i++)
102 PendingTouchEvent* pTouchEvent = null;
103 __pPendingTouchEventList->GetAt(i, pTouchEvent);
106 __pPendingTouchEventList->RemoveAll();
107 delete __pPendingTouchEventList;
110 if (__pPendingEventList)
112 for (int i = 0; i < __pPendingEventList->GetCount(); i++)
114 PendingEvent* pEvent = null;
115 __pPendingEventList->GetAt(i, pEvent);
118 __pPendingEventList->RemoveAll();
119 delete __pPendingEventList;
124 _AppWidgetContext::GetAppContext(void) const
126 return __pAppContext;
129 _AppWidgetPopupContext*
130 _AppWidgetContext::GetAppWidgetPopup(void) const
132 return __pAppWidgetPopup;
136 _AppWidgetContext::OnAdded(void)
138 SendAddRequest(GetWidth(), GetHeight());
142 _AppWidgetContext::OnRemoved(void)
144 return SendRemoveRequest();
148 _AppWidgetContext::OnUpdate(const String& argument)
152 AppWidgetManagerService* pMgrService = AppWidgetManagerService::GetInstance();
153 SysTryReturnVoidResult(NID_SHELL, pMgrService, E_SYSTEM, "[E_SYSTEM] Failed to get an instance of AppWidgetManagerService.");
155 // Queueing the pointer of paused context.
156 if (this->IsPaused())
159 if (!argument.IsEmpty())
161 __pendingArgument = argument;
164 __hasPendingRequest = true;
165 SysLog(NID_SHELL, "Update is requested but the %ls is paused.", (this->GetAppId()).GetPointer());
169 result r = this->SendUpdateRequest(GetWidth(), GetHeight(), argument);
170 SysTryLog(NID_SHELL, !IsFailed(r), "Failed to execute SendUpdateRequest.");
172 SystemTime::GetTicks(this->__lastUpdatedTime);
173 SysLog(NID_SHELL, "The last updated time is %lld.", this->__lastUpdatedTime);
175 __hasPendingRequest = false;
176 __pendingArgument.Clear();
181 _AppWidgetContext::OnResize(int width, int height)
183 SysSecureLog(NID_SHELL, "appId(%ls), instanceId(%ls), width(%d), height(%d), priority(%d)", GetProviderId().GetPointer(), GetInstanceId().GetPointer(), GetWidth(), GetHeight(), GetPriority());
188 SendResizeRequest(width, height);
192 _AppWidgetContext::RequestUpdate(const String& argument)
194 AppWidgetManagerService* pMgrService = AppWidgetManagerService::GetInstance();
195 SysTryReturnResult(NID_SHELL, pMgrService, E_SYSTEM, "[E_SYSTEM] Failed to get an instance of AppWidgetManagerService.");
197 result r = pMgrService->RequestUpdate(this, argument);
198 SysTryReturnResult(NID_SHELL, !IsFailed(r), r, "Failed to request update.");
204 _AppWidgetContext::OnForeground(void)
206 SysLog(NID_SHELL, "I");
210 SysLog(NID_SHELL, "%ls is already resumed.", (this->GetAppId()).GetPointer());
214 this->SetForeground(true);
216 if (__hasPendingRequest == true)
218 RequestUpdate(__pendingArgument);
222 if (this->GetPeriod() > 0)
224 long long currentTicks = 0;
225 SystemTime::GetTicks(currentTicks);
227 SysLog(NID_SHELL, "current[%lld] - updatedTime[%lld] = [%lld], period[%d]",
228 currentTicks, this->GetLastUpdatedTime(), currentTicks - this->GetLastUpdatedTime(), this->GetPeriod());
230 bool isPeriodExpired = (currentTicks - this->GetLastUpdatedTime()) >= (this->GetPeriod());
233 SysLog(NID_SHELL, "The period is expired.");
239 SysLog(NID_SHELL, "O");
243 _AppWidgetContext::OnBackground(void)
245 SysLog(NID_SHELL, "OnBackground");
249 SysLog(NID_SHELL, "%ls is already paused.", (this->GetAppId()).GetPointer());
252 SetForeground(false);
256 _AppWidgetContext::IsPaused(void) const
258 return IsForeground() ? false : true;
262 _AppWidgetContext::OnPopupCreated(double x, double y, int width, int height)
264 __pAppWidgetPopup = new (nothrow) _AppWidgetPopupContext(GetUserInfo(), GetProviderId(), GetInstanceId(), GetWidth(), GetHeight(), GetPriority(), this);
265 __pAppWidgetPopup->OnPopupCreated(x, y, width, height);
269 _AppWidgetContext::OnPopupDestoyed(void)
271 SysLog(NID_SHELL, "");
273 if (__pAppWidgetPopup)
275 __pAppWidgetPopup->OnPopupDestoyed();
276 delete __pAppWidgetPopup;
277 __pAppWidgetPopup = null;
282 _AppWidgetContext::SendAddRequest(int width, int height)
284 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
286 return SendRequestToApp(GetAppId(), APPWIDGET_ON_ADD, pArgs.release());
290 _AppWidgetContext::SendUpdateRequest(int width, int height, const String& argument)
292 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
294 pArgs->Add(new (nothrow) String(ARG_KEY_ARGUMENT), new (nothrow) String(argument));
296 return SendRequestToApp(GetAppId(), APPWIDGET_ON_UPDATE, pArgs.release());
300 _AppWidgetContext::SendResizeRequest(int width, int height)
302 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN() );
304 return SendRequestToApp(GetAppId(), APPWIDGET_ON_RESIZE, pArgs.release());
308 _AppWidgetContext::SendRemoveRequest(void)
310 std::unique_ptr<HashMap, AllElementsDeleter> pArgs (CreateRequestArgsN());
312 return SendRequestToApp(GetAppId(), APPWIDGET_ON_REMOVE, pArgs.release());
316 _AppWidgetContext::SendPendingEvent(void)
318 SysTryReturnResult(NID_SHELL, __pPendingEventList->GetCount() > 0 , E_DATA_NOT_FOUND, "There is no pending event.");
320 result r = E_SUCCESS;
321 PendingEvent* pEvent = null;
322 __pPendingEventList->GetAt(0, pEvent);
326 SysLog(NID_SHELL, "SendPendingEvent by IPC [%d existed.]", __pPendingEventList->GetCount());
327 r = _AppWidgetRequestHelper::SendIpcRequest(GetClientId(), pEvent->operation, pEvent->pArg);
329 result r1 = __pPendingEventList->RemoveAt(0);
330 SysTryLog(NID_SHELL, !IsFailed(r1), "Failed to remove the context.");
333 SysTryReturnResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "SendIpcRequest failed.");
337 SysLog(NID_SHELL, "SendPendingEvent by IPC [0 existed.]");
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::SendTouchEvent(buffer_event eventType, double timeStamp, double x, double y)
360 if (__pAppContext->GetConnectionState() == _AppContext::CONNECTED && IsRemoteBufferCreated())
362 SysAssert(IsSharedMemCreated() == true);
363 SysLog(NID_SHELL, "%d, %f, %f", eventType, x, y);
364 AppWidgetManagerService::GetInstance()->SendTouchEvent(GetClientId(), GetInstanceId(), eventType, timeStamp, x, y);
368 __pPendingTouchEventList->Add(new (nothrow) PendingTouchEvent(eventType, timeStamp, x, y));
370 if( AppManager::GetInstance()->IsRunning(this->GetAppId() ) == 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(eventType)));
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 return SendRequestToApp(GetAppId(), APPWIDGET_ON_TOUCH, pArgs.get());
388 _AppWidgetContext::SendRequestToApp(const AppId& appId, const String& operation, HashMap* pArgs)
390 result r = E_SUCCESS;
392 if ( __pAppContext->GetConnectionState() == _AppContext::NONE || __pAppContext->GetConnectionState() == _AppContext::DISCONNECTED)
394 SysLog(NID_SHELL, "The application is not running.");
395 result r = _AppWidgetContextBase::SendRequestToApp(appId, operation, pArgs);
396 SysTryReturn(NID_SHELL, !IsFailed(r), r, r, "[%s] Failed to SendRequestToApp", GetErrorMessage(r));
398 __pAppContext->__isWaitingResult = true;
399 __pAppContext->SetConnectionState(_AppContext::CONNECTING);
403 if ( __pAppContext->GetConnectionState() == _AppContext::CONNECTING || __pAppContext->__isWaitingResult == true)
405 SysLog(NID_SHELL, "The application is running but IPC is not connected yet.");
406 __pPendingEventList->Add(new (nothrow) PendingEvent(operation, pArgs));
410 SysLog(NID_SHELL, "The application is running and IPC is connected.");
411 r = _AppWidgetRequestHelper::SendIpcRequest(GetClientId(), operation, pArgs);
413 pArgs->RemoveAll(true);
415 __pAppContext->__isWaitingResult = true;
423 _AppWidgetContext::RequestUpdateRemote(int width, int height)
425 std::unique_ptr<char[]> packageName(_StringConverter::CopyToCharArrayN(GetProviderId()));
426 std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
427 std::unique_ptr<char[]> content_info(_StringConverter::CopyToCharArrayN(GetUserInfo()));
429 int ret = provider_send_updated(packageName.get(), id.get(), width, height, GetPriority(), content_info.get(), null);
430 SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "[E_SYSTEM] failed to provider_send_updated");
432 SendPendingTouchEvent();
433 SysLog(NID_SHELL, "Done");
438 _AppWidgetContext::SendAccessStatus(int accessStatus)
440 std::unique_ptr<char[]> packageName(_StringConverter::CopyToCharArrayN(GetProviderId()));
441 std::unique_ptr<char[]> id(_StringConverter::CopyToCharArrayN(GetInstanceId()));
443 int ret = provider_send_access_status(packageName.get(), id.get(), accessStatus);
444 SysLog(NID_SHELL, "[LB_ACCESS] provider_send_access_status is called. : ret = %d, status = %d", ret, accessStatus);
445 SysTryReturnResult(NID_SHELL, ret >= 0 , E_SYSTEM, "[E_SYSTEM] failed to provider_send_access_status");
450 Tizen::Base::Collection::HashMap*
451 _AppWidgetContext::CreateRequestArgsN(void)
453 HashMap* pArgs = new (nothrow) HashMap(SingleObjectDeleter);
456 pArgs->Add(new (nothrow) String(ARG_KEY_INSTANCE_ID), new (nothrow) String(GetInstanceId()));
457 pArgs->Add(new (nothrow) String(ARG_KEY_PROVIDER_NAME), new (nothrow) String(GetProviderName()));
458 pArgs->Add(new (nothrow) String(ARG_KEY_USER_INFO), new (nothrow) String(GetUserInfo()));
459 pArgs->Add(new (nothrow) String(ARG_KEY_WIDTH), new (nothrow) String(Integer::ToString(GetWidth())));
460 pArgs->Add(new (nothrow) String(ARG_KEY_HEIGHT), new (nothrow) String(Integer::ToString(GetHeight())));
466 _AppWidgetContext::GetPeriod(void) const
468 SysLog(NID_SHELL, "GetPeriod[%d]", __updateMillis);
469 return __updateMillis;
473 _AppWidgetContext::GetLastUpdatedTime(void) const
475 return __lastUpdatedTime;
479 _AppWidgetContext::GetClientId(void) const
481 return GetAppContext()->GetClientId();
485 _AppWidgetContext::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
487 if (&timer == &__updateTimer)
489 SysLog(NID_SHELL, "update timer is expired for appWidget app(%ls).", GetProviderId().GetPointer());
494 }}} // Tizen::Shell::App