Ajouter Play Integrity à votre application Android

1. Introduction

Dernière mise à jour : 4 janvier 2023

Qu'est-ce que Play Integrity ?

L'API Play Integrity protège vos applis et vos jeux contre les interactions potentiellement dangereuses et frauduleuses. Vous pouvez utiliser l'API Play Integrity pour obtenir des évaluations de l'intégrité de votre appli et de votre appareil, qui vous aideront à prendre les mesures appropriées pour réduire les attaques et les abus comme la fraude, la tricherie et les accès non autorisés.

Solutions précédentes

L'API Play Integrity remplace deux solutions précédentes : la bibliothèque de licences d'applis et l'API SafetyNet Attestation. L'utilisation de Play Integrity est recommandée pour les nouvelles applis. Pour les applis existantes qui utilisent les solutions antérieures, vous devez envisager de passer à Play Integrity.

Choisir un chemin d'accès

Play Integrity inclut des options de bibliothèque pour différents types d'applis :

  • Jeux ou autres applis écrites en C/C++
  • Applications écrites en Kotlin ou en Java
  • Jeux développés avec le moteur Unity

Cet atelier de programmation comprend des chemins d'accès pour les trois options. Vous pouvez choisir les chemins adaptés à vos besoins de développement. L'atelier de programmation implique la création et le déploiement d'un serveur backend. Ce serveur est partagé entre les trois types d'applis.

Objectifs de l'atelier

Dans cet atelier de programmation, vous allez intégrer Play Integrity dans une application exemple, et utiliser l'API pour vérifier l'intégrité d'un appareil et de l'application. Vous allez déployer une petite appli de serveur backend permettant de vérifier l'intégrité.

Points abordés

  • Intégrer la bibliothèque Play Integrity à une appli
  • Utiliser l'API Play Integrity pour effectuer une vérification de l'intégrité
  • Traiter de manière sécurisée une évaluation d'intégrité à l'aide d'un serveur
  • Interpréter les résultats de l'évaluation de l'intégrité

Cet atelier de programmation est consacré à Play Integrity. Les concepts et les blocs de code non pertinents ne sont pas expliqués en détail et vous sont fournis afin que vous puissiez simplement les copier-coller.

Ce dont vous aurez besoin

  • Un compte Google avec un compte de développeur Android actif, l'accès à la Play Console et l'accès à la console Google Cloud.
  • Pour les chemins d'accès C++ ou Kotlin, Android Studio 2021.1.1 ou version ultérieure.
  • Pour le chemin d'accès Unity, Unity 2020 LTS ou version ultérieure.
  • Un appareil Android connecté à votre ordinateur, sur lequel les options pour les développeurs et le débogage USB sont activés.

Cet atelier de programmation comprend des liens vers des ressources sur la signature et l'importation de builds dans la Play Console, mais suppose une certaine connaissance de ce processus.

2. Obtenir le code

Les projets de l'atelier de programmation sont disponibles dans un dépôt Git. Le répertoire parent du dépôt contient quatre répertoires :

  • Le répertoire server contient le code de l'exemple de serveur que vous allez déployer.
  • Le répertoire cpp contient un projet Android Studio permettant d'ajouter Play Integrity à une appli ou à un jeu C++.
  • Le répertoire kotlin contient un projet Android Studio permettant d'ajouter Play Integrity à une appli Android standard.
  • Le répertoire unity contient un projet créé avec la version LTS 2020 du moteur Unity pour ajouter Play Integrity à un projet Unity.

Dans chacun des exemples de répertoires client, il existe deux sous-répertoires :

  • Le répertoire start, qui contient la version du projet que nous allons modifier pour cet atelier de programmation.
  • Le répertoire final, dont la version du projet correspond à celle du projet une fois l'atelier de programmation terminé.

Cloner le dépôt

À partir de la ligne de commande, accédez au répertoire dans lequel vous souhaitez placer le répertoire racine add-play-integrity-codelab, puis clonez le projet depuis GitHub à l'aide de la syntaxe suivante :

git clone https://github.com/android/add-play-integrity-codelab.git

Ajouter des dépendances (C++ uniquement)

Si vous avez l'intention d'utiliser le chemin d'accès C++, vous devez initialiser les sous-modules du dépôt pour configurer la bibliothèque Dear ImGui, qui sera utilisée pour l'interface utilisateur. Pour ce faire, utilisez la ligne de commande suivante :

  1. Remplacez le répertoire de travail par : add-play-integrity-codelab/cpp/start/third-party
  2. git submodule update --init

3. Comprendre les fonctions du client et du serveur

Un élément clé du modèle de sécurité Play Integrity consiste à déplacer les opérations de validation de l'appareil vers un serveur sécurisé que vous contrôlez. L'exécution de ces opérations sur le serveur permet de se protéger de scénarios tels qu'un appareil compromis qui tente de déployer une attaque par relecture ou qui falsifie le contenu d'un message.

L'exemple de serveur proposé dans cet atelier de programmation est fourni à titre d'illustration. Par souci de simplicité, il est dépourvu de nombreuses fonctionnalités qui pourraient être utiles dans un environnement de production. Sa liste de valeurs générées n'est stockée que dans la mémoire et n'est pas sauvegardée dans un espace de stockage persistant. Les points de terminaison du serveur ne sont pas configurés pour exiger une authentification.

Le point de terminaison performCommand

Le serveur fournit un point de terminaison /performCommand accessible via une requête HTTP POST. Le corps de la requête doit être une charge utile JSON avec les paires clé/valeur suivantes :

{
   "commandString": "command-here",
   "tokenString": "token-here"
}

Le point de terminaison /performCommand renvoie une charge utile JSON avec les paires clé/valeur suivantes :

{
   "commandSuccess": true/false,
   "diagnosticMessage": "summary text",
   "expressToken": "token-here"
}

Le contenu réel du paramètre commandString n'a pas d'importance. Le serveur valide l'intégrité de commandString en utilisant Play Integrity, mais n'utilise pas la valeur de la commande. Toutes les versions du client utilisent la valeur "TRANSFER FROM alice TO bob CURRENCY gems QUANTITY 1000".

La valeur du paramètre tokenString doit être, au choix :

  • Un jeton généré par l'API Play Integrity
  • Un jeton express renvoyé par un précédent appel réussi à /performCommand

Le serveur déchiffre et valide le jeton fourni par l'API Play Integrity. Le résultat du déchiffrement est une charge utile JSON de signaux d'intégrité. Le serveur peut accepter ou refuser la commande en fonction de la valeur des signaux. Si le jeton est déchiffré, une description récapitulative des signaux est renvoyée dans diagnosticMessage. Vous ne devriez normalement pas renvoyer ces informations au client dans une appli de production, mais les clients de l'atelier de programmation les utilisent pour afficher le résultat de votre opération sans avoir à consulter les journaux du serveur. Si une condition d'erreur se produit lors du traitement du jeton, l'erreur est renvoyée dans diagnosticMessage.

Génération de nonce

Pour effectuer une requête Play Integrity, vous devez générer un nonce et l'associer à la requête. Le nonce permet de garantir qu'une requête d'intégrité est unique et n'est traitée qu'une seule fois. Le nonce permet également de vérifier que le contenu du message associé à la requête d'intégrité n'a pas été falsifié. Pour en savoir plus sur les nonces Play Integrity, consultez la documentation.

Dans cet atelier de programmation, le nonce est généré en combinant deux valeurs :

  • Un nombre aléatoire de 128 bits généré par un générateur de nombres aléatoires cryptographiquement sécurisés
  • Un hachage SHA-256 de la valeur commandString

L'API Play Integrity s'attend à ce que le nonce soit une chaîne au format Base64 sans remplissage encodée en URL. Pour créer la chaîne nonce, cet atelier de programmation convertit les tableaux d'octets du nombre aléatoire et des valeurs de hachage en chaînes hexadécimales, puis les concatène. La chaîne obtenue est une chaîne Base64 valide, mais elle n'est pas encodée ni décodée en tant que telle.

Les clients de l'atelier de programmation récupèrent le nombre aléatoire en appelant un point de terminaison /getRandom sur le serveur à l'aide d'une requête HTTP GET. Il s'agit de la méthode de génération aléatoire la plus sécurisée, car le serveur peut vérifier qu'il s'agit de la source du nombre aléatoire utilisé dans la requête de commande. Toutefois, cela implique un aller-retour supplémentaire vers le serveur. Les clients peuvent éliminer cet aller-retour en générant le nombre aléatoire eux-mêmes, ce qui constitue un compromis en termes de sécurité.

Jeton express

Comme l'appel à l'API Play Integrity est coûteux, le serveur fournit également un jeton express, une autre méthode d'authentification offrant un niveau de sécurité inférieur pour un coût moindre. Un jeton express est renvoyé dans le champ expressToken par un appel réussi à /serverCommand avec une vérification d'intégrité concluante. L'appel de l'API Play Integrity est coûteux en termes de calcul et vise à protéger les opérations importantes. En renvoyant le jeton express, le serveur fournit une authentification moins sécurisée pour effectuer des opérations moins importantes ou qui se produisent trop souvent pour justifier une validation complète avec l'API Play Integrity. Vous pouvez utiliser un jeton express au lieu d'un jeton Play Integrity lorsque vous appelez /serverCommand. Chaque jeton express est à usage unique. Les appels réussis à /serverCommand à l'aide d'un jeton express valide renvoient un nouveau jeton express.

Dans l'implémentation de l'atelier de programmation, comme le jeton express est généré de manière unique sur le serveur, les commandes sont encore protégées contre les attaques par relecture. Toutefois, les jetons express sont moins sécurisés, car ils omettent la protection contre le hachage et ne peuvent pas détecter les modifications apportées à l'appareil après l'appel initial à l'API Play Integrity.

Architecture du serveur de l'atelier de programmation

Pour cet atelier de programmation, vous pouvez instancier un serveur en utilisant l'exemple de programme de serveur inclus écrit en Kotlin à l'aide du framework Ktor. Le projet inclut des fichiers de configuration permettant de le déployer sur Google Cloud App Engine. Les instructions de cet atelier de programmation portent sur la création et le déploiement sur App Engine. Si vous utilisez un autre fournisseur cloud, Ktor propose des instructions de déploiement pour plusieurs services cloud. Vous pouvez modifier le projet en conséquence et le déployer sur le service de votre choix. Vous pouvez également procéder au déploiement sur votre propre instance de serveur local.

Il n'est pas nécessaire d'utiliser l'exemple de code pour votre serveur. Si vous avez un framework d'appli Web que vous préférez, vous pouvez implémenter les points de terminaison /getRandom et /performCommand dans votre propre framework à l'aide de l'exemple de serveur de l'atelier de programmation.

Conception client

Les trois versions du client, C++, Kotlin et Unity, présentent une interface utilisateur similaire.

Le bouton Request random (Demander un nombre aléatoire) appelle le point de terminaison /getRandom sur le serveur. Le résultat s'affiche dans un champ de texte. Cela permet de vérifier la connexion et la fonction du serveur avant d'ajouter l'intégration de Play Integrity.

Le bouton Call server with Integrity check (Appeler le serveur avec vérification de l'intégrité) n'a aucun effet au début de l'atelier de programmation. Suivez les étapes ci-dessous pour ajouter du code aux opérations suivantes :

  • Appeler /getRandom pour obtenir un nombre aléatoire
  • Générer un nonce
  • Créer une requête Play Integrity à l'aide du nonce
  • Appeler /performCommand à l'aide du jeton généré par la requête Play Integrity
  • Afficher les résultats de /performCommand

Les résultats de la commande sont affichés dans un champ de texte. Pour que la commande aboutisse, il s'agit d'un récapitulatif des informations de verdict de l'appareil renvoyées par la vérification Play Integrity.

Le bouton Call server with express token (Appeler le serveur avec un jeton express) s'affiche après une opération Call server with integrity check (Appeler le serveur avec vérification de l'intégrité) réussie. Il appelle /performCommand à l'aide du jeton express de la classe /performCommand précédente. Un champ de texte permet d'afficher le succès ou l'échec de la commande. La valeur d'un jeton express renvoyé est affichée dans le champ de texte utilisé pour les nombres aléatoires.

Les fonctions de l'API Play Integrity qui signalent des erreurs le font en renvoyant un code d'erreur. Pour en savoir plus sur ces codes d'erreur, consultez la documentation sur Play Integrity. Certaines erreurs peuvent être dues à des conditions environnementales, telles qu'une connexion Internet instable ou un appareil surchargé. Pour de telles erreurs, envisagez d'inclure une option de nouvelle tentative avec un intervalle exponentiel entre les tentatives. Dans cet atelier de programmation, les erreurs Play Integrity sont affichées dans Logcat.

4. Configurer Google Cloud App Engine

Pour utiliser Google Cloud, procédez comme suit :

  1. Inscrivez-vous sur Google Cloud Platform. Utilisez le même compte Google que celui enregistré dans la Play Console.
  2. Créez un compte de facturation.
  3. Installez et initialisez le SDK Google Cloud.

Utilisez la Google Cloud CLI nouvellement installée pour exécuter les commandes suivantes :

  1. Installez l'extension App Engine pour Java : gcloud components install app-engine-java.
  2. Créez un projet Cloud en remplaçant $yourname dans la commande suivante par un identifiant unique : gcloud projects create $yourprojectname --set-as-default
  3. Créez une appli App Engine dans le projet Cloud : gcloud app create.

5. Déployer le serveur

Définir le nom du package de l'application

Au cours de cette étape, vous allez ajouter le nom du package de l'appli au code du serveur. Dans un éditeur de texte, ouvrez le fichier source ValidateCommand.kt. Il se trouve dans le répertoire suivant :

add-play-integrity-codelab/server/src/main/kotlin/com/google/play/integrity/codelab/server/util

Recherchez la ligne suivante, remplacez le texte de l'espace réservé par un identifiant de package unique, puis enregistrez le fichier :

const val APPLICATION_PACKAGE_IDENTIFIER = "com.your.app.package"

Vous définirez ensuite cet identifiant dans votre projet client avant d'importer l'appli dans la Play Console.

Créer le serveur et le déployer sur App Engine

Utilisez la Google Cloud CLI pour exécuter la commande suivante à partir du répertoire add-play-integrity/server afin de créer et de déployer le serveur :

Sous Linux ou macOS :

./gradlew appengineDeploy

Sous Microsoft Windows :

gradlew.bat appengineDeploy

Notez l'emplacement du service déployé dans la sortie d'un déploiement réussi. Vous aurez besoin de cette URL pour configurer le client afin qu'il communique avec le serveur.

Vérifier le déploiement

Vous pouvez utiliser la Google Cloud CLI pour exécuter la commande suivante afin de vérifier que le serveur fonctionne correctement :

gcloud app browse

Cette commande ouvre un navigateur Web et l'URL racine. L'exemple de serveur doit afficher le message Hello World! lorsqu'il est accédé depuis l'URL racine.

6. Configurer l'appli dans la Play Console

Configurer l'intégrité des applis dans la Play Console

Si vous disposez déjà d'une entrée d'appli dans la Play Console, vous pouvez l'utiliser pour cet atelier de programmation. Vous pouvez également créer une appli dans la Play Console. Après avoir sélectionné ou créé l'appli dans la Play Console, vous devez configurer l'intégrité de l'appli. Dans le menu de gauche de la Play Console, sélectionnez App integrity (Intégrité de l'appli) dans la section Release (Publier).

Cliquez sur le bouton Link Cloud project (Associer un projet Cloud). Sélectionnez le projet Google Cloud que vous avez utilisé avec le serveur, puis cliquez sur le bouton Link project (Associer le projet).

Accès à Google Cloud pour votre serveur

Votre serveur backend doit déchiffrer le jeton d'intégrité généré sur le client par l'API Play Integrity. Play Integrity propose deux options de gestion des clés : les clés générées et gérées par Google, ou les clés fournies par le développeur. Cet atelier de programmation utilise le comportement par défaut recommandé des clés gérées par Google.

Avec les clés gérées par Google, votre serveur backend transmet le jeton d'intégrité chiffré aux serveurs Google Play pour le déchiffrement. Le serveur de l'atelier de programmation utilise la bibliothèque cliente des API Google pour communiquer avec les serveurs Google Play.

Maintenant que le serveur est opérationnel et que vous avez configuré l'appli dans la Play Console, vous pouvez commencer à personnaliser le ou les clients correspondant aux plates-formes de votre choix. Toutes les étapes pour une plate-forme donnée sont regroupées. Vous pouvez donc ignorer les instructions correspondant aux plates-formes que vous n'utilisez pas.

7. Créer et exécuter le client (C++)

Exécutez Android Studio. Dans la fenêtre Welcome to Android Studio (Bienvenue dans Android Studio), cliquez sur le bouton Open (Ouvrir) et ouvrez le projet Android Studio situé dans add-play-integrity-codelab/cpp/start.

Mettre à jour l'ID d'application

Avant d'importer un build sur Google Play, vous devez remplacer l'ID d'application par défaut par un ID unique. Procédez comme suit :

  1. Dans le volet Project (Projet) d'Android Studio, recherchez le fichier build.gradle sous start/app et ouvrez-le.
  2. Recherchez l'instruction applicationId.
  3. Remplacez com.google.play.integrity.codelab.cpp par le nom du package que vous avez choisi lors du déploiement du serveur, puis enregistrez le fichier.
  4. En haut du fichier, une bannière s'affiche pour vous informer que les fichiers Gradle ont été modifiés. Cliquez sur Sync Now (Synchroniser) pour actualiser et resynchroniser le fichier.
  5. Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier AndroidManifest.xml sous start/app/src/main.
  6. Recherchez l'instruction package="com.example.google.codelab.playintegritycpp".
  7. Remplacez com.example.google.codelab.playintegritycpp par le nom unique du package, puis enregistrez le fichier.
  8. Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier PlayIntegrityCodelabActivity sous start/app/src/main/java/com.example.google.codelab.playintegritycpp.
  9. Recherchez l'instruction package com.example.google.codelab.playintegritycpp.
  10. Remplacez com.example.google.codelab.playintegritycpp par le nom de votre package unique.
  11. Effectuez un clic droit sur le nom du package, puis sélectionnez Show Context Actions (Afficher les actions contextuelles).
  12. Sélectionnez Move to (Déplacer vers) (le nouveau nom de package).
  13. Le cas échéant, cliquez sur le bouton Synch Now (Synchroniser) en haut du fichier.

Mettre à jour les URL du serveur

Le projet doit être mis à jour pour pointer vers les emplacements de l'URL où vous avez déployé le serveur.

  1. Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier server_urls.hpp sous start/app/src/main/cpp.
  2. Ajoutez l'URL racine qui s'affiche lorsque vous avez déployé le serveur dans les définitions GET_RANDOM_URL et PERFORM_COMMAND_URL, puis enregistrez le fichier.

Vous devez obtenir le résultat suivant :

constexpr char GET_RANDOM_URL[] = "https://your-play-integrity-server.uc.r.appspot.com/getRandom";
constexpr char PERFORM_COMMAND_URL[] = "https://your-play-integrity-server.uc.r.appspot.com/performCommand";

L'URL spécifique varie en fonction du nom de votre projet et de la région Google Cloud que vous avez utilisée pour déployer votre serveur.

Compiler et exécuter

Connectez un appareil Android configuré pour le développement. Dans Android Studio, créez le projet et exécutez-le sur l'appareil connecté. L'appli devrait se présenter comme suit :

429ccc112f78d454.png

Appuyez sur le bouton Request random (Demander un nombre aléatoire) pour exécuter du code qui envoie une requête HTTP à votre serveur afin de demander un nombre aléatoire. Après un bref délai, vous devriez voir le nombre aléatoire s'afficher à l'écran :

62ace42ba1fa80.png

Si un message d'erreur s'affiche, la sortie du volet Logcat peut contenir plus de détails.

Après avoir vérifié que vous communiquez avec le serveur en récupérant une valeur aléatoire, vous pouvez commencer à intégrer l'API Play Integrity.

8. Ajouter Play Integrity au projet (C++)

Télécharger le SDK

Vous devez télécharger et extraire le SDK Play Core. Procédez comme suit :

  1. Téléchargez le SDK Play Core placé dans un fichier .zip à partir de la page SDK Play Core natif.
  2. Extrayez le fichier ZIP.
  3. Assurez-vous que le répertoire nouvellement extrait est nommé play-core-native-sdk, puis copiez-le ou déplacez-le dans le répertoire add-play-integrity-codelab/cpp/start.

Mettre à jour le fichier build.gradle

Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier build.gradle au niveau du module dans le répertoire start/app.

Ajoutez la ligne suivante sous la ligne apply plugin: 'com.android.application' :

def playcoreDir = file("../play-core-native-sdk")

Recherchez le bloc externalNativeBuild dans le bloc defaultConfig et modifiez l'instruction arguments dans le bloc cmake pour qu'elle corresponde à ce qui suit :

                arguments "-DANDROID_STL=c++_shared",
                          "-DPLAYCORE_LOCATION=$playcoreDir"

Ajoutez le code suivant à la fin du bloc android :

    buildTypes {
        release {
            proguardFiles getDefaultProguardFile("proguard-android.txt"),
                          "proguard-rules.pro",
                          "$playcoreDir/proguard/common.pgcfg",
                          "$playcoreDir/proguard/integrity.pgcfg"
        }
    }

Ajoutez cette ligne à la fin du bloc dependencies :

    implementation files("$playcoreDir/playcore.aar")

Enregistrez les modifications. En haut du fichier, une bannière s'affiche pour vous informer que les fichiers Gradle ont été modifiés. Cliquez sur Sync Now (Synchroniser) pour actualiser et resynchroniser le fichier.

Mettre à jour le fichier CMakeList.txt

Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier CMakeLists.txt dans le répertoire start/app/src/main/cpp.

Ajoutez les lignes suivantes sous les commandes find_package :

include("${PLAYCORE_LOCATION}/playcore.cmake")
add_playcore_static_library()

Recherchez la ligne target_include_directories(game PRIVATE et ajoutez-y la ligne suivante :

        ${PLAYCORE_LOCATION}/include

Recherchez la ligne target_link_libraries(game et ajoutez-y la ligne suivante :

        playcore

Enregistrez le fichier. En haut du fichier, une bannière s'affiche pour vous informer que les fichiers de compilation externes ont été modifiés. Cliquez sur Sync Now (Synchroniser) pour actualiser et resynchroniser le fichier.

Dans le menu Build (Compilation), sélectionnez Make project (Créer un projet) et vérifiez que le projet a bien été compilé.

9. Envoyer une requête d'intégrité (C++)

Votre appli obtient des informations sur l'intégrité à l'aide de l'API Play Integrity pour demander un jeton que vous envoyez à votre serveur pour déchiffrement et vérification. Vous allez maintenant ajouter du code au projet pour initialiser l'API Play Integrity et l'utiliser pour envoyer une requête d'intégrité.

Ajouter un bouton de commande

Dans une appli ou un jeu existant, vous pouvez effectuer une vérification de l'intégrité avant des activités spécifiques, comme un achat en magasin ou une session de jeu multijoueur. Dans cet atelier de programmation, nous ajouterons un bouton à notre interface utilisateur pour déclencher manuellement une vérification de l'intégrité et appeler le serveur, en transmettant le jeton Play Integrity généré.

Le projet d'atelier de programmation contient une classe ClientManager, définie dans les fichiers sources client_manager.cpp et client_manager.hpp. Pour plus de commodité, ce fichier a déjà été ajouté au projet, mais il lui manque le code d'implémentation que vous allez désormais ajouter.

Pour ajouter le bouton de l'interface utilisateur, commencez par ouvrir le fichier demo_scene.cpp à partir du volet Project (Projet) d'Android Studio, dans le répertoire start/app/src/main/cpp. Commencez par localiser la fonction DemoScene::GenerateCommandIntegrity() vide et ajoutez le code suivant :

    const auto commandResult =
            NativeEngine::GetInstance()->GetClientManager()->GetOperationResult();
    if (commandResult != ClientManager::SERVER_OPERATION_PENDING) {
        if (ImGui::Button("Call server with integrity check")) {
            DoCommandIntegrity();
        }
    }

Recherchez ensuite la fonction DemoScene::DoCommandIntegrity() vide. Ajoutez le code suivant :

    ClientManager *clientManager = NativeEngine::GetInstance()->GetClientManager();
    clientManager->StartCommandIntegrity();
    mServerRandom = clientManager->GetCurrentRandomString();

Enregistrez le fichier. Vous allez maintenant mettre à jour la classe ClientManager de l'exemple pour ajouter la fonctionnalité Play Integrity réelle.

Mettre à jour le fichier d'en-tête du gestionnaire

Ouvrez le fichier client_manager.hpp à partir du volet Project (Projet) d'Android Studio, dans le répertoire start/app/src/main/cpp.

Incluez le fichier d'en-tête de l'API Play Integrity en ajoutant la ligne suivante sous la ligne #include "util.hpp" :

#include "play/integrity.h"

La classe ClientManager doit contenir des références aux objets IntegrityTokenRequest et IntegrityTokenResponse. Ajoutez les lignes suivantes sous la définition de classe ClientManager :

    IntegrityTokenRequest *mTokenRequest;
    IntegrityTokenResponse *mTokenResponse;

Enregistrez le fichier.

Initialiser et arrêter Play Integrity

Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier client_manager.cpp dans le répertoire start/app/src/main/cpp.

Recherchez le constructeur ClientManager::ClientManager(). Remplacez l'instruction mInitialized = false; par le code suivant :

    mTokenRequest = nullptr;
    mTokenResponse = nullptr;

    const android_app *app = NativeEngine::GetInstance()->GetAndroidApp();
    const IntegrityErrorCode errorCode = IntegrityManager_init(app->activity->vm,
                                                               app->activity->javaGameActivity);
    if (errorCode == INTEGRITY_NO_ERROR) {
        mInitialized = true;
    } else {
        mInitialized = false;
        ALOGE("Play Integrity initialization failed with error: %d", errorCode);
        ALOGE("Fatal Error: Play Integrity is unavailable and cannot be used.");
    }

Ajoutez le code suivant au destructeur ClientManager::~ClientManager() :

    if (mInitialized) {
        IntegrityManager_destroy();
        mInitialized = false;
    }

Demander un jeton d'intégrité

Demander un jeton d'intégrité à l'API Play Integrity est une opération asynchrone. Vous devez créer un objet de requête de jeton, lui attribuer une valeur nonce et effectuer la requête de jeton. Pour ce faire, ajoutez le code suivant à la fonction ClientManager::StartCommandIntegrity() vide :

    // Only one request can be in-flight at a time
    if (mStatus != CLIENT_MANAGER_REQUEST_TOKEN) {
        mResult = SERVER_OPERATION_PENDING;
        // Request a fresh random
        RequestRandom();
        if (mValidRandom) {
            GenerateNonce();
            IntegrityTokenRequest_create(&mTokenRequest);
            IntegrityTokenRequest_setNonce(mTokenRequest, mCurrentNonce.c_str());

            const IntegrityErrorCode errorCode =
                    IntegrityManager_requestIntegrityToken(mTokenRequest, &mTokenResponse);
            if (errorCode != INTEGRITY_NO_ERROR) {
                // Log the error, in a real application, for potentially
                // transient errors such as network connectivity, you should
                // add retry with an exponential backoff
                ALOGE("Play Integrity returned error: %d", errorCode);
                CleanupRequest();
                mStatus = CLIENT_MANAGER_IDLE;
            } else {
                mStatus = CLIENT_MANAGER_REQUEST_TOKEN;
            }
        }
    }

Étant donné que la requête de jeton fonctionne de manière asynchrone, vous devez vérifier qu'elle est terminée. La classe ClientManager comporte une fonction Update(), qui est appelée dans la boucle de mise à jour de l'appli. Ajoutez le code suivant à la fonction ClientManager::Update() pour vérifier l'état de la requête de jeton et traiter le résultat une fois la requête terminée :

    if (mStatus == CLIENT_MANAGER_REQUEST_TOKEN) {
        IntegrityResponseStatus responseStatus = INTEGRITY_RESPONSE_UNKNOWN;
        const IntegrityErrorCode errorCode =
                IntegrityTokenResponse_getStatus(mTokenResponse, &responseStatus);
        if (errorCode != INTEGRITY_NO_ERROR) {
            // Log the error, in a real application, for potentially
            // transient errors such as network connectivity, you should
            // add retry with an exponential backoff
            ALOGE("Play Integrity returned error: %d", errorCode);
            CleanupRequest();
            mStatus = CLIENT_MANAGER_IDLE;
        } else if (responseStatus == INTEGRITY_RESPONSE_COMPLETED) {
            std::string tokenString = IntegrityTokenResponse_getToken(mTokenResponse);
            SendCommandToServer(tokenString);
            CleanupRequest();
            mStatus = CLIENT_MANAGER_RESPONSE_AVAILABLE;
        }
    }

Nettoyer les objets de la requête

Lorsque vous avez terminé d'utiliser les objets de requête et de réponse par jeton, vous devez indiquer à l'API Play Integrity de les détruire et de récupérer leurs ressources. Ajoutez le code suivant à la fonction ClientManager::CleanupRequest() :

    if (mTokenResponse != nullptr) {
        IntegrityTokenResponse_destroy(mTokenResponse);
        mTokenResponse = nullptr;
    }
    if (mTokenRequest != nullptr) {
        IntegrityTokenRequest_destroy(mTokenRequest);
        mTokenRequest = nullptr;
    }

Dans le menu Build (Compilation), sélectionnez Make project (Créer un projet) et vérifiez que le projet a bien été compilé.

10. Envoyer le jeton au serveur (C++)

Vous allez maintenant ajouter du code pour envoyer une commande comprenant le jeton d'intégrité à votre serveur. Vous ajouterez également du code pour traiter le résultat.

Ajoutez le code suivant à la fonction ClientManager::SendCommandToServer() :

// Note that for simplicity, we are doing HTTP operations as
// synchronous blocking instead of managing them from a
// separate network thread
HTTPClient client;
std::string errorString;

// Manually construct the json payload for ServerCommand
std::string payloadString = COMMAND_JSON_PREFIX;
payloadString += TEST_COMMAND;
payloadString += COMMAND_JSON_TOKEN;
payloadString += token;
payloadString += COMMAND_JSON_SUFFIX;

auto result = client.Post(PERFORM_COMMAND_URL, payloadString, &errorString);
if (!result) {
   ALOGE("SendCommandToServer Curl reported error: %s", errorString.c_str());
   mResult = SERVER_OPERATION_NETWORK_ERROR;
} else {
   ALOGI("SendCommandToServer result: %s", (*result).c_str())
   // Preset to success, ParseResult will set a failure result if the parsing
   // errors.
   mResult = SERVER_OPERATION_SUCCESS;
   ParseResult(*result);
}

Ajoutez le code suivant à la fonction ClientManager::ParseResult() :

    bool validJson = false;
    JsonLookup jsonLookup;
    if (jsonLookup.ParseJson(resultJson)) {
        // Look for all of our needed fields in the returned json
        auto commandSuccess = jsonLookup.GetBoolValueForKey(COMMANDSUCCESS_KEY);
        if (commandSuccess) {
            auto diagnosticString = jsonLookup.GetStringValueForKey(DIAGNOSTICMESSAGE_KEY);
            if (diagnosticString) {
                auto expressString = jsonLookup.GetStringValueForKey(EXPRESSTOKEN_KEY);
                if (expressString) {
                    if (*commandSuccess) {
                        // Express token only valid if the server reports the command succeeded
                        mValidExpressToken = true;
                    } else {
                        mValidExpressToken = false;
                        mResult = SERVER_OPERATION_REJECTED_VERDICT;
                    }
                    mCurrentSummary = *diagnosticString;
                    mCurrentExpressToken = *expressString;
                    validJson = true;
                }
            }
        }
    }
    if (!validJson) {
        mResult = SERVER_OPERATION_INVALID_RESULT;
    }

Vous allez maintenant générer un app bundle signé et l'importer dans la Play Console pour tester l'appli.

11. Compiler et importer (C++)

Créer et configurer un keystore pour l'appli

Android exige que toutes les applis soient signées numériquement avec un certificat avant d'être installées ou mises à jour sur un appareil.

Nous allons créer un keystore pour l'appli dans cet atelier de programmation. Si vous publiez une mise à jour d'un jeu existant, réutilisez le même keystore que pour la version précédente de l'appli.

Créer un keystore et créer un app bundle

Suivez les étapes de la section Keystore avec Android Studio pour créer un keystore, puis utilisez-le pour générer un build signé du jeu. Dans Android Studio, sélectionnez Generate Signed Bundle / APK (Générer un app bundle/APK signé) dans le menu Build (Compilation) pour commencer le processus de compilation. Sélectionnez l'option App Bundle lorsque vous êtes invité à sélectionner un Android App Bundle ou un APK. À la fin du processus, vous disposerez d'un fichier .aab adapté à l'importation dans la Google Play Console.

Importer dans la Play Console

Après avoir créé un fichier App Bundle, importez-le dans la Play Console. Il est recommandé d'utiliser le canal de test interne pour accéder rapidement à votre build.

Exécuter le build de test

Vous devez maintenant télécharger et exécuter la version de test depuis le Play Store. Pour le moment, la fonction contient un code de réussite d'espace réservé qui enverra le jeton d'intégrité à votre serveur. Par conséquent, le démarrage d'une vérification de l'intégrité devrait aboutir et afficher l'écran suivant :

ef5f55d73f808791.png

Félicitations, vous avez intégré Play Integrity dans une appli C++ ! Passez à d'autres exemples de clients ou passez à la fin de cet atelier de programmation.

12. Créer et exécuter le client (Unity)

Le projet Unity a été créé avec Unity 2020 LTS (2020.3.31f1), mais il devrait être compatible avec les versions supérieures d'Unity. Le plug-in Play Integrity pour Unity est compatible avec Unity 2018 LTS ou version ultérieure.

Configuration du projet

Procédez comme suit :

  1. Dans Unity Hub ou l'éditeur Unity, ouvrez le projet Unity situé dans add-play-integrity-codelab/unity/start.
  2. Une fois le projet chargé, sélectionnez Build Settings (Paramètres de compilation) dans le menu File (Fichier) d'Unity.
  3. Dans la fenêtre Build Settings (Paramètres de compilation), définissez la plate-forme sur Android.
  4. Dans la fenêtre Build Settings (Paramètres de compilation), cliquez sur le bouton Player Settings (Paramètres du lecteur).
  5. Dans la fenêtre Project Settings (Paramètres du projet), dans la catégorie Player (Lecteur), accédez à la section Settings for Android (Paramètres pour Android). Développez la liste Other settings (Autres paramètres).

b994587b808c7be4.png

  1. Recherchez l'entrée Package Name (Nom du package) sous Identification.

d036e5be73096083.png

  1. Remplacez le nom du package par l'identifiant que vous avez choisi lors du déploiement du serveur.
  2. Fermez la fenêtre Project Settings (Paramètres du projet).
  3. Sélectionnez Save Project (Enregistrer le projet) dans le menu File (Fichier) d'Unity.

Mettre à jour les URL du serveur

Le projet doit être mis à jour pour pointer vers les emplacements de l'URL où vous avez déployé le serveur. Pour ce faire, procédez comme suit :

  1. Ouvrez le fichier PlayIntegrityController.cs à partir du dossier Scripts dans un IDE ou un éditeur de texte.
  2. Modifiez les valeurs des variables URL_GETRANDOM et URL_PERFORMCOMMAND pour qu'elles pointent vers votre serveur.
  3. Enregistrez le fichier.

Vous devez obtenir le résultat suivant :

    private readonly string URL_GETRANDOM = "https://your-play-integrity-server.uc.r.appspot.com/getRandom";
    private readonly string URL_PERFORMCOMMAND = "https://your-play-integrity-server.uc.r.appspot.com/performCommand";

L'URL spécifique varie en fonction du nom de votre projet et de la région Google Cloud que vous avez utilisée pour déployer votre serveur.

Tester le fonctionnement du serveur

Vous pouvez tester le fonctionnement du serveur en exécutant le projet dans l'éditeur Unity. Procédez comme suit :

  1. Ouvrez le fichier de scène SampleScene situé dans le dossier Scenes.
  2. Cliquez sur le bouton Play (Lecture) dans l'éditeur.
  3. Cliquez sur le bouton Request Random (Demander un nombre aléatoire) sur l'écran Game (Jeu).

Après un bref délai, la valeur aléatoire doit ressembler à ceci :

f22c56cdd2e56050.png

13. Ajouter le plug-in Play Integrity au projet (Unity)

Télécharger le plug-in

Dans un navigateur Web, ouvrez la page des versions du dépôt GitHub des plug-ins Unity Play. Utilisez la version la plus récente des plug-ins. Téléchargez le fichier com.google.play.integrity-<version>.unitypackage pour Play Integrity dans la liste Assets (Composants).

Installer le plug-in

Dans la barre de menu de l'éditeur Unity, sélectionnez Assets -> Import Package -> Custom Package… (Composants > Importer un package > Package personnalisé…), puis ouvrez le fichier .unitypackage que vous avez téléchargé. Lorsque la fenêtre Import Unity Package (Importer un package Unity) s'affiche, cliquez sur le bouton Import (Importer).

Le plug-in inclut le Gestionnaire de dépendances externes pour Unity (EDM4U). EDM4U implémente la résolution automatique des dépendances pour les composants Java requis pour utiliser Play Integrity. Lorsque vous êtes invité à activer la résolution automatique des dépendances, cliquez sur le bouton Enable (Activer).

5bf0be9139fab036.png

Nous vous recommandons vivement d'utiliser la résolution automatique. Les problèmes de dépendance peuvent empêcher la compilation ou l'exécution de votre projet.

14. Envoyer une requête d'intégrité (Unity)

Créer une demande d'intégrité

Pour créer une demande d'intégrité, procédez comme suit :

  1. Ouvrez le fichier PlayIntegrityController.cs à partir du dossier Scripts dans un IDE ou un éditeur de texte.
  2. Ajoutez la ligne suivante au bloc d'instructions using en haut du fichier :
using Google.Play.Integrity;
  1. Recherchez la fonction RunIntegrityCommand() et remplacez l'instruction yield return null; par le code suivant :
        // Call our server to retrieve a random number.
        yield return GetRandomRequest();
        if (!string.IsNullOrEmpty(_randomString))
        {
            // Create an instance of an integrity manager.
            var integrityManager = new IntegrityManager();

            // Request the integrity token by providing a nonce.
            var tokenRequest = new IntegrityTokenRequest(GenerateNonceString(_randomString,
                TEST_COMMAND));
            var requestIntegrityTokenOperation =
                integrityManager.RequestIntegrityToken(tokenRequest);

            // Wait for PlayAsyncOperation to complete.
            yield return requestIntegrityTokenOperation;

            // Check the resulting error code.
            if (requestIntegrityTokenOperation.Error != IntegrityErrorCode.NoError)
            {
                // Log the error, in a real application, for potentially
                // transient errors such as network connectivity, you should
                // add retry with an exponential backoff
                Debug.Log($@"IntegrityAsyncOperation failed with error: 
                    {requestIntegrityTokenOperation.Error.ToString()}");
                yield break;
            }

            // Get the response.
            var tokenResponse = requestIntegrityTokenOperation.GetResult();

            // Send the command to our server with a POST request, including the
            // token, which will be decrypted and verified on the server.
            yield return PostServerCommand(tokenResponse.Token);
        }

Envoyer la commande au serveur

Pour continuer à modifier le fichier PlayIntegrityController.cs, localisez la fonction PostServerCommand() et remplacez l'instruction yield return null; par le code suivant :

        // Start a HTTP POST request to the performCommand URL, sending it the
        // command and integrity token data provided by Play Integrity.
        var serverCommand = new ServerCommand(TEST_COMMAND, tokenResponse);
        var commandRequest = new UnityWebRequest(URL_PERFORMCOMMAND, "POST");
        string commandJson = JsonUtility.ToJson(serverCommand);
        byte[] jsonBuffer = Encoding.UTF8.GetBytes(commandJson);
        commandRequest.uploadHandler = new UploadHandlerRaw(jsonBuffer);
        commandRequest.downloadHandler = new DownloadHandlerBuffer();
        commandRequest.SetRequestHeader(CONTENT_TYPE, JSON_CONTENT);
        yield return commandRequest.SendWebRequest();

        if (commandRequest.result == UnityWebRequest.Result.Success)
        {
            // Parse the command result Json
            var commandResult = JsonUtility.FromJson<CommandResult>(
                commandRequest.downloadHandler.text);
            if (commandResult != null)
            {
                resultLabel.text = commandResult.diagnosticMessage;
                _expressToken = commandResult.expressToken;
                if (commandResult.commandSuccess)
                {
                    resultLabel.color = Color.green;
                    expressButton.SetActive(true);
                }
                else
                {
                    resultLabel.color = Color.black;
                    expressButton.SetActive(false);
                }
            }
            else
            {
                Debug.Log("Invalid CommandResult json");
            }
        }
        else
        {
            Debug.Log($"Web request error on processToken: {commandRequest.error}");
        }

Enregistrez le fichier.

15. Créer et importer (Unity)

Utilisez l'éditeur Unity Android Keystore Manager pour configurer votre build à signer afin de l'importer dans la Play Console.

Après avoir configuré les informations de signature, procédez comme suit :

  1. Sélectionnez Build > Build Settings (Compilation > Paramètres de compilation) dans le menu Unity (Fichier) d'Unity.
  2. Assurez-vous que SampleScene est inclus dans la liste Scenes in Build (Scènes en cours de compilation).
  3. Assurez-vous que l'option Build App Bundle (Google Play) (Créer un app bundle [Google Play]) est cochée.
  4. Cliquez sur le bouton Build (Compiler) et nommez votre fichier d'exportation.

Après avoir créé un fichier App Bundle, importez-le dans la Play Console. Il est recommandé d'utiliser le canal de test interne pour accéder rapidement à votre build.

Vous pouvez maintenant télécharger et installer votre build pour effectuer une vérification de l'intégrité. Les résultats doivent ressembler à ceci :

fa83cdb1a700ca0b.png

Félicitations, vous avez intégré Play Integrity à un projet de moteur Unity ! Passez à d'autres exemples de clients ou passez à la fin de cet atelier de programmation.

16. Créer et exécuter le projet (Kotlin)

Exécutez Android Studio. Dans la fenêtre Welcome to Android Studio (Bienvenue dans Android Studio), cliquez sur le bouton Open (Ouvrir) et ouvrez le projet Android Studio situé dans add-play-integrity-codelab/kotlin/start.

Mettre à jour l'ID d'application

Avant d'importer un build sur Google Play, vous devez remplacer l'ID d'application par défaut par un ID unique. Procédez comme suit :

  1. Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier build.gradle du module PlayIntegrityCodelab.app.
  2. Recherchez l'instruction applicationId.
  3. Remplacez com.example.google.codelab.playintegritykotlin par l'identifiant que vous avez choisi lors du déploiement du serveur, puis enregistrez le fichier.
  4. En haut du fichier, une bannière s'affiche pour vous informer que les fichiers Gradle ont été modifiés. Cliquez sur Sync Now (Synchroniser) pour actualiser et resynchroniser le fichier.

Mettre à jour les URL du serveur

Le projet doit être mis à jour pour pointer vers l'emplacement de l'URL où vous avez déployé le serveur. Pour ce faire, procédez comme suit :

  1. Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier IntegrityServer sous start/app/src/main/java/com.example.google.codelab.playintegritykotlin/integrity.
  2. Remplacez l'URL ‘https://your.play-integrity.server.com' par l'URL de base de votre serveur, puis enregistrez le fichier.

Vous devez obtenir le résultat suivant :

    private val SERVER_URL: String = "https://your-play-integrity-server.uc.r.appspot.com"

L'URL spécifique varie en fonction du nom de votre projet et de la région Google Cloud que vous avez utilisée pour déployer votre serveur.

Compiler et exécuter

Connectez un appareil Android configuré pour le développement. Dans Android Studio, créez le projet et exécutez-le sur l'appareil connecté. L'appli devrait se présenter comme suit :

d77ca71dc209452f.png

Au démarrage, l'appli appelle le point de terminaison getRandom sur votre serveur et affiche le résultat. Si une erreur se produit, par exemple en cas d'URL incorrecte ou si le serveur ne fonctionne pas, une boîte de dialogue s'affiche. Vous pouvez sélectionner le bouton Request Random (Demander un nombre aléatoire) pour récupérer un nouveau nombre aléatoire sur le serveur. Le bouton Call server with Integrity check (Appeler le serveur avec vérification de l'intégrité) n'est encore associé à aucune action. Vous ajouterez cette fonctionnalité dans les sections suivantes.

17. Ajouter Play Integrity au projet (Kotlin)

Pour ajouter la bibliothèque Play Integrity et les dépendances associées au projet, procédez comme suit :

  1. Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier build.gradle sous start/app.
  2. Recherchez le bloc dependencies en bas du fichier.
  3. Ajoutez les lignes suivantes en bas du bloc dependencies :
    implementation "com.google.android.play:integrity:1.0.1"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.1"
  1. Enregistrez le fichier.
  2. En haut du fichier, une bannière s'affiche pour vous informer que les fichiers Gradle ont été modifiés. Cliquez sur Sync Now (Synchroniser) pour actualiser et resynchroniser le fichier.

L'exemple Kotlin utilise des coroutines. La bibliothèque kotlinx-coroutines-play-services ajoute des extensions qui facilitent l'utilisation d'objets Task asynchrones Play Integrity à partir de coroutines Kotlin.

18. Envoyer une requête d'intégrité (Kotlin)

Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier IntegrityServer sous start/app/src/main/java/com.example.google.codelab.playintegritykotlin/integrity. En bas du fichier se trouve une fonction integrityCommand vide. L'UI appelle cette fonction lorsque vous appuyez sur le bouton Call server with integrity check (Appeler le serveur avec vérification de l'intégrité).

Vous allez ajouter du code à la fonction integrityCommand pour effectuer les opérations suivantes :

  1. Récupérer sur le serveur un nombre aléatoire actualisé à utiliser lors de la création d'un nonce et à associer à la vérification de l'intégrité
  2. Appeler l'API Play Integrity pour effectuer une requête d'intégrité et recevoir un jeton d'intégrité contenant les résultats
  3. Envoyer la commande et le jeton d'intégrité à votre serveur à l'aide d'une requête HTTP POST
  4. Traiter et afficher les résultats

Ajoutez le code suivant à la fonction vide integrityCommand :

        // Set our state to working to trigger a switch to the waiting UI
        _serverState.emit(ServerState(
            ServerStatus.SERVER_STATUS_WORKING))
        // Request a fresh random from the server as part
        // of the nonce we will generate for the request
        var integrityRandom = IntegrityRandom("", 0U)
        try {
            val returnedRandom = httpClient.get<IntegrityRandom>(
                SERVER_URL + "/getRandom")
            integrityRandom = returnedRandom
        } catch (t: Throwable) {
            Log.d(TAG, "getRandom exception " + t.message)
            _serverState.emit(ServerState(ServerStatus.SERVER_STATUS_UNREACHABLE,
                IntegrityRandom("", 0U)))
        }

        // If we have a random, we are ready to request an integrity token
        if (!integrityRandom.random.isNullOrEmpty()) {
            val nonceString = GenerateNonce.GenerateNonceString(TEST_COMMAND,
                integrityRandom.random)
            // Create an instance of an IntegrityManager
            val integrityManager = IntegrityManagerFactory.create(context)

            // Use the nonce to configure a request for an integrity token
            try {
                val integrityTokenResponse: Task<IntegrityTokenResponse> =
                    integrityManager.requestIntegrityToken(
                        IntegrityTokenRequest.builder()
                            .setNonce(nonceString)
                            .build()
                    )
                // Wait for the integrity token to be generated
                integrityTokenResponse.await()
                if (integrityTokenResponse.isSuccessful && integrityTokenResponse.result != null) {
                    // Post the received token to our server
                    postCommand(integrityTokenResponse.result!!.token(), integrityRandom)
                } else {
                    Log.d(TAG, "requestIntegrityToken failed: " +
                            integrityTokenResponse.result.toString())
                    _serverState.emit(ServerState(ServerStatus.SERVER_STATUS_FAILED_TO_GET_TOKEN))
                }
            } catch (t: Throwable) {
                Log.d(TAG, "requestIntegrityToken exception " + t.message)
                _serverState.emit(ServerState(ServerStatus.SERVER_STATUS_FAILED_TO_GET_TOKEN))
            }
        }

Le code permettant de POST la commande à votre serveur a été divisé en une fonction postCommand distincte. Ajoutez le code suivant à la fonction vide postCommand :

        try {
            val commandResult = httpClient.post<CommandResult>(
                SERVER_URL + "/performCommand") {
                contentType(ContentType.Application.Json)
                body = ServerCommand(TEST_COMMAND, tokenString)
            }
            _serverState.emit(ServerState(ServerStatus.SERVER_STATUS_REACHABLE,
                integrityRandom,
                commandResult.diagnosticMessage,
                commandResult.commandSuccess,
                commandResult.expressToken))
        } catch (t: Throwable) {
            Log.d(TAG, "performCommand exception " + t.message)
            _serverState.emit(ServerState(ServerStatus.SERVER_STATUS_UNREACHABLE))
        }

Corrigez les importations manquantes et enregistrez le fichier.

19. Afficher les résultats (Kotlin)

Mettre à jour l'interface utilisateur avec le résumé des résultats

L'UI affiche actuellement le texte d'espace réservé pour le résumé de l'évaluation de l'intégrité. Pour remplacer l'espace réservé par le résumé, procédez comme suit :

  1. Dans le volet Project (Projet) d'Android Studio, ouvrez le fichier MainView.kt sous start/app/src/main/java/com.example.google.codelab.playintegritykotlin/ui/main.
  2. Accédez à la fin de la fonction MainUI, recherchez l'instruction text = "None", et remplacez-la par le code suivant :
                        text = state.serverState.serverVerdict,
  1. Corrigez les importations manquantes et enregistrez le fichier.

20. Compiler et importer (Kotlin)

Créer et configurer un keystore pour l'appli

Android exige que toutes les applis soient signées numériquement avec un certificat avant d'être installées ou mises à jour sur un appareil.

Nous allons créer un keystore pour l'appli dans cet atelier de programmation. Si vous publiez une mise à jour d'un jeu existant, réutilisez le même keystore que pour la version précédente de l'appli.

Créer un keystore et créer un app bundle

Suivez les étapes de la section Keystore avec Android Studio pour créer un keystore, puis utilisez-le pour générer un build signé du jeu. Dans Android Studio, sélectionnez Generate Signed Bundle / APK (Générer un app bundle/APK signé) dans le menu Build (Compilation) pour commencer le processus de compilation. Sélectionnez l'option App Bundle lorsque vous êtes invité à sélectionner un Android App Bundle ou un APK. À la fin du processus, vous disposerez d'un fichier .aab adapté à l'importation dans la Google Play Console.

Importer dans la Play Console

Après avoir créé un fichier App Bundle, importez-le dans la Play Console. Il est recommandé d'utiliser le canal de test interne pour accéder rapidement à votre build.

Exécuter le build de test

Vous devez maintenant télécharger et exécuter la version de test depuis le Play Store. Si vous sélectionnez le bouton Call server with integrity check (Appeler le serveur avec vérification d'intégrité), l'écran suivant devrait s'afficher :

3291795e192396c9.png

21. Félicitations

Félicitations, vous avez ajouté Play Integrity à une appli Android !

Complément d'informations