Merge branch 'tizen_3.0' into tizen
[platform/core/api/webapi-plugins.git] / src / notification / notification_manager.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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 #include "notification/notification_manager.h"
18
19 #include <fcntl.h>
20 #include <unistd.h>
21
22 #include <app_control_internal.h>
23 #include <device/led.h>
24 #include <notification_internal.h>
25 #include <notification_list.h>
26 #include <app_common.h>
27
28 #include "common/converter.h"
29 #include "common/logger.h"
30 #include "common/scope_exit.h"
31
32 #include "notification/status_notification.h"
33 #include "notification/user_notification.h"
34 #include "notification/common_notification.h"
35
36 namespace extension {
37 namespace notification {
38
39 using namespace common;
40
41 NotificationManager::NotificationManager() {
42   LoggerD("Enter");
43 }
44
45 NotificationManager::~NotificationManager() {
46   LoggerD("Enter");
47 }
48
49 NotificationManager* NotificationManager::GetInstance() {
50   LoggerD("Enter");
51   static NotificationManager instance;
52   return &instance;
53 }
54
55 PlatformResult NotificationManager::Post(const picojson::object& args,
56                                          picojson::object& out) {
57   LoggerD("Enter");
58   return StatusNotification::PostStatusNotification(args, false, &out);
59 }
60
61 PlatformResult NotificationManager::PostUserNoti(const picojson::object& args,
62                                          picojson::object& out) {
63   LoggerD("Enter");
64   return UserNotification::PostUserNotification(args, false, &out);
65 }
66
67 PlatformResult NotificationManager::Update(const picojson::object& args) {
68   LoggerD("Enter");
69   return StatusNotification::PostStatusNotification(args, true, nullptr);
70 }
71
72 PlatformResult NotificationManager::UpdateUserNoti(const picojson::object& args) {
73   LoggerD("Enter");
74   return UserNotification::PostUserNotification(args, true, nullptr);
75 }
76
77
78 PlatformResult NotificationManager::Remove(const picojson::object& args) {
79   LoggerD("Enter");
80   int id = std::stoi(FromJson<std::string>(args, "id"));
81
82   int ret = notification_delete_by_priv_id(nullptr, NOTIFICATION_TYPE_NONE, id);
83   if (NOTIFICATION_ERROR_NONE != ret) {
84     return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR,
85                           "Cannot remove notification error",
86                           ("Cannot remove notification error: %d", ret));
87   }
88
89   return PlatformResult(ErrorCode::NO_ERROR);
90 }
91
92 PlatformResult NotificationManager::RemoveAll() {
93   LoggerD("Enter");
94   int ret = notification_delete_all(NOTIFICATION_TYPE_NOTI);
95   if (NOTIFICATION_ERROR_NONE != ret) {
96     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
97                           "Notification noti remove all failed",
98                           ("Notification remove all failed: %d", ret));
99   }
100
101   ret = notification_delete_all(NOTIFICATION_TYPE_ONGOING);
102   if (NOTIFICATION_ERROR_NONE != ret) {
103     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
104                           "Notification ongoing remove all failed",
105                           ("Notification remove all failed: %d", ret));
106   }
107
108   return PlatformResult(ErrorCode::NO_ERROR);
109 }
110
111 PlatformResult NotificationManager::Get(const picojson::object& args,
112                                         picojson::object& out, bool is_new_impl) {
113   LoggerD("Enter");
114   int id;
115   try {
116     id = std::stoi(FromJson<std::string>(args, "id"));
117   } catch (...) {
118     LoggerE("Failed to convert string to int");
119     return PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert string to int.");
120   }
121
122   app_control_h app_control = nullptr;
123   notification_h noti_handle = nullptr;
124
125   SCOPE_EXIT {
126     if (app_control) {
127       app_control_destroy(app_control);
128     }
129     free(noti_handle);
130   };
131
132   PlatformResult status = StatusNotification::GetNotiHandle(id, &noti_handle);
133   if (status.IsError())
134   {
135     LoggerE("Failed: GetNotiHandle");
136     return status;
137   }
138
139   status = StatusNotification::GetAppControl(noti_handle, &app_control);
140   if (status.IsError())
141   {
142     LoggerE("Failed: GetAppControl");
143     return status;
144   }
145
146   if (!is_new_impl) {
147     status = StatusNotification::ToJson(id, noti_handle, app_control, &out);
148   } else {
149     status = UserNotification::ToJson(id, noti_handle, app_control, &out);
150   }
151   if (status.IsError())
152   {
153     LoggerE("Failed: ToJson");
154     return status;
155   }
156   return PlatformResult(ErrorCode::NO_ERROR);
157 }
158
159 PlatformResult NotificationManager::GetAll(picojson::array& out, bool is_new_impl) {
160   LoggerD("Enter");
161   notification_h noti = nullptr;
162   notification_list_h noti_list = nullptr;
163   notification_list_h noti_list_iter = nullptr;
164   char* package = nullptr;
165
166   if (APP_ERROR_NONE == app_get_id(&package)) {
167     LoggerD("Package id: %s", package);
168   } else {
169     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
170                           "Could not get package id");
171   }
172   const std::string package_str = package;
173   free(package);
174
175   int ret = notification_get_detail_list(package_str.c_str(), NOTIFICATION_GROUP_ID_NONE,
176                                          NOTIFICATION_PRIV_ID_NONE, -1, &noti_list);
177   if (NOTIFICATION_ERROR_NONE != ret) {
178     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
179                           "Get notification list error",
180                           ("Get notification list error: %d", ret));
181   }
182
183   SCOPE_EXIT { notification_free_list(noti_list); };
184
185   noti_list_iter = notification_list_get_head(noti_list);
186
187   while (nullptr != noti_list_iter) {
188     noti = notification_list_get_data(noti_list_iter);
189     if (nullptr != noti) {
190       int noti_priv = -1;
191       ret = notification_get_id(noti, nullptr, &noti_priv);
192       if (NOTIFICATION_ERROR_NONE != ret) {
193         return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
194                               "Cannot get notification id error",
195                               ("Cannot get notification id, error: %d", ret));
196       }
197
198       app_control_h app_control = nullptr;
199       PlatformResult status =
200           StatusNotification::GetAppControl(noti, &app_control);
201
202       SCOPE_EXIT {
203           if (app_control) {
204               app_control_destroy(app_control);
205           }
206       };
207
208       if (status.IsError())
209         return status;
210
211       picojson::object noti_item = picojson::object();
212
213       if (!is_new_impl) {
214         status =
215             StatusNotification::ToJson(noti_priv, noti, app_control, &noti_item);
216       } else {
217         status =
218             UserNotification::ToJson(noti_priv, noti, app_control, &noti_item);
219       }
220       if (status.IsError())
221         return status;
222
223       out.push_back(picojson::value(noti_item));
224     }
225
226     noti_list_iter = notification_list_get_next(noti_list_iter);
227   }
228
229   return PlatformResult(ErrorCode::NO_ERROR);
230 }
231
232 PlatformResult NotificationManager::PlayLEDCustomEffect(
233     const picojson::object& args) {
234   LoggerD("Enter");
235
236   int timeOn = FromJson<double>(args, "timeOn");
237   int timeOff = FromJson<double>(args, "timeOff");
238   unsigned int color = FromJson<double>(args, "color");
239
240   auto& flags = FromJson<picojson::array>(args, "flags");
241   unsigned int platformFlags = 0;
242   for (auto flag : flags) {
243     std::string flagStr = JsonCast<std::string>(flag);
244     if ("LED_CUSTOM_DEFAULT" == flagStr)
245       platformFlags |= LED_CUSTOM_DEFAULT;
246     else if ("LED_CUSTOM_DUTY_ON" == flagStr)
247       platformFlags |= LED_CUSTOM_DUTY_ON;
248   }
249
250   int ret;
251   ret = device_led_play_custom(timeOn, timeOff, color, platformFlags);
252   if (DEVICE_ERROR_NONE != ret) {
253     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot play LED custom effect",
254                               ("Cannot play LED custom effect: ",ret));
255   }
256
257   return PlatformResult(ErrorCode::NO_ERROR);
258 }
259
260 PlatformResult NotificationManager::StopLEDCustomEffect() {
261   LoggerD("Enter");
262
263   int ret = device_led_stop_custom();
264   if (DEVICE_ERROR_NONE != ret) {
265     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot stop LED custom effect",
266                               ("Cannot stop LED custom effect: ",ret));
267   }
268
269   return PlatformResult(ErrorCode::NO_ERROR);
270 }
271
272 common::PlatformResult NotificationManager::SaveTemplate(const picojson::object& args) {
273   LoggerD("Enter");
274   std::string name = FromJson<std::string>(args, "name");
275   notification_h noti_handle = nullptr;
276   int ret;
277   SCOPE_EXIT {
278     notification_free(noti_handle);
279   };
280
281   PlatformResult status = PlatformResult(ErrorCode::NO_ERROR);
282   const auto& new_impl_it = args.find("newImpl");
283   if (args.end() != new_impl_it && new_impl_it->second.get<bool>()) {
284     status = UserNotification::GetNotiHandleFromJson(args, false, &noti_handle);
285   } else {
286     status = StatusNotification::GetNotiHandleFromJson(args, false, &noti_handle);
287   }
288
289   if (status.IsError()) {
290     return status;
291   }
292
293   ret = notification_save_as_template(noti_handle, name.c_str());
294   if (NOTIFICATION_ERROR_NONE != ret) {
295     LoggerD("Error: %d (%s)", ret, get_error_message(ret));
296     if (NOTIFICATION_ERROR_MAX_EXCEEDED == ret) {
297       return LogAndCreateResult(ErrorCode::QUOTA_EXCEEDED_ERR,
298                                 "Maximum number of templates exceeded",
299                                 ("Maximum number of templates exceeded, error: %d", ret));
300     } else {
301       return LogAndCreateResult(ErrorCode::ABORT_ERR,
302                                 "Saving template failed",
303                                 ("Saving template failed, error: %d", ret));
304     }
305   }
306
307   return PlatformResult(ErrorCode::NO_ERROR);
308 }
309
310
311 common::PlatformResult NotificationManager::CreateFromTemplate(const picojson::object& args,
312                                                                picojson::object& out) {
313   LoggerD("Enter");
314   std::string name = FromJson<std::string>(args, "name");
315
316   notification_h noti_handle = nullptr;
317   noti_handle = notification_create_from_template(name.c_str());
318   if (!noti_handle) {
319     return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR,
320                               "The template with given name not found",
321                               ("The template with given name not found, handle is nullptr"));
322   }
323
324   SCOPE_EXIT {
325     notification_free(noti_handle);
326   };
327
328   //This method is designed to return only UserNotification objects
329   PlatformResult status = UserNotification::ToJson(0, noti_handle, nullptr, &out);
330   if (status.IsError())
331   {
332     LoggerE("Failed: ToJson");
333     return status;
334   }
335   return PlatformResult(ErrorCode::NO_ERROR);
336 }
337
338 }  // namespace notification
339 }  // namespace extension