Merge "[ACR][Add|Modify] change return value for OnXXXInitializing() for LiveboxProvi...
[platform/framework/native/shell.git] / src / core / FShell_NotificationManagerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FShell_NotificationManagerImpl.cpp
20  * @brief               This is the placeholder for _NotificationManagerImpl class.
21  */
22
23 #include <unique_ptr.h>
24 #include <appsvc/appsvc.h>
25 #include <bundle.h>
26 #include <notification/notification.h>
27 #include <appfw/app.h>
28 #include <appfw/app_manager.h>
29 #include <appfw/app_ui_notification.h>
30 #include <badge.h>
31
32 #include <FBaseSysLog.h>
33 #include <FApp.h>
34 //#include <FAppTypes.h>
35 #include <FShellNotificationManager.h>
36 #include <FShellNotificationRequest.h>
37
38 //#include <FBaseInternalTypes.h>
39 #include <FBase_StringConverter.h>
40 #include "FApp_AppInfo.h"
41 #include "FApp_Aul.h"
42 #include "FIoFile.h"
43 #include "FAppPkg_PackageManagerImpl.h"
44 #include "FApp_AppArg.h"
45 #include "FAppPkgPackageAppInfo.h"
46 #include "FAppPkg_PackageAppInfoImpl.h"
47 #include "FShell_NotificationManagerImpl.h"
48 #include "FShell_NotificationRequestImpl.h"
49
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Collection;
52 using namespace Tizen::App;
53 using namespace Tizen::App::Package;
54 using namespace Tizen::Io;
55 using namespace Tizen::Shell;
56
57 extern "C" int service_create_request(bundle *data, service_h *service);
58 extern "C" int service_to_bundle(service_h service, bundle** data);
59
60 namespace
61 {
62
63 result
64 ConvertNotificationResult(int error)
65 {
66         switch (error)
67         {
68         case NOTIFICATION_ERROR_NONE:
69                 return E_SUCCESS;
70         case NOTIFICATION_ERROR_INVALID_DATA:
71                 return E_INVALID_ARG;
72         case NOTIFICATION_ERROR_NO_MEMORY:
73                 return E_OUT_OF_MEMORY;
74         case NOTIFICATION_ERROR_FROM_DB:
75                 return E_DATABASE;
76         case NOTIFICATION_ERROR_ALREADY_EXIST_ID:
77                 return E_OPERATION_FAILED;
78         case NOTIFICATION_ERROR_NOT_EXIST_ID:
79                 return E_OPERATION_FAILED;
80         default:
81                 return E_OPERATION_FAILED;
82         }
83 }
84
85 bool
86 IsPosted(ui_notification_h handle)
87 {
88         struct ui_notification_s
89         {
90                 void* raw_handle;
91                 bool ongoing;
92                 bool posted;
93                 bool removed;
94                 char *icon;
95                 struct tm *time;
96                 char *title;
97                 char *content;
98                 service_h service;
99                 char *sound;
100                 bool vibration;
101         };
102
103         if (handle == NULL)
104         {
105                 return false;
106         }
107
108         ui_notification_s* pStruct = reinterpret_cast<ui_notification_s*>(handle);
109
110         return pStruct->posted;
111 }
112
113 } // namespace
114
115
116 namespace Tizen { namespace Shell
117 {
118
119 _NotificationManagerImpl::_NotificationManagerImpl(void)
120         : __notifyPrivitId(-1)
121         , __notifyPrivitIdForOngoing(-1)
122 {
123 }
124
125 _NotificationManagerImpl::~_NotificationManagerImpl(void)
126 {
127 }
128
129 result
130 _NotificationManagerImpl::Construct(void)
131 {
132         return E_SUCCESS;
133 }
134
135 const _NotificationManagerImpl*
136 _NotificationManagerImpl::GetInstance(const NotificationManager& notiMgr)
137 {
138         return notiMgr.__pNotificationManagerImpl;
139 }
140
141 _NotificationManagerImpl*
142 _NotificationManagerImpl::GetInstance(NotificationManager& notiMgr)
143 {
144         return notiMgr.__pNotificationManagerImpl;
145 }
146
147 int
148 _NotificationManagerImpl::GetBadgeNumber(void) const
149 {
150         Tizen::App::App* pApp = Tizen::App::App::GetInstance();
151         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(pApp->GetAppId()));
152
153         int count = GetBadgeCount(pAppId.get());
154         SysTryReturn(NID_APP, count != -1, count, E_OPERATION_FAILED, "[%s] The operation has failed. Badge may not exist.",
155                                  GetErrorMessage(E_OPERATION_FAILED));
156
157         ClearLastResult();
158         return count;
159 }
160
161 result
162 _NotificationManagerImpl::NotifyMessageImpl(const NotificationRequest& notiMessage, bool isOngoing)
163 {
164         return NotifyMessage(NOTIFY_TYPE_SIMPLE, isOngoing, notiMessage);
165 }
166
167 result
168 _NotificationManagerImpl::NotifyMessageImpl(const AppId& appId, const NotificationRequest& notiMessage, bool isOngoing)
169 {
170         return NotifyMessage(NOTIFY_TYPE_APP_ID, isOngoing, notiMessage, &appId);
171 }
172
173
174 result
175 _NotificationManagerImpl::Notify(int badgeNumber)
176 {
177         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
178
179         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
180         {
181                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
182         }
183
184         Tizen::App::App* pApp = Tizen::App::App::GetInstance();
185         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(pApp->GetAppId()));
186
187         if (badgeNumber == 0)
188         {
189                 RemoveBadge(pAppId.get());
190         }
191         else
192         if (badgeNumber > 0)
193         {
194                 SetBadgeCount(pAppId.get(), badgeNumber);
195         }
196
197         return E_SUCCESS;
198 }
199
200 result
201 _NotificationManagerImpl::Notify(const String& messageText)
202 {
203         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
204
205         NotificationRequest request;
206         request.SetAlertText(messageText);
207         request.SetAppMessage(L"");
208
209         return NotifyMessage(NOTIFY_TYPE_SIMPLE, false, request);
210 }
211
212 result
213 _NotificationManagerImpl::Notify(const String& messageText, int badgeNumber)
214 {
215         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
216         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
217
218         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
219         {
220                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
221         }
222
223         NotificationRequest request;
224         request.SetAlertText(messageText);
225         request.SetBadgeNumber(badgeNumber);
226         request.SetAppMessage(L"");
227
228         return NotifyMessage(NOTIFY_TYPE_SIMPLE, false, request);
229 }
230
231 result
232 _NotificationManagerImpl::Notify(const String& messageText, int badgeNumber, const String& launchArguments)
233 {
234         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
235         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
236         SysTryReturnResult(NID_APP, launchArguments != null && launchArguments.GetLength() > 0, E_INVALID_ARG,
237                                            "launchArguments is less than 0.");
238
239         SysTryReturnResult(NID_APP, launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
240                                            "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
241
242         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
243         {
244                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
245         }
246
247         NotificationRequest request;
248         request.SetAlertText(messageText);
249         request.SetBadgeNumber(badgeNumber);
250         request.SetAppMessage(launchArguments);
251
252         return NotifyMessage(NOTIFY_TYPE_SIMPLE, false, request);
253 }
254
255 int
256 _NotificationManagerImpl::GetBadgeNumber(const AppId& appId) const
257 {
258         bool b = _Aul::IsInstalled(appId);
259         SysTryReturn(NID_APP, b == true, -1, E_APP_NOT_INSTALLED, "[E_OBJ_NOT_FOUND] The application %ls is not installed",
260                                  appId.GetPointer());
261         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
262         int count = GetBadgeCount(pAppId.get());
263
264         SysTryReturn(NID_APP, count != -1, count, E_OPERATION_FAILED, "[%s] The operation has failed. Badge may not exist.",
265                                  GetErrorMessage(E_OPERATION_FAILED));
266         ClearLastResult();
267
268         return count;
269 }
270
271 result
272 _NotificationManagerImpl::NotifyOngoingActivity(const String& messageText)
273 {
274         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
275
276         NotificationRequest request;
277         request.SetAlertText(messageText);
278
279         return NotifyMessage(NOTIFY_TYPE_SIMPLE, true, request);
280 }
281
282 result
283 _NotificationManagerImpl::NotifyOngoingActivity(const String& messageText, const String& launchArguments)
284 {
285         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
286         SysTryReturnResult(NID_APP, launchArguments.GetLength() > 0, E_INVALID_ARG, "launchArguments is less than 0.");
287         SysTryReturnResult(NID_APP, launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
288                                            "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
289
290         NotificationRequest request;
291         request.SetAlertText(messageText);
292         request.SetAppMessage(launchArguments);
293
294         return NotifyMessage(NOTIFY_TYPE_SIMPLE, true, request);
295 }
296
297 result
298 _NotificationManagerImpl::RemoveOngoingActivityNotificationByAppId(const AppId& appId)
299 {
300         return RemoveNotificationByAppId(appId, true);
301 }
302
303
304 result
305 _NotificationManagerImpl::RemoveNotificationByAppId(const AppId& appId)
306 {
307         return RemoveNotificationByAppId(appId, false);
308 }
309
310 result
311 _NotificationManagerImpl::NotifyTextMessage(const String& messageText) const
312 {
313         SysTryReturnResult(NID_APP, !messageText.IsEmpty(), E_INVALID_ARG, "MessageText is less than 0.");
314
315         std::unique_ptr<char[]> pMsg(_StringConverter::CopyToCharArrayN(messageText));
316         int res = notification_status_message_post(pMsg.get());
317
318         result r = E_SUCCESS;
319         switch (res)
320         {
321         case NOTIFICATION_ERROR_NONE:
322                 // success
323                 break;
324         case NOTIFICATION_ERROR_INVALID_DATA:
325                 r = E_INVALID_ARG;
326                 break;
327         case NOTIFICATION_ERROR_IO:
328                 r = E_SYSTEM;
329                 break;
330         default:
331                 r = E_SYSTEM;
332                 break;
333         }
334
335         SysLog(NID_APP, "[%s] %ls posted.", GetErrorMessage(r), messageText.GetPointer());
336         return r;
337 }
338
339 result
340 _NotificationManagerImpl::NotifyByAppControl(const Tizen::Base::String& operationId, const Tizen::Base::String* pUriData, const Tizen::Base::String* pDataType,
341                                                                                          const Tizen::Base::Collection::IMap* pExtraData, const NotificationRequest& request)
342 {
343         result r = E_SUCCESS;
344
345         r = NotifyMessage(NOTIFY_TYPE_APP_CONTROL, false, request, null, &operationId, pUriData, pDataType, pExtraData);
346         return r;
347 }
348
349 result
350 _NotificationManagerImpl::NotifyOngoingActivityByAppControl(const Tizen::Base::String& operationId, const Tizen::Base::String* pUriData, const Tizen::Base::String* pDataType,
351                                                                                                                         const Tizen::Base::Collection::IMap* pExtraData, const NotificationRequest& request)
352 {
353         result r = E_SUCCESS;
354
355         r = NotifyMessage(NOTIFY_TYPE_APP_CONTROL, true, request, null, &operationId, pUriData, pDataType, pExtraData);
356         return r;
357 }
358
359
360 result
361 _NotificationManagerImpl::NotifyMessage(_NotifyType notifyType, bool isOngoing, const NotificationRequest& notifyRequest, const AppId* pAppId,
362                                                                                 const Tizen::Base::String* pOperationId, const Tizen::Base::String* pUriData, const Tizen::Base::String* pDataType, const Tizen::Base::Collection::IMap* pExtraData)
363 {
364         result r = E_SUCCESS;
365         std::unique_ptr<char[]> pAppIdChar(null);
366         const _NotificationRequestImpl* pRequestImpl = _NotificationRequestImpl::GetInstance(notifyRequest);
367         SysTryReturnResult(NID_APP, pRequestImpl != null, E_INVALID_ARG, "Invalid argument is used.");
368
369         // Set pAppIdChar
370         if ((notifyType == NOTIFY_TYPE_SIMPLE) || (notifyType == NOTIFY_TYPE_APP_CONTROL))
371         {
372 //              char* pkgname = null;
373 //              app_get_id(&pkgname);   // AppId. (Not package Id)
374 //              SysTryReturnResult(NID_APP, pkgname != NULL, E_OBJ_NOT_FOUND,"Cannot acquire package name for current application.");
375 //              const String currentAppId(pkgname);
376 //              free(pkgname);
377                 Tizen::App::App* pApp = Tizen::App::App::GetInstance();
378                 const String currentAppId = pApp->GetAppId();
379                 std::unique_ptr<char[]> pAppIdTemp(_StringConverter::CopyToCharArrayN(currentAppId));
380                 pAppIdChar = std::move(pAppIdTemp);
381                 SysLog(NID_APP, "app_get_id: %ls", currentAppId.GetPointer());
382         }
383         else
384         if (notifyType == NOTIFY_TYPE_APP_ID)
385         {
386                 bool isAppInstalled = _Aul::IsInstalled(*pAppId);
387                 SysTryReturnResult(NID_APP, isAppInstalled == true, E_APP_NOT_INSTALLED, "The application %ls is not installed", pAppId->GetPointer());
388                 std::unique_ptr<char[]> pAppIdTemp(_StringConverter::CopyToCharArrayN(*pAppId));
389                 pAppIdChar = std::move(pAppIdTemp);
390         }
391         else
392         {
393                 SysTryReturnResult(NID_APP, false, E_INVALID_ARG, "Invalid argument is used.");
394         }
395
396         const int badgeNumber = notifyRequest.GetBadgeNumber();
397         const int badgeOffset = notifyRequest.GetBadgeOffset();
398         const String& contentText = notifyRequest.GetAlertText();
399         // Allow change the badge without other properties.
400         if (badgeNumber != -1 || badgeOffset != -1)
401         {
402                 // Set - Badge
403                 if (badgeOffset != 0)
404                 {
405                         int badgeNumber = GetBadgeCount(pAppIdChar.get());
406                         if (badgeNumber <= 0)
407                         {
408                                 SetBadgeCount(pAppIdChar.get(), badgeOffset);
409                         }
410                         else
411                         {
412                                 SetBadgeCount(pAppIdChar.get(), badgeNumber + badgeOffset);
413                         }
414                 }
415                 else
416                 {
417                         if (badgeNumber == 0)
418                         {
419                                 RemoveBadge(pAppIdChar.get());
420                         }
421                         else
422                         if (badgeNumber > 0)
423                         {
424                                 SetBadgeCount(pAppIdChar.get(), badgeNumber);
425                         }
426                 }
427                 if (!(isOngoing || !contentText.IsEmpty()))
428                 {
429                         SysLog(NID_APP, "No valid for Notification, just for set a badgeNumber update.");
430                         return E_SUCCESS;
431                 }
432         }
433         SysTryReturnResult(NID_APP, (isOngoing || !contentText.IsEmpty()), E_INVALID_ARG, "Invalid argument is used. MessageText is Empty");
434
435         const String& titleText = notifyRequest.GetTitleText();
436         const String& launchArguments = notifyRequest.GetAppMessage();
437         const String& iconPath = notifyRequest.GetIconFilePath();
438         const String& soundPath = notifyRequest.GetSoundFilePath();
439         const notification_type_e notiType = isOngoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
440         int notiPrivateId = isOngoing ? __notifyPrivitIdForOngoing : __notifyPrivitId;
441         notification_h notiHandle = null;
442         bundle* pBundle = null;
443         bool needUpdate = false;
444         bundle* service_data = null;
445         _AppArg arg;
446         service_h hSvc = null;
447         notification_ly_type_e layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
448
449         // Notification creation
450         if (notiPrivateId != -1)
451         {
452                 notiHandle = notification_load(pAppIdChar.get(), notiPrivateId);
453                 SysTryLog(NID_APP, notiHandle != null, "Get notiHandle(%d) from notiPrivateId(%d).", notiHandle, notiPrivateId);
454         }
455
456         if (notiHandle == null)
457         {
458                 SysLog(NID_APP, "Previous notification(%d) no more valid - create new notification", notiPrivateId);
459                 notiPrivateId = -1;             // reset
460                 notiHandle = notification_create(notiType);
461         }
462         else
463         {
464                 needUpdate = true;              // No need to notification_insert.
465         }
466         SysTryReturnResult(NID_APP, notiHandle != null , E_SYSTEM, "A system error has been occurred. Notification creation/load failed ");
467
468         // Content text(Alert text)
469         std::unique_ptr<char[]> pMsg(_StringConverter::CopyToCharArrayN(contentText));
470
471         // Title text
472         std::unique_ptr<char[]> pTitleText(null);
473         if (!titleText.IsEmpty())
474         {
475                 std::unique_ptr<char[]> pTitleTextTemp(_StringConverter::CopyToCharArrayN(titleText));
476                 pTitleText = std::move(pTitleTextTemp);
477         }
478         else
479         {
480                 char* pAppName = null;
481                 app_manager_get_app_name(pAppIdChar.get(), &pAppName);
482                 if (pAppName)
483                 {
484                         String appName(pAppName);
485                         std::unique_ptr<char[]> pTitleTextTemp(_StringConverter::CopyToCharArrayN(appName));
486                         pTitleText = std::move(pTitleTextTemp);
487                         free(pAppName);
488                         //SysLog(NID_APP, "Application Id is %ls.", appName.GetPointer());
489                 }
490                 else
491                 {
492                         SysTryLog(NID_APP, pTitleText, "Failed to get title from app_manager_get_app_name for default setting.");
493                 }
494         }
495         // Icon file path
496         std::unique_ptr<char[]> pIconPath(null);
497         if (!iconPath.IsEmpty())
498         {
499                 std::unique_ptr<char[]> pIconPathTemp(_StringConverter::CopyToCharArrayN(iconPath));
500                 pIconPath = std::move(pIconPathTemp);
501         }
502         else
503         {
504                 std::unique_ptr<PackageAppInfo> pPackageAppInfo(_PackageManagerImpl::GetInstance()->GetPackageAppInfoN(pAppIdChar.get()));
505                 const String& appIconPath(_PackageAppInfoImpl::GetInstance(pPackageAppInfo.get())->GetAppNotificationIconPath());
506
507                 if (!appIconPath.IsEmpty() && File::IsFileExist(appIconPath))
508                 {
509                         std::unique_ptr<char[]> pIconPathTemp(_StringConverter::CopyToCharArrayN(appIconPath));
510                         pIconPath = std::move(pIconPathTemp);
511                 }
512                 else
513                 {
514                         char* pDefaultIconPath = null;
515                         app_manager_get_app_icon_path(pAppIdChar.get(), &pDefaultIconPath);
516                         if (pDefaultIconPath)
517                         {
518                                 String iconPath(pDefaultIconPath);
519                                 std::unique_ptr<char[]> pIconPathTemp(_StringConverter::CopyToCharArrayN(iconPath));
520                                 pIconPath = std::move(pIconPathTemp);
521                                 free(pDefaultIconPath);
522                         }
523                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set icon path  failed.", GetErrorMessage(r));
524                 }
525         }
526         // Sound file path
527         std::unique_ptr<char[]> pSoundPath(null);
528         if (!soundPath.IsEmpty())
529         {
530                 std::unique_ptr<char[]> pSoundPathTemp(_StringConverter::CopyToCharArrayN(soundPath));
531                 pSoundPath = std::move(pSoundPathTemp);
532         }
533         // Set - AppId
534         if (notifyType == NOTIFY_TYPE_APP_ID)
535         {
536                 r = ConvertNotificationResult(notification_set_pkgname(notiHandle, pAppIdChar.get()));
537                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Package name failed.", GetErrorMessage(r));
538         }
539         // Set - title text
540         if (pTitleText.get())
541         {
542                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_TITLE, pTitleText.get(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
543                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Title Text failed.", GetErrorMessage(r));
544         }
545         // Set - content text
546         if (pMsg.get())
547         {
548                 r = notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_CONTENT, pMsg.get(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
549                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Title Text failed.", GetErrorMessage(r));
550         }
551         // Set - icon file path
552         r = ConvertNotificationResult(notification_set_image(notiHandle, NOTIFICATION_IMAGE_TYPE_ICON, pIconPath.get()));
553         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set icon path  failed.", GetErrorMessage(r));
554         // Set - sound file path
555         r = ConvertNotificationResult(notification_set_sound(notiHandle, NOTIFICATION_SOUND_TYPE_USER_DATA, pSoundPath.get()));
556         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set sound  failed.", GetErrorMessage(r));
557
558         // Set extended - text, thumbnail and background image
559         if (!isOngoing)
560         {
561                 // Extended style set
562                 String countText = notifyRequest.GetNotificationCountText();
563                 NotificationStyle notiStyle= notifyRequest.GetNotificationStyle();
564                 if (notiStyle == NOTIFICATION_STYLE_THUMBNAIL)
565                 {
566                         layout = NOTIFICATION_LY_NOTI_THUMBNAIL;
567                 }
568                 else
569                 if (notiStyle == NOTIFICATION_STYLE_NORMAL && !countText.IsEmpty())
570                 {
571                         layout = NOTIFICATION_LY_NOTI_EVENT_MULTIPLE;
572                 }
573
574                 if (!countText.IsEmpty())
575                 {
576                         std::unique_ptr<char[]> text(_StringConverter::CopyToCharArrayN(countText));
577                         r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, text.get(),
578                                                                                                                                 NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
579                 }
580
581                 String bgImageFilePath = notifyRequest.GetBackgroundImageFilePath();
582                 if (!bgImageFilePath.IsEmpty() && File::IsFileExist(bgImageFilePath))
583                 {
584                         std::unique_ptr<char[]> pBgImageFilePath(_StringConverter::CopyToCharArrayN(bgImageFilePath));
585                         r = ConvertNotificationResult(notification_set_image(notiHandle, NOTIFICATION_IMAGE_TYPE_BACKGROUND, pBgImageFilePath.get()));
586                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Background image path failed.", GetErrorMessage(r));
587                 }
588
589
590                 if (notiStyle == NOTIFICATION_STYLE_THUMBNAIL)
591                 {
592                         const IList* pThumbnailList = pRequestImpl->GetMessageThumbnailFilePathList();
593                         if (pThumbnailList)
594                         {
595                                 const static notification_image_type_e thumbnailListEnum[] = {NOTIFICATION_IMAGE_TYPE_LIST_1, NOTIFICATION_IMAGE_TYPE_LIST_2,
596                                                 NOTIFICATION_IMAGE_TYPE_LIST_3, NOTIFICATION_IMAGE_TYPE_LIST_4, NOTIFICATION_IMAGE_TYPE_LIST_5 };
597                                 int itemCount = pThumbnailList->GetCount();
598                                 const int maxCount = sizeof(thumbnailListEnum)/sizeof(thumbnailListEnum[0]);
599                                 if (itemCount > maxCount)
600                                 {
601                                         itemCount = maxCount;
602                                 }
603                                 for (int i = 0; i < itemCount; i++)
604                                 {
605                                         const String* pThumbnailPath = static_cast<const String*>(pThumbnailList->GetAt(i));
606                                         // TODO: check pThumbnailPath
607                                         std::unique_ptr<char[]> filePath(_StringConverter::CopyToCharArrayN(*pThumbnailPath));
608                                         r = ConvertNotificationResult(notification_set_image(notiHandle, thumbnailListEnum[i], filePath.get()));
609                                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set thumnail path  failed.", GetErrorMessage(r));
610                                 }
611                         }
612                 }
613                 else
614                 {
615                         // TODO: Check the valid
616                         const IList* pMessageTextList = pRequestImpl->GetMessageTextList();
617                         if (pMessageTextList && pMessageTextList->GetCount())
618                         {
619                                 const String* pText1 = static_cast<const String*>(pMessageTextList->GetAt(0));
620                                 if (pText1)
621                                 {
622                                         int matchIndex;
623                                         if (E_SUCCESS == pText1->IndexOf(L'\t', 0, matchIndex))
624                                         {
625                                                 // Make two token
626                                                 String subText;
627                                                 pText1->SubString(0, matchIndex+1, subText);
628                                                 std::unique_ptr<char[]> leftText(_StringConverter::CopyToCharArrayN(subText));
629                                                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_1, leftText.get(),
630                                                                                                                                                         NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
631                                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Text failed.", GetErrorMessage(r));
632                                                 subText.Clear();
633                                                 if (E_SUCCESS == pText1->SubString(matchIndex+1, subText))
634                                                 {
635                                                         std::unique_ptr<char[]> rightText(_StringConverter::CopyToCharArrayN(subText));
636                                                         r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_SUB_1, rightText.get(),
637                                                                                                                                                                 NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
638                                                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Sub Text failed.", GetErrorMessage(r));
639                                                 }
640                                         }
641                                         else
642                                         {
643                                                 std::unique_ptr<char[]> leftText(_StringConverter::CopyToCharArrayN(*pText1));
644                                                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_1, leftText.get(),
645                                                                                                                                                         NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
646                                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Text failed.", GetErrorMessage(r));
647                                         }
648                                 }
649                                 const String* pText2 = static_cast<const String*>(pMessageTextList->GetAt(1));
650                                 if (pText2)
651                                 {
652                                         int matchIndex;
653                                         // 2.1: Multiple layout has single line text for 2nd information text.
654                                         if ((layout == NOTIFICATION_LY_NOTI_EVENT_MULTIPLE && E_SUCCESS) == (pText2->IndexOf(L'\t', 0, matchIndex)))
655                                         {
656                                                 // Make two token
657                                                 String subText;
658                                                 pText2->SubString(0, matchIndex+1, subText);
659                                                 std::unique_ptr<char[]> leftText(_StringConverter::CopyToCharArrayN(subText));
660                                                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_2, leftText.get(),
661                                                                                                                                                         NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
662                                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Text failed.", GetErrorMessage(r));
663                                                 subText.Clear();
664                                                 if (E_SUCCESS == pText2->SubString(matchIndex+1, subText))
665                                                 {
666                                                         std::unique_ptr<char[]> rightText(_StringConverter::CopyToCharArrayN(subText));
667                                                         r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_SUB_2, rightText.get(),
668                                                                                                                                                                 NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
669                                                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Sub Text failed.", GetErrorMessage(r));
670                                                 }
671                                         }
672                                         else
673                                         {
674                                                 std::unique_ptr<char[]> leftText(_StringConverter::CopyToCharArrayN(*pText2));
675                                                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_2, leftText.get(),
676                                                                                                                                                         NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
677                                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Text failed.", GetErrorMessage(r));
678                                         }
679                                 }
680                         }
681                         else
682                         if (needUpdate)
683                         {       // Reset text for update case. also must be check the previous text with get_text
684                                 char* pRetStr = null;
685                                 notification_get_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_1, &pRetStr);
686                                 if (pRetStr)
687                                 {
688                                         const static notification_text_type_e infoTextEnums[] = { NOTIFICATION_TEXT_TYPE_INFO_1, NOTIFICATION_TEXT_TYPE_INFO_SUB_1,
689                                                                                                                                                          NOTIFICATION_TEXT_TYPE_INFO_2, NOTIFICATION_TEXT_TYPE_INFO_SUB_2 };
690                                         for (unsigned int i = 0; i < sizeof(infoTextEnums)/sizeof(infoTextEnums[0]); i++)
691                                         {
692                                                 notification_set_text(notiHandle, infoTextEnums[i], null, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
693                                         }
694                                 }
695                         }
696                 }
697         }
698
699         // Set - service
700         r = arg.Construct(launchArguments);
701         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
702
703         pBundle = arg.GetBundle();
704
705         service_create_request(pBundle, &hSvc);
706         SysTryCatch(NID_APP, hSvc != null, r = E_SYSTEM, r, "[%s] A system error has been occurred. service_create_request failed.", GetErrorMessage(E_SYSTEM));
707
708         if (notifyType == NOTIFY_TYPE_SIMPLE || notifyType == NOTIFY_TYPE_APP_ID)
709         {
710                 service_set_app_id(hSvc, pRequestImpl->IsAppBinding() ? pAppIdChar.get() : null);
711         }
712         else
713         if (notifyType == NOTIFY_TYPE_APP_CONTROL)
714         {
715
716                 std::unique_ptr<char[]> pOperationIdChar(_StringConverter::CopyToCharArrayN(*pOperationId));
717                 service_set_operation(hSvc, pOperationIdChar.get());
718                 if (pUriData)
719                 {
720                         std::unique_ptr<char[]> pUri(_StringConverter::CopyToCharArrayN(*pUriData));
721                         service_set_uri(hSvc, pUri.get());
722                 }
723                 if (pDataType)
724                 {
725                         std::unique_ptr<char[]> pMime(_StringConverter::CopyToCharArrayN(*pDataType));
726                         service_set_mime(hSvc, pMime.get());
727                 }
728                 if (pExtraData)
729                 {
730                         std::unique_ptr<Tizen::Base::Collection::IMapEnumerator> pMapEnum(pExtraData->GetMapEnumeratorN());
731                         if (pMapEnum)
732                         {
733                                 while (pMapEnum->MoveNext() == E_SUCCESS)
734                                 {
735                                         String* pKey = static_cast<String* > (pMapEnum->GetKey());
736                                         String* pValue = static_cast<String* > (pMapEnum->GetValue());
737                                         if (pKey && pValue)
738                                         {
739                                                 std::unique_ptr<char[]> pKeyString(_StringConverter::CopyToCharArrayN(*pKey));
740                                                 std::unique_ptr<char[]> pValueString(_StringConverter::CopyToCharArrayN(*pValue));
741                                                 service_add_extra_data(hSvc, pKeyString.get(), pValueString.get());
742                                         }
743                                         else
744                                         {
745                                                 SysLog(NID_APP, "pKey or pValue is ivalid.");
746                                         }
747                                 }
748                         }
749                 }
750         }
751
752         if (service_to_bundle(hSvc, &service_data) == SERVICE_ERROR_NONE)
753         {
754                 notification_set_property(notiHandle, 0);
755                 notification_set_execute_option(notiHandle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, service_data);
756         }
757         else
758         {
759                 SysLog(NID_APP, "service_to_bundle failed");
760         }
761
762         // Set layout
763         if (isOngoing)
764         {
765                 OngoingActivityType activityType = notifyRequest.GetOngoingActivityType();
766                 if (activityType == ONGOING_ACTIVITY_TYPE_TEXT)
767                 {
768                         layout = NOTIFICATION_LY_ONGOING_EVENT;
769                 }
770                 else
771                 {
772                         layout = NOTIFICATION_LY_ONGOING_PROGRESS;
773                 }
774         }
775         notification_set_layout(notiHandle, layout);
776
777         // For ongoing
778         if (isOngoing)
779         {
780                 OngoingActivityType activityType = notifyRequest.GetOngoingActivityType();
781                 int progress = notifyRequest.GetOngoingActivityProgress();
782
783                 switch (activityType)
784                 {
785                 case ONGOING_ACTIVITY_TYPE_PROGRESS_PERCENTAGE:
786                         if (needUpdate)
787                         {
788                                 r = ConvertNotificationResult(notification_update_progress(notiHandle, notiPrivateId, progress/100.));
789                         }
790                         else
791                         {
792                                 r = ConvertNotificationResult(notification_set_progress(notiHandle, progress/100.));
793                         }
794                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification update failure.", GetErrorMessage(r));
795                         break;
796
797                 case ONGOING_ACTIVITY_TYPE_PROGRESS_BYTE:
798                         if (needUpdate)
799                         {
800                                 r = ConvertNotificationResult(notification_update_size(notiHandle, notiPrivateId, progress));
801                         }
802                         else
803                         {
804                                 r = ConvertNotificationResult(notification_set_size(notiHandle, progress));
805                         }
806                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification update failure.", GetErrorMessage(r));
807                         break;
808
809                 case ONGOING_ACTIVITY_TYPE_TEXT:
810                         // Do nothing
811                         break;
812
813                 default:
814                         r = E_OPERATION_FAILED;
815                         break;
816                 }
817                 if (needUpdate)
818                 {
819                         r = ConvertNotificationResult(notification_update_content(notiHandle, notiPrivateId, pMsg.get()));
820                 }
821                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification update failure.", GetErrorMessage(r));
822         }
823
824         // insert for new notification
825         if (!needUpdate)
826         {       // new
827                 r = ConvertNotificationResult(notification_insert(notiHandle, &notiPrivateId));
828                 SysLog(NID_APP, "Insert notification and get new notiPrivateId(%d)", notiPrivateId);
829                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification post failure.", GetErrorMessage(r));
830                 if (isOngoing)
831                 {
832                         __notifyPrivitIdForOngoing  = notiPrivateId;
833                 }
834                 else
835                 {
836                         __notifyPrivitId = notiPrivateId;
837                 }
838         }
839
840         // notification_update just for non ongoing and text type ongoing only.
841         if (needUpdate && !isOngoing)
842         {
843                 notification_update(notiHandle);
844                 SysLog(NID_APP, "Notification update from notiPrivateId(%d)", notiPrivateId);
845         }
846
847
848 CATCH:
849         service_destroy(hSvc);
850         notification_free(notiHandle);
851         return r;
852 }
853
854 result
855 _NotificationManagerImpl::RemoveNotification(void)
856 {
857         return RemoveNotification(false);
858 }
859
860 result
861 _NotificationManagerImpl::RemoveOngoingActivityNotification(void)
862 {
863         return RemoveNotification(true);
864 }
865
866 result
867 _NotificationManagerImpl::RemoveNotification(bool onGoing)
868 {
869         result r = E_SUCCESS;
870         notification_error_e err = NOTIFICATION_ERROR_NONE;
871         const notification_type_e notiType = onGoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
872         const int notiPrivateId = onGoing ? __notifyPrivitIdForOngoing : __notifyPrivitId;
873
874         if (notiPrivateId != -1)
875         {
876                 notification_h notiHandle = notification_load(null, notiPrivateId);
877                 if (notiHandle)
878                 {
879                         err = notification_delete(notiHandle);
880                         SysLog(NID_APP, "Notification deleted.");
881                 }
882                 else
883                 {
884                         SysLog(NID_APP, "Notification already deleted.");
885                 }
886                 notification_free(notiHandle);
887         }
888         else
889         {
890                 err = notification_delete_all_by_type(null, notiType);
891                 SysLog(NID_APP, "All [%s] notification deleted.", onGoing ? "Ongoing" : "Normal");
892         }
893
894         switch (err)
895         {
896         case NOTIFICATION_ERROR_NONE:
897                 r = E_SUCCESS;
898                 break;
899
900         case NOTIFICATION_ERROR_INVALID_DATA:
901                 r = E_INVALID_ARG;
902                 break;
903
904         default:
905                 r = E_SYSTEM;
906                 break;
907         }
908
909         return r;
910 }
911
912 result
913 _NotificationManagerImpl::RemoveNotificationByAppId(const Tizen::App::AppId& appId, bool onGoing)
914 {
915         result r = E_SUCCESS;
916         notification_error_e err = NOTIFICATION_ERROR_NONE;
917         bool isValidAppId = _Aul::IsInstalled(appId);
918         SysTryReturnResult(NID_APP, isValidAppId == true, E_APP_NOT_INSTALLED, "The application %ls is not installed", appId.GetPointer());
919
920         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
921         const notification_type_e notiType = onGoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
922         const int notiPrivateId = onGoing ? __notifyPrivitIdForOngoing : __notifyPrivitId;
923
924         if (notiPrivateId != -1)
925         {
926                 notification_h notiHandle = notification_load(pAppId.get(), notiPrivateId);
927                 if (notiHandle)
928                 {
929                         err = notification_delete(notiHandle);
930                         SysLog(NID_APP, "Notification deleted.");
931                 }
932                 else
933                 {
934                         SysLog(NID_APP, "Notification already deleted.");
935                 }
936                 notification_free(notiHandle);
937         }
938         else
939         {
940                 err = notification_delete_all_by_type(pAppId.get(), notiType);
941                 SysLog(NID_APP, "All [%s] notification deleted.", onGoing ? "Ongoing" : "Normal");
942         }
943
944         switch (err)
945         {
946         case NOTIFICATION_ERROR_NONE:
947                 r = E_SUCCESS;
948                 break;
949
950         case NOTIFICATION_ERROR_INVALID_DATA:
951                 r = E_INVALID_ARG;
952                 break;
953
954         default:
955                 r = E_SYSTEM;
956                 break;
957         }
958
959         return r;
960 }
961
962 void
963 _NotificationManagerImpl::RemoveBadge(const char* pkgName) const
964 {
965         bool badgeExist = false;
966         badge_error_e badgeError = badge_is_existing(pkgName, &badgeExist);
967         SysLog(NID_APP, "badge_is_existing: exitst= %d, error= %d.", badgeExist, badgeError);   //#####
968         if (badgeExist)
969         {
970                 badgeError = badge_remove(pkgName);
971                 SysLog(NID_APP, "badge_remove: error= %d.", badgeError);        //#####
972         }
973         SysLog(NID_APP, "Badge removed.");
974 }
975
976 void
977 _NotificationManagerImpl::SetBadgeCount(const char* pkgName, int badgeCount) const
978 {
979         bool badgeExist;
980         badge_error_e badgeError = badge_is_existing(pkgName, &badgeExist);
981         SysLog(NID_APP, "badge_is_existing: error= %d.", badgeError);   //#####
982         if (!badgeExist)
983         {
984                 badgeError = badge_create(pkgName, pkgName);
985                 SysLog(NID_APP, "badge_create: error= %d.", badgeError);        //#####
986         }
987
988         badge_set_count(pkgName, badgeCount);
989         SysLog(NID_APP, "badge_set_count: badgeNumber= %d.", badgeCount);
990 }
991
992 int
993 _NotificationManagerImpl::GetBadgeCount(const char* pkgName) const
994 {
995         unsigned int count = 0;
996
997         badge_error_e badgeError = badge_get_count(pkgName, &count);
998         if (badgeError == BADGE_ERROR_NONE)
999         {
1000                 SysLog(NID_APP, "badge_get_count: ret= %d.", count);
1001                 return count;
1002         }
1003         else
1004         {
1005                 SysLog(NID_APP, "badge_get_count: error= %d.", badgeError);
1006                 return -1;
1007         }
1008 }
1009
1010 } }    // Tizen::Shell