Documentation de référence sur la gestion des licences

Classes et interfaces de bibliothèque LVL

Le tableau 1 liste tous les fichiers sources de la bibliothèque LVL (License Verification Library), disponibles via le SDK Android. Tous les fichiers font partie du package com.android.vending.licensing.

Tableau 1. Résumé des classes et des interfaces de bibliothèque LVL.

Catégorie Nom Description
Vérification de la licence et résultat LicenseChecker Classe (ou sous-classe) que vous instanciez pour lancer une vérification de licence.
LicenseCheckerCallback Interface que vous implémentez pour gérer le résultat de la vérification de la licence.
Règle Policy Interface que vous implémentez pour déterminer si vous autorisez l'accès à l'application, en fonction de la réponse de la licence.
ServerManagedPolicy Implémentation par défaut de Policy. Utilise les paramètres fournis par le serveur de gestion des licences pour gérer le stockage local des données de licence, la validité des licences et les relances.
StrictPolicy Implémentation alternative de Policy. Applique les licences uniquement en fonction d'une réponse de licence directe du serveur. Pas de mise en cache ni de nouvelle tentative de requête.
Obscurcissement des données
(facultatif)
Offuscateur Interface que vous implémentez si vous utilisez une règle (Policy) (telle que ServerManagedPolicy) qui met en cache les données de réponse de licence dans un stockage persistant. Applique un algorithme d'obscurcissement pour encoder et décoder les données en cours d'écriture ou de lecture.
AESObfuscator Implémentation par défaut d'un offuscateur qui utilise un algorithme de chiffrement/déchiffrement AES pour obscurcir/désobscurcir des données.
Limites liées aux appareils
(facultatif)
DeviceLimiter Interface que vous implémentez si vous souhaitez limiter l'utilisation d'une application à un appareil spécifique. Appelée par LicenseValidator. L'implémentation de DeviceLimiter est déconseillée pour la plupart des applications, car elle nécessite un serveur backend et peut entraîner une perte d'accès de l'utilisateur aux applications sous licence, sauf si elles sont conçues avec soin.
NullDeviceLimiter Implémentation par défaut de DeviceLimiter, qui est no-op (permet d'accéder à tous les appareils).
Cœur de la bibliothèque, aucune intégration nécessaire ResponseData Classe qui contient les champs d'une réponse de licence.
LicenseValidator Classe qui déchiffre et vérifie une réponse reçue du serveur de gestion des licences.
ValidationException Classe qui indique les erreurs qui se produisent lors de la validation de l'intégrité des données gérées par un offuscateur.
PreferenceObfuscator Classe utilitaire qui écrit/lit des données obscurcies dans le stockage SharedPreferences du système.
ILicensingService Interface IPC à sens unique via laquelle une demande de vérification de licence est transmise au client Google Play.
ILicenseResultListener Implémentation de rappel IPC à sens unique via laquelle l'application reçoit une réponse asynchrone du serveur de gestion des licences.

Réponse du serveur

Le tableau 2 liste tous les champs de réponse de licence renvoyés par le serveur de gestion des licences.

Tableau 2. Récapitulatif des champs de réponse de licence renvoyés par le serveur Google Play.

Champ Description
responseCode Code de réponse renvoyé par le serveur de gestion des licences. Les codes de réponse sont décrits dans les Codes de réponse du serveur.
signedData La concaténation d'une chaîne contenant les données renvoyées par le serveur de gestion des licences, comme suit : responseCode|nonce|packageName|versionCode|userId|timestamp:extras.
  • responseCode : le code de réponse renvoyé par le serveur de gestion des licences.
  • nonce : identifiant de nonce de la requête.
  • packageName : le nom du package de l'application dont la licence doit être vérifiée.
  • versionCode : le code de version de l'application dont la licence doit être vérifiée.
  • userId : un identifiant utilisateur unique par application, dans lequel le même utilisateur obtient un identifiant différent pour une application différente.
  • timestamp : le nombre de millisecondes s'écoulant entre l'epoch du 01/01/1970 à 00:00:00 UTC et la requête.
  • extras : des informations supplémentaires pour faciliter la gestion des licences de l'application. Les champs supplémentaires sont décrits dans la section Champs supplémentaires de la réponse du serveur.
signature Signature de signedData à l'aide d'une clé propre à l'application.

Codes de réponse du serveur

Le tableau 3 liste tous les codes de réponse de licence compatibles avec le serveur de gestion des licences. En général, une application doit gérer tous ces codes de réponse. Par défaut, la classe LicenseValidator du LVL assure la gestion nécessaire de ces codes de réponse.

Tableau 3. Récapitulatif des codes de réponse renvoyés par le serveur Google Play dans une réponse de licence.

Code de réponse Représentation par nombre entier Description Signed? Bonus Commentaires
LICENSED 0 L'utilisateur dispose de la licence pour l'application. L'utilisateur a acheté l'application ou est autorisé à télécharger et à installer la version alpha ou bêta de l'application. Oui VTGT, GR Autorise l'accès en fonction des contraintes de Policy.
LICENSED_OLD_KEY 2 L'utilisateur dispose de la licence pour l'application, mais une version mise à jour, signée avec une autre clé, est disponible. Oui VT, GT, GR, UT Autorise optionnellement l'accès en fonction des contraintes de Policy.

peut indiquer si la paire de clés utilisée par la version d'application installée n'est pas valide ou a été compromise. L'application peut autoriser l'accès si nécessaire ou informer l'utilisateur qu'une mise à niveau est disponible, et limiter l'utilisation jusqu'à la mise à niveau.

NOT_LICENSED 1 L'utilisateur ne dispose pas de la licence pour l'application. Non Ne pas autoriser l'accès
ERROR_CONTACTING_SERVER 257 Erreur locale : l'application Google Play n'a pas pu accéder au serveur de gestion des licences, peut-être en raison de problèmes de disponibilité du réseau. Non Relancez la vérification des licences conformément aux limites de relances de Policy.
ERROR_SERVER_FAILURE 4 Erreur serveur : le serveur n'a pas pu charger la paire de clés de l'application pour l'attribution des licences. Non Relancez la vérification des licences conformément aux limites de relances de Policy.
ERROR_INVALID_PACKAGE_NAME 258 Erreur locale : l'application a demandé une vérification de licence pour un package qui n'est pas installé sur l'appareil. Non Ne relancez pas la vérification des licences.

Généralement causée par une erreur de développement.

ERROR_NON_MATCHING_UID 259 Erreur locale : l'application a demandé une vérification des licences pour un package dont l'UID (package, paire de l'ID utilisateur) ne correspond pas à celui de l'application à l'origine de la demande. Non Ne relancez pas la vérification des licences.

Généralement causée par une erreur de développement.

ERROR_NOT_MARKET_MANAGED 3 Erreur serveur : l'application (nom du package) n'a pas été reconnue par Google Play. Non Ne relancez pas la vérification des licences.

Peut indiquer que l'application n'a pas été publiée via Google Play ou qu'il existe une erreur de développement dans l'implémentation de la licence.

Remarque : Comme indiqué dans Configurer l'environnement de test, le code de réponse peut être remplacé manuellement pour le développeur de l'application et tout utilisateur test enregistré via la Google Play Console.

Remarque : Auparavant, vous pouviez tester une application en important une version brouillon non publiée de celle-ci. Cette fonctionnalité n'est plus disponible. Vous devez à présent la publier sur le canal de distribution alpha ou bêta. Pour en savoir plus, consultez la page Les versions provisoires d'applications ne sont plus acceptées.

Réponses du serveur : extras

Pour aider votre application à gérer l'accès à l'application tout au long de la période de remboursement et à fournir d'autres informations, le serveur de gestion des licences inclut plusieurs informations dans les réponses de licence. Plus précisément, le service fournit des valeurs recommandées pour la période de validité de la licence de l'application, le délai de grâce pour les relances, le nombre maximal de relances autorisées et d'autres paramètres. Si votre application utilise des fichiers d'extension pour APK, la réponse inclut également les noms, les tailles et les URL des fichiers. Le serveur ajoute les paramètres en tant que paires clé/valeur dans le champ "Extras" de la réponse de licence.

Toute implémentation de Policy peut extraire les paramètres supplémentaires de la réponse de licence et les utiliser au besoin. L'implémentation de Policy par défaut de la bibliothèque LVL, ServerManagedPolicy, sert d'implémentation opérationnelle et montre comment obtenir, stocker et utiliser les paramètres.

Tableau 4. Résumé des paramètres de gestion des licences fournis par le serveur Google Play dans une réponse de licence.

ExtraDescription
VT Code temporel de la validité de la licence. Indique la date et l'heure à laquelle la réponse de licence actuelle (mise en cache) expire et doit être revérifiée sur le serveur de gestion des licences. Consultez la section ci-dessous sur la période de validité de la licence.
GT Horodatage du délai de grâce. Spécifie la fin de la période au cours de laquelle une règle peut autoriser l'accès à l'application, même si l'état de la réponse est RETRY (relancez).

La valeur est gérée par le serveur, mais elle est généralement supérieure ou égale à cinq jours. Consultez la section ci-dessous : Période de relance et nombre maximal de relances.

GR Nombre maximal de relances. Spécifie le nombre de RETRY de vérifications consécutives de la règle Policy doit autoriser avant de refuser à l'utilisateur l'accès à l'application.

La valeur est gérée par le serveur, mais elle est généralement supérieure ou égale à dix jours. Consultez la section ci-dessous : Période de relance et nombre maximal de relances.

UT Horodatage de mise à jour. Indique le jour et l'heure auquel la mise à jour la plus récente de cette application a été importée et publiée.

Le serveur renvoie cet extra seulement pour les réponses LICENSED_OLD_KEYS, afin de permettre à Policy de déterminer le temps écoulé depuis la publication d'une mise à jour avec de nouvelles clés de licence avant de refuser l'accès des utilisateurs à l'application.

FILE_URL1 ou FILE_URL2 URL d'un fichier d'extension (1 pour le fichier principal et 2 pour le fichier correctif). Utilisez cette option pour télécharger le fichier via HTTP.
FILE_NAME1 ou FILE_NAME2 Nom du fichier d'extension (1 pour le fichier principal et 2 pour le fichier correctif). Vous devez utiliser ce nom lorsque vous enregistrez le fichier sur l'appareil.
FILE_SIZE1 ou FILE_SIZE2 Taille du fichier en octets (1 pour le fichier principal, 2 pour le fichier correctif). À utiliser pour faciliter le téléchargement et pour vous assurer que l'espace de stockage partagé de l'appareil est suffisant avant le téléchargement.

Période de validité de la licence

Le serveur de gestion des licences Google Play définit une période de validité de la licence pour toutes les applications téléchargées. La période exprime l'intervalle de temps pendant lequel l'état de la licence d'une application doit être considéré comme immuable et pouvant être mis en cache par une Policy de licence dans l'application. Le serveur de gestion des licences inclut la période de validité dans sa réponse à toutes les vérifications de licence, en ajoutant un horodatage de fin de validité à la réponse en tant qu'extra sous la clé VT. Une Policy peut extraire la valeur de clé VT et l'utiliser pour autoriser l'accès à l'application de manière conditionnelle sans revérifier la licence, jusqu'à expiration de la période de validité.

La validité de la licence signale à une Policy de licence lorsque l'état de la licence doit être revérifié auprès du serveur de gestion des licences. Elle n'est pas destinée à insinuer qu'une application est effectivement sous licence. Autrement dit, lorsque la période de validité de la licence de l'application expire, cela ne signifie pas que l'application n'est plus sous licence, mais simplement que Policy doit revérifier l'état de la licence avec le serveur. Ensuite, tant que la période de validité de la licence n'a pas expiré, la Policy peut mettre en cache l'état initial de la licence localement et renvoyer l'état de la licence mis en cache au lieu d'envoyer une nouvelle vérification des licences au serveur.

Le serveur de gestion des licences gère la période de validité pour aider l'application à attribuer correctement les licences pendant la période de remboursement proposée par Google Play pour les applications payantes. Il définit la période de validité en fonction de l'achat ou non de l'application et, le cas échéant, de sa date. Plus précisément, le serveur définit une période de validité comme suit :

  • Pour une application payante, le serveur définit la période de validité initiale de la licence afin que la réponse de la licence reste valide tant que l'application est remboursable. Une Policy de licence dans l'application peut mettre en cache le résultat de la vérification initiale de la licence et n'a pas besoin de la vérifier à nouveau avant la fin de la période de validité.
  • Lorsqu'une application n'est plus remboursable, le serveur définit une période de validité plus longue, généralement un nombre de jours.
  • Pour une application sans frais, le serveur définit la période de validité sur une valeur très élevée (long.MAX_VALUE). Cela garantit que, si Policy a mis en cache l'horodatage de validité en local, il n'aura pas besoin de revérifier l'état de la licence de l'application à l'avenir.

L'implémentation de ServerManagedPolicy utilise l'horodatage extrait (mValidityTimestamp) comme condition principale pour déterminer si l'état de la licence doit être revérifié avant d'autoriser l'utilisateur à accéder à l'application.

Période de relance et nombre maximal de relances

Dans certains cas, les conditions du système ou du réseau peuvent empêcher la vérification des licences d'une application d'atteindre le serveur de gestion des licences, ou empêcher la réponse du serveur d'atteindre l'application cliente Google Play. Par exemple, l'utilisateur peut lancer une application lorsqu'aucune connexion au réseau mobile ni aucune connexion de données n'est disponible (en avion, par exemple), lorsque la connexion réseau est instable ou que le signal du réseau mobile est faible.

Lorsque des problèmes de réseau empêchent ou interrompent la vérification des licences, le client Google Play envoie une notification à l'application en renvoyant un code de réponse RETRY à la méthode processServerResponse() de Policy. En cas de problème système, par exemple lorsque l'application ne parvient pas à s'associer à l'implémentation de ILicensingService de Google Play, la bibliothèque LicenseChecker appelle la méthode processServerResponse() avec un code de réponse RETRY.

En général, le code de réponse RETRY indique à l'application qu'une erreur s'est produite et a empêché la vérification d'une licence.

Le serveur Google Play aide une application à gérer l'attribution de licences en cas d'erreur en définissant un nouveau "délai de grâce" et un nombre maximal de relances recommandé. Le serveur inclut ces valeurs dans toutes les réponses de vérification de licence, en les ajoutant en tant qu'extras dans les clés GT et GR.

La Policy de l'application peut extraire les extras GT et GR, et les utiliser pour autoriser l'accès à l'application de manière conditionnelle, comme suit :

  • Pour une vérification de licence qui génère une réponse RETRY, la Policy doit mettre en cache le code de réponse RETRY et augmenter le nombre de réponses RETRY.
  • Le champ Policy doit permettre à l'utilisateur d'accéder à l'application, à condition que le délai de grâce des relances soit toujours actif ou que le nombre maximal de relances n'ait pas été atteint.

La ServerManagedPolicy utilise les valeurs GT et GR fournies par le serveur, comme décrit ci-dessus. L'exemple ci-dessous montre le traitement conditionnel des réponses aux relances dans la méthode allow(). Le nombre de réponses RETRY est conservé dans la méthode processServerResponse(), et non affiché.

Kotlin

fun allowAccess(): Boolean {
    val ts = System.currentTimeMillis()
    return when(lastResponse) {
        LICENSED -> {
            // Check if the LICENSED response occurred within the validity timeout.
            ts <= validityTimestamp  // Cached LICENSED response is still valid.
        }
        RETRY -> {
            ts < lastResponseTime + MILLIS_PER_MINUTE &&
                    // Only allow access if we are within the retry period
                    // or we haven't used up our max retries.
                    (ts <= retryUntil || retryCount <= maxRetries)
        }
        else -> false
    }
}

Java

public boolean allowAccess() {
    long ts = System.currentTimeMillis();
    if (lastResponse == LicenseResponse.LICENSED) {
        // Check if the LICENSED response occurred within the validity timeout.
        if (ts <= validityTimestamp) {
            // Cached LICENSED response is still valid.
            return true;
        }
    } else if (lastResponse == LicenseResponse.RETRY &&
                ts < lastResponseTime + MILLIS_PER_MINUTE) {
        // Only allow access if we are within the retry period
        // or we haven't used up our max retries.
        return (ts <= retryUntil || retryCount <= maxRetries);
    }
    return false;
}