69 lines
3.6 KiB
Markdown
69 lines
3.6 KiB
Markdown
# Interacting with Nanoapps from Client Code
|
||
|
||
[TOC]
|
||
|
||
Code that interacts with a nanoapp, for example within an Android app, is known
|
||
as the *client* of the nanoapp. There are two ways to interact with nanoapps
|
||
from the host (application processor): (1) Java (above the Context Hub HAL, from
|
||
the Android framework or an APK), and (2) native vendor code (beneath the
|
||
Context Hub HAL). Most clients, especially those with a UI component, should use
|
||
the Java method, unless a vendor-partition native implementation is required
|
||
(e.g. if interacting with a nanoapp is used to implement a different HAL, or if
|
||
communication with other beneath-HAL modules is required).
|
||
|
||
Interaction between nanoapps and clients occur through a flexible message
|
||
passing interface. Refer to the Nanoapp Developer Guide for recommendations on
|
||
how to design a protocol for use with a nanoapp.
|
||
|
||
## Java APIs
|
||
|
||
CHRE is exposed to Android apps holding the appropriate permissions through the
|
||
[ContextHubManager](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/hardware/location/ContextHubManager.java)
|
||
and the associated
|
||
[ContextHubClient](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/hardware/location/ContextHubClient.java)
|
||
system APIs.
|
||
|
||
To use the above APIs, your application must have access to the
|
||
`ACCESS_CONTEXT_HUB` permission, which is restricted to `signature|privileged`.
|
||
This permission must be declared in the app’s [Android
|
||
Manifest](https://developer.android.com/guide/topics/manifest/uses-permission-element),
|
||
and is only granted to APKs that are signed with the same key as the platform
|
||
(“signature” scope) or are preinstalled in the privileged apps folder *and* are
|
||
present on the [privileged permission
|
||
allowlist](https://source.android.com/devices/tech/config/perms-allowlist).
|
||
|
||
The recommended flow for Java nanoapp client code is as follows:
|
||
|
||
1. Retrieve the ContextHubManager object via
|
||
`Context.getSystemService(ContextHubManager.class)` - this will produce a
|
||
valid handle if the device supports `FEATURE_CONTEXT_HUB` as indicated by
|
||
`PackageManager.hasSystemFeature()`
|
||
2. Retrieve a reference to a Context Hub via
|
||
`ContextHubManager.getContextHubs()`
|
||
3. Confirm that the nanoapp is loaded and retrieve its version number by calling
|
||
`ContextHubManager.queryNanoApps()`
|
||
4. If the nanoapp was found, create a `ContextHubClient` object through
|
||
`ContextHubManager.createClient()`. This can be used to communicate with your
|
||
nanoapp, and receive notifications of system events like reset. Note that the
|
||
`createClient()` API supports two modes of operation, which define how events
|
||
and data are passed to the client: direct callback with
|
||
`ContextHubClientCallback` (requires a persistent process), or
|
||
`PendingIntent` with `ContextHubIntentEvent` (can start an app’s process when
|
||
an event occurs). To send messages to the nanoapp, use
|
||
`ContextHubClient.sendMessageToNanoApp()`.
|
||
|
||
## Vendor Native
|
||
|
||
Depending on the details of the platform implementation, you may also be able to
|
||
interact with CHRE directly, beneath the Context Hub HAL, by using socket IPC as
|
||
exposed by the CHRE daemon reference implementation. This approach has some
|
||
advantages, like being able to interact with system nanoapps that are not
|
||
exposed at the Java level, and it can be used with other low-level beneath-HAL
|
||
code. However, it is not suitable for use from native code within an Android
|
||
app.
|
||
|
||
See `host/common/test/chre_test_client.cc` for an example of how to use this
|
||
interface. Note that SELinux configuration is generally required to allowlist
|
||
access to the CHRE socket.
|
||
|