e30e2e035c21477e8ee8cd0dfa0b70c7361ad991
[platform/framework/native/appwidget-service.git] / src / FShell_AppContext.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 #include <FBase.h>
25 #include <FBaseSysLog.h>
26 #include <FBaseColHashMap.h>
27 #include <FBaseColIMapEnumeratorT.h>
28 #include <FAppApp.h>
29 #include <FBaseComparerT.h>
30 #include <FApp_AppManagerImpl.h>
31 #include "FShell_AppWidgetContext.h"
32 #include "FShell_AppWidgetContextHelper.h"
33 #include "FShell_TemplateUtil.h"
34
35 namespace Tizen { namespace Shell  { namespace App
36 {
37
38 using namespace std;
39 using namespace Tizen::App;
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Collection;
42 using namespace Tizen::System;
43
44 static const wchar_t INVALID_INSTANCE[] = L"file://invalid instance id";
45
46 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
47 // _AppContext class
48 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
49 _AppContext::_AppContext(const AppId& appId)
50         :__appId(appId)
51         ,__isWaitingResult(false)
52         ,__ipcClientId(0)
53         ,__connectionState(CONNECTION_STATE_NONE)
54         ,__pPendingEventList(null)
55 {
56
57         __pPendingEventList = new (nothrow) ArrayListT<PendingEvent*>();
58         SysTryReturnVoidResult(NID_SHELL, __pPendingEventList, E_OUT_OF_MEMORY, "");
59
60         result r = __pPendingEventList->Construct();
61         SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "Failed to execute Construct.");
62
63         r = __appWidgetContextList.Construct();
64         SysTryReturnVoidResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "Failed to execute Construct.");
65 }
66
67 _AppContext::~_AppContext(void)
68 {
69         SysLog(NID_SHELL, "Enter");
70
71         if (__pPendingEventList)
72         {
73                 for (int i = 0; i < __pPendingEventList->GetCount(); i++)
74                 {
75                         PendingEvent* pEvent = null;
76                         __pPendingEventList->GetAt(i, pEvent);
77                         delete pEvent;
78                 }
79                 __pPendingEventList->RemoveAll();
80                 delete __pPendingEventList;
81         }
82
83         IMapEnumeratorT<String, _AppWidgetContext*>* pMapEnum = __appWidgetContextList.GetMapEnumeratorN();
84         if (pMapEnum != null)
85         {
86                 while (pMapEnum->MoveNext() == E_SUCCESS)
87                 {
88                         _AppWidgetContext* pAppWidgetContext = null;
89                         pMapEnum->GetValue(pAppWidgetContext);
90                         delete pAppWidgetContext;
91                 }
92
93                 delete pMapEnum;
94         }
95
96         SysLog(NID_SHELL, "Exit");
97 }
98
99 result
100 _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)
101 {
102         _AppWidgetContext* pAppWidgetContext = null;
103         bool containsKey = false;
104
105         __appWidgetContextList.ContainsKey(instanceId, containsKey);
106         if (containsKey == true)
107         {
108                 SysSecureLog(NID_SHELL, "The appwidget(%ls) is already exist, so requesting to update.", instanceId.GetPointer() );
109
110                 __appWidgetContextList.GetValue(instanceId, pAppWidgetContext);
111                 pAppWidgetContext->OnUpdate(L"");
112         }
113         else
114         {
115                 pAppWidgetContext = new (std::nothrow)_AppWidgetContext(this, instanceId, providerId, width, height, userInfo, period, priority);
116                 SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OUT_OF_MEMORY, "");
117
118                 __appWidgetContextList.Add(instanceId, pAppWidgetContext);
119                 pAppWidgetContext->OnAdded();
120
121                 SysSecureLog(NID_SHELL, "%ls, %ls, count(%d)", pAppWidgetContext->GetProviderId().GetPointer(), pAppWidgetContext->GetInstanceId().GetPointer(), __appWidgetContextList.GetCount());
122         }
123         return E_SUCCESS;
124 }
125
126 result
127 _AppContext::UpdateAppWidget(const Tizen::Base::String& instanceId)
128 {
129         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
130         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
131
132         pAppWidgetContext->OnUpdate(L"");
133
134         return E_SUCCESS;
135 }
136
137 result
138 _AppContext::ResizeAppWidget(const Tizen::Base::String& instanceId, int width, int height)
139 {
140         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
141         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
142
143         pAppWidgetContext->OnResize(width, height);
144
145         return E_SUCCESS;
146 }
147
148 result
149 _AppContext::CreateAppWidgetPopup(const Tizen::Base::String& instanceId, double x, double y, int width, int height)
150 {
151         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
152         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
153
154         pAppWidgetContext->OnPopupCreated(x, y, width, height);
155
156         return E_SUCCESS;
157 }
158
159 result
160 _AppContext::DestroyAppWidget(const Tizen::Base::String& instanceId, bool isTriggeredByViewer)
161 {
162         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
163         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
164
165         __appWidgetContextList.Remove(instanceId);
166
167         result r = pAppWidgetContext->OnRemoved(isTriggeredByViewer);
168         SysTryLog(NID_SHELL, !IsFailed(r), "Failed to execute OnRemoved.");
169
170         delete pAppWidgetContext;
171
172     SysLog(NID_SHELL, "AppWidget(%ls) is removed. remain count(%d)", instanceId.GetPointer(), __appWidgetContextList.GetCount());
173         return E_SUCCESS;
174 }
175
176 result
177 _AppContext::DestroyAppWidgetPopup(const Tizen::Base::String& instanceId)
178 {
179         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
180         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
181
182         pAppWidgetContext->OnPopupDestoyed();
183
184         return E_SUCCESS;
185 }
186
187 _ConnectionState
188 _AppContext::GetConnectionState(void) const
189 {
190         return __connectionState;
191 }
192
193 void
194 _AppContext::SetConnectionState(_ConnectionState state)
195 {
196         __connectionState = state;
197 }
198
199 Tizen::App::AppId
200 _AppContext::GetAppId(void) const
201 {
202         return __appId;
203 }
204
205 int
206 _AppContext::GetClientId(void) const
207 {
208         return __ipcClientId;
209 }
210
211 void
212 _AppContext::OnIpcConnected(int clientId)
213 {
214         __ipcClientId = clientId;
215         SetConnectionState(CONNECTION_STATE_CONNECTED);
216 }
217
218 void
219 _AppContext::OnIpcDisconnected(void)
220 {
221         __ipcClientId = -1;
222         SetConnectionState(CONNECTION_STATE_DISCONNECTED);
223
224         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
225         SysTryReturnVoidResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "");
226
227         _AppWidgetContext* pAppWidgetContext = null;
228         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
229         {
230                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
231                 if (pAppWidgetContext)
232                 {
233                         pAppWidgetContext->OnDisconnected();
234                 }
235         }
236 }
237
238 void
239 _AppContext::SetWaitingStatus(bool status)
240 {
241         __isWaitingResult = status;
242 }
243
244 bool
245 _AppContext::GetWaitingStatus(void) const
246 {
247         return __isWaitingResult;
248 }
249
250 result
251 _AppContext::SendRequestToApp(const AppId& providerAppId, const String& operation, HashMap* pArgs)
252 {
253         result r = E_SUCCESS;
254
255         if (GetConnectionState() == CONNECTION_STATE_NONE || GetConnectionState() == CONNECTION_STATE_DISCONNECTED)
256         {
257                 SysLog(NID_SHELL, "The application is not running.");
258                 result r = _AppWidgetRequestHelper::SendAppControlRequest(providerAppId, operation, pArgs);
259                 SysTryReturn(NID_SHELL, !IsFailed(r), r, r, "[%s] Failed to SendRequestToApp", GetErrorMessage(r));
260
261                 SetWaitingStatus(true);
262                 SetConnectionState(CONNECTION_STATE_CONNECTING);
263         }
264         else
265         {
266                 if (GetConnectionState() == CONNECTION_STATE_CONNECTING || GetWaitingStatus() == true)
267                 {
268                         SysLog(NID_SHELL, "The application is running but IPC is not connected yet.");
269                         __pPendingEventList->Add(new (nothrow) PendingEvent(operation, pArgs));
270                 }
271                 else
272                 {
273                         SysLog(NID_SHELL, "The application is running and IPC is connected.");
274                         r  = _AppWidgetRequestHelper::SendIpcRequest(GetClientId(), operation, pArgs);
275
276                         pArgs->RemoveAll(true);
277                         delete pArgs;
278                         SetWaitingStatus(true);
279                 }
280         }
281
282         return E_SUCCESS;
283 }
284
285 result
286 _AppContext::SendPendingEvent(void)
287 {
288         SetWaitingStatus(false);
289         TryReturn(__pPendingEventList->GetCount() > 0, E_DATA_NOT_FOUND, "This context has no pending event. Please find next pending event context.");
290
291         PendingEvent* pEvent = null;
292         __pPendingEventList->GetAt(0, pEvent);
293         __pPendingEventList->RemoveAt(0);
294         SysLog(NID_SHELL, "(%d) Remains in __pPendingEventList.", __pPendingEventList->GetCount());
295
296         result r = _AppWidgetRequestHelper::SendIpcRequest(GetClientId(), pEvent->operation, pEvent->pArg);
297         delete pEvent;
298         SysTryReturnResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "SendIpcRequest failed.");
299
300         return E_SUCCESS;
301 }
302
303 result
304 _AppContext::RequestUpdateInstance(const Tizen::Base::String& instanceId, const Tizen::Base::String& argument)
305 {
306         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
307         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
308
309         return pAppWidgetContext->OnUpdateAsync(this, argument);
310 }
311
312 result
313 _AppContext::AcquireRemoteBuffer(const Tizen::Base::String& instanceId, int width, int height, int& bufferId)
314 {
315         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
316         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
317
318         bufferId = pAppWidgetContext->AcquireRemoteBuffer(width, height);
319
320         return E_SUCCESS;
321 }
322
323 result
324 _AppContext::AcquireRemoteBufferForPD(const Tizen::Base::String& instanceId, int width, int height, int& bufferId)
325 {
326         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
327         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
328
329         bufferId = pAppWidgetContext->AcquireRemoteBufferForPD(width, height);
330
331         return E_SUCCESS;
332 }
333
334 result
335 _AppContext::SyncRemoteBuffer(const Tizen::Base::String& instanceId, int width, int height)
336 {
337         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
338         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
339
340         return pAppWidgetContext->SyncRemoteBuffer(width, height);
341 }
342
343 result
344 _AppContext::SyncRemoteBufferForPD(const Tizen::Base::String& instanceId)
345 {
346         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
347         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
348
349         return pAppWidgetContext->SyncRemoteBufferForPD();
350 }
351
352 result
353 _AppContext::SendAccessStatus(const Tizen::Base::String& instanceId, int accessStatus)
354 {
355         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
356         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
357
358         return pAppWidgetContext->SendAccessStatus(accessStatus);
359 }
360
361 _AppWidgetContext*
362 _AppContext::FindAppWidget(const String& instanceId) const
363 {
364         _AppWidgetContext* pAppWidgetContext = null;
365
366         if (instanceId == INVALID_INSTANCE)
367         {
368                 pAppWidgetContext = FindInvalidAppWidget();
369         }
370         else
371         {
372                 result r = __appWidgetContextList.GetValue(instanceId, pAppWidgetContext);
373                 SysTryReturn(NID_SHELL, !IsFailed(r), null, E_OBJ_NOT_FOUND, "instanceId(%ls) is not found", instanceId.GetPointer() );
374         }
375         return pAppWidgetContext;
376 }
377
378 _AppWidgetContext*
379 _AppContext::FindInvalidAppWidget(void) const
380 {
381         SysTryReturn(NID_SHELL, GetConnectionState() == CONNECTION_STATE_NONE, null, E_INVALID_STATE, "[E_INVALID_STATE] connectionState(%d)", GetConnectionState());
382
383         _AppWidgetContext* pAppWidgetContext = null;
384         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
385         SysTryReturn(NID_SHELL, pAppWidgetContextEnum, null, E_SYSTEM, "");
386
387         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
388         {
389                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
390                 if (pAppWidgetContext)
391                 {
392                         //TODO: check whether this app context has only one instance of _AppWidgetContext
393                         return pAppWidgetContext;
394                 }
395         }
396         return null;
397 }
398
399 int
400 _AppContext::GetProviderCount(void) const
401 {
402         return __appWidgetContextList.GetCount();
403 }
404
405 result
406 _AppContext::RequestUpdate(const Tizen::Base::String& providerName, const Tizen::Base::String& argument)
407 {
408         SysLog(NID_SHELL, "Enter.");
409         bool found = false;
410
411         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
412         SysTryReturnResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "Failed to invoke __appWidgetContextList.GetMapEnumeratorN()");
413
414         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
415         {
416                 _AppWidgetContext* pAppWidgetContext = null;
417                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
418
419                 if (pAppWidgetContext->GetProviderName() == providerName)
420                 {
421                         pAppWidgetContext->OnUpdateAsync(this, argument);
422                         found = true;
423                 }
424         }
425
426         SysLog(NID_SHELL, "Exit.");
427         return (found) ? E_SUCCESS : E_OBJ_NOT_FOUND;
428 }
429
430 result
431 _AppContext::RequestUpdateAllInactiveted(void)
432 {
433         SysLog(NID_SHELL, "Exit.");
434         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
435         SysTryReturnResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "Failed to invoke __appWidgetContextList.GetMapEnumeratorN()");
436
437         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
438         {
439                 _AppWidgetContext* pAppWidgetContext = null;
440                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
441
442                 if (pAppWidgetContext->IsActive() == false)
443                 {
444                         pAppWidgetContext->OnUpdateAsync(this, L"");
445                 }
446         }
447
448         SysLog(NID_SHELL, "Exit.");
449         return E_SUCCESS;
450 }
451
452 result
453 _AppContext::OnAppWidgetBackground(const Tizen::Base::String& instanceId)
454 {
455         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
456         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
457
458         pAppWidgetContext->OnBackground();
459
460         return E_SUCCESS;
461 }
462
463 result
464 _AppContext::OnAppWidgetBackgroundAll(void)
465 {
466         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
467         SysTryReturnResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "Failed to invoke GetMapEnumeratorN()");
468
469         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
470         {
471                 _AppWidgetContext* pAppWidgetContext = null;
472                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
473                 if (pAppWidgetContext)
474                 {
475                         pAppWidgetContext->OnBackground();
476                 }
477         }
478
479         return E_SUCCESS;
480 }
481
482 result
483 _AppContext::OnAppWidgetForeground(const Tizen::Base::String& instanceId)
484 {
485         _AppWidgetContext* pAppWidgetContext = FindAppWidget(instanceId);
486         SysTryReturnResult(NID_SHELL, pAppWidgetContext, E_OBJ_NOT_FOUND, "Failed to find _AppWidgetContext.");
487
488         pAppWidgetContext->OnForeground();
489
490         return E_SUCCESS;
491 }
492
493 result
494 _AppContext::OnAppWidgetForegroundAll(void)
495 {
496         unique_ptr< IMapEnumeratorT<String, _AppWidgetContext*> > pAppWidgetContextEnum(__appWidgetContextList.GetMapEnumeratorN());
497         SysTryReturnResult(NID_SHELL, pAppWidgetContextEnum, E_SYSTEM, "Failed to invoke GetMapEnumeratorN()");
498
499         while (pAppWidgetContextEnum->MoveNext() == E_SUCCESS)
500         {
501                 _AppWidgetContext* pAppWidgetContext = null;
502                 pAppWidgetContextEnum->GetValue(pAppWidgetContext);
503                 if (pAppWidgetContext)
504                 {
505                         pAppWidgetContext->OnForeground();
506                 }
507         }
508
509         return E_SUCCESS;
510 }
511
512 void
513 _AppContext::HandleUserEvent(Tizen::Base::Collection::IList* pArgs)
514 {
515         _AppWidgetContext* pAppWidgetContext = dynamic_cast<_AppWidgetContext*>( pArgs->GetAt(1) );
516         SysTryReturnVoidResult(NID_SHELL, pAppWidgetContext != null, E_INVALID_STATE, "_AppWidget is null!.");
517
518         String* pArgument = dynamic_cast<String*>( pArgs->GetAt(2) );
519         SysTryReturnVoidResult(NID_SHELL, pArgument != null, E_INVALID_STATE, "pArgument is null!.");
520
521         pAppWidgetContext->OnUpdate(*pArgument);
522 }
523
524 }}}  // Tizen::Shell::App