Erros e métodos de interface

Esta seção detalha os métodos e erros da interface.

Métodos nulos

Os métodos que não retornam resultados são traduzidos em métodos Java que retornam void. Por exemplo, a declaração HIDL:

doThisWith(float param);

… se torna:

void doThisWith(float param);

Métodos de resultado único

Os métodos que retornam um único resultado são traduzidos nos equivalentes do Java, que também retornam um único resultado. Por exemplo:

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

… se torna:

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

Métodos de vários resultados

Para cada método que retorna mais de um resultado, uma classe de callback é gerada e fornece todos os resultados no método onValues. Esse callback atua como um parâmetro adicional para o método. Por exemplo, o seguinte:

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

… se torna:

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

Um autor da chamada de oneProducesTwoThings() normalmente usa uma classe interna ou lambda anônima para implementar o callback localmente:

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

ou:

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

Também é possível definir uma classe para usar como um callback…

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

… e transmita uma instância de MyCallback como o terceiro parâmetro para oneProducesTwoThings().

Erros de transporte e destinatários falecidos

Como as implementações de serviço podem ser executadas em um processo diferente, em alguns casos, o cliente pode permanecer ativo mesmo quando o processo que implementa uma interface é encerrado. As chamadas em um objeto de interface hospedado em um processo morto falham com um erro de transporte (uma exceção de execução gerada pelo método chamado). É possível recuperar essa falha solicitando uma nova instância do serviço chamando I<InterfaceName>.getService(). No entanto, esse método só funciona se o processo que travou for reiniciado e registrar novamente os serviços com o gerenciador de serviços, o que geralmente é verdadeiro para implementações do HAL.

Os clientes de uma interface também podem registrar um destinatário de morte para receber uma notificação quando um serviço for encerrado. Erros de transporte ainda podem ocorrer se uma chamada for feita no momento em que o servidor for encerrado. Para se registrar para essas notificações em uma interface IFoo recuperada, um cliente pode fazer o seguinte:

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

O parâmetro recipient precisa ser uma implementação da interface HwBinder.DeathRecipient fornecida pelo HIDL. A interface contém um único método serviceDied() que é chamado quando o processo que hospeda a interface é encerrado.

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

O parâmetro cookie contém o cookie transmitido com a chamada para linkToDeath(). Também é possível cancelar o registro de um beneficiário após o registro usando:

foo.unlinkToDeath(recipient);