1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #ifndef QGEOROUTINGMANAGERENGINE_TEST_H
30 #define QGEOROUTINGMANAGERENGINE_TEST_H
31 
32 #include <qgeoserviceprovider.h>
33 #include <qgeoroutingmanagerengine.h>
34 #include <QLocale>
35 #include <qgeoaddress.h>
36 #include <qgeoroutereply.h>
37 #include <QtLocation/private/qgeoroute_p.h>
38 
39 #include <QDebug>
40 #include <QTimer>
41 #include <QTimerEvent>
42 
43 QT_USE_NAMESPACE
44 
45 
46 class QGeoRoutePrivateDefaultAlt : public QGeoRoutePrivateDefault
47 {
48 public:
QGeoRoutePrivateDefaultAlt()49     QGeoRoutePrivateDefaultAlt() : QGeoRoutePrivateDefault()
50     {
51         m_travelTime = 123456; // To identify this is actually a QGeoRoutePrivateDefaultAlt
52     }
QGeoRoutePrivateDefaultAlt(const QGeoRoutePrivateDefaultAlt & other)53     QGeoRoutePrivateDefaultAlt(const QGeoRoutePrivateDefaultAlt &other)
54         : QGeoRoutePrivateDefault(other) {}
~QGeoRoutePrivateDefaultAlt()55     ~QGeoRoutePrivateDefaultAlt() {}
56 
setTravelTime(int travelTime)57     void setTravelTime(int travelTime) override
58     {
59         Q_UNUSED(travelTime);
60     }
61 };
62 
63 class QGeoRouteAlt : public QGeoRoute
64 {
65 public:
QGeoRouteAlt()66     QGeoRouteAlt()
67     : QGeoRoute(QExplicitlySharedDataPointer<QGeoRoutePrivate>(new QGeoRoutePrivateDefaultAlt()))
68     {
69     }
70 };
71 
72 class RouteReplyTest :public QGeoRouteReply
73 {
74     Q_OBJECT
75 
76 public:
QGeoRouteReply(QGeoRouteRequest (),parent)77     RouteReplyTest(QObject *parent=0) :QGeoRouteReply (QGeoRouteRequest(), parent)
78     {}
callSetError(Error error,const QString & errorString)79     void  callSetError ( Error error, const QString & errorString ) {setError(error, errorString);}
callSetFinished(bool finished)80     void  callSetFinished ( bool finished ) {setFinished(finished);}
callSetRoutes(const QList<QGeoRoute> & routes)81     void  callSetRoutes(const QList<QGeoRoute> &routes) {setRoutes(routes);}
82 };
83 
84 class QGeoRoutingManagerEngineTest: public QGeoRoutingManagerEngine
85 {
86     Q_OBJECT
87     RouteReplyTest* routeReply_;
88     bool finishRequestImmediately_;
89     int timerId_;
90     QGeoRouteReply::Error errorCode_;
91     QString errorString_;
92     bool alternateGeoRouteImplementation_;
93 
94 public:
QGeoRoutingManagerEngineTest(const QVariantMap & parameters,QGeoServiceProvider::Error * error,QString * errorString)95     QGeoRoutingManagerEngineTest(const QVariantMap &parameters,
96         QGeoServiceProvider::Error *error, QString *errorString) :
97         QGeoRoutingManagerEngine(parameters),
98         routeReply_(0),
99         finishRequestImmediately_(true),
100         timerId_(0),
101         errorCode_(QGeoRouteReply::NoError),
102         alternateGeoRouteImplementation_(false)
103     {
104         Q_UNUSED(error);
105         Q_UNUSED(errorString);
106 
107         if (parameters.contains("gc_finishRequestImmediately")) {
108             finishRequestImmediately_ = qvariant_cast<bool>(parameters.value("gc_finishRequestImmediately"));
109         }
110 
111         if (parameters.contains("gc_alternateGeoRoute")) {
112             alternateGeoRouteImplementation_ = qvariant_cast<bool>(parameters.value("gc_alternateGeoRoute"));
113         }
114 
115         setLocale(QLocale (QLocale::German, QLocale::Germany));
116         setSupportedFeatureTypes (
117                     QGeoRouteRequest::NoFeature | QGeoRouteRequest::TollFeature |
118                     QGeoRouteRequest::HighwayFeature | QGeoRouteRequest::PublicTransitFeature |
119                     QGeoRouteRequest::FerryFeature | QGeoRouteRequest::TunnelFeature |
120                     QGeoRouteRequest::DirtRoadFeature | QGeoRouteRequest::ParksFeature |
121                     QGeoRouteRequest::MotorPoolLaneFeature );
122         setSupportedFeatureWeights (
123                     QGeoRouteRequest::NeutralFeatureWeight | QGeoRouteRequest::PreferFeatureWeight |
124                     QGeoRouteRequest::RequireFeatureWeight | QGeoRouteRequest::AvoidFeatureWeight |
125                     QGeoRouteRequest::DisallowFeatureWeight );
126         setSupportedManeuverDetails (
127                     QGeoRouteRequest::NoManeuvers | QGeoRouteRequest::BasicManeuvers);
128         setSupportedRouteOptimizations (
129                     QGeoRouteRequest::ShortestRoute | QGeoRouteRequest::FastestRoute |
130                     QGeoRouteRequest::MostEconomicRoute | QGeoRouteRequest::MostScenicRoute);
131         setSupportedSegmentDetails (
132                     QGeoRouteRequest::NoSegmentData | QGeoRouteRequest::BasicSegmentData );
133         setSupportedTravelModes (
134                     QGeoRouteRequest::CarTravel | QGeoRouteRequest::PedestrianTravel |
135                     QGeoRouteRequest::BicycleTravel | QGeoRouteRequest::PublicTransitTravel |
136                     QGeoRouteRequest::TruckTravel );
137     }
138 
calculateRoute(const QGeoRouteRequest & request)139     virtual QGeoRouteReply* calculateRoute(const QGeoRouteRequest& request)
140     {
141         routeReply_ = new RouteReplyTest();
142         connect(routeReply_, SIGNAL(aborted()), this, SLOT(requestAborted()));
143 
144         if (request.numberAlternativeRoutes() > 70) {
145             errorCode_ = (QGeoRouteReply::Error)(request.numberAlternativeRoutes() - 70);
146             errorString_ = "error";
147         } else {
148             errorCode_ = QGeoRouteReply::NoError;
149             errorString_ = "";
150         }
151         setRoutes(request, routeReply_);
152         if (finishRequestImmediately_) {
153             if (errorCode_) {
154                 routeReply_->callSetError(errorCode_, errorString_);
155             } else {
156                 routeReply_->callSetError(QGeoRouteReply::NoError, "no error");
157                 routeReply_->callSetFinished(true);
158             }
159         } else {
160             // we only allow serialized requests in QML - previous must have been aborted or finished
161             Q_ASSERT(timerId_ == 0);
162             timerId_ = startTimer(200);
163         }
164         return static_cast<QGeoRouteReply*>(routeReply_);
165     }
166 
setRoutes(const QGeoRouteRequest & request,RouteReplyTest * reply)167     void setRoutes(const QGeoRouteRequest& request, RouteReplyTest* reply)
168     {
169         QList<QGeoRoute> routes;
170         int travelTime = 0;
171         if (request.extraParameters().contains("test-traveltime"))
172             travelTime = request.extraParameters().value("test-traveltime").toMap().value("requestedTime").toInt();
173 
174         for (int i = 0; i < request.numberAlternativeRoutes(); ++i) {
175             QGeoRoute route;
176             if (alternateGeoRouteImplementation_)
177                 route = QGeoRouteAlt();
178             route.setPath(request.waypoints());
179             route.setTravelTime(travelTime);
180 
181             const QList<QVariantMap> metadata = request.waypointsMetadata();
182             for (const auto &meta: metadata) {
183                 if (meta.contains("extra")) {
184                     QVariantMap extra = meta.value("extra").toMap();
185                     if (extra.contains("user_distance"))
186                         route.setDistance(meta.value("extra").toMap().value("user_distance").toMap().value("distance").toDouble());
187                 }
188             }
189 
190             if (request.departureTime().isValid()) {
191                 QVariantMap extendedAttributes = route.extendedAttributes();
192                 extendedAttributes["tst_departureTime"] = request.departureTime();
193                 route.setExtendedAttributes(extendedAttributes);
194             }
195 
196             routes.append(route);
197         }
198         reply->callSetRoutes(routes);
199     }
200 
201 public Q_SLOTS:
requestAborted()202     void requestAborted()
203     {
204         if (timerId_) {
205             killTimer(timerId_);
206             timerId_ = 0;
207         }
208         errorCode_ = QGeoRouteReply::NoError;
209         errorString_ = "";
210     }
211 
212 protected:
timerEvent(QTimerEvent * event)213      void timerEvent(QTimerEvent *event)
214      {
215          Q_UNUSED(event);
216          Q_ASSERT(timerId_ == event->timerId());
217          Q_ASSERT(routeReply_);
218          killTimer(timerId_);
219          timerId_ = 0;
220          if (errorCode_) {
221              routeReply_->callSetError(errorCode_, errorString_);
222              emit error(routeReply_, errorCode_, errorString_);
223          } else {
224              routeReply_->callSetError(QGeoRouteReply::NoError, "no error");
225              routeReply_->callSetFinished(true);
226              emit finished(routeReply_);
227          }
228      }
229 };
230 
231 #endif
232