# 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.