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