1e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol/* 2e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * Copyright (C) 2017 The Android Open Source Project 3e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * 4e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * Licensed under the Apache License, Version 2.0 (the "License"); 5e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * you may not use this file except in compliance with the License. 6e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * You may obtain a copy of the License at 7e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * 8e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * http://www.apache.org/licenses/LICENSE-2.0 9e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * 10e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * Unless required by applicable law or agreed to in writing, software 11e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * distributed under the License is distributed on an "AS IS" BASIS, 12e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * See the License for the specific language governing permissions and 14e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol * limitations under the License. 15e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol */ 16e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol 17a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#include <chre.h> 18e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol#include <cinttypes> 19e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol 203884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung#include "chre/util/macros.h" 21a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#include "chre/util/nanoapp/log.h" 2227d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol#include "chre/util/time.h" 23a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol 24a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#define LOG_TAG "[GnssWorld]" 25a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol 26e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#ifdef CHRE_NANOAPP_INTERNAL 27e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignolnamespace chre { 28e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolnamespace { 29e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#endif // CHRE_NANOAPP_INTERNAL 30e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol 313884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung//! A dummy cookie to pass into the location session async request. 323884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chungconst uint32_t kLocationSessionCookie = 0x1337; 3327d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol 3427d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol//! The minimum time to the next fix for a location. 3527d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignolconstexpr Milliseconds kLocationMinTimeToNextFix(0); 3627d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol 373884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung//! The interval in seconds between location updates. 383884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chungconst uint32_t kLocationIntervals[] = { 393884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 30, 403884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 15, 413884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 30, 423884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 15, 433884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 0, 443884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 10, 453884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung}; 463884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 473884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung//! Whether Gnss Location capability is supported by the platform 483884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chungbool gLocationSupported = false; 493884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 503884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chunguint32_t gTimerHandle; 513884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chunguint32_t gTimerCount = 0; 523884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 533884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung//! Whether an async result has been received. 543884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chungbool gAsyncResultReceived = false; 553884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 563884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chungvoid makeLocationRequest() { 573884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung uint32_t interval = kLocationIntervals[gTimerCount++]; 583884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGI("Modifying location update interval to %" PRIu32 " sec", interval); 593884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 603884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (interval > 0) { 613884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (chreGnssLocationSessionStartAsync( 623884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung interval * 1000, 633884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung kLocationMinTimeToNextFix.getMilliseconds(), 643884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung &kLocationSessionCookie)) { 653884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGI("Location session start request sent"); 663884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } else { 673884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGE("Error sending location session start request"); 683884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } 693884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } else { 703884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (chreGnssLocationSessionStopAsync( 713884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung &kLocationSessionCookie)) { 723884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGI("Location session stop request sent"); 733884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } else { 743884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGE("Error sending location session stop request"); 753884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } 763884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } 773884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 783884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung // set a timer to verify reception of async result. 793884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung gTimerHandle = chreTimerSet( 803884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung CHRE_GNSS_ASYNC_RESULT_TIMEOUT_NS, /* 5 sec in CHRE 1.1 */ 813884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung nullptr /* data */, true /* oneShot */); 823884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung} 833884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 843884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chungvoid handleTimerEvent(const void *eventData) { 853884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGI("Timer event received, count %d", gTimerCount); 863884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (!gAsyncResultReceived) { 873884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGE("Async result not received!"); 883884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } 893884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung gAsyncResultReceived = false; 903884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 913884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (gLocationSupported && gTimerCount < ARRAY_SIZE(kLocationIntervals)) { 923884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung makeLocationRequest(); 933884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } 943884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung} 953884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 9627d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignolvoid handleGnssAsyncResult(const chreAsyncResult *result) { 9727d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol if (result->requestType == CHRE_GNSS_REQUEST_TYPE_LOCATION_SESSION_START) { 9827d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol if (result->success) { 9927d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol LOGI("Successfully requested a GNSS location session"); 1003884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung gAsyncResultReceived = true; 10127d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol } else { 10227d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol LOGE("Error requesting GNSS scan monitoring with %" PRIu8, 10327d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol result->errorCode); 10427d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol } 10527d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol 1063884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (result->cookie != &kLocationSessionCookie) { 10727d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol LOGE("Location session start request cookie mismatch"); 10827d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol } 1093884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } else if (result->requestType 1103884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung == CHRE_GNSS_REQUEST_TYPE_LOCATION_SESSION_STOP) { 1113884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (result->success) { 1123884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGI("Successfully stopped a GNSS location session"); 1133884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung gAsyncResultReceived = true; 1143884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } else { 1153884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGE("Error stoppinging GNSS scan monitoring with %" PRIu8, 1163884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung result->errorCode); 1173884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } 1183884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung 1193884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (result->cookie != &kLocationSessionCookie) { 1203884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGE("Location session stop request cookie mismatch"); 1213884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung } 12227d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol } else { 1233884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung LOGE("Received invalid async result %" PRIu8, result->requestType); 12427d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol } 12527d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol} 12627d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol 127f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignolvoid handleGnssLocationEvent(const chreGnssLocationEvent *event) { 128f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol LOGI("Received location: %" PRId32 ", %" PRId32, event->latitude_deg_e7, 129f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol event->longitude_deg_e7); 130f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol LOGI(" timestamp (ms): %" PRIu64, event->timestamp); 131f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol LOGI(" altitude (m): %f", event->altitude); 132f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol LOGI(" speed (m/s): %f", event->speed); 133f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol LOGI(" bearing (deg): %f", event->bearing); 134f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol LOGI(" accuracy: %f", event->accuracy); 135f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol LOGI(" flags: %" PRIx16, event->flags); 136f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol} 137f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol 138e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolbool nanoappStart() { 139a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("App started as instance %" PRIu32, chreGetInstanceId()); 140e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol 141e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol const char *gnssCapabilitiesStr; 142e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol uint32_t gnssCapabilities = chreGnssGetCapabilities(); 143e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol switch (gnssCapabilities) { 144e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol case CHRE_GNSS_CAPABILITIES_LOCATION 145e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol | CHRE_GNSS_CAPABILITIES_MEASUREMENTS: 146e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol gnssCapabilitiesStr = "LOCATION | MEASUREMENTS"; 1473884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung gLocationSupported = true; 148e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol break; 149e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol case CHRE_GNSS_CAPABILITIES_LOCATION: 150e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol gnssCapabilitiesStr = "LOCATION"; 1513884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung gLocationSupported = true; 152e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol break; 153e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol case CHRE_GNSS_CAPABILITIES_MEASUREMENTS: 154e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol gnssCapabilitiesStr = "MEASUREMENTS"; 155e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol break; 156e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol case CHRE_GNSS_CAPABILITIES_NONE: 157e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol gnssCapabilitiesStr = "NONE"; 158e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol break; 159e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol default: 160e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol gnssCapabilitiesStr = "INVALID"; 161e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol } 162e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol 163a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("Detected GNSS support as: %s (%" PRIu32 ")", 164a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol gnssCapabilitiesStr, gnssCapabilities); 16527d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol 1663884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung if (gLocationSupported) { 1673884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung makeLocationRequest(); 16827d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol } 16927d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol 170e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol return true; 171e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol} 172e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol 173e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolvoid nanoappHandleEvent(uint32_t senderInstanceId, 174e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol uint16_t eventType, 175e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol const void *eventData) { 17627d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol switch (eventType) { 17727d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol case CHRE_EVENT_GNSS_ASYNC_RESULT: 17827d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol handleGnssAsyncResult(static_cast<const chreAsyncResult *>(eventData)); 17927d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol break; 180f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol case CHRE_EVENT_GNSS_LOCATION: 181f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol handleGnssLocationEvent( 182f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol static_cast<const chreGnssLocationEvent *>(eventData)); 183f6dd8800732ba8c24448e4cd4fa3a135a218b509Andrew Rossignol break; 1843884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung case CHRE_EVENT_TIMER: 1853884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung handleTimerEvent(eventData); 1863884ae8a863be35992abc3c172a29f84ba8a4b83Meng-hsuan Chung break; 18727d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol default: 18827d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol LOGW("Unhandled event type %" PRIu16, eventType); 18927d4adedb8c7d1f4b41388efb04a30a9038f33e1Andrew Rossignol } 190e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol} 191e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol 1922b9d71a9f6a9e8cc0e787957d022154231f29962Brian Duddievoid nanoappEnd() { 193a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("Stopped"); 194e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol} 195e47c28ffe449ca6b91ad0604be2bf164cdd490a3Andrew Rossignol 196e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#ifdef CHRE_NANOAPP_INTERNAL 1979d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} // anonymous namespace 1989d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} // namespace chre 199e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol 2009d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie#include "chre/util/nanoapp/app_id.h" 2019d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie#include "chre/platform/static_nanoapp_init.h" 202e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol 2039d5b500a223ef73560f0dce38f50b809bde5dd0dBrian DuddieCHRE_STATIC_NANOAPP_INIT(GnssWorld, chre::kGnssWorldAppId, 0); 204e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#endif // CHRE_NANOAPP_INTERNAL 205