8#include <QtCore/private/qcore_ohos_p.h>
9#include <QtCore/private/qnapi_p.h>
10#include <QtCore/private/qohoscommon_p.h>
11#include <QtCore/private/qohoslogger_p.h>
12#include <QtCore/qset.h>
13#include <QtCore/qmath.h>
14#include <QtPositioning/qgeosatelliteinfo.h>
52 QOhosJsState &jsState, QNapi::Object satelliteStatusInfoObject)
54 auto satelliteConstellationArray = QNapi::getOptionalPropOrEmpty<QNapi::Array>(
55 satelliteStatusInfoObject,
"satelliteConstellation");
57 return !satelliteConstellationArray.IsEmpty()
59 QNapi::getArrayElements<std::vector<SatelliteConstellationCategory>, QNapi::Number>(
60 satelliteConstellationArray,
61 [&](
auto satelliteConstellation) {
62 return jsState.mapOhosEnumFromJs<SatelliteConstellationCategory>(satelliteConstellation);
68 QOhosJsState &, QNapi::Object satelliteStatusInfoObject)
70 auto satelliteAdditionalInfoArray = QNapi::getOptionalPropOrEmpty<QNapi::Array>(
71 satelliteStatusInfoObject,
"satelliteAdditionalInfo");
73 return !satelliteAdditionalInfoArray.IsEmpty()
75 QNapi::getArrayElements<std::vector<
int>, QNapi::Number>(satelliteAdditionalInfoArray))
81 int satelliteUsedInValueFlag = jsState.eval<QNapi::Number>(
82 "@ohos.geoLocationManager.SatelliteAdditionalInfo.SATELLITES_ADDITIONAL_INFO_USED_IN_FIX");
84 return (satelliteAdditionalInfo & satelliteUsedInValueFlag) != 0;
88 QOhosJsState &jsState, QNapi::Object satelliteStatusInfoObject)
90 int satellitesNumber = satelliteStatusInfoObject.get<QNapi::Number>(
"satellitesNumber");
91 auto satelliteIds = QNapi::getArrayElements<std::vector<
int>, QNapi::Number>(
92 satelliteStatusInfoObject.get<QNapi::Array>(
"satelliteIds"));
93 auto carrierToNoiseDensities = QNapi::getArrayElements<std::vector<
double>, QNapi::Number>(
94 satelliteStatusInfoObject.get<QNapi::Array>(
"carrierToNoiseDensitys"));
95 auto altitudes = QNapi::getArrayElements<std::vector<
double>, QNapi::Number>(
96 satelliteStatusInfoObject.get<QNapi::Array>(
"altitudes"));
97 auto azimuths = QNapi::getArrayElements<std::vector<
double>, QNapi::Number>(
98 satelliteStatusInfoObject.get<QNapi::Array>(
"azimuths"));
99 auto satelliteConstellations = tryGetSatelliteConstelationCategoriesFromSatelliteStatusInfoObject(
100 jsState, satelliteStatusInfoObject);
101 auto satelliteAdditionalInfos = tryGetSatelliteAdditionalInfosFromSatelliteStatusInfoObject(
102 jsState, satelliteStatusInfoObject);
104 std::vector<SatelliteInfo> satelliteInfos;
105 satelliteInfos.reserve(satellitesNumber);
107 for (
int i = 0; i < satellitesNumber; i++) {
108 satelliteInfos.push_back(SatelliteInfo{
109 .id = satelliteIds[i],
110 .carrierToNoiseDensity = carrierToNoiseDensities[i],
111 .altitude = altitudes[i],
112 .azimuth = azimuths[i],
113 .optConstellationCategory = satelliteConstellations.has_value()
114 ? std::make_optional(satelliteConstellations.value()[i])
116 .usedInFix = satelliteAdditionalInfos.has_value()
117 ? isSatelliteUsedInFix(jsState, satelliteAdditionalInfos.value()[i])
122 return satelliteInfos;
128 switch (constellationCategory) {
129 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_UNKNOWN:
130 return QGeoSatelliteInfo::Undefined;
131 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_GPS:
132 return QGeoSatelliteInfo::GPS;
133 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_GLONASS:
134 return QGeoSatelliteInfo::GLONASS;
135 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_SBAS:
136 return QGeoSatelliteInfo::SBAS;
137 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_QZSS:
138 return QGeoSatelliteInfo::QZSS;
139 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_BEIDOU:
140 return QGeoSatelliteInfo::BEIDOU;
141 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_GALILEO:
142 return QGeoSatelliteInfo::GALILEO;
143 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_IRNSS:
144 return QGeoSatelliteInfo::IRNSS;
147 qOhosReportFatalErrorAndAbort(
148 "%s Received an unknown SatelliteConstellationCategory: %d",
149 Q_FUNC_INFO, constellationCategory);
153 QObject *contextObject, QOhosConsumer<std::vector<SatelliteInfo>> satelliteStatusInfoConsumer)
155 qOhosDebug(QtForOhos) << Q_FUNC_INFO << contextObject;
157 auto contextObjectRef = QtOhos::makeQThreadSafeRef(contextObject);
158 auto sharedSatelliteStatusInfoConsumer =
159 QtOhos::moveToSharedPtr(std::move(satelliteStatusInfoConsumer));
160 auto weakSatelliteStatusInfoConsumer = QtOhos::makeWeakPtr(sharedSatelliteStatusInfoConsumer);
162 auto registrationHandle = QOhosJsThreadGateway::eval(
163 [&](QOhosJsState &jsState) {
164 return QtOhos::registerOnOffMethodsBasedEventHandler(
165 getGeoLocationManagerObject(jsState),
"satelliteStatusChange",
166 [contextObjectRef, weakSatelliteStatusInfoConsumer](
const QOhosCallbackInfo &cbInfo) {
167 auto satelliteStatusInfo = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
168 auto satelliteInfos = convertJsSatelliteStatusInfoObjectToQGeoSatelliteInfos(
169 cbInfo.jsState(), satelliteStatusInfo);
170 contextObjectRef.visitInQtThreadIfAlive(
171 [weakSatelliteStatusInfoConsumer, satelliteInfos](
auto &) {
172 auto sharedSatelliteStatusInfoConsumer = weakSatelliteStatusInfoConsumer.lock();
173 if (sharedSatelliteStatusInfoConsumer)
174 (*sharedSatelliteStatusInfoConsumer)(satelliteInfos);
179 return QtOhos::moveToSharedPtr(
180 std::make_pair(registrationHandle, sharedSatelliteStatusInfoConsumer));
206 void startUpdatesHelper();
207 void setErrorHelper(Error error);
209 void handleSatelliteStatusInfoUpdate(std::vector<SatelliteInfo> updatedSatelliteStatusInfo);
210 void handleSingleUpdateFinished();
211 void handleUpdateFinished();
213 QSet<UpdateType> m_updateTypes;
214 std::shared_ptr<
void> m_updateSatelliteStatusInfoProducerHandle;
215 std::unique_ptr<QGeoPositionInfoSource> m_positionInfoSource;
217 std::unique_ptr<QTimer> m_singleUpdateTimeoutTimer;
219 std::optional<QList<QGeoSatelliteInfo>> m_lastUpdatedSatellitesInView;
220 std::optional<QList<QGeoSatelliteInfo>> m_lastUpdatedSatellitesInUse;
228 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
235 qOhosDebug(QtForOhos) << Q_FUNC_INFO << msec;
237 if (msec != updateAsOftenAsNecessaryInterval)
238 qOhosWarning(QtForOhos) << Q_FUNC_INFO <<
"Specific update intervals are not supported";
243 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
250 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
257 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
260 qOhosWarning(QtForOhos) << Q_FUNC_INFO <<
"Location permission not granted. Can't start updates";
261 setErrorHelper(QGeoSatelliteInfoSource::AccessError);
265 if (m_updateTypes.contains(UpdateType::ContinuousUpdate))
268 m_updateTypes.insert(UpdateType::ContinuousUpdate);
270 if (!m_updateSatelliteStatusInfoProducerHandle && !m_positionInfoSource)
271 startUpdatesHelper();
276 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
278 m_updateTypes.remove(UpdateType::ContinuousUpdate);
280 handleUpdateFinished();
285 qOhosDebug(QtForOhos) << Q_FUNC_INFO << timeout;
288 qOhosWarning(QtForOhos) << Q_FUNC_INFO <<
"Location permission not granted. Can't request update";
289 setErrorHelper(QGeoSatelliteInfoSource::AccessError);
293 if (m_updateTypes.contains(UpdateType::SingleUpdate))
296 m_updateTypes.insert(UpdateType::SingleUpdate);
298 if (!m_updateSatelliteStatusInfoProducerHandle && !m_positionInfoSource)
299 startUpdatesHelper();
301 m_singleUpdateTimeoutTimer = makeSingleShotUpdateTimeoutTimer(
303 if (m_lastUpdatedSatellitesInUse.has_value() && m_lastUpdatedSatellitesInView.has_value()) {
304 Q_EMIT satellitesInUseUpdated(m_lastUpdatedSatellitesInUse.value());
305 Q_EMIT satellitesInViewUpdated(m_lastUpdatedSatellitesInView.value());
307 Q_EMIT errorOccurred(QGeoSatelliteInfoSource::UpdateTimeoutError);
310 handleSingleUpdateFinished();
316 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
318 m_updateSatelliteStatusInfoProducerHandle =
319 registerSatelliteStatusInfoProducerConsumer(
320 this, [
this](
auto updatedSatelliteInfos) {
321 handleSatelliteStatusInfoUpdate(updatedSatelliteInfos);
324 m_positionInfoSource = std::unique_ptr<QGeoPositionInfoSource>(tryMakeQOhosGeoPositionInfoSource());
325 if (!m_positionInfoSource)
326 qOhosReportFatalErrorAndAbort(
"%s positionInfoSource is invalid", Q_FUNC_INFO);
328 m_positionInfoSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
329 m_positionInfoSource->startUpdates();
334 qOhosWarning(QtForOhos) << Q_FUNC_INFO << error;
336 if (m_error == error)
341 if (error != QGeoSatelliteInfoSource::NoError)
342 Q_EMIT QGeoSatelliteInfoSource::errorOccurred(m_error);
346 std::vector<SatelliteInfo> updatedSatellites)
348 qOhosDebug(QtForOhos) << Q_FUNC_INFO <<
"found" << updatedSatellites.size() <<
"satellites";
350 QList<QGeoSatelliteInfo> satellitesInView;
351 QList<QGeoSatelliteInfo> satellitesInUse;
353 for (
const auto &updatedSatellite : updatedSatellites) {
354 if (qFuzzyIsNull(updatedSatellite.carrierToNoiseDensity))
357 QGeoSatelliteInfo satelliteInfo;
358 satelliteInfo.setSatelliteIdentifier(updatedSatellite.id);
359 satelliteInfo.setSatelliteSystem(
360 updatedSatellite.optConstellationCategory.has_value()
361 ? convertSatelliteConstellationCategoryToQt(updatedSatellite.optConstellationCategory.value())
362 : QGeoSatelliteInfo::SatelliteSystem::Undefined);
363 satelliteInfo.setSignalStrength(updatedSatellite.carrierToNoiseDensity);
364 satelliteInfo.setAttribute(QGeoSatelliteInfo::Azimuth, updatedSatellite.azimuth);
365 satelliteInfo.setAttribute(QGeoSatelliteInfo::Elevation, updatedSatellite.altitude);
367 satellitesInView.append(satelliteInfo);
368 if (updatedSatellite.usedInFix)
369 satellitesInUse.append(satelliteInfo);
372 Q_EMIT satellitesInUseUpdated(satellitesInUse);
373 Q_EMIT satellitesInViewUpdated(satellitesInView);
375 m_lastUpdatedSatellitesInView = satellitesInView;
376 m_lastUpdatedSatellitesInUse = satellitesInUse;
378 if (m_updateTypes.contains(UpdateType::SingleUpdate))
379 handleSingleUpdateFinished();
384 m_updateTypes.remove(UpdateType::SingleUpdate);
386 m_singleUpdateTimeoutTimer.reset();
388 handleUpdateFinished();
393 if (m_updateTypes.empty()) {
394 m_positionInfoSource.reset();
395 m_updateSatelliteStatusInfoProducerHandle.reset();
396 m_lastUpdatedSatellitesInView.reset();
397 m_lastUpdatedSatellitesInUse.reset();
413 static constexpr const char *
fullTypeName =
"@ohos.geoLocationManager.SatelliteConstellationCategory";
int minimumUpdateInterval() const override
Error error() const override
Returns the last error that occurred.
void requestUpdate(int timeout) override
Attempts to get the current satellite information and emit satellitesInViewUpdated() and satellitesIn...
void setUpdateInterval(int msec) override
QOhosGeoSatelliteInfoSource(QObject *parent)
~QOhosGeoSatelliteInfoSource() override
void startUpdates() override
Starts emitting updates at regular intervals.
void stopUpdates() override
Stops emitting updates at regular intervals.
SatelliteConstellationCategory
@ CONSTELLATION_CATEGORY_SBAS
@ CONSTELLATION_CATEGORY_GLONASS
@ CONSTELLATION_CATEGORY_UNKNOWN
@ CONSTELLATION_CATEGORY_GPS
@ CONSTELLATION_CATEGORY_BEIDOU
@ CONSTELLATION_CATEGORY_GALILEO
@ CONSTELLATION_CATEGORY_IRNSS
@ CONSTELLATION_CATEGORY_QZSS
bool isSatelliteUsedInFix(QOhosJsState &jsState, int satelliteAdditionalInfo)
QGeoSatelliteInfo::SatelliteSystem convertSatelliteConstellationCategoryToQt(SatelliteConstellationCategory constellationCategory)
std::shared_ptr< void > registerSatelliteStatusInfoProducerConsumer(QObject *contextObject, QOhosConsumer< std::vector< SatelliteInfo > > satelliteStatusInfoConsumer)
std::optional< std::vector< int > > tryGetSatelliteAdditionalInfosFromSatelliteStatusInfoObject(QOhosJsState &, QNapi::Object satelliteStatusInfoObject)
constexpr int updateAsOftenAsNecessaryInterval
std::vector< SatelliteInfo > convertJsSatelliteStatusInfoObjectToQGeoSatelliteInfos(QOhosJsState &jsState, QNapi::Object satelliteStatusInfoObject)
std::optional< std::vector< SatelliteConstellationCategory > > tryGetSatelliteConstelationCategoriesFromSatelliteStatusInfoObject(QOhosJsState &jsState, QNapi::Object satelliteStatusInfoObject)
QGeoSatelliteInfoSource * makeQOhosGeoSatelliteInfoSource(QObject *parent)
bool checkLocationOrApproximatelyLocationPermissionGranted()
std::optional< SatelliteConstellationCategory > optConstellationCategory
double carrierToNoiseDensity