Méthodes d'interface et amp; les erreurs

Cette section détaille les méthodes et les erreurs de l'interface.

Méthodes annulées

Les méthodes qui ne renvoient pas de résultats sont traduites en méthodes Java qui renvoient void . Par exemple, la déclaration HIDL :

doThisWith(float param);

… devient:

void doThisWith(float param);

Méthodes à résultat unique

Les méthodes qui renvoient un seul résultat sont traduites dans leurs équivalents Java renvoyant également un seul résultat. Par exemple, ce qui suit :

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

… devient:

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

Méthodes à résultats multiples

Pour chaque méthode qui renvoie plusieurs résultats, une classe de rappel est générée et fournit tous les résultats dans sa méthode onValues . Ce rappel agit comme un paramètre supplémentaire à la méthode. Par exemple, ce qui suit :

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

… devient:

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

Un appelant de oneProducesTwoThings() utiliserait généralement une classe interne anonyme ou lambda pour implémenter le rappel localement :

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)));

Vous pouvez également définir une classe à utiliser comme rappel…

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

… et transmettez une instance de MyCallback comme troisième paramètre à oneProducesTwoThings() .

Erreurs de transport et destinataires décédés

Étant donné que les implémentations de services peuvent s'exécuter dans un processus différent, dans certains cas, le client peut rester en vie même lorsque le processus implémentant une interface meurt. Les appels sur un objet d'interface hébergé dans un processus mort échouent avec une erreur de transport (une exception d'exécution levée par la méthode appelée). La récupération après un tel échec est possible en demandant une nouvelle instance du service en appelant I<InterfaceName>.getService() . Cependant, cette méthode ne fonctionne que si le processus qui s'est écrasé a redémarré et réenregistré ses services auprès du servicemanager (ce qui est généralement vrai pour les implémentations HAL).

Les clients d'une interface peuvent également enregistrer un destinataire décédé pour recevoir une notification en cas de décès d'un service. Des erreurs de transport peuvent toujours se produire si un appel est effectué au moment même où le serveur tombe en panne. Pour s'inscrire à de telles notifications sur une interface IFoo récupérée, un client peut procéder comme suit :

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

Le paramètre recipient doit être une implémentation de l’interface HwBinder.DeathRecipient fournie par HIDL. L'interface contient une seule méthode serviceDied() qui est appelée lorsque le processus hébergeant l'interface meurt.

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

Le paramètre cookie contient le cookie qui a été transmis avec l'appel à linkToDeath() . Il est également possible de désinscrire un destinataire de décès après l'avoir enregistré en utilisant :

foo.unlinkToDeath(recipient);