Méthodes et erreurs d'interface

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

Méthodes sans valeur de retour

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 en équivalents Java qui renvoient également un seul résultat. Par exemple:

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 à plusieurs résultats

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

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() utilise généralement une classe interne ou un lambda anonyme 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 en tant que troisième paramètre à oneProducesTwoThings().

Erreurs de transport et destinataires de décès

Étant donné que les implémentations de service peuvent s'exécuter dans un processus différent, dans certains cas, le client peut rester actif même lorsque le processus implémentant une interface s'arrête. Les appels sur un objet d'interface hébergé dans un processus mort échouent avec une erreur de transport (une exception d'exécution générée par la méthode appelée). Pour récupérer une telle erreur, demandez une nouvelle instance du service en appelant I<InterfaceName>.getService(). Toutefois, cette méthode ne fonctionne que si le processus qui a planté 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 de fin de vie pour recevoir une notification lorsqu'un service prend fin. Des erreurs de transport peuvent toujours se produire si un appel est effectué juste au moment où le serveur s'arrête. 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 ne contient qu'une seule méthode serviceDied(), qui est appelée lorsque le processus hébergeant l'interface s'arrête.

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

Le paramètre cookie contient le cookie transmis avec l'appel à linkToDeath(). Vous pouvez également annuler l'enregistrement d'un destinataire de notification de décès après l'avoir enregistré à l'aide des méthodes suivantes:

foo.unlinkToDeath(recipient);