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