• 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/util/nanoapp/log.h"
27 #include "chre_api/chre.h"
28 #include "chre_nsl_internal/platform/shared/debug_dump.h"
29 #include "chre_nsl_internal/util/macros.h"
30 #include "chre_nsl_internal/util/system/napp_permissions.h"
31 #ifdef CHRE_NANOAPP_USES_WIFI
32 #include "chre_nsl_internal/util/system/wifi_util.h"
33 #endif
34 
35 #ifndef LOG_TAG
36 #define LOG_TAG "[NSL]"
37 #endif  // LOG_TAG
38 
39 /**
40  * @file
41  * The Nanoapp Support Library (NSL) that gets built with nanoapps to act as an
42  * intermediary to the reference CHRE implementation. It provides hooks so the
43  * app can be registered with the system, and also provides a layer where we can
44  * implement cross-version compatibility features as needed.
45  */
46 
47 namespace {
48 
49 constexpr uint32_t kNanoappPermissions = 0
50 // DO NOT USE this macro outside of specific CHQTS nanoapps. This is only used
51 // to allow testing of invalid permission declarations.
52 #ifdef CHRE_TEST_NANOAPP_PERMS
53                                          | CHRE_TEST_NANOAPP_PERMS
54 #else
55 #ifdef CHRE_NANOAPP_USES_AUDIO
56     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_AUDIO)
57 #endif
58 #ifdef CHRE_NANOAPP_USES_BLE
59     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_BLE)
60 #endif
61 #ifdef CHRE_NANOAPP_USES_GNSS
62     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_GNSS)
63 #endif
64 #ifdef CHRE_NANOAPP_USES_WIFI
65     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_WIFI)
66 #endif
67 #ifdef CHRE_NANOAPP_USES_WWAN
68     | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_WWAN)
69 #endif
70 #endif  // CHRE_TEST_NANOAPP_PERMS
71     ;
72 
73 #if defined(CHRE_SLPI_UIMG_ENABLED) || defined(CHRE_TCM_ENABLED)
74 constexpr int kIsTcmNanoapp = 1;
75 #else
76 constexpr int kIsTcmNanoapp = 0;
77 #endif  // CHRE_SLPI_UIMG_ENABLED
78 
79 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && defined(CHRE_NANOAPP_USES_GNSS)
80 // Return a v1.3+ GnssLocationEvent for the nanoapp when running on a v1.2-
81 // platform.
translateLegacyGnssLocation(const chreGnssLocationEvent & legacyEvent)82 chreGnssLocationEvent translateLegacyGnssLocation(
83     const chreGnssLocationEvent &legacyEvent) {
84   // Copy v1.2- fields over to a v1.3+ event.
85   chreGnssLocationEvent newEvent = {};
86   newEvent.timestamp = legacyEvent.timestamp;
87   newEvent.latitude_deg_e7 = legacyEvent.latitude_deg_e7;
88   newEvent.longitude_deg_e7 = legacyEvent.longitude_deg_e7;
89   newEvent.altitude = legacyEvent.altitude;
90   newEvent.speed = legacyEvent.speed;
91   newEvent.bearing = legacyEvent.bearing;
92   newEvent.accuracy = legacyEvent.accuracy;
93   newEvent.flags = legacyEvent.flags;
94 
95   // Unset flags that are defined in v1.3+ but not in v1.2-.
96   newEvent.flags &= ~(CHRE_GPS_LOCATION_HAS_ALTITUDE_ACCURACY |
97                       CHRE_GPS_LOCATION_HAS_SPEED_ACCURACY |
98                       CHRE_GPS_LOCATION_HAS_BEARING_ACCURACY);
99   return newEvent;
100 }
101 
nanoappHandleEventCompat(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)102 void nanoappHandleEventCompat(uint32_t senderInstanceId, uint16_t eventType,
103                               const void *eventData) {
104   if (eventType == CHRE_EVENT_GNSS_LOCATION &&
105       chreGetApiVersion() < CHRE_API_VERSION_1_3) {
106     chreGnssLocationEvent event = translateLegacyGnssLocation(
107         *static_cast<const chreGnssLocationEvent *>(eventData));
108     nanoappHandleEvent(senderInstanceId, eventType, &event);
109   } else {
110     nanoappHandleEvent(senderInstanceId, eventType, eventData);
111   }
112 }
113 #endif
114 
115 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && defined(CHRE_NANOAPP_USES_BLE)
reverseServiceDataUuid(struct chreBleGenericFilter * filter)116 void reverseServiceDataUuid(struct chreBleGenericFilter *filter) {
117   if (filter->type != CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE ||
118       filter->len == 0) {
119     return;
120   }
121   std::swap(filter->data[0], filter->data[1]);
122   std::swap(filter->dataMask[0], filter->dataMask[1]);
123   if (filter->len == 1) {
124     filter->data[0] = 0x0;
125     filter->dataMask[0] = 0x0;
126     filter->len = 2;
127   }
128 }
129 
serviceDataFilterEndianSwapRequired(const struct chreBleScanFilter * filter)130 bool serviceDataFilterEndianSwapRequired(
131     const struct chreBleScanFilter *filter) {
132   if (chreGetApiVersion() >= CHRE_API_VERSION_1_8 || filter == nullptr) {
133     return false;
134   }
135   for (size_t i = 0; i < filter->scanFilterCount; i++) {
136     if (filter->scanFilters[i].type ==
137             CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE &&
138         filter->scanFilters[i].len > 0) {
139       return true;
140     }
141   }
142   return false;
143 }
144 #endif
145 
146 }  // anonymous namespace
147 
148 //! Used to determine the given unstable ID that was provided when building this
149 //! nanoapp, if any. The symbol is placed in its own section so it can be
150 //! stripped to determine if the nanoapp changed compared to a previous version.
151 //! We also align the variable to match the minimum alignment of the surrounding
152 //! sections, since for compilers with a default size-1 alignment, there might
153 //! be a spill-over from the previous segment if not zero-padded, when we
154 //! attempt to read the string.
155 extern "C" DLL_EXPORT const char _chreNanoappUnstableId[]
156     __attribute__((section(".unstable_id"))) __attribute__((aligned(8))) =
157         NANOAPP_UNSTABLE_ID;
158 
159 extern "C" DLL_EXPORT const struct chreNslNanoappInfo _chreNslDsoNanoappInfo = {
160     /* magic */ CHRE_NSL_NANOAPP_INFO_MAGIC,
161     /* structMinorVersion */ CHRE_NSL_NANOAPP_INFO_STRUCT_MINOR_VERSION,
162     /* isSystemNanoapp */ NANOAPP_IS_SYSTEM_NANOAPP,
163     /* isTcmNanoapp */ kIsTcmNanoapp,
164     /* reservedFlags */ 0,
165     /* reserved */ 0,
166     /* targetApiVersion */ CHRE_API_VERSION,
167 
168     // These values are supplied by the build environment.
169     /* vendor */ NANOAPP_VENDOR_STRING,
170     /* name */ NANOAPP_NAME_STRING,
171     /* appId */ NANOAPP_ID,
172     /* appVersion */ NANOAPP_VERSION,
173     /* entryPoints */
174     {
175         /* start */ nanoappStart,
176 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && defined(CHRE_NANOAPP_USES_GNSS)
177         /* handleEvent */ nanoappHandleEventCompat,
178 #else
179         /* handleEvent */ nanoappHandleEvent,
180 #endif
181         /* end */ nanoappEnd,
182     },
183     /* appVersionString */ _chreNanoappUnstableId,
184     /* appPermissions */ kNanoappPermissions,
185 };
186 
getChreNslDsoNanoappInfo()187 const struct chreNslNanoappInfo *getChreNslDsoNanoappInfo() {
188   return &_chreNslDsoNanoappInfo;
189 }
190 
191 // The code section below provides default implementations for new symbols
192 // introduced in CHRE API v1.2+ to provide binary compatibility with previous
193 // CHRE implementations. Note that we don't presently include symbols for v1.1,
194 // as the current known set of CHRE platforms that use this NSL implementation
195 // are all v1.1+.
196 // If a nanoapp knows that it is only targeting the latest platform version, it
197 // can define the CHRE_NANOAPP_DISABLE_BACKCOMPAT flag, so this indirection will
198 // be avoided at the expense of a nanoapp not being able to load at all on prior
199 // implementations.
200 
201 #ifndef CHRE_NANOAPP_DISABLE_BACKCOMPAT
202 
203 #include <dlfcn.h>
204 
205 namespace {
206 // Populate chreNanoappInfo for CHRE API pre v1.8.
populateChreNanoappInfoPre18(struct chreNanoappInfo * info)207 void populateChreNanoappInfoPre18(struct chreNanoappInfo *info) {
208   info->rpcServiceCount = 0;
209   info->rpcServices = nullptr;
210   memset(&info->reserved, 0, sizeof(info->reserved));
211 }
212 }  // namespace
213 
214 /**
215  * Lazily calls dlsym to find the function pointer for a given function
216  * (provided without quotes) in another library (i.e. the CHRE platform DSO),
217  * caching and returning the result.
218  */
219 #define CHRE_NSL_LAZY_LOOKUP(functionName)            \
220   ({                                                  \
221     static bool lookupPerformed = false;              \
222     static decltype(functionName) *funcPtr = nullptr; \
223     if (!lookupPerformed) {                           \
224       funcPtr = reinterpret_cast<decltype(funcPtr)>(  \
225           dlsym(RTLD_NEXT, STRINGIFY(functionName))); \
226       lookupPerformed = true;                         \
227     }                                                 \
228     funcPtr;                                          \
229   })
230 
231 #ifdef CHRE_NANOAPP_USES_AUDIO
232 
233 WEAK_SYMBOL
chreAudioGetSource(uint32_t handle,struct chreAudioSource * audioSource)234 bool chreAudioGetSource(uint32_t handle, struct chreAudioSource *audioSource) {
235   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioGetSource);
236   return (fptr != nullptr) ? fptr(handle, audioSource) : false;
237 }
238 
239 WEAK_SYMBOL
chreAudioConfigureSource(uint32_t handle,bool enable,uint64_t bufferDuration,uint64_t deliveryInterval)240 bool chreAudioConfigureSource(uint32_t handle, bool enable,
241                               uint64_t bufferDuration,
242                               uint64_t deliveryInterval) {
243   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioConfigureSource);
244   return (fptr != nullptr)
245              ? fptr(handle, enable, bufferDuration, deliveryInterval)
246              : false;
247 }
248 
249 WEAK_SYMBOL
chreAudioGetStatus(uint32_t handle,struct chreAudioSourceStatus * status)250 bool chreAudioGetStatus(uint32_t handle, struct chreAudioSourceStatus *status) {
251   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioGetStatus);
252   return (fptr != nullptr) ? fptr(handle, status) : false;
253 }
254 
255 #endif /* CHRE_NANOAPP_USES_AUDIO */
256 
257 #ifdef CHRE_NANOAPP_USES_BLE
258 
259 WEAK_SYMBOL
chreBleGetCapabilities()260 uint32_t chreBleGetCapabilities() {
261   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetCapabilities);
262   return (fptr != nullptr) ? fptr() : CHRE_BLE_CAPABILITIES_NONE;
263 }
264 
265 WEAK_SYMBOL
chreBleGetFilterCapabilities()266 uint32_t chreBleGetFilterCapabilities() {
267   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetFilterCapabilities);
268   return (fptr != nullptr) ? fptr() : CHRE_BLE_FILTER_CAPABILITIES_NONE;
269 }
270 
271 WEAK_SYMBOL
chreBleFlushAsync(const void * cookie)272 bool chreBleFlushAsync(const void *cookie) {
273   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleFlushAsync);
274   return (fptr != nullptr) ? fptr(cookie) : false;
275 }
276 
277 WEAK_SYMBOL
chreBleStartScanAsync(chreBleScanMode mode,uint32_t reportDelayMs,const struct chreBleScanFilter * filter)278 bool chreBleStartScanAsync(chreBleScanMode mode, uint32_t reportDelayMs,
279                            const struct chreBleScanFilter *filter) {
280   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStartScanAsync);
281   if (fptr == nullptr) {
282     return false;
283   } else if (!serviceDataFilterEndianSwapRequired(filter)) {
284     return fptr(mode, reportDelayMs, filter);
285   }
286   // For nanoapps compiled against v1.8+ working with earlier versions of CHRE,
287   // convert service data filters to big-endian format.
288   chreBleScanFilter convertedFilter = *filter;
289   auto genericFilters = static_cast<chreBleGenericFilter *>(
290       chreHeapAlloc(sizeof(chreBleGenericFilter) * filter->scanFilterCount));
291   if (genericFilters == nullptr) {
292     LOG_OOM();
293     return false;
294   }
295   memcpy(genericFilters, filter->scanFilters,
296          filter->scanFilterCount * sizeof(chreBleGenericFilter));
297   for (size_t i = 0; i < filter->scanFilterCount; i++) {
298     reverseServiceDataUuid(&genericFilters[i]);
299   }
300   convertedFilter.scanFilters = genericFilters;
301   bool success = fptr(mode, reportDelayMs, &convertedFilter);
302   chreHeapFree(const_cast<chreBleGenericFilter *>(convertedFilter.scanFilters));
303   return success;
304 }
305 
306 WEAK_SYMBOL
chreBleStopScanAsync()307 bool chreBleStopScanAsync() {
308   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStopScanAsync);
309   return (fptr != nullptr) ? fptr() : false;
310 }
311 
312 WEAK_SYMBOL
chreBleReadRssiAsync(uint16_t connectionHandle,const void * cookie)313 bool chreBleReadRssiAsync(uint16_t connectionHandle, const void *cookie) {
314   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleReadRssiAsync);
315   return (fptr != nullptr) ? fptr(connectionHandle, cookie) : false;
316 }
317 
318 WEAK_SYMBOL
chreBleGetScanStatus(struct chreBleScanStatus * status)319 bool chreBleGetScanStatus(struct chreBleScanStatus *status) {
320   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetScanStatus);
321   return (fptr != nullptr) ? fptr(status) : false;
322 }
323 
324 #endif /* CHRE_NANOAPP_USES_BLE */
325 
326 WEAK_SYMBOL
chreConfigureHostSleepStateEvents(bool enable)327 void chreConfigureHostSleepStateEvents(bool enable) {
328   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureHostSleepStateEvents);
329   if (fptr != nullptr) {
330     fptr(enable);
331   }
332 }
333 
334 WEAK_SYMBOL
chreIsHostAwake(void)335 bool chreIsHostAwake(void) {
336   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreIsHostAwake);
337   return (fptr != nullptr) ? fptr() : false;
338 }
339 
340 #ifdef CHRE_NANOAPP_USES_GNSS
341 
342 WEAK_SYMBOL
chreGnssConfigurePassiveLocationListener(bool enable)343 bool chreGnssConfigurePassiveLocationListener(bool enable) {
344   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGnssConfigurePassiveLocationListener);
345   return (fptr != nullptr) ? fptr(enable) : false;
346 }
347 
348 #endif /* CHRE_NANOAPP_USES_GNSS */
349 
350 #ifdef CHRE_NANOAPP_USES_WIFI
351 
352 WEAK_SYMBOL
chreWifiRequestScanAsync(const struct chreWifiScanParams * params,const void * cookie)353 bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params,
354                               const void *cookie) {
355   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiRequestScanAsync);
356 
357   if (fptr == nullptr) {
358     // Should never happen
359     return false;
360   } else if (chreGetApiVersion() < CHRE_API_VERSION_1_5) {
361     const struct chreWifiScanParams legacyParams =
362         chre::translateToLegacyWifiScanParams(params);
363     return fptr(&legacyParams, cookie);
364   } else {
365     return fptr(params, cookie);
366   }
367 }
368 
369 WEAK_SYMBOL
chreWifiRequestRangingAsync(const struct chreWifiRangingParams * params,const void * cookie)370 bool chreWifiRequestRangingAsync(const struct chreWifiRangingParams *params,
371                                  const void *cookie) {
372   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiRequestRangingAsync);
373   return (fptr != nullptr) ? fptr(params, cookie) : false;
374 }
375 
376 WEAK_SYMBOL
chreWifiNanRequestRangingAsync(const struct chreWifiNanRangingParams * params,const void * cookie)377 bool chreWifiNanRequestRangingAsync(
378     const struct chreWifiNanRangingParams *params, const void *cookie) {
379   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanRequestRangingAsync);
380   return (fptr != nullptr) ? fptr(params, cookie) : false;
381 }
382 
383 WEAK_SYMBOL
chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig * config,const void * cookie)384 bool chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig *config,
385                           const void *cookie) {
386   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanSubscribe);
387   return (fptr != nullptr) ? fptr(config, cookie) : false;
388 }
389 
390 WEAK_SYMBOL
chreWifiNanSubscribeCancel(uint32_t subscriptionID)391 bool chreWifiNanSubscribeCancel(uint32_t subscriptionID) {
392   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanSubscribeCancel);
393   return (fptr != nullptr) ? fptr(subscriptionID) : false;
394 }
395 
396 #endif /* CHRE_NANOAPP_USES_WIFI */
397 
398 WEAK_SYMBOL
chreSensorFind(uint8_t sensorType,uint8_t sensorIndex,uint32_t * handle)399 bool chreSensorFind(uint8_t sensorType, uint8_t sensorIndex, uint32_t *handle) {
400   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorFind);
401   if (fptr != nullptr) {
402     return fptr(sensorType, sensorIndex, handle);
403   } else if (sensorIndex == 0) {
404     return chreSensorFindDefault(sensorType, handle);
405   } else {
406     return false;
407   }
408 }
409 
410 WEAK_SYMBOL
chreSensorConfigureBiasEvents(uint32_t sensorHandle,bool enable)411 bool chreSensorConfigureBiasEvents(uint32_t sensorHandle, bool enable) {
412   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorConfigureBiasEvents);
413   return (fptr != nullptr) ? fptr(sensorHandle, enable) : false;
414 }
415 
416 WEAK_SYMBOL
chreSensorGetThreeAxisBias(uint32_t sensorHandle,struct chreSensorThreeAxisData * bias)417 bool chreSensorGetThreeAxisBias(uint32_t sensorHandle,
418                                 struct chreSensorThreeAxisData *bias) {
419   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorGetThreeAxisBias);
420   return (fptr != nullptr) ? fptr(sensorHandle, bias) : false;
421 }
422 
423 WEAK_SYMBOL
chreSensorFlushAsync(uint32_t sensorHandle,const void * cookie)424 bool chreSensorFlushAsync(uint32_t sensorHandle, const void *cookie) {
425   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorFlushAsync);
426   return (fptr != nullptr) ? fptr(sensorHandle, cookie) : false;
427 }
428 
429 WEAK_SYMBOL
chreConfigureDebugDumpEvent(bool enable)430 void chreConfigureDebugDumpEvent(bool enable) {
431   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureDebugDumpEvent);
432   if (fptr != nullptr) {
433     fptr(enable);
434   }
435 }
436 
437 WEAK_SYMBOL
chreDebugDumpLog(const char * formatStr,...)438 void chreDebugDumpLog(const char *formatStr, ...) {
439   auto *fptr = CHRE_NSL_LAZY_LOOKUP(platform_chreDebugDumpVaLog);
440   if (fptr != nullptr) {
441     va_list args;
442     va_start(args, formatStr);
443     fptr(formatStr, args);
444     va_end(args);
445   }
446 }
447 
448 WEAK_SYMBOL
chreSendMessageWithPermissions(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback)449 bool chreSendMessageWithPermissions(void *message, size_t messageSize,
450                                     uint32_t messageType, uint16_t hostEndpoint,
451                                     uint32_t messagePermissions,
452                                     chreMessageFreeFunction *freeCallback) {
453   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSendMessageWithPermissions);
454   if (fptr != nullptr) {
455     return fptr(message, messageSize, messageType, hostEndpoint,
456                 messagePermissions, freeCallback);
457   } else {
458     return chreSendMessageToHostEndpoint(message, messageSize, messageType,
459                                          hostEndpoint, freeCallback);
460   }
461 }
462 
463 WEAK_SYMBOL
chreUserSettingGetState(uint8_t setting)464 int8_t chreUserSettingGetState(uint8_t setting) {
465   int8_t settingState = CHRE_USER_SETTING_STATE_UNKNOWN;
466   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreUserSettingGetState);
467   if (fptr != nullptr) {
468     settingState = fptr(setting);
469   }
470   return settingState;
471 }
472 
473 WEAK_SYMBOL
chreUserSettingConfigureEvents(uint8_t setting,bool enable)474 void chreUserSettingConfigureEvents(uint8_t setting, bool enable) {
475   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreUserSettingConfigureEvents);
476   if (fptr != nullptr) {
477     fptr(setting, enable);
478   }
479 }
480 
481 WEAK_SYMBOL
chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,bool enable)482 bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,
483                                             bool enable) {
484   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureHostEndpointNotifications);
485   return (fptr != nullptr) ? fptr(hostEndpointId, enable) : false;
486 }
487 
488 WEAK_SYMBOL
chrePublishRpcServices(struct chreNanoappRpcService * services,size_t numServices)489 bool chrePublishRpcServices(struct chreNanoappRpcService *services,
490                             size_t numServices) {
491   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chrePublishRpcServices);
492   return (fptr != nullptr) ? fptr(services, numServices) : false;
493 }
494 
495 WEAK_SYMBOL
chreGetHostEndpointInfo(uint16_t hostEndpointId,struct chreHostEndpointInfo * info)496 bool chreGetHostEndpointInfo(uint16_t hostEndpointId,
497                              struct chreHostEndpointInfo *info) {
498   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetHostEndpointInfo);
499   return (fptr != nullptr) ? fptr(hostEndpointId, info) : false;
500 }
501 
chreGetNanoappInfoByAppId(uint64_t appId,struct chreNanoappInfo * info)502 bool chreGetNanoappInfoByAppId(uint64_t appId, struct chreNanoappInfo *info) {
503   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetNanoappInfoByAppId);
504   bool success = (fptr != nullptr) ? fptr(appId, info) : false;
505   if (success && chreGetApiVersion() < CHRE_API_VERSION_1_8) {
506     populateChreNanoappInfoPre18(info);
507   }
508   return success;
509 }
510 
chreGetNanoappInfoByInstanceId(uint32_t instanceId,struct chreNanoappInfo * info)511 bool chreGetNanoappInfoByInstanceId(uint32_t instanceId,
512                                     struct chreNanoappInfo *info) {
513   auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetNanoappInfoByInstanceId);
514   bool success = (fptr != nullptr) ? fptr(instanceId, info) : false;
515   if (success && chreGetApiVersion() < CHRE_API_VERSION_1_8) {
516     populateChreNanoappInfoPre18(info);
517   }
518   return success;
519 }
520 
521 #endif  // CHRE_NANOAPP_DISABLE_BACKCOMPAT
522