Interface methods and errors

This section details interface methods and errors.

Void methods

Methods that don't 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);