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/qohosjstools_p.h>
12#include <QtCore/private/qohoslogger_p.h>
13#include <QtCore/qset.h>
14#include <QtCore/qmath.h>
15#include <QtPositioning/qgeosatelliteinfo.h>
44 QOhosJsState &jsState, QNapi::Object satelliteStatusInfoObject)
46 auto satelliteConstellationArray = QNapi::getOptionalPropOrEmpty<QNapi::Array>(
47 satelliteStatusInfoObject,
"satelliteConstellation");
49 return !satelliteConstellationArray.IsEmpty()
51 QNapi::getArrayElements<std::vector<SatelliteConstellationCategory>, QNapi::Number>(
52 satelliteConstellationArray,
53 [&](
auto satelliteConstellation) {
54 return jsState.mapOhosEnumFromJs<SatelliteConstellationCategory>(satelliteConstellation);
60 QOhosJsState &, QNapi::Object satelliteStatusInfoObject)
62 auto satelliteAdditionalInfoArray = QNapi::getOptionalPropOrEmpty<QNapi::Array>(
63 satelliteStatusInfoObject,
"satelliteAdditionalInfo");
65 return !satelliteAdditionalInfoArray.IsEmpty()
67 QNapi::getArrayElements<std::vector<
int>, QNapi::Number>(satelliteAdditionalInfoArray))
73 int satelliteUsedInValueFlag = jsState.eval<QNapi::Number>(
74 "@ohos.geoLocationManager.SatelliteAdditionalInfo.SATELLITES_ADDITIONAL_INFO_USED_IN_FIX");
76 return (satelliteAdditionalInfo & satelliteUsedInValueFlag) != 0;
80 QOhosJsState &jsState, QNapi::Object satelliteStatusInfoObject)
82 int satellitesNumber = satelliteStatusInfoObject.get<QNapi::Number>(
"satellitesNumber");
83 auto satelliteIds = QNapi::getArrayElements<std::vector<
int>, QNapi::Number>(
84 satelliteStatusInfoObject.get<QNapi::Array>(
"satelliteIds"));
85 auto carrierToNoiseDensities = QNapi::getArrayElements<std::vector<
double>, QNapi::Number>(
86 satelliteStatusInfoObject.get<QNapi::Array>(
"carrierToNoiseDensitys"));
87 auto altitudes = QNapi::getArrayElements<std::vector<
double>, QNapi::Number>(
88 satelliteStatusInfoObject.get<QNapi::Array>(
"altitudes"));
89 auto azimuths = QNapi::getArrayElements<std::vector<
double>, QNapi::Number>(
90 satelliteStatusInfoObject.get<QNapi::Array>(
"azimuths"));
91 auto satelliteConstellations = tryGetSatelliteConstelationCategoriesFromSatelliteStatusInfoObject(
92 jsState, satelliteStatusInfoObject);
93 auto satelliteAdditionalInfos = tryGetSatelliteAdditionalInfosFromSatelliteStatusInfoObject(
94 jsState, satelliteStatusInfoObject);
96 std::vector<SatelliteInfo> satelliteInfos;
97 satelliteInfos.reserve(satellitesNumber);
99 for (
int i = 0; i < satellitesNumber; i++) {
100 satelliteInfos.push_back(SatelliteInfo{
101 .id = satelliteIds[i],
102 .carrierToNoiseDensity = carrierToNoiseDensities[i],
103 .altitude = altitudes[i],
104 .azimuth = azimuths[i],
105 .optConstellationCategory = satelliteConstellations.has_value()
106 ? std::make_optional(satelliteConstellations.value()[i])
108 .usedInFix = satelliteAdditionalInfos.has_value()
109 ? isSatelliteUsedInFix(jsState, satelliteAdditionalInfos.value()[i])
114 return satelliteInfos;
120 switch (constellationCategory) {
121 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_UNKNOWN:
122 return QGeoSatelliteInfo::Undefined;
123 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_GPS:
124 return QGeoSatelliteInfo::GPS;
125 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_GLONASS:
126 return QGeoSatelliteInfo::GLONASS;
127 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_SBAS:
128 return QGeoSatelliteInfo::SBAS;
129 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_QZSS:
130 return QGeoSatelliteInfo::QZSS;
131 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_BEIDOU:
132 return QGeoSatelliteInfo::BEIDOU;
133 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_GALILEO:
134 return QGeoSatelliteInfo::GALILEO;
135 case SatelliteConstellationCategory::CONSTELLATION_CATEGORY_IRNSS:
136 return QGeoSatelliteInfo::IRNSS;
139 qOhosReportFatalErrorAndAbort(
140 "%s Received an unknown SatelliteConstellationCategory: %d",
141 Q_FUNC_INFO, constellationCategory);
145 QObject *contextObject, QOhosConsumer<std::vector<SatelliteInfo>> satelliteStatusInfoConsumer)
147 qOhosDebug(QtForOhos) << Q_FUNC_INFO << contextObject;
149 auto contextObjectRef = QtOhos::makeQThreadSafeRef(contextObject);
150 auto sharedSatelliteStatusInfoConsumer =
151 QtOhos::moveToSharedPtr(std::move(satelliteStatusInfoConsumer));
152 auto weakSatelliteStatusInfoConsumer = QtOhos::makeWeakPtr(sharedSatelliteStatusInfoConsumer);
154 auto registrationHandle = QOhosJsThreadGateway::eval(
155 [&](QOhosJsState &jsState) {
156 return QtOhos::makeProxyWithJsThreadDeleter(
157 registerQOhosOnOffMethodsBasedEventHandler(
158 getGeoLocationManagerObject(jsState),
"satelliteStatusChange",
159 [contextObjectRef, weakSatelliteStatusInfoConsumer](
const QOhosCallbackInfo &cbInfo) {
160 auto satelliteStatusInfo = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
161 auto satelliteInfos = convertJsSatelliteStatusInfoObjectToQGeoSatelliteInfos(
162 cbInfo.jsState(), satelliteStatusInfo);
163 contextObjectRef.visitInQtThreadIfAlive(
164 [weakSatelliteStatusInfoConsumer, satelliteInfos](
auto &) {
165 auto sharedSatelliteStatusInfoConsumer = weakSatelliteStatusInfoConsumer.lock();
166 if (sharedSatelliteStatusInfoConsumer)
167 (*sharedSatelliteStatusInfoConsumer)(satelliteInfos);
172 return QtOhos::moveToSharedPtr(
173 std::make_pair(registrationHandle, sharedSatelliteStatusInfoConsumer));
199 void startUpdatesHelper();
200 void setErrorHelper(Error error);
202 void handleSatelliteStatusInfoUpdate(std::vector<SatelliteInfo> updatedSatelliteStatusInfo);
203 void handleSingleUpdateFinished();
204 void handleUpdateFinished();
206 QSet<UpdateType> m_updateTypes;
207 std::shared_ptr<
void> m_updateSatelliteStatusInfoProducerHandle;
208 std::unique_ptr<QGeoPositionInfoSource> m_positionInfoSource;
210 std::unique_ptr<QTimer> m_singleUpdateTimeoutTimer;
212 std::optional<QList<QGeoSatelliteInfo>> m_lastUpdatedSatellitesInView;
213 std::optional<QList<QGeoSatelliteInfo>> m_lastUpdatedSatellitesInUse;
221 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
228 qOhosDebug(QtForOhos) << Q_FUNC_INFO << msec;
230 if (msec != updateAsOftenAsNecessaryInterval)
231 qOhosWarning(QtForOhos) << Q_FUNC_INFO <<
"Specific update intervals are not supported";
236 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
243 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
250 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
253 qOhosWarning(QtForOhos) << Q_FUNC_INFO <<
"Location permission not granted. Can't start updates";
254 setErrorHelper(QGeoSatelliteInfoSource::AccessError);
258 if (m_updateTypes.contains(UpdateType::ContinuousUpdate))
261 m_updateTypes.insert(UpdateType::ContinuousUpdate);
263 if (!m_updateSatelliteStatusInfoProducerHandle && !m_positionInfoSource)
264 startUpdatesHelper();
269 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
271 m_updateTypes.remove(UpdateType::ContinuousUpdate);
273 handleUpdateFinished();
278 qOhosDebug(QtForOhos) << Q_FUNC_INFO << timeout;
281 qOhosWarning(QtForOhos) << Q_FUNC_INFO <<
"Location permission not granted. Can't request update";
282 setErrorHelper(QGeoSatelliteInfoSource::AccessError);
286 if (m_updateTypes.contains(UpdateType::SingleUpdate))
289 m_updateTypes.insert(UpdateType::SingleUpdate);
291 if (!m_updateSatelliteStatusInfoProducerHandle && !m_positionInfoSource)
292 startUpdatesHelper();
294 m_singleUpdateTimeoutTimer = makeSingleShotUpdateTimeoutTimer(
296 if (m_lastUpdatedSatellitesInUse.has_value() && m_lastUpdatedSatellitesInView.has_value()) {
297 Q_EMIT satellitesInUseUpdated(m_lastUpdatedSatellitesInUse.value());
298 Q_EMIT satellitesInViewUpdated(m_lastUpdatedSatellitesInView.value());
300 Q_EMIT errorOccurred(QGeoSatelliteInfoSource::UpdateTimeoutError);
303 handleSingleUpdateFinished();
309 qOhosDebug(QtForOhos) << Q_FUNC_INFO;
311 m_updateSatelliteStatusInfoProducerHandle =
312 registerSatelliteStatusInfoProducerConsumer(
313 this, [
this](
auto updatedSatelliteInfos) {
314 handleSatelliteStatusInfoUpdate(updatedSatelliteInfos);
317 m_positionInfoSource = std::unique_ptr<QGeoPositionInfoSource>(tryMakeQOhosGeoPositionInfoSource());
318 if (!m_positionInfoSource)
319 qOhosReportFatalErrorAndAbort(
"%s positionInfoSource is invalid", Q_FUNC_INFO);
321 m_positionInfoSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
322 m_positionInfoSource->startUpdates();
327 qOhosWarning(QtForOhos) << Q_FUNC_INFO << error;
329 if (m_error == error)
334 if (error != QGeoSatelliteInfoSource::NoError)
335 Q_EMIT QGeoSatelliteInfoSource::errorOccurred(m_error);
339 std::vector<SatelliteInfo> updatedSatellites)
341 qOhosDebug(QtForOhos) << Q_FUNC_INFO <<
"found" << updatedSatellites.size() <<
"satellites";
343 QList<QGeoSatelliteInfo> satellitesInView;
344 QList<QGeoSatelliteInfo> satellitesInUse;
346 QSet<std::pair<
int,
int>> seenIds;
348 for (
const auto &updatedSatellite : updatedSatellites) {
349 if (qFuzzyIsNull(updatedSatellite.carrierToNoiseDensity))
352 QGeoSatelliteInfo satelliteInfo;
353 satelliteInfo.setSatelliteIdentifier(updatedSatellite.id);
354 satelliteInfo.setSatelliteSystem(
355 updatedSatellite.optConstellationCategory.has_value()
356 ? convertSatelliteConstellationCategoryToQt(updatedSatellite.optConstellationCategory.value())
357 : QGeoSatelliteInfo::SatelliteSystem::Undefined);
358 satelliteInfo.setSignalStrength(updatedSatellite.carrierToNoiseDensity);
359 satelliteInfo.setAttribute(QGeoSatelliteInfo::Azimuth, updatedSatellite.azimuth);
360 satelliteInfo.setAttribute(QGeoSatelliteInfo::Elevation, updatedSatellite.altitude);
362 const auto uid = std::make_pair(
static_cast<
int>(satelliteInfo.satelliteSystem()),
363 satelliteInfo.satelliteIdentifier());
364 if (seenIds.contains(uid))
368 satellitesInView.append(satelliteInfo);
369 if (updatedSatellite.usedInFix)
370 satellitesInUse.append(satelliteInfo);
373 Q_EMIT satellitesInUseUpdated(satellitesInUse);
374 Q_EMIT satellitesInViewUpdated(satellitesInView);
376 m_lastUpdatedSatellitesInView = satellitesInView;
377 m_lastUpdatedSatellitesInUse = satellitesInUse;
379 if (m_updateTypes.contains(UpdateType::SingleUpdate))
380 handleSingleUpdateFinished();
385 m_updateTypes.remove(UpdateType::SingleUpdate);
387 m_singleUpdateTimeoutTimer.reset();
389 handleUpdateFinished();
394 if (m_updateTypes.empty()) {
395 m_positionInfoSource.reset();
396 m_updateSatelliteStatusInfoProducerHandle.reset();
397 m_lastUpdatedSatellitesInView.reset();
398 m_lastUpdatedSatellitesInUse.reset();
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.
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
QtOhos::enums::ohos::geoLocationManager::SatelliteConstellationCategory SatelliteConstellationCategory
std::vector< SatelliteInfo > convertJsSatelliteStatusInfoObjectToQGeoSatelliteInfos(QOhosJsState &jsState, QNapi::Object satelliteStatusInfoObject)
std::optional< std::vector< SatelliteConstellationCategory > > tryGetSatelliteConstelationCategoriesFromSatelliteStatusInfoObject(QOhosJsState &jsState, QNapi::Object satelliteStatusInfoObject)
SatelliteConstellationCategory
QGeoSatelliteInfoSource * makeQOhosGeoSatelliteInfoSource(QObject *parent)
bool checkLocationOrApproximatelyLocationPermissionGranted()
std::optional< SatelliteConstellationCategory > optConstellationCategory
double carrierToNoiseDensity