upload tizen1.0 source
[platform/framework/web/wrt.git] / src / view / common / view_logic_web_notification_support.cpp
1 /*
2  * Copyright (c) 2011 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  * @file    view_logic_web_notification_support.cpp
18  * @author  Jihoon Chung (jihoon.chung@samsung.com)
19  * @brief   Implementation file of web Notification API used by ViewLogic
20  */
21
22 #include "view_logic_web_notification_support.h"
23 #include <string>
24 #include <dpl/log/log.h>
25 #include <dpl/string.h>
26
27 #include <notification.h>
28 #include <pcrecpp.h>
29 #include <sstream>
30 #include <curl/curl.h>
31 #include <widget_model.h>
32
33 namespace {
34 const char* PATTERN_CHECK_EXTERNAL = "^http(s)?://\\w+.*$";
35 }
36
37 namespace ViewModule {
38 namespace WebNotification {
39
40 bool notificationShow(WebNotificationDataPtr notiData);
41 bool notificationHide(WebNotificationDataPtr notiData);
42 bool isExternalUri(const std::string &pattern, const std::string &uri);
43 bool downloadImage(WebNotificationDataPtr notiData);
44 size_t curlWriteData(void *ptr, size_t size, size_t nmemb, FILE *stream);
45
46 WebNotificationData::WebNotificationData(WidgetModel* widgetModel,
47                                          uint64_t id) :
48     m_widgetModel(widgetModel),
49     m_id(id)
50 {
51     Assert(m_widgetModel);
52 }
53
54 WebNotificationData::~WebNotificationData()
55 {
56 }
57
58 bool showWebNotification(WebNotificationDataPtr notiData)
59 {
60     LogInfo("showWebNotification called");
61
62     /* TODO : register notification to database */
63     return notificationShow(notiData);
64 }
65
66 bool cancelWebNotification(WebNotificationDataPtr /*notiData*/)
67 {
68     LogInfo("cancelWebNotification called");
69     return false;
70 }
71
72 bool notificationShow(WebNotificationDataPtr notiData)
73 {
74     LogDebug("notificationShow called");
75     Assert(notiData);
76     notification_h noti_h = NULL;
77     notification_error_e error = NOTIFICATION_ERROR_NONE;
78
79     Try {
80         // create notification
81         noti_h = notification_new(
82             NOTIFICATION_TYPE_NOTI, NOTIFICATION_GROUP_ID_NONE, notiData->m_id);
83         if (!noti_h) {
84             LogError("Fail to notification_new");
85             return false;
86         }
87
88         // set notification title
89         error = notification_set_text(
90             noti_h,
91             NOTIFICATION_TEXT_TYPE_TITLE,
92             notiData->m_title.c_str(),
93             NULL,
94             NOTIFICATION_VARIABLE_TYPE_NONE);
95         if (error != NOTIFICATION_ERROR_NONE) {
96             ThrowMsg(Exception::NotificationShowError, "Fail to set title");
97         }
98
99         // set notification content
100         error = notification_set_text(
101             noti_h,
102             NOTIFICATION_TEXT_TYPE_CONTENT,
103             notiData->m_body.c_str(),
104             NULL,
105             NOTIFICATION_VARIABLE_TYPE_NONE);
106         if (error != NOTIFICATION_ERROR_NONE) {
107             ThrowMsg(Exception::NotificationShowError,
108                      "Fail to set content:" << error);
109         }
110
111         //check uri is "http", https" or not
112         bool validIconURL = true;
113         LogInfo("url path is " << notiData->m_iconURL);
114         if (isExternalUri(PATTERN_CHECK_EXTERNAL, notiData->m_iconURL)) {
115             //download image from url
116             validIconURL = downloadImage(notiData);
117         }
118
119         //set image
120         // If fail to download external image, skip to set image.
121         // In this case, set to default package image.
122         if (true == validIconURL) {
123             error = notification_set_image(
124                 noti_h,
125                 NOTIFICATION_IMAGE_TYPE_ICON,
126                 notiData->m_iconURL.c_str());
127             if (error != NOTIFICATION_ERROR_NONE) {
128                 ThrowMsg(Exception::NotificationShowError,
129                          "Fail to free notification: " << error);
130             }
131         }
132
133         // insert notification
134         int priv_id = NOTIFICATION_PRIV_ID_NONE;
135         error = notification_insert(noti_h, &priv_id);
136         if (error != NOTIFICATION_ERROR_NONE) {
137             ThrowMsg(Exception::NotificationShowError,
138                      "Fail to insert notification: " << error);
139         }
140
141         LogInfo("Notification is inserted!");
142         LogInfo("noti id =[" << notiData->m_id << "] " <<
143                 "priv_id =[" << priv_id << "]");
144
145         if (noti_h) {
146             error = notification_free(noti_h);
147             if (error != NOTIFICATION_ERROR_NONE) {
148                         ThrowMsg(Exception::NotificationShowError,
149                                  "Fail to free notification: " << error);
150             }
151             noti_h = NULL;
152         }
153         return true;
154     } Catch(Exception::NotificationShowError) {
155         LogError(_rethrown_exception.GetMessage());
156         notification_free(noti_h);
157         noti_h = NULL;
158         return false;
159     } Catch(DPL::Exception) {
160         LogError(_rethrown_exception.GetMessage());
161         return false;
162     }
163 }
164
165 bool notificationHide(WebNotificationDataPtr notiData)
166 {
167     LogInfo("notificationHide called");
168
169     Assert(notiData);
170     return true;
171 }
172
173 bool isExternalUri(const std::string &pattern, const std::string &uri)
174 {
175     LogInfo("isExternalUri called");
176
177     pcrecpp::RE_Options pcreOpt;
178     pcreOpt.set_caseless(true);
179     pcrecpp::RE re(pattern, pcreOpt);
180
181     return re.FullMatch(uri);
182 }
183
184 bool downloadImage(WebNotificationDataPtr notiData)
185 {
186     LogInfo("downloadImage called");
187
188     Assert(notiData);
189     // download path is
190     // /opt/apps/pkgname/data + '/' + filename
191     std::string downloadPath =
192     DPL::ToUTF8String(
193             notiData->m_widgetModel->PersistentStoragePath.Get()) +  "/";
194     LogDebug("downloadPath " << downloadPath);
195
196     // Make valid filename
197     // If there is already exist filename, rename to "filename_%d"
198     std::string fileName =
199         notiData->m_iconURL.substr(notiData->m_iconURL.rfind('/') + 1);
200     LogDebug("fileName from URL: " << fileName);
201     std::string rename = fileName;
202     unsigned int renameSuffixNb = 0;
203     while (0 == access((downloadPath + rename).c_str(), F_OK)) {
204         std::ostringstream suffixOstr;
205         suffixOstr.str("");
206         suffixOstr << fileName << "_" << renameSuffixNb++;
207
208         rename = fileName;
209         rename.insert(rename.find('.'), suffixOstr.str());
210     }
211
212     downloadPath += rename;
213     LogDebug("Valid file path : " << downloadPath);
214
215     // Download image by curl
216     FILE *fp = NULL;
217     CURL *curl = NULL;
218
219     Try {
220         curl = curl_easy_init();
221         if (NULL == curl) {
222             ThrowMsg(Exception::InitError, "fail to curl_easy_init");
223         }
224
225         fp = fopen(downloadPath.c_str(), "wb");
226         if (fp == NULL) {
227             ThrowMsg(Exception::InitError, "fail to open");
228         }
229
230         curl_easy_setopt(curl, CURLOPT_URL, notiData->m_iconURL.c_str());
231         curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
232         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlWriteData);
233
234         CURLcode err = curl_easy_perform(curl);
235         if (0 != err) {
236             ThrowMsg(Exception::DownloadImageError,
237                      "fail to curl_easy_perform: " << err);
238         }
239         fclose(fp);
240         curl_easy_cleanup(curl);
241     } Catch (DPL::Exception) {
242         LogError(_rethrown_exception.GetMessage());
243         fclose(fp);
244         curl_easy_cleanup(curl);
245         return false;
246     }
247
248     LogDebug("Download success.. downloadedImgPath: " << downloadPath);
249     notiData->m_iconURL = downloadPath;
250     return true;
251 }
252
253 size_t curlWriteData(void *ptr, size_t size, size_t nmemb, FILE *stream)
254 {
255     size_t written = fwrite(ptr, size, nmemb, stream);
256     return written;
257 }
258
259 } // namespace WebNotification
260 } //namespace ViewModule