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 ¶meters, 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