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