Interface Methods & Errors

This section details interface methods and errors.

Void methods

Methods that do not return results are translated into Java methods that return void. For example, the HIDL declaration:

doThisWith(float param);

… becomes:

void doThisWith(float param);

Single-result methods

Methods that return a single result are translated into their Java equivalents also returning a single result. For example, the following:

doQuiteABit(int32_t a, int64_t b,
            float c, double d) generates (double something);

… becomes:

double doQuiteABit(int a, long b, float c, double d);

Multiple-result methods

For each method that returns more than one result, a callback class is generated that supplies all the results in its onValues method. That callback acts as an additional parameter to the method. For example, the following:

oneProducesTwoThings(SomeEnum x) generates (double a, double b);

… becomes:

public interface oneProducesTwoThingsCallback {
    public void onValues(double a, double b);
}
void oneProducesTwoThings(byte x, oneProducesTwoThingsCallback cb);

A caller of oneProducesTwoThings() would typically use an anonymous inner class or lambda to implement the callback locally:

someInstanceOfFoo.oneProducesTwoThings(
         5 /* x */,
         new IFoo.oneProducesTwoThingsCallback() {
          @Override
          void onValues(double a, double b) {
             // do something interesting with a and b.
             ...
          }});

or:

someInstanceOfFoo.oneProducesTwoThings(5 /* x */,
    (a, b) -> a > 3.0 ? f(a, b) : g(a, b)));

You can also define a class to use as a callback …

class MyCallback implements oneProducesTwoThingsCallback {
  public void onValues(double a, double b) {
    // do something interesting with a and b.
  }
}

… and pass an instance of MyCallback as the third parameter to oneProducesTwoThings().

Transport errors and death recipients

Because service implementations can run in a different process, in some cases the client can stay alive even when the process implementing an interface dies. Calls on an interface object hosted in a dead process fail with a transport error (a runtime exception thrown by the called method). Recovery from such a failure is possible by requesting a new instance of the service by calling I<InterfaceName>.getService(). However, this method works only if the process that crashed has restarted and re-registered its services with the servicemanager (which is generally true for HAL implementations).

Clients of an interface can also register a death recipient to get a notification when a service dies. Transport errors can still occur if a call is made just as the server dies. To register for such notifications on a retrieved IFoo interface, a client can do the following:

foo.linkToDeath(recipient, 1481 /* cookie */);

The recipient parameter must be an implementation of the interface HwBinder.DeathRecipient provided by HIDL. The interface contains a single method serviceDied() that is called when the process hosting the interface dies.

final class DeathRecipient implements HwBinder.DeathRecipient {
    @Override
    public void serviceDied(long cookie) {
        // Deal with service going away
    }
}

The cookie parameter contains the cookie that was passed with the call to linkToDeath(). It's also possible to unregister a death recipient after registering it using:

foo.unlinkToDeath(recipient);