Add beta version to sandbox
[apps/onscreenapp.git] / app / eventhandler.cpp
1 /*
2  * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
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 "eventhandler.h"
18 #include <functional>
19 #include <QUrl>
20 #include <QDebug>
21 #include <QJsonDocument>
22 #include <QJsonObject>
23 #include <QQuickWindow>
24 #include <QPixmap>
25 #include <QBitmap>
26 #include <QImage>
27
28 void* EventHandler::myThis = 0;
29 #define SCREEN_AREA "OnScreen"
30 #define SCREEN_NAME "OnScreenApp"
31
32 EventHandler::EventHandler(QObject *parent) :
33     QObject(parent),
34     mp_hs(NULL),
35     mp_wm(NULL),
36     mp_qw(NULL)
37 {
38     m_isActive = false;
39     m_vecOSM.clear();
40 }
41
42 EventHandler::~EventHandler()
43 {
44     if (mp_hs != NULL) {
45         delete mp_hs;
46     }
47     if (mp_wm != NULL) {
48         delete mp_wm;
49     }
50 }
51
52 void EventHandler::init(int port, const char *token)
53 {
54     myThis = this;
55     mp_wm = new QLibWindowmanager();
56     mp_wm->init(port, token);
57
58     mp_hs = new LibHomeScreen();
59     mp_hs->init(port, token);
60     
61     mp_hs->registerCallback(nullptr, EventHandler::onRep_static);
62     mp_hs->set_event_handler(LibHomeScreen::Event_OnScreenMessage, [this](json_object *object){
63         struct json_object *value;
64         json_object_object_get_ex(object, "display_message", &value);
65         const char *display_message = json_object_get_string(value);
66
67         HMI_DEBUG("onscreenapp", "display_message = %s", display_message);
68
69         QString data(display_message);
70         QJsonDocument doc = QJsonDocument::fromJson(data.toUtf8());
71         QJsonObject jsonObj(doc.object());
72
73         ON_SCREEN_MESSAGE osm;
74
75         if (jsonObj.contains("app")) {
76             HMI_DEBUG("onscreenapp", "json parse. app is %s", jsonObj["app"].toString().toStdString().c_str());
77             osm.app = jsonObj["app"].toString();
78         }
79
80         if (jsonObj.contains("message")) {
81             HMI_DEBUG("onscreenapp", "json parse. message is %s", jsonObj["message"].toString().toStdString().c_str());
82             osm.message = jsonObj["message"].toString();
83         }
84
85         if (jsonObj.contains("file")) {
86             HMI_DEBUG("onscreenapp", "json parse. file is %s", jsonObj["file"].toString().toStdString().c_str());
87             osm.file = jsonObj["file"].toString();
88
89             if (osm.file.left(1) == "/") {
90                 osm.file = QUrl::fromLocalFile(osm.file).toString();
91             }
92         }
93
94         if (jsonObj.contains("mask")) {
95             HMI_DEBUG("onscreenapp", "json parse. mask is %s", jsonObj["mask"].toString().toStdString().c_str());
96             osm.mask = jsonObj["mask"].toString();
97
98             if (osm.mask.left(1) == "/") {
99                 osm.mask = QUrl::fromLocalFile(osm.mask).toString();
100             }
101         }
102
103         bool isNewApp = true;
104         for(QVector<ON_SCREEN_MESSAGE>::iterator it = m_vecOSM.begin(); it != m_vecOSM.end(); ++it) {
105             if (it->app == osm.app) {
106                 it->message = osm.message;
107                 it->file = osm.file;
108                 it->mask = osm.mask;
109                 isNewApp = false;
110                 break;
111             }
112         }
113
114         if (isNewApp) {
115             m_vecOSM.append(osm);
116         }
117
118         if (osm.app == "Phone") {
119             if (osm.message == "incoming call") {
120                 this->activateSurface(osm.app);
121                 emit this->signalLoader(QVariant(osm.file));
122                 emit this->signalSetClearBackgroud();
123             }
124             else if (osm.message == "call rejected") {
125                 this->deactivateSurface(osm.app);
126             }
127         }
128         else if (osm.app == "System") {
129             if (osm.message == "error") {
130                 this->activateSurface(osm.app);
131                 emit this->signalLoader(QVariant(osm.file));
132                 emit this->signalSetClearBackgroud();
133             }
134             else if (osm.message == "rejected") {
135                 this->deactivateSurface(osm.app);
136             }
137         }
138         else {
139             if (osm.message == "onscreenapp:unload") {
140                 this->deactivateSurface(osm.app);
141             }
142             else {
143                 this->activateSurface(osm.app);
144                 if (osm.file.isEmpty()) {
145                     emit this->signalSetDefaultBackgroud(QVariant(osm.message));
146                 }
147                 else {
148                     emit this->signalLoader(QVariant(osm.file));
149                     emit this->signalSetClearBackgroud();
150                 }
151
152                 emit this->signalOnScreenMessage(QVariant(osm.message));
153             }
154         }
155
156         if (osm.mask.isEmpty()) {
157             this->setWindowMask(":/images/default_1079x400.png");
158         }
159         else {
160             this->setWindowMask(osm.mask);
161         }
162
163     });
164
165     if (mp_wm->requestSurface(SCREEN_NAME) != 0) {
166         HMI_DEBUG("onscreenapp", "!!!!LayoutHandler requestSurface Failed!!!!!");
167         exit(EXIT_FAILURE);
168     }
169
170     mp_wm->set_event_handler(QLibWindowmanager::Event_SyncDraw, [this](json_object *object) {
171         HMI_DEBUG("onscreenapp", "Surface %s got syncDraw!", SCREEN_NAME);
172         this->mp_wm->endDraw(SCREEN_NAME);
173     });
174
175     mp_wm->set_event_handler(QLibWindowmanager::Event_Active, [this](json_object *object) {
176         struct json_object *value;
177         json_object_object_get_ex(object, "drawing_name", &value);
178         const char *name = json_object_get_string(value);
179
180         HMI_DEBUG("onscreenapp", "Event_Active kKeyDrawingName = %s", name);
181     });
182
183     mp_wm->set_event_handler(QLibWindowmanager::Event_Inactive, [this](json_object *object) {
184         struct json_object *value;
185         json_object_object_get_ex(object, "drawing_name", &value);
186         const char *name = json_object_get_string(value);
187
188         HMI_DEBUG("onscreenapp", "Event_Inactive kKeyDrawingName = %s", name);
189     });
190
191     HMI_DEBUG("onscreenapp", "LayoutHander::init() finished.");
192 }
193
194 void EventHandler::setQuickWindow(QQuickWindow *qw)
195 {
196     mp_qw = qw;
197 }
198
199 void EventHandler::onRep_static(struct json_object* reply_contents)
200 {
201     static_cast<EventHandler*>(EventHandler::myThis)->onRep(reply_contents);
202 }
203 void EventHandler::onRep(struct json_object* reply_contents)
204 {
205     const char* str = json_object_to_json_string(reply_contents);
206     HMI_DEBUG("onscreenapp", "EventHandler::onReply %s", str);
207 }
208
209 void EventHandler::activateSurface(QString app)
210 {
211     HMI_DEBUG("onscreenapp", "EventHandler::activateSurface()");
212     if (m_isActive == false) {
213         m_isActive = true;
214         mp_wm->activateSurface(SCREEN_NAME);
215     }
216
217     QString label = SCREEN_AREA + app;
218     mp_wm->activateSurface(label, SCREEN_AREA);
219 }
220
221 void EventHandler::deactivateSurface(QString app)
222 {
223     HMI_DEBUG("onscreenapp", "EventHandler::deactivateSurface()");
224
225     for(QVector<ON_SCREEN_MESSAGE>::iterator it = m_vecOSM.begin(); it != m_vecOSM.end(); ++it) {
226         if (it->app == app) {
227             m_vecOSM.erase(it);
228             break;
229         }
230     }
231
232     if (m_vecOSM.length() > 0) {
233         ON_SCREEN_MESSAGE osm = m_vecOSM.last();
234
235         if (!osm.file.isEmpty()) {
236             emit this->signalLoader(QVariant(osm.file));
237             emit this->signalSetClearBackgroud();
238             emit this->signalOnScreenMessage(QVariant(osm.message));
239         }
240
241         if (osm.mask.isEmpty()) {
242             this->setWindowMask(":/images/default_1079x400.png");
243         }
244         else {
245             this->setWindowMask(osm.mask);
246         }
247
248     } else {
249         // nothing on screen
250         emit this->signalLoader(QVariant(""));
251         mp_wm->deactivateSurface(SCREEN_NAME);
252         m_isActive = false;
253     }
254 }
255
256 void EventHandler::onScreenReply(const QString &message)
257 {
258     HMI_DEBUG("onscreenapp", "EventHandler::onScreenReply()");
259     mp_hs->onScreenReply(message.toLatin1());
260 }
261
262 #if USE_TEST_DISPLAY
263 void EventHandler::slotActivateSurface(){
264     // This is needed for first rendering when the app is launched
265     if(!m_isActive){
266         m_isActive = true;
267         this->activateSurface();
268     }
269 }
270 #endif
271
272 void EventHandler::setWindowMask(QString maskfile)
273 {
274     HMI_DEBUG("onscreenapp", "EventHandler::setWindowMask()");
275     HMI_DEBUG("onscreenapp", "maskfile = %s", maskfile.toStdString().c_str());
276
277     QImage img(maskfile);
278     QPixmap mask = QPixmap::fromImage(img);
279
280     if (mask.hasAlphaChannel()) {
281         HMI_DEBUG("onscreenapp", "input maskfile has alpha.");
282         mp_qw->setMask(mask.mask());
283     }
284     else {
285         HMI_DEBUG("onscreenapp", "!!!! maskfile does not have alpha!!!!");
286     }
287 }