[Release] livebox.web-provider-1.46
[platform/framework/web/web-provider.git] / src / Core / BoxSchemeHandler.cpp
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
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  * @file    BoxSchemeHandler.cpp
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  */
20
21 #include <string.h>
22 #include <ctime>
23 #include "Box.h"
24 #include "Service/AppControl.h"
25 #include "Service/PeriodChanger.h"
26 #include "Service/ScrollHolder.h"
27 #include "Service/MessageManager.h"
28 #include "Util/Log.h"
29 #include "BoxSchemeHandler.h"
30
31 using namespace Service;
32
33 static const std::string BOX_SCHEME("box://");
34 static const std::string BOX_SCHEME_RELOAD("box://reload");
35 static const std::string BOX_SCHEME_CHANGE_PERIOD("box://change-period");
36 static const std::string BOX_SCHEME_LAUNCH_BROWSER("box://launch-browser");
37 static const std::string BOX_SCHEME_SCROLL_START("box://scroll-start");
38 static const std::string BOX_SCHEME_SCROLL_STOP("box://scroll-stop");
39 static const std::string BOX_SCHEME_SEND_MESSAGE_TO_PD("box://send-message-to-pd");
40 static const std::string BOX_SCHEME_SEND_MESSAGE_TO_BOX("box://send-message-to-box");
41
42 static const std::string HTTP_SCHEME("http://");
43 static const std::string HTTPS_SCHEME("https://");
44
45 // static variable intialization
46 BoxSchemeHandler* BoxSchemeHandler::s_instance = NULL;
47
48 BoxSchemeHandler::BoxSchemeHandler()
49     : m_boxMap()
50 {
51     LogD("enter");
52 }
53
54 BoxSchemeHandler::~BoxSchemeHandler()
55 {
56     LogD("enter");
57 }
58
59 BoxSchemeHandler* BoxSchemeHandler::Instance()
60 {
61     LogD("enter");
62     if (!s_instance) {
63         s_instance = new BoxSchemeHandler();
64     }
65
66     return s_instance;
67 }
68
69 void BoxSchemeHandler::registerBox(std::string& instanceId, Box* box)
70 {
71     LogD("enter");
72
73     if (getBox(instanceId)) {
74         LogD("already registered");
75         return;
76     }
77
78     m_boxMap.insert(BoxMapPair(instanceId, box));
79 }
80
81 void BoxSchemeHandler::unregisterBox(std::string& instanceId)
82 {
83     LogD("enter");
84     m_boxMap.erase(instanceId);
85 }
86
87 bool BoxSchemeHandler::process(std::string& instanceId, std::string& uri)
88 {
89     LogD("enter");
90
91     if (!isBoxScheme(uri)) {
92         return false;
93     }
94
95     if (!uri.compare(BOX_SCHEME_RELOAD)) {
96        return handleReload(instanceId);
97     }
98
99     if (!uri.compare(
100                 0,
101                 BOX_SCHEME_CHANGE_PERIOD.size(),
102                 BOX_SCHEME_CHANGE_PERIOD)) 
103     {
104         std::string key("period");
105         std::string period = parse(uri, key);
106         if (period.empty()) {
107             return handleChangePeriod(instanceId);
108         }
109
110         return handleChangePeriod(instanceId, std::atof(period.c_str()));
111     }
112
113     if (!uri.compare(
114                 0,
115                 BOX_SCHEME_LAUNCH_BROWSER.size(),
116                 BOX_SCHEME_LAUNCH_BROWSER))
117     {
118         std::string key("url");
119         std::string url = parse(uri, key);
120         return handleLaunchBrowser(instanceId, url);
121     }
122
123     if (!uri.compare(BOX_SCHEME_SCROLL_START)) {
124        return handleScroll(instanceId, true);
125     }
126
127     if (!uri.compare(BOX_SCHEME_SCROLL_STOP)) {
128        return handleScroll(instanceId, false);
129     }
130
131     if (!uri.compare(
132                 0,
133                 BOX_SCHEME_SEND_MESSAGE_TO_BOX.size(),
134                 BOX_SCHEME_SEND_MESSAGE_TO_BOX))
135     {
136         std::string key("message");
137         std::string message = parse(uri, key);
138         return handleSendMessage(instanceId, MessageManager::TO_BOX, message);
139     }
140
141     if (!uri.compare(
142                 0,
143                 BOX_SCHEME_SEND_MESSAGE_TO_PD.size(),
144                 BOX_SCHEME_SEND_MESSAGE_TO_PD))
145     {
146         std::string key("message");
147         std::string message = parse(uri, key);
148         return handleSendMessage(instanceId, MessageManager::TO_PD, message);
149     }
150     LogD("unknown box scheme protocol");
151     return false;
152 }
153
154 bool BoxSchemeHandler::isBoxScheme(std::string& uri)
155 {
156     LogD("enter");
157     if(!uri.compare(0, BOX_SCHEME.size(), BOX_SCHEME)) {
158         return true;
159     }
160
161     return false;
162 }
163
164 Box* BoxSchemeHandler::getBox(std::string& instanceId)
165 {
166     LogD("enter");
167
168     auto it = m_boxMap.find(instanceId);
169     if (it != m_boxMap.end()) {
170         LogD("registered: %s (%p)", it->first.c_str(), it->second);
171         return it->second;
172     }
173
174     return NULL;
175 }
176
177 bool BoxSchemeHandler::handleScroll(std::string& instanceId, bool start)
178 {
179     using namespace Service::ScrollHolder;
180
181     LogD("enter");
182         Box* box = getBox(instanceId);
183     if (!box) {
184         LogD("unregistered instance");
185         return false;
186     }
187
188     holdHorizontalScroll(box->m_boxInfo->boxId, instanceId, start);
189     return true;
190 }
191
192 bool BoxSchemeHandler::handleReload(std::string& instanceId)
193 {
194     LogD("enter");
195     Box* box = getBox(instanceId);
196     if (!box) {
197         LogD("unregistered instance");
198         return false;
199     }
200
201     // In the future, new content info can be set by caller
202     box->updateInternal();
203     return true;
204 }
205
206 bool BoxSchemeHandler::handleChangePeriod(std::string& instanceId, float requestedPeriod)
207 {
208     LogD("enter");
209
210     Box* box = getBox(instanceId);
211     if (!box) {
212         LogD("no box for update period");
213         return false;
214     }
215
216     m_periodChanger =
217         Service::PeriodChanger::create(
218             box->m_boxInfo->boxId, instanceId,
219             box->m_boxInfo->period, requestedPeriod);
220
221     return m_periodChanger->change();
222 }
223
224 bool BoxSchemeHandler::handleLaunchBrowser(std::string& instanceId, std::string& url)
225 {
226     LogD("enter");
227     if (!url.compare(0, HTTP_SCHEME.size(), HTTP_SCHEME) ||
228         !url.compare(0, HTTPS_SCHEME.size(), HTTPS_SCHEME))
229     {
230         return Service::AppControl::launchBrowser(url);
231     }
232
233     return false;
234 }
235
236 bool BoxSchemeHandler::handleSendMessage(
237         std::string& instanceId, 
238         MessageManager::ReceiverType receiver, 
239         std::string& message)
240 {
241     LogD("enter");
242     Box* box = getBox(instanceId);
243     if (!box) {
244         LogD("no box for update period");
245         return false;
246     };
247
248     // set webview of receiver
249     Evas_Object* webview;
250     switch (receiver) {
251     case MessageManager::TO_BOX:
252         webview = box->m_view->getBoxWebView();
253         break;
254     case MessageManager::TO_PD:
255         webview = box->m_view->getPdWebView();
256         break;
257     default:
258         LogD("not supported receiver");
259         return false;
260     }
261
262     return m_messageManager->send(webview, receiver, message); 
263 }
264
265 std::string BoxSchemeHandler::parse(std::string& uri, std::string& key)
266 {
267     LogD("enter");
268
269     // TODO url parameter SHOULD be parsed using std::regex, not manually
270     std::string value("");
271
272     unsigned found = uri.find_first_of("?");
273     if (found == std::string::npos) {
274         LogD("no query");
275         return value;
276     }
277
278     std::string query = std::string(uri, found + 1);
279     found = 0;
280     do {
281         LogD("enter\n");
282         unsigned seperator = query.find_first_of("=", found + 1);
283         if (seperator == std::string::npos) {
284             LogD("no '=' character\n");
285             break;
286         }
287
288         unsigned next = query.find_first_of("@", found + 1);
289         if (!query.compare(found, key.size(), key)) {
290             LogD("key matched!\n");
291             value = std::string(query, seperator + 1, next - seperator - 1);
292             break;
293         }
294
295         found = next + 1;
296     } while (found && found != std::string::npos);
297
298     LogD("URL query parsing result: key -> %s, value -> %s", key.c_str(), value.c_str());
299     return value;
300 }