• 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 #include <cinttypes>
18 
19 #include "chre/util/macros.h"
20 #include "chre/util/nanoapp/log.h"
21 #include "chre/util/time.h"
22 #include "chre_api/chre.h"
23 
24 #define LOG_TAG "[SensorWorld]"
25 
26 #ifdef CHRE_NANOAPP_INTERNAL
27 namespace chre {
28 namespace {
29 #endif  // CHRE_NANOAPP_INTERNAL
30 
31 using chre::kOneMillisecondInNanoseconds;
32 using chre::Milliseconds;
33 using chre::Seconds;
34 
35 namespace {
36 
37 //! Enable BreakIt test mode.
38 // In BreakIt test mode, a timer will be set periodically to randomly
39 // enable/disable each sensor.
40 constexpr bool kBreakIt = false;
41 constexpr Milliseconds kBreakItPeriod = Milliseconds(2000);
42 uint32_t gBreakItTimerHandle;
43 
44 //! Enable chreSensorFlushAsync test
45 // When enabled, SensorWorld will set a timer to invoke
46 // chreSensorFlushAsync(sensors[kFlushSensorIndex].handle)
47 // halfway through sensors[kFlushSensorIndex].latency
48 //
49 // If CHRE_EVENT_SENSOR_FLUSH_COMPLETE is not received before
50 // kFlushItTimeout expires, an error message will be logged.
51 constexpr bool kFlushIt = true;
52 constexpr uint32_t kFlushCookie = 0xdeadbeef;
53 constexpr uint32_t kFlushSensorIndex = 0;  // CHRE_SENSOR_TYPE_ACCELEROMETER
54 uint32_t gFlushItTimerHandle;
55 
56 constexpr Milliseconds kFlushItTimeout = Milliseconds(5000);
57 uint32_t gFlushItTimeoutTimerHandle;
58 
59 //! Whether to enable sensor event logging or not.
60 constexpr bool kEnableSensorEventLogging = true;
61 
62 //! Enable/disable all sensors by default.
63 // This allows disabling all sensens by default and enabling only targeted
64 // sensors for testing by locally overriding 'enable' field in SensorState.
65 // Note that enabling BreakIt test disables all sensors at init by default.
66 constexpr bool kEnableDefault = !kBreakIt;
67 
68 struct SensorState {
69   const uint8_t type;
70   const uint8_t sensorIndex;
71   uint32_t handle;
72   bool isInitialized;
73   bool enable;
74   uint64_t interval;  // nsec
75   uint64_t latency;   // nsec
76   chreSensorInfo info;
77 };
78 
79 SensorState sensors[] = {
80     {
81         .type = CHRE_SENSOR_TYPE_ACCELEROMETER,
82         .sensorIndex = 0,
83         .handle = 0,
84         .isInitialized = false,
85         .enable = kEnableDefault,
86         .interval = Milliseconds(80).toRawNanoseconds(),
87         .latency = Seconds(4).toRawNanoseconds(),
88         .info = {},
89     },
90     {
91         .type = CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT,
92         .sensorIndex = 0,
93         .handle = 0,
94         .isInitialized = false,
95         .enable = false,  // InstantMotion is triggered by Prox
96         .interval = CHRE_SENSOR_INTERVAL_DEFAULT,
97         .latency = CHRE_SENSOR_LATENCY_DEFAULT,
98         .info = {},
99     },
100     {
101         .type = CHRE_SENSOR_TYPE_STATIONARY_DETECT,
102         .sensorIndex = 0,
103         .handle = 0,
104         .isInitialized = false,
105         .enable = false,  // StationaryDetect is triggered by Prox
106         .interval = CHRE_SENSOR_INTERVAL_DEFAULT,
107         .latency = CHRE_SENSOR_LATENCY_DEFAULT,
108         .info = {},
109     },
110     {
111         .type = CHRE_SENSOR_TYPE_GYROSCOPE,
112         .sensorIndex = 0,
113         .handle = 0,
114         .isInitialized = false,
115         .enable = kEnableDefault,
116         .interval = Milliseconds(80).toRawNanoseconds(),
117         .latency = Seconds(4).toRawNanoseconds(),
118         .info = {},
119     },
120     {
121         .type = CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD,
122         .sensorIndex = 0,
123         .handle = 0,
124         .isInitialized = false,
125         .enable = kEnableDefault,
126         .interval = Milliseconds(80).toRawNanoseconds(),
127         .latency = Seconds(4).toRawNanoseconds(),
128         .info = {},
129     },
130     {
131         .type = CHRE_SENSOR_TYPE_PRESSURE,
132         .sensorIndex = 0,
133         .handle = 0,
134         .isInitialized = false,
135         .enable = kEnableDefault,
136         .interval = Milliseconds(200).toRawNanoseconds(),
137         .latency = Seconds(4).toRawNanoseconds(),
138         .info = {},
139     },
140     {
141         .type = CHRE_SENSOR_TYPE_LIGHT,
142         .sensorIndex = 0,
143         .handle = 0,
144         .isInitialized = false,
145         .enable = kEnableDefault,
146         .interval = Milliseconds(200).toRawNanoseconds(),
147         .latency = 0,
148         .info = {},
149     },
150     {
151         .type = CHRE_SENSOR_TYPE_PROXIMITY,
152         .sensorIndex = 0,
153         .handle = 0,
154         .isInitialized = false,
155         .enable = kEnableDefault,
156         .interval = Milliseconds(200).toRawNanoseconds(),
157         .latency = 0,
158         .info = {},
159     },
160     {
161         .type = CHRE_SENSOR_TYPE_STEP_DETECT,
162         .sensorIndex = 0,
163         .handle = 0,
164         .isInitialized = false,
165         .enable = kEnableDefault,
166         .interval = CHRE_SENSOR_INTERVAL_DEFAULT,
167         .latency = CHRE_SENSOR_LATENCY_ASAP,
168         .info = {},
169     },
170     {
171         .type = CHRE_SENSOR_TYPE_STEP_COUNTER,
172         .sensorIndex = 0,
173         .handle = 0,
174         .isInitialized = false,
175         .enable = kEnableDefault,
176         .interval = CHRE_SENSOR_INTERVAL_DEFAULT,
177         .latency = CHRE_SENSOR_LATENCY_ASAP,
178         .info = {},
179     },
180     {
181         .type = CHRE_SENSOR_TYPE_ACCELEROMETER_TEMPERATURE,
182         .sensorIndex = 0,
183         .handle = 0,
184         .isInitialized = false,
185         .enable = kEnableDefault,
186         .interval = Seconds(2).toRawNanoseconds(),
187         .latency = 0,
188         .info = {},
189     },
190     {
191         .type = CHRE_SENSOR_TYPE_GYROSCOPE_TEMPERATURE,
192         .sensorIndex = 0,
193         .handle = 0,
194         .isInitialized = false,
195         .enable = kEnableDefault,
196         .interval = Seconds(2).toRawNanoseconds(),
197         .latency = 0,
198         .info = {},
199     },
200     {
201         .type = CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD_TEMPERATURE,
202         .sensorIndex = 0,
203         .handle = 0,
204         .isInitialized = false,
205         .enable = kEnableDefault,
206         .interval = Seconds(2).toRawNanoseconds(),
207         .latency = 0,
208         .info = {},
209     },
210     {
211         .type = CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER,
212         .sensorIndex = 0,
213         .handle = 0,
214         .isInitialized = false,
215         .enable = kEnableDefault,
216         .interval = Milliseconds(80).toRawNanoseconds(),
217         .latency = Seconds(4).toRawNanoseconds(),
218         .info = {},
219     },
220     {
221         .type = CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE,
222         .sensorIndex = 0,
223         .handle = 0,
224         .isInitialized = false,
225         .enable = kEnableDefault,
226         .interval = Milliseconds(80).toRawNanoseconds(),
227         .latency = Seconds(4).toRawNanoseconds(),
228         .info = {},
229     },
230     {
231         .type = CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD,
232         .sensorIndex = 0,
233         .handle = 0,
234         .isInitialized = false,
235         .enable = kEnableDefault,
236         .interval = Milliseconds(80).toRawNanoseconds(),
237         .latency = Seconds(4).toRawNanoseconds(),
238         .info = {},
239     },
240 };
241 
242 // Conditional logging macro
243 #define CLOGI(fmt, ...)              \
244   do {                               \
245     if (kEnableSensorEventLogging) { \
246       LOGI(fmt, ##__VA_ARGS__);      \
247     }                                \
248   } while (0);
249 
250 // Helpers for testing InstantMotion and StationaryDetect
251 enum class MotionMode {
252   Instant,
253   Stationary,
254 };
255 
256 // Storage to help access InstantMotion and StationaryDetect sensor handle and
257 // info
258 size_t motionSensorIndices[2];
259 MotionMode motionMode = MotionMode::Instant;
260 
getMotionSensorIndex()261 size_t getMotionSensorIndex() {
262   motionMode = (motionMode == MotionMode::Instant) ? MotionMode::Stationary
263                                                    : MotionMode::Instant;
264   return motionSensorIndices[static_cast<size_t>(motionMode)];
265 }
266 
267 //! Used to loop through all sensors to query sensor sampling status.
268 size_t statusIndex = 0;
269 
270 // Obtains 16-bit psuedo-random numbers.
getNextLfsrState()271 uint16_t getNextLfsrState() {
272   // 15-bit LFSR with feedback polynomial x^15 + x^14 + 1 gives us a
273   // pseudo-random sequence over all 32767 possible values
274   static uint16_t lfsr = 0x1337;
275   uint16_t nextBit = ((lfsr << 14) ^ (lfsr << 13)) & 0x4000;
276   lfsr = nextBit | (lfsr >> 1);
277 
278   return lfsr;
279 }
280 
getSensorName(uint32_t sensorHandle)281 const char *getSensorName(uint32_t sensorHandle) {
282   for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) {
283     if (sensors[i].handle == sensorHandle) {
284       return sensors[i].info.sensorName;
285     }
286   }
287   return nullptr;
288 }
289 
handleTimerEvent(const uint32_t * ev)290 void handleTimerEvent(const uint32_t *ev) {
291   if (*ev == gFlushItTimerHandle) {
292     LOGI("FlushIt Timer Fired");
293     if (chreSensorFlushAsync(sensors[kFlushSensorIndex].handle,
294                              &kFlushCookie)) {
295       gFlushItTimeoutTimerHandle =
296           chreTimerSet(kFlushItTimeout.toRawNanoseconds(),
297                        &gFlushItTimeoutTimerHandle, true /* oneShot */);
298     } else {
299       LOGE("chreSensorFlushAsync failed");
300     }
301 
302   } else if (*ev == gFlushItTimeoutTimerHandle) {
303     LOGE("chreSensorFlushAsync Timeout");
304 
305   } else if (*ev == gBreakItTimerHandle) {
306     for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) {
307       SensorState &sensor = sensors[i];
308 
309       bool enable = getNextLfsrState() & 0x1;
310       if (sensor.isInitialized && sensor.enable != enable) {
311         sensor.enable = enable;
312 
313         bool status;
314         if (!enable) {
315           status = chreSensorConfigureModeOnly(sensor.handle,
316                                                CHRE_SENSOR_CONFIGURE_MODE_DONE);
317         } else {
318           enum chreSensorConfigureMode mode =
319               sensor.info.isOneShot ? CHRE_SENSOR_CONFIGURE_MODE_ONE_SHOT
320                                     : CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS;
321           status = chreSensorConfigure(sensor.handle, mode, sensor.interval,
322                                        sensor.latency);
323         }
324 
325         LOGI("Configure [enable %d, status %d]: %s", enable, status,
326              sensor.info.sensorName);
327       }
328     }
329 
330     gBreakItTimerHandle =
331         chreTimerSet(kBreakItPeriod.toRawNanoseconds(), &gBreakItTimerHandle,
332                      true /* oneShot */);
333   }
334 }
335 
handleThreeAxisEvent(const chreSensorThreeAxisData * ev,uint16_t eventType)336 void handleThreeAxisEvent(const chreSensorThreeAxisData *ev,
337                           uint16_t eventType) {
338   const auto header = ev->header;
339   const auto *data = ev->readings;
340   const auto accuracy = header.accuracy;
341   uint64_t sampleTime = header.baseTimestamp;
342   uint64_t chreTime = chreGetTime();
343 
344   float x = 0, y = 0, z = 0;
345   for (size_t i = 0; i < header.readingCount; i++) {
346     x += data[i].v[0];
347     y += data[i].v[1];
348     z += data[i].v[2];
349     sampleTime += data[i].timestampDelta;
350   }
351   x /= header.readingCount;
352   y /= header.readingCount;
353   z /= header.readingCount;
354 
355   CLOGI("%s, %d samples: %f %f %f, accuracy: %u, t=%" PRIu64 " ms",
356         getSensorName(header.sensorHandle), header.readingCount,
357         static_cast<double>(x), static_cast<double>(y), static_cast<double>(z),
358         accuracy, header.baseTimestamp / kOneMillisecondInNanoseconds);
359 
360   if (eventType == CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_DATA) {
361     CLOGI("UncalGyro time: first %" PRIu64 " last %" PRIu64 " chre %" PRIu64
362           " delta [%" PRId64 ", %" PRId64 "]ms",
363           header.baseTimestamp, sampleTime, chreTime,
364           static_cast<int64_t>(header.baseTimestamp - chreTime) /
365               static_cast<int64_t>(kOneMillisecondInNanoseconds),
366           static_cast<int64_t>(sampleTime - chreTime) /
367               static_cast<int64_t>(kOneMillisecondInNanoseconds));
368   }
369 }
370 
handleFloatEvent(const chreSensorFloatData * ev)371 void handleFloatEvent(const chreSensorFloatData *ev) {
372   const auto header = ev->header;
373 
374   float v = 0;
375   for (size_t i = 0; i < header.readingCount; i++) {
376     v += ev->readings[i].value;
377   }
378   v /= header.readingCount;
379 
380   CLOGI("%s, %d samples: %f, accuracy = %u, t=%" PRIu64 " ms",
381         getSensorName(header.sensorHandle), header.readingCount,
382         static_cast<double>(v), header.accuracy,
383         header.baseTimestamp / kOneMillisecondInNanoseconds);
384 }
385 
handleProximityEvent(const chreSensorByteData * ev)386 void handleProximityEvent(const chreSensorByteData *ev) {
387   const auto header = ev->header;
388   const auto reading = ev->readings[0];
389   uint64_t sampleTime = header.baseTimestamp;
390   uint64_t chreTime = chreGetTime();
391 
392   CLOGI("%s, %d samples: isNear %d, invalid %d, accuracy: %u",
393         getSensorName(header.sensorHandle), header.readingCount, reading.isNear,
394         reading.invalid, header.accuracy);
395 
396   CLOGI("Prox time: sample %" PRIu64 " chre %" PRIu64 " delta %" PRId64 "ms",
397         header.baseTimestamp, chreTime,
398         static_cast<int64_t>(sampleTime - chreTime) / 1000000);
399 
400   // Enable InstantMotion and StationaryDetect alternatively on near->far.
401   if (reading.isNear == 0 && !kBreakIt) {
402     size_t motionSensorIndex = getMotionSensorIndex();
403     bool status = chreSensorConfigure(
404         sensors[motionSensorIndex].handle, CHRE_SENSOR_CONFIGURE_MODE_ONE_SHOT,
405         CHRE_SENSOR_INTERVAL_DEFAULT, CHRE_SENSOR_LATENCY_DEFAULT);
406     LOGI("Requested %s: %s", sensors[motionSensorIndex].info.sensorName,
407          status ? "success" : "failure");
408   }
409 
410   // Exercise chreGetSensorSamplingStatus on one sensor on near->far.
411   if (sensors[statusIndex].isInitialized && reading.isNear == 0) {
412     struct chreSensorSamplingStatus status;
413     bool success =
414         chreGetSensorSamplingStatus(sensors[statusIndex].handle, &status);
415     LOGI("%s success %d: enabled %d interval %" PRIu64 " latency %" PRIu64,
416          sensors[statusIndex].info.sensorName, success, status.enabled,
417          status.interval, status.latency);
418   }
419   statusIndex = (statusIndex + 1) % ARRAY_SIZE(sensors);
420 }
421 
422 }  // namespace
423 
nanoappStart()424 bool nanoappStart() {
425   LOGI("App started on platform ID %" PRIx64, chreGetPlatformId());
426 
427   for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) {
428     SensorState &sensor = sensors[i];
429     sensor.isInitialized =
430         chreSensorFind(sensor.type, sensor.sensorIndex, &sensor.handle);
431     LOGI("Sensor %zu initialized: %s with handle %" PRIu32, i,
432          sensor.isInitialized ? "true" : "false", sensor.handle);
433 
434     if (sensor.type == CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT) {
435       motionSensorIndices[static_cast<size_t>(MotionMode::Instant)] = i;
436     } else if (sensor.type == CHRE_SENSOR_TYPE_STATIONARY_DETECT) {
437       motionSensorIndices[static_cast<size_t>(MotionMode::Stationary)] = i;
438     }
439 
440     if (sensor.isInitialized) {
441       // Get sensor info
442       chreSensorInfo &info = sensor.info;
443       bool infoStatus = chreGetSensorInfo(sensor.handle, &info);
444       if (infoStatus) {
445         LOGI("SensorInfo: %s, Type=%" PRIu8
446              " OnChange=%d OneShot=%d Passive=%d "
447              "minInterval=%" PRIu64 "nsec",
448              info.sensorName, info.sensorType, info.isOnChange, info.isOneShot,
449              info.supportsPassiveMode, info.minInterval);
450       } else {
451         LOGE("chreGetSensorInfo failed");
452       }
453 
454       // Subscribe to sensors
455       if (sensor.enable) {
456         float odrHz = 1e9f / static_cast<float>(sensor.interval);
457         float latencySec = static_cast<float>(sensor.latency) / 1e9f;
458         bool status = chreSensorConfigure(sensor.handle,
459                                           CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS,
460                                           sensor.interval, sensor.latency);
461         LOGI("Requested data: odr %f Hz, latency %f sec, %s",
462              static_cast<double>(odrHz), static_cast<double>(latencySec),
463              status ? "success" : "failure");
464       }
465     }
466   }
467 
468   // Set timer for BreakIt test.
469   if (kBreakIt) {
470     gBreakItTimerHandle =
471         chreTimerSet(kBreakItPeriod.toRawNanoseconds(), &gBreakItTimerHandle,
472                      true /* oneShot */);
473   }
474 
475   if (kFlushIt) {
476     // Triger a flush half way through the target sensor latency
477     gFlushItTimerHandle =
478         chreTimerSet(sensors[kFlushSensorIndex].latency / 2,
479                      &gFlushItTimerHandle, true /* oneShot */);
480   }
481 
482   return true;
483 }
484 
nanoappHandleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)485 void nanoappHandleEvent(uint32_t senderInstanceId, uint16_t eventType,
486                         const void *eventData) {
487   UNUSED_VAR(senderInstanceId);
488 
489   switch (eventType) {
490     case CHRE_EVENT_SENSOR_ACCELEROMETER_DATA:
491     case CHRE_EVENT_SENSOR_UNCALIBRATED_ACCELEROMETER_DATA:
492     case CHRE_EVENT_SENSOR_GYROSCOPE_DATA:
493     case CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_DATA:
494     case CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA:
495     case CHRE_EVENT_SENSOR_UNCALIBRATED_GEOMAGNETIC_FIELD_DATA:
496       handleThreeAxisEvent(
497           static_cast<const chreSensorThreeAxisData *>(eventData), eventType);
498       break;
499 
500     case CHRE_EVENT_SENSOR_PRESSURE_DATA:
501     case CHRE_EVENT_SENSOR_LIGHT_DATA:
502     case CHRE_EVENT_SENSOR_ACCELEROMETER_TEMPERATURE_DATA:
503     case CHRE_EVENT_SENSOR_GYROSCOPE_TEMPERATURE_DATA:
504     case CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_TEMPERATURE_DATA:
505       handleFloatEvent(static_cast<const chreSensorFloatData *>(eventData));
506       break;
507 
508     case CHRE_EVENT_SENSOR_PROXIMITY_DATA:
509       handleProximityEvent(static_cast<const chreSensorByteData *>(eventData));
510       break;
511 
512     case CHRE_EVENT_SENSOR_INSTANT_MOTION_DETECT_DATA:
513     case CHRE_EVENT_SENSOR_STATIONARY_DETECT_DATA:
514     case CHRE_EVENT_SENSOR_STEP_DETECT_DATA: {
515       const auto *ev = static_cast<const chreSensorOccurrenceData *>(eventData);
516       const auto header = ev->header;
517 
518       CLOGI("%s, %d samples, accuracy: %u", getSensorName(header.sensorHandle),
519             header.readingCount, header.accuracy);
520       break;
521     }
522 
523     case CHRE_EVENT_SENSOR_STEP_COUNTER_DATA: {
524       const auto *ev = static_cast<const chreSensorUint64Data *>(eventData);
525       const auto header = ev->header;
526       const uint64_t reading = ev->readings[header.readingCount - 1].value;
527 
528       CLOGI("%s, %" PRIu16 " samples: latest %" PRIu64,
529             getSensorName(header.sensorHandle), header.readingCount, reading);
530       break;
531     }
532 
533     case CHRE_EVENT_SENSOR_SAMPLING_CHANGE: {
534       const auto *ev =
535           static_cast<const chreSensorSamplingStatusEvent *>(eventData);
536 
537       CLOGI("Sampling Change: handle %" PRIu32 ", status: interval %" PRIu64
538             " latency %" PRIu64 " enabled %d",
539             ev->sensorHandle, ev->status.interval, ev->status.latency,
540             ev->status.enabled);
541       break;
542     }
543 
544     case CHRE_EVENT_TIMER:
545       if (kBreakIt || kFlushIt) {
546         handleTimerEvent(static_cast<const uint32_t *>(eventData));
547       } else {
548         LOGE("Timer event received with kBreakIt and kFlushIt disabled");
549       }
550       break;
551 
552     case CHRE_EVENT_SENSOR_FLUSH_COMPLETE: {
553       const auto *ev =
554           static_cast<const chreSensorFlushCompleteEvent *>(eventData);
555       chreTimerCancel(gFlushItTimeoutTimerHandle);
556 
557       LOGI("Flush Complete: handle %" PRIu32 ", errorCode: %d",
558            ev->sensorHandle, ev->errorCode);
559       break;
560     }
561 
562     default:
563       LOGW("Unhandled event %d", eventType);
564       break;
565   }
566 }
567 
nanoappEnd()568 void nanoappEnd() {
569   LOGI("Stopped");
570 }
571 
572 #ifdef CHRE_NANOAPP_INTERNAL
573 }  // anonymous namespace
574 }  // namespace chre
575 
576 #include "chre/platform/static_nanoapp_init.h"
577 #include "chre/util/nanoapp/app_id.h"
578 #include "chre/util/system/napp_permissions.h"
579 
580 CHRE_STATIC_NANOAPP_INIT(SensorWorld, chre::kSensorWorldAppId, 0,
581                          chre::NanoappPermissions::CHRE_PERMS_NONE);
582 #endif  // CHRE_NANOAPP_INTERNAL
583