• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // Note that to avoid always polluting the include paths of nanoapps, we use
18 // symlinks under the chre_nsl_internal include path to the "real" files, e.g.
19 // chre_nsl_internal/platform/shared maps to the same files that would normally
20 // be included via chre/platform/shared
21 
22 #include "chre_nsl_internal/platform/shared/nanoapp_support_lib_dso.h"
23 
24 #include <algorithm>
25 
26 #include "chre_api/chre.h"
27 #include "chre_nsl_internal/platform/shared/debug_dump.h"
28 #include "chre_nsl_internal/util/macros.h"
29 #include "chre_nsl_internal/util/system/napp_permissions.h"
30 #ifdef CHRE_NANOAPP_USES_WIFI
31 #include "chre_nsl_internal/util/system/wifi_util.h"
32 #endif
33 
34 #ifndef LOG_TAG
35 #define LOG_TAG "[NSL]"
36 #endif  // LOG_TAG
37 
38 /**
39  * @file
40  * The Nanoapp Support Library (NSL) that gets built with nanoapps to act as an
41  * intermediary to the reference CHRE implementation. It provides hooks so the
42  * app can be registered with the system, and also provides a layer where we can
43  * implement cross-version compatibility features as needed.
44  */
45 
46 namespace {
47 
48 constexpr uint32_t kNanoappPermissions = 0
49 // DO NOT USE this macro outside of specific CHQTS nanoapps. This is only used
50 // to allow testing of invalid permission declarations.
51 #ifdef CHRE_TEST_NANOAPP_PERMS
52                                          | CHRE_TEST_NANOAPP_PERMS
53 #else
54 #ifdef CHRE_NANOAPP_USES_AUDIO
55     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_AUDIO)
56 #endif
57 #ifdef CHRE_NANOAPP_USES_BLE
58     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_BLE)
59 #endif
60 #ifdef CHRE_NANOAPP_USES_GNSS
61     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_GNSS)
62 #endif
63 #ifdef CHRE_NANOAPP_USES_WIFI
64     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_WIFI)
65 #endif
66 #ifdef CHRE_NANOAPP_USES_WWAN
67     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_WWAN)
68 #endif
69 #endif  // CHRE_TEST_NANOAPP_PERMS
70     ;
71 
72 #if defined(CHRE_SLPI_UIMG_ENABLED) || defined(CHRE_TCM_ENABLED)
73 constexpr int kIsTcmNanoapp = 1;
74 #else
75 constexpr int kIsTcmNanoapp = 0;
76 #endif  // CHRE_SLPI_UIMG_ENABLED
77 
78 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && defined(CHRE_NANOAPP_USES_GNSS)
79 // Return a v1.3+ GnssLocationEvent for the nanoapp when running on a v1.2-
80 // platform.
translateLegacyGnssLocation(const chreGnssLocationEvent & legacyEvent)81 chreGnssLocationEvent translateLegacyGnssLocation(
82     const chreGnssLocationEvent &legacyEvent) {
83   // Copy v1.2- fields over to a v1.3+ event.
84   chreGnssLocationEvent newEvent = {};
85   newEvent.timestamp = legacyEvent.timestamp;
86   newEvent.latitude_deg_e7 = legacyEvent.latitude_deg_e7;
87   newEvent.longitude_deg_e7 = legacyEvent.longitude_deg_e7;
88   newEvent.altitude = legacyEvent.altitude;
89   newEvent.speed = legacyEvent.speed;
90   newEvent.bearing = legacyEvent.bearing;
91   newEvent.accuracy = legacyEvent.accuracy;
92   newEvent.flags = legacyEvent.flags;
93 
94   // Unset flags that are defined in v1.3+ but not in v1.2-.
95   newEvent.flags &= ~(CHRE_GPS_LOCATION_HAS_ALTITUDE_ACCURACY |
96                       CHRE_GPS_LOCATION_HAS_SPEED_ACCURACY |
97                       CHRE_GPS_LOCATION_HAS_BEARING_ACCURACY);
98   return newEvent;
99 }
100 
nanoappHandleEventCompat(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)101 void nanoappHandleEventCompat(uint32_t senderInstanceId, uint16_t eventType,
102                               const void *eventData) {
103   if (eventType == CHRE_EVENT_GNSS_LOCATION &&
104       chreGetApiVersion() < CHRE_API_VERSION_1_3) {
105     chreGnssLocationEvent event = translateLegacyGnssLocation(
106         *static_cast<const chreGnssLocationEvent *>(eventData));
107     nanoappHandleEvent(senderInstanceId, eventType, &event);
108   } else {
109     nanoappHandleEvent(senderInstanceId, eventType, eventData);
110   }
111 }
112 #endif
113 
114 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && \
115     defined(CHRE_NANOAPP_USES_BLE) &&            \
116     defined(CHRE_FIRST_SUPPORTED_API_VERSION) && \
117     CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
reverseServiceDataUuid(struct chreBleGenericFilter * filter)118 void reverseServiceDataUuid(struct chreBleGenericFilter *filter) {
119   if (filter->type != CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE ||
120       filter->len == 0) {
121     return;
122   }
123   std::swap(filter->data[0], filter->data[1]);
124   std::swap(filter->dataMask[0], filter->dataMask[1]);
125   if (filter->len == 1) {
126     filter->data[0] = 0x0;
127     filter->dataMask[0] = 0x0;
128     filter->len = 2;
129   }
130 }
131 
serviceDataFilterEndianSwapRequired(const struct chreBleScanFilter * filter)132 bool serviceDataFilterEndianSwapRequired(
133     const struct chreBleScanFilter *filter) {
134   if (chreGetApiVersion() >= CHRE_API_VERSION_1_8 || filter == nullptr) {
135     return false;
136   }
137   for (size_t i = 0; i < filter->scanFilterCount; i++) {
138     if (filter->scanFilters[i].type ==
139             CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE &&
140         filter->scanFilters[i].len > 0) {
141       return true;
142     }
143   }
144   return false;
145 }
146 #endif  // !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) &&
147         // defined(CHRE_NANOAPP_USES_BLE) &&
148         // defined(CHRE_FIRST_SUPPORTED_API_VERSION) &&
149         // CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
150 
151 }  // anonymous namespace
152 
153 //! Used to determine the given unstable ID that was provided when building this
154 //! nanoapp, if any. The symbol is placed in its own section so it can be
155 //! stripped to determine if the nanoapp changed compared to a previous version.
156 //! We also align the variable to match the minimum alignment of the surrounding
157 //! sections, since for compilers with a default size-1 alignment, there might
158 //! be a spill-over from the previous segment if not zero-padded, when we
159 //! attempt to read the string.
160 extern "C" DLL_EXPORT const char _chreNanoappUnstableId[]
161     __attribute__((section(".unstable_id"))) __attribute__((aligned(8))) =
162         NANOAPP_UNSTABLE_ID;
163 
164 extern "C" DLL_EXPORT const struct chreNslNanoappInfo _chreNslDsoNanoappInfo = {
165     /* magic */ CHRE_NSL_NANOAPP_INFO_MAGIC,
166     /* structMinorVersion */ CHRE_NSL_NANOAPP_INFO_STRUCT_MINOR_VERSION,
167     /* isSystemNanoapp */ NANOAPP_IS_SYSTEM_NANOAPP,
168     /* isTcmNanoapp */ kIsTcmNanoapp,
169     /* reservedFlags */ 0,
170     /* reserved */ 0,
171     /* targetApiVersion */ CHRE_API_VERSION,
172 
173     // These values are supplied by the build environment.
174     /* vendor */ NANOAPP_VENDOR_STRING,
175     /* name */ NANOAPP_NAME_STRING,
176     /* appId */ NANOAPP_ID,
177     /* appVersion */ NANOAPP_VERSION,
178     /* entryPoints */
179     {
180         /* start */ nanoappStart,
181 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && defined(CHRE_NANOAPP_USES_GNSS)
182         /* handleEvent */ nanoappHandleEventCompat,
183 #else
184         /* handleEvent */ nanoappHandleEvent,
185 #endif
186         /* end */ nanoappEnd,
187     },
188     /* appVersionString */ _chreNanoappUnstableId,
189     /* appPermissions */ kNanoappPermissions,
190 };
191 
getChreNslDsoNanoappInfo()192 const struct chreNslNanoappInfo *getChreNslDsoNanoappInfo() {
193   return &_chreNslDsoNanoappInfo;
194 }
195 
196 // The code section below provides default implementations for new symbols
197 // introduced in CHRE API v1.2+ to provide binary compatibility with previous
198 // CHRE implementations. Note that we don't presently include symbols for v1.1,
199 // as the current known set of CHRE platforms that use this NSL implementation
200 // are all v1.1+.
201 // If a nanoapp knows that it is only targeting the latest platform version, it
202 // can define the CHRE_NANOAPP_DISABLE_BACKCOMPAT flag, so this indirection will
203 // be avoided at the expense of a nanoapp not being able to load at all on prior
204 // implementations.
205 
206 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT)
207 
208 #if !defined(CHRE_FIRST_SUPPORTED_API_VERSION)
209 #error "CHRE_FIRST_SUPPORTED_API_VERSION must be defined for this platform"
210 #elif CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_1
211 #error "CHRE_FIRST_SUPPORTED_API_VERSION must be at least CHRE_API_VERSION_1_1"
212 #endif  // !defined(CHRE_FIRST_SUPPORTED_API_VERSION)
213 
214 #include <dlfcn.h>
215 
216 namespace {
217 
218 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
219 // Populate chreNanoappInfo for CHRE API pre v1.8.
populateChreNanoappInfoPre18(struct chreNanoappInfo * info)220 void populateChreNanoappInfoPre18(struct chreNanoappInfo *info) {
221   info->rpcServiceCount = 0;
222   info->rpcServices = nullptr;
223   memset(&info->reserved, 0, sizeof(info->reserved));
224 }
225 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
226 
227 }  // namespace
228 
229 /**
230  * Lazily calls dlsym to find the function pointer for a given function
231  * (provided without quotes) in another library (i.e. the CHRE platform DSO),
232  * caching and returning the result.
233  */
234 #define CHRE_NSL_LAZY_LOOKUP(functionName)            \
235   ({                                                  \
236     static bool lookupPerformed = false;              \
237     static decltype(functionName) *funcPtr = nullptr; \
238     if (!lookupPerformed) {                           \
239       funcPtr = reinterpret_cast<decltype(funcPtr)>(  \
240           dlsym(RTLD_NEXT, STRINGIFY(functionName))); \
241       lookupPerformed = true;                         \
242     }                                                 \
243     funcPtr;                                          \
244   })
245 
246 #ifdef CHRE_NANOAPP_USES_AUDIO
247 
248 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
249 WEAK_SYMBOL
chreAudioGetSource(uint32_t handle,struct chreAudioSource * audioSource)250 bool chreAudioGetSource(uint32_t handle, struct chreAudioSource *audioSource) {
251   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioGetSource);
252   return (fptr != nullptr) ? fptr(handle, audioSource) : false;
253 }
254 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
255 
256 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
257 WEAK_SYMBOL
chreAudioConfigureSource(uint32_t handle,bool enable,uint64_t bufferDuration,uint64_t deliveryInterval)258 bool chreAudioConfigureSource(uint32_t handle, bool enable,
259                               uint64_t bufferDuration,
260                               uint64_t deliveryInterval) {
261   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioConfigureSource);
262   return (fptr != nullptr)
263              ? fptr(handle, enable, bufferDuration, deliveryInterval)
264              : false;
265 }
266 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
267 
268 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
269 WEAK_SYMBOL
chreAudioGetStatus(uint32_t handle,struct chreAudioSourceStatus * status)270 bool chreAudioGetStatus(uint32_t handle, struct chreAudioSourceStatus *status) {
271   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioGetStatus);
272   return (fptr != nullptr) ? fptr(handle, status) : false;
273 }
274 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
275 
276 #endif /* CHRE_NANOAPP_USES_AUDIO */
277 
278 #ifdef CHRE_NANOAPP_USES_BLE
279 
280 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
281 WEAK_SYMBOL
chreBleGetCapabilities()282 uint32_t chreBleGetCapabilities() {
283   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetCapabilities);
284   return (fptr != nullptr) ? fptr() : CHRE_BLE_CAPABILITIES_NONE;
285 }
286 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
287 
288 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
289 WEAK_SYMBOL
chreBleGetFilterCapabilities()290 uint32_t chreBleGetFilterCapabilities() {
291   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetFilterCapabilities);
292   return (fptr != nullptr) ? fptr() : CHRE_BLE_FILTER_CAPABILITIES_NONE;
293 }
294 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
295 
296 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_7
297 WEAK_SYMBOL
chreBleFlushAsync(const void * cookie)298 bool chreBleFlushAsync(const void *cookie) {
299   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleFlushAsync);
300   return (fptr != nullptr) ? fptr(cookie) : false;
301 }
302 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_7 */
303 
304 // NOTE: The backward compatibility provided by this stub is only needed below
305 // CHRE v1.8 so we check the first API version for the platform against v1.8.
306 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
307 WEAK_SYMBOL
chreBleStartScanAsync(chreBleScanMode mode,uint32_t reportDelayMs,const struct chreBleScanFilter * filter)308 bool chreBleStartScanAsync(chreBleScanMode mode, uint32_t reportDelayMs,
309                            const struct chreBleScanFilter *filter) {
310   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStartScanAsync);
311   if (fptr == nullptr) {
312     return false;
313   } else if (!serviceDataFilterEndianSwapRequired(filter)) {
314     return fptr(mode, reportDelayMs, filter);
315   }
316   // For nanoapps compiled against v1.8+ working with earlier versions of CHRE,
317   // convert service data filters to big-endian format.
318   chreBleScanFilter convertedFilter = *filter;
319   auto genericFilters = static_cast<chreBleGenericFilter *>(
320       chreHeapAlloc(sizeof(chreBleGenericFilter) * filter->scanFilterCount));
321   if (genericFilters == nullptr) {
322     chreLog(CHRE_LOG_ERROR, "Alloc failure in chreBleStartScanAsync NSL");
323     return false;
324   }
325   memcpy(genericFilters, filter->scanFilters,
326          filter->scanFilterCount * sizeof(chreBleGenericFilter));
327   for (size_t i = 0; i < filter->scanFilterCount; i++) {
328     reverseServiceDataUuid(&genericFilters[i]);
329   }
330   convertedFilter.scanFilters = genericFilters;
331   bool success = fptr(mode, reportDelayMs, &convertedFilter);
332   chreHeapFree(const_cast<chreBleGenericFilter *>(convertedFilter.scanFilters));
333   return success;
334 }
335 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
336 
337 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_9
338 WEAK_SYMBOL
chreBleStartScanAsyncV1_9(chreBleScanMode mode,uint32_t reportDelayMs,const struct chreBleScanFilterV1_9 * filter,const void * cookie)339 bool chreBleStartScanAsyncV1_9(chreBleScanMode mode, uint32_t reportDelayMs,
340                                const struct chreBleScanFilterV1_9 *filter,
341                                const void *cookie) {
342   if (chreGetApiVersion() < CHRE_API_VERSION_1_9) {
343     return false;
344   }
345   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStartScanAsyncV1_9);
346   if (fptr == nullptr) {
347     return false;
348   }
349   return fptr(mode, reportDelayMs, filter, cookie);
350 }
351 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_9 */
352 
353 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
354 WEAK_SYMBOL
chreBleStopScanAsync()355 bool chreBleStopScanAsync() {
356   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStopScanAsync);
357   return (fptr != nullptr) ? fptr() : false;
358 }
359 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
360 
361 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_9
362 WEAK_SYMBOL
chreBleStopScanAsyncV1_9(const void * cookie)363 bool chreBleStopScanAsyncV1_9(const void *cookie) {
364   if (chreGetApiVersion() < CHRE_API_VERSION_1_9) {
365     return false;
366   }
367   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStopScanAsyncV1_9);
368   if (fptr == nullptr) {
369     return false;
370   }
371   return fptr(cookie);
372 }
373 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_9 */
374 
375 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
376 WEAK_SYMBOL
chreBleReadRssiAsync(uint16_t connectionHandle,const void * cookie)377 bool chreBleReadRssiAsync(uint16_t connectionHandle, const void *cookie) {
378   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleReadRssiAsync);
379   return (fptr != nullptr) ? fptr(connectionHandle, cookie) : false;
380 }
381 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
382 
383 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
384 WEAK_SYMBOL
chreBleGetScanStatus(struct chreBleScanStatus * status)385 bool chreBleGetScanStatus(struct chreBleScanStatus *status) {
386   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetScanStatus);
387   return (fptr != nullptr) ? fptr(status) : false;
388 }
389 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
390 
391 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11
392 WEAK_SYMBOL
chreBleSocketAccept(uint64_t socketId)393 bool chreBleSocketAccept(uint64_t socketId) {
394   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleSocketAccept);
395   return (fptr != nullptr) ? fptr(socketId) : false;
396 }
397 
398 WEAK_SYMBOL
chreBleSocketSend(uint64_t socketId,const void * data,uint16_t length,chreBleSocketPacketFreeFunction * freeCallback)399 int32_t chreBleSocketSend(uint64_t socketId, const void *data, uint16_t length,
400                           chreBleSocketPacketFreeFunction *freeCallback) {
401   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleSocketSend);
402   return (fptr != nullptr) ? fptr(socketId, data, length, freeCallback)
403                            : CHRE_ERROR_NOT_SUPPORTED;
404 }
405 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11 */
406 
407 #endif /* CHRE_NANOAPP_USES_BLE */
408 
409 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
410 WEAK_SYMBOL
chreConfigureHostSleepStateEvents(bool enable)411 void chreConfigureHostSleepStateEvents(bool enable) {
412   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureHostSleepStateEvents);
413   if (fptr != nullptr) {
414     fptr(enable);
415   }
416 }
417 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
418 
419 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
420 WEAK_SYMBOL
chreIsHostAwake(void)421 bool chreIsHostAwake(void) {
422   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreIsHostAwake);
423   return (fptr != nullptr) ? fptr() : false;
424 }
425 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
426 
427 #ifdef CHRE_NANOAPP_USES_GNSS
428 
429 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
430 WEAK_SYMBOL
chreGnssConfigurePassiveLocationListener(bool enable)431 bool chreGnssConfigurePassiveLocationListener(bool enable) {
432   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGnssConfigurePassiveLocationListener);
433   return (fptr != nullptr) ? fptr(enable) : false;
434 }
435 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
436 
437 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11
438 WEAK_SYMBOL
chreGnssLocationSessionStartAsyncV1_11(uint32_t minIntervalMs,uint32_t minTimeToNextFixMs,const void * cookie,enum chreGnssSource source)439 bool chreGnssLocationSessionStartAsyncV1_11(uint32_t minIntervalMs,
440                                             uint32_t minTimeToNextFixMs,
441                                             const void *cookie,
442                                             enum chreGnssSource source) {
443   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGnssLocationSessionStartAsyncV1_11);
444   if (fptr != nullptr) {
445     return fptr(minIntervalMs, minTimeToNextFixMs, cookie, source);
446   }
447   if (source == CHRE_GNSS_SOURCE_UNSPECIFIED ||
448       source == CHRE_GNSS_SOURCE_LOCAL) {
449     return chreGnssLocationSessionStartAsync(minIntervalMs, minTimeToNextFixMs,
450                                              cookie);
451   }
452   return false;
453 }
454 
455 WEAK_SYMBOL
chreGnssMeasurementSessionStartAsyncV1_11(uint32_t minIntervalMs,const void * cookie,enum chreGnssSource source)456 bool chreGnssMeasurementSessionStartAsyncV1_11(uint32_t minIntervalMs,
457                                                const void *cookie,
458                                                enum chreGnssSource source) {
459   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGnssMeasurementSessionStartAsyncV1_11);
460   if (fptr != nullptr) {
461     return fptr(minIntervalMs, cookie, source);
462   }
463   if (source == CHRE_GNSS_SOURCE_UNSPECIFIED ||
464       source == CHRE_GNSS_SOURCE_LOCAL) {
465     return chreGnssMeasurementSessionStartAsync(minIntervalMs, cookie);
466   }
467   return false;
468 }
469 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11 */
470 
471 #endif /* CHRE_NANOAPP_USES_GNSS */
472 
473 #ifdef CHRE_NANOAPP_USES_WIFI
474 
475 // NOTE: The backward compatibility provided by this stub is only needed below
476 // CHRE v1.5 so we check the first API version for the platform against v1.5.
477 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
478 WEAK_SYMBOL
chreWifiRequestScanAsync(const struct chreWifiScanParams * params,const void * cookie)479 bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params,
480                               const void *cookie) {
481   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiRequestScanAsync);
482 
483   if (fptr == nullptr) {
484     // Should never happen
485     return false;
486   } else if (chreGetApiVersion() < CHRE_API_VERSION_1_5) {
487     const struct chreWifiScanParams legacyParams =
488         chre::translateToLegacyWifiScanParams(params);
489     return fptr(&legacyParams, cookie);
490   } else {
491     return fptr(params, cookie);
492   }
493 }
494 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
495 
496 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
497 WEAK_SYMBOL
chreWifiRequestRangingAsync(const struct chreWifiRangingParams * params,const void * cookie)498 bool chreWifiRequestRangingAsync(const struct chreWifiRangingParams *params,
499                                  const void *cookie) {
500   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiRequestRangingAsync);
501   return (fptr != nullptr) ? fptr(params, cookie) : false;
502 }
503 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
504 
505 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
506 WEAK_SYMBOL
chreWifiNanRequestRangingAsync(const struct chreWifiNanRangingParams * params,const void * cookie)507 bool chreWifiNanRequestRangingAsync(
508     const struct chreWifiNanRangingParams *params, const void *cookie) {
509   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanRequestRangingAsync);
510   return (fptr != nullptr) ? fptr(params, cookie) : false;
511 }
512 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
513 
514 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
515 WEAK_SYMBOL
chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig * config,const void * cookie)516 bool chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig *config,
517                           const void *cookie) {
518   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanSubscribe);
519   return (fptr != nullptr) ? fptr(config, cookie) : false;
520 }
521 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
522 
523 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
524 WEAK_SYMBOL
chreWifiNanSubscribeCancel(uint32_t subscriptionID)525 bool chreWifiNanSubscribeCancel(uint32_t subscriptionID) {
526   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanSubscribeCancel);
527   return (fptr != nullptr) ? fptr(subscriptionID) : false;
528 }
529 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
530 
531 #endif /* CHRE_NANOAPP_USES_WIFI */
532 
533 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
534 WEAK_SYMBOL
chreSensorFind(uint8_t sensorType,uint8_t sensorIndex,uint32_t * handle)535 bool chreSensorFind(uint8_t sensorType, uint8_t sensorIndex, uint32_t *handle) {
536   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorFind);
537   if (fptr != nullptr) {
538     return fptr(sensorType, sensorIndex, handle);
539   } else if (sensorIndex == 0) {
540     return chreSensorFindDefault(sensorType, handle);
541   } else {
542     return false;
543   }
544 }
545 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
546 
547 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
548 WEAK_SYMBOL
chreSensorConfigureBiasEvents(uint32_t sensorHandle,bool enable)549 bool chreSensorConfigureBiasEvents(uint32_t sensorHandle, bool enable) {
550   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorConfigureBiasEvents);
551   return (fptr != nullptr) ? fptr(sensorHandle, enable) : false;
552 }
553 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
554 
555 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
556 WEAK_SYMBOL
chreSensorGetThreeAxisBias(uint32_t sensorHandle,struct chreSensorThreeAxisData * bias)557 bool chreSensorGetThreeAxisBias(uint32_t sensorHandle,
558                                 struct chreSensorThreeAxisData *bias) {
559   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorGetThreeAxisBias);
560   return (fptr != nullptr) ? fptr(sensorHandle, bias) : false;
561 }
562 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
563 
564 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
565 WEAK_SYMBOL
chreSensorFlushAsync(uint32_t sensorHandle,const void * cookie)566 bool chreSensorFlushAsync(uint32_t sensorHandle, const void *cookie) {
567   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorFlushAsync);
568   return (fptr != nullptr) ? fptr(sensorHandle, cookie) : false;
569 }
570 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
571 
572 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4
573 WEAK_SYMBOL
chreConfigureDebugDumpEvent(bool enable)574 void chreConfigureDebugDumpEvent(bool enable) {
575   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureDebugDumpEvent);
576   if (fptr != nullptr) {
577     fptr(enable);
578   }
579 }
580 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4 */
581 
582 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4
583 WEAK_SYMBOL
chreDebugDumpLog(const char * formatStr,...)584 void chreDebugDumpLog(const char *formatStr, ...) {
585   auto *fptr = CHRE_NSL_LAZY_LOOKUP(platform_chreDebugDumpVaLog);
586   if (fptr != nullptr) {
587     va_list args;
588     va_start(args, formatStr);
589     fptr(formatStr, args);
590     va_end(args);
591   }
592 }
593 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4 */
594 
595 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
596 WEAK_SYMBOL
chreSendMessageWithPermissions(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback)597 bool chreSendMessageWithPermissions(void *message, size_t messageSize,
598                                     uint32_t messageType, uint16_t hostEndpoint,
599                                     uint32_t messagePermissions,
600                                     chreMessageFreeFunction *freeCallback) {
601   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSendMessageWithPermissions);
602   if (fptr != nullptr) {
603     return fptr(message, messageSize, messageType, hostEndpoint,
604                 messagePermissions, freeCallback);
605   } else {
606     return chreSendMessageToHostEndpoint(message, messageSize, messageType,
607                                          hostEndpoint, freeCallback);
608   }
609 }
610 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
611 
612 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
613 WEAK_SYMBOL
chreSendReliableMessageAsync(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback,const void * cookie)614 bool chreSendReliableMessageAsync(void *message, size_t messageSize,
615                                   uint32_t messageType, uint16_t hostEndpoint,
616                                   uint32_t messagePermissions,
617                                   chreMessageFreeFunction *freeCallback,
618                                   const void *cookie) {
619   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSendReliableMessageAsync);
620   if (fptr != nullptr) {
621     return fptr(message, messageSize, messageType, hostEndpoint,
622                 messagePermissions, freeCallback, cookie);
623   } else {
624     return false;
625   }
626 }
627 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
628 
629 // Begin endpoint messaging APIs
630 
631 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11
632 WEAK_SYMBOL
chreMsgGetEndpointInfo(uint64_t hubId,uint64_t endpointId,struct chreMsgEndpointInfo * info)633 bool chreMsgGetEndpointInfo(uint64_t hubId, uint64_t endpointId,
634                             struct chreMsgEndpointInfo *info) {
635   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgGetEndpointInfo);
636   return fptr != nullptr ? fptr(hubId, endpointId, info) : false;
637 }
638 
639 WEAK_SYMBOL
chreMsgConfigureEndpointReadyEvents(uint64_t hubId,uint64_t endpointId,bool enable)640 bool chreMsgConfigureEndpointReadyEvents(uint64_t hubId, uint64_t endpointId,
641                                          bool enable) {
642   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgConfigureEndpointReadyEvents);
643   return fptr != nullptr ? fptr(hubId, endpointId, enable) : false;
644 }
645 
646 WEAK_SYMBOL
chreMsgConfigureServiceReadyEvents(uint64_t hubId,const char * serviceDescriptor,bool enable)647 bool chreMsgConfigureServiceReadyEvents(uint64_t hubId,
648                                         const char *serviceDescriptor,
649                                         bool enable) {
650   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgConfigureServiceReadyEvents);
651   return fptr != nullptr ? fptr(hubId, serviceDescriptor, enable) : false;
652 }
653 
654 WEAK_SYMBOL
chreMsgSessionGetInfo(uint16_t sessionId,struct chreMsgSessionInfo * info)655 bool chreMsgSessionGetInfo(uint16_t sessionId,
656                            struct chreMsgSessionInfo *info) {
657   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgSessionGetInfo);
658   return fptr != nullptr ? fptr(sessionId, info) : false;
659 }
660 
661 WEAK_SYMBOL
chreMsgPublishServices(const struct chreMsgServiceInfo * services,size_t numServices)662 bool chreMsgPublishServices(const struct chreMsgServiceInfo *services,
663                             size_t numServices) {
664   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgPublishServices);
665   return fptr != nullptr ? fptr(services, numServices) : false;
666 }
667 
668 WEAK_SYMBOL
chreMsgSessionOpenAsync(uint64_t hubId,uint64_t endpointId,const char * serviceDescriptor)669 bool chreMsgSessionOpenAsync(uint64_t hubId, uint64_t endpointId,
670                              const char *serviceDescriptor) {
671   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgSessionOpenAsync);
672   return fptr != nullptr ? fptr(hubId, endpointId, serviceDescriptor) : false;
673 }
674 
675 WEAK_SYMBOL
chreMsgSessionCloseAsync(uint16_t sessionId)676 bool chreMsgSessionCloseAsync(uint16_t sessionId) {
677   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgSessionCloseAsync);
678   return fptr != nullptr ? fptr(sessionId) : false;
679 }
680 
681 WEAK_SYMBOL
chreMsgSend(void * message,size_t messageSize,uint32_t messageType,uint16_t sessionId,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback)682 bool chreMsgSend(void *message, size_t messageSize, uint32_t messageType,
683                  uint16_t sessionId, uint32_t messagePermissions,
684                  chreMessageFreeFunction *freeCallback) {
685   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgSend);
686   return fptr != nullptr ? fptr(message, messageSize, messageType, sessionId,
687                                 messagePermissions, freeCallback)
688                          : false;
689 }
690 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11 */
691 
692 // End endpoint messaging APIs
693 
694 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
695 WEAK_SYMBOL
chreUserSettingGetState(uint8_t setting)696 int8_t chreUserSettingGetState(uint8_t setting) {
697   int8_t settingState = CHRE_USER_SETTING_STATE_UNKNOWN;
698   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreUserSettingGetState);
699   if (fptr != nullptr) {
700     settingState = fptr(setting);
701   }
702   return settingState;
703 }
704 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
705 
706 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
707 WEAK_SYMBOL
chreUserSettingConfigureEvents(uint8_t setting,bool enable)708 void chreUserSettingConfigureEvents(uint8_t setting, bool enable) {
709   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreUserSettingConfigureEvents);
710   if (fptr != nullptr) {
711     fptr(setting, enable);
712   }
713 }
714 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
715 
716 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
717 WEAK_SYMBOL
chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,bool enable)718 bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,
719                                             bool enable) {
720   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureHostEndpointNotifications);
721   return (fptr != nullptr) ? fptr(hostEndpointId, enable) : false;
722 }
723 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
724 
725 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
726 WEAK_SYMBOL
chrePublishRpcServices(struct chreNanoappRpcService * services,size_t numServices)727 bool chrePublishRpcServices(struct chreNanoappRpcService *services,
728                             size_t numServices) {
729   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chrePublishRpcServices);
730   return (fptr != nullptr) ? fptr(services, numServices) : false;
731 }
732 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
733 
734 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
735 WEAK_SYMBOL
chreGetHostEndpointInfo(uint16_t hostEndpointId,struct chreHostEndpointInfo * info)736 bool chreGetHostEndpointInfo(uint16_t hostEndpointId,
737                              struct chreHostEndpointInfo *info) {
738   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetHostEndpointInfo);
739   return (fptr != nullptr) ? fptr(hostEndpointId, info) : false;
740 }
741 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
742 
743 // NOTE: The backward compatibility provided by this stub is only needed below
744 // CHRE v1.8 so we check the first API version for the platform against v1.8.
745 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
chreGetNanoappInfoByAppId(uint64_t appId,struct chreNanoappInfo * info)746 bool chreGetNanoappInfoByAppId(uint64_t appId, struct chreNanoappInfo *info) {
747   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetNanoappInfoByAppId);
748   bool success = (fptr != nullptr) ? fptr(appId, info) : false;
749   if (success && chreGetApiVersion() < CHRE_API_VERSION_1_8) {
750     populateChreNanoappInfoPre18(info);
751   }
752   return success;
753 }
754 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
755 
756 // NOTE: The backward compatibility provided by this stub is only needed below
757 // CHRE v1.8 so we check the first API version for the platform against v1.8.
758 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
chreGetNanoappInfoByInstanceId(uint32_t instanceId,struct chreNanoappInfo * info)759 bool chreGetNanoappInfoByInstanceId(uint32_t instanceId,
760                                     struct chreNanoappInfo *info) {
761   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetNanoappInfoByInstanceId);
762   bool success = (fptr != nullptr) ? fptr(instanceId, info) : false;
763   if (success && chreGetApiVersion() < CHRE_API_VERSION_1_8) {
764     populateChreNanoappInfoPre18(info);
765   }
766   return success;
767 }
768 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
769 
770 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
771 WEAK_SYMBOL
chreGetCapabilities()772 uint32_t chreGetCapabilities() {
773   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetCapabilities);
774   return (fptr != nullptr) ? fptr() : CHRE_CAPABILITIES_NONE;
775 }
776 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
777 
778 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
779 WEAK_SYMBOL
chreGetMessageToHostMaxSize()780 uint32_t chreGetMessageToHostMaxSize() {
781   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetMessageToHostMaxSize);
782   return (fptr != nullptr) ? fptr() : CHRE_MESSAGE_TO_HOST_MAX_SIZE;
783 }
784 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
785 
786 #endif  // !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT)
787