Comment faire une capture d’écran d’une autre application par programmation sans autorisation root, comme Trial UX Trial?

Comment faire une capture d’écran d’une autre application par programmation sans autorisation root, comme Trial UX Trial?

  1. Je sais que je peux capturer le bitmap de la vue racine dans mon application. Mais je ne peux pas obtenir la vue racine de l’autre application lorsque mon application s’exécute en arrière-plan

    bitmap = Bitmap.createBitmap(rootview.getDrawingCache());

  2. Il existe une autorisation pour capturer le tampon d’image actuel dans le manifeste: android.permission.READ_FRAME_BUFFER . Mais certains sites Web disent que c’est uniquement pour les applications de signature.

    Vérifier les permissions Android – Niveaux de protection

Après avoir essayé Trial UX Trial, j’ai lu la permission:

  • INTERNET: pour se connecter au serveur de captures d’écran localhost pour un téléphone rooté.
  • SYSTEM_ALERT_WINDOW: pour le bouton de caméra le plus haut.
  • VIBRATE: pour un retour de vibration.
  • WRITE_EXTERNAL_STORAGE: pour enregistrer la capture d’écran.
  • GET_TASKS: pour détecter l’activité de définition de développement de premier plan pour la méthode de capture non rootée et non préchargée.

Il semble que SYSTEM_ALERT_WINDOW ou GET_TASKS permettent à l’application de prendre des captures d’écran. J’ai deux devinettes de comment ça marche:

  1. Il peut être en mesure d’accéder à l’ Activity de l’activité de premier plan, il obtient la vue racine de l’ Activity , capture sa capture d’écran.
  2. Appeler glreadpixels

Si vous essayez une de mes conjectures, s’il vous plaît laissez-moi savoir le résultat.

C’est extrêmement difficile. J’ai passé plusieurs années à essayer de le faire. J’ai finalement réussi, mais toute solution impliquera un effort commercial et technique.


Mise à jour mars 2015

La plupart des choses ci-dessous ne sont plus à jour. Il y a maintenant, après toutes ces années, un paquet android.media.projection https://developer.android.com/reference/android/media/projection/package-summary.html qui permet enfin ce dont vous avez besoin!


Capture de l’image d’écran de votre propre application

Pour être complet, je veux inclure votre propre commentaire que vous pouvez capturer une image de votre propre application en utilisant Bitmap.createBitmap(rootview.getDrawingCache()); et des mécanismes similaires.

Capturer l’écran d’une autre application pendant que vous êtes en arrière-plan

Utilisation de l’autorisation READ_FRAMEBUFFER

Tout d’abord, vous avez raison de dire qu’une application normale ne peut pas utiliser la permission READ_FRAMEBUFFER , car elle est au niveau “signature”. Cela signifie que vous devez être signé par la même clé que la ROM du système Android pour pouvoir prendre une telle capture d’écran.

Je pensais que c’était un peu sortingste, alors en 2009, j’ai fait une soumission de projet open source Android pour lui demander de l’ouvrir 1 . La réponse de Dianne Hackborn, l’architecte Android, était:

Um non. Absolument pas.

Alors, ça s’est bien passé, alors! Par conséquent, cette autorisation est encore signature à ce jour.

Si vous captureScreen de cette autorisation, vous pourriez toutefois appeler le membre ISurfaceComposer de ISurfaceComposer 2 . Vous aurez besoin d’écrire du code natif pour accéder à cette fonction, en utilisant le NDK Android ainsi que des API non documentées. Cependant, c’est possible.

En interne, dans le sous-système graphique Android, un appel glReadPixels est glReadPixels pour récupérer les pixels du GPU sur le processeur. (Le GPU est utilisé pour la plupart des compositing sur Android. En fait, Android 4.0+ prend en charge les compositeurs de matériel supplémentaires, et le Surface Flinger doit faire encore plus de travail pour récupérer ces pixels dans le processeur.)

Cet appel fonctionne à merveille, sauf pour quelques petits problèmes:

  • Le risque d’utiliser une API non prise en charge qui pourrait se briser à tout moment.
  • Le tracas de l’appeler en C ++
  • Cela provoque le blocage des pipelines GPU, ce qui peut perturber les concepteurs de GPU mais ne pose pas vraiment de problèmes dans la réalité
  • Il repose sur une large bande passante entre le GPU et le CPU. Ceci est parfois problématique car les architectures de mémoire sont conçues pour envoyer des données dans la direction opposée. Cependant, il me semble rappeler que toutes les architectures de chipset Android modernes partagent directement la mémoire entre le GPU et le CPU, sauf une (il peut s’agir de Broadcom? Je ne me souviens plus), ce qui peut ralentir ce mécanisme.

… et un gros problème …

  • Plus important encore, en tant qu’écrivain d’application normal, vous ne pouvez même pas appeler cette API en raison des permissions requirejses au niveau de la signature.

Pourtant, sur la plupart des appareils Android, vous pouvez obtenir 10 images par seconde. Mieux encore, cette API prend effectivement en charge la mise à l’échelle de l’image résultante dans le matériel sur le GPU , donc si vous êtes intelligent, vous pouvez pré-dimensionner l’image à la taille requirejse avant même que les pixels ne touchent le processeur. Cela peut donc être extrêmement performant.

Notez bien entendu qu’en tant glReadPixels applications, vous ne pouvez pas appeler glReadPixels car vous n’avez pas access au contexte OpenGL approprié. C’est la propriété du flinger de surface.

Utiliser /dev/graphics/fb0 et similaire

Certains sont tentés d’essayer de lire ces fichiers de périphériques Linux qui représentent le framebuffer. Cependant, il y a trois problèmes:

  • Vous avez besoin de root.
  • Parfois, ils ne sont même pas là.
  • Souvent, ils ne représentent pas l’image réelle à l’écran. Rappelez-vous sur Android que les graphiques sont composées sur le GPU. Il n’y a donc pas de raison pour que le processeur ait access à une copie de l’image écran composite complète, ce qui n’est souvent pas le cas. Ce fichier contient parfois des déchirures (au mieux) et une image de mémoire (au pire). Fait intéressant, certains des outils pour les téléphones enracinés utilisent cette méthode, ce qui, à mon avis, est une erreur. Si vous avez root, vous avez par définition toutes les permissions Android et pouvez donc appeler l’API captureScreen ci-dessus pour obtenir une image correcte.

Utilisation de partenaires matériels

Nous entrons maintenant dans les solutions qui nécessitent une action commerciale.

Parler aux fabricants de puces Android présente souvent une solution. Comme ils conçoivent le matériel, ils ont access au framebuffer – et sont souvent en mesure de fournir des bibliothèques qui évitent complètement le modèle d’permissions Android en accédant simplement à leurs pilotes de kernel personnalisés directement.

Si vous visez un modèle de téléphone spécifique, c’est souvent une bonne solution. Bien sûr, les chances sont que vous devrez coopérer avec le fabricant de téléphone ainsi que le fabricant de silicium.

Parfois, cela peut donner des résultats exceptionnels . Par exemple, j’ai entendu dire qu’il est possible sur certains matériels de diriger le framebuffer matériel du téléphone directement dans l’encodeur vidéo H.264 du téléphone et de récupérer un stream vidéo pré-encodé de tout ce qui se trouve sur l’écran du téléphone. Exceptionnel. (Malheureusement, je sais seulement que cela est possible sur les puces TI OMAP, qui se retirent progressivement du marché du téléphone 3 ).

Utiliser des trous de sécurité

Android applique rigoureusement son modèle de permission et dispose de peu de failles de sécurité. Cependant, les OEM Android peuvent parfois être plus négligents.

Par exemple, un équipementier majeur dont le nom commence par S a implémenté un moyen de capturer l’écran en utilisant une frappe. Il enregistre dans un fichier lisible dans le monde entier sur la carte SD. En théorie, vous pourriez trouver ce qui intercepte ces clés et voir comment cela fonctionne. Peut-être pourriez-vous faire quelque chose de similaire.

Et peut-être y a-t-il un moyen pour un autre grand équipementier dont le nom commence aussi par S.

Non, je ne vais pas entrer plus en détail dans cette section. Pour savoir comment faire ces choses, je devrais avoir un logiciel d’ingénierie inverse, et cela pourrait être illégal. Bonne chance, cependant.

Travailler avec les fabricants de téléphones

Comme décrit précédemment, les fabricants de téléphones ont facilement access à une API qui fonctionne . Et les fabricants de téléphones ont les permissions de niveau de signature requirejses.

Il vous suffit donc de faire signer votre logiciel par le fabricant du téléphone.

Ceci est cependant difficile . En signant le logiciel, le fabricant de téléphone garantit sa qualité – il doit donc vouloir vérifier votre code source. En outre, en raison de la nature d’Android – s’ils signent le logiciel, ils doivent le dissortingbuer. Vous ne pouvez pas le mettre sur le marché s’il est signé par la signature de quelqu’un d’autre.

Cependant, les OEM n’ont pas besoin de l’inclure dans la ROM: ils peuvent toujours le dissortingbuer sur le marché Android. Mais tu ne peux pas.

Une bonne solution serait si chaque fournisseur signait une petite bibliothèque à laquelle un SDK commun pouvait accéder. Ce qui m’amène à …

Travailler avec des partenaires logiciels qui ont déjà résolu ce problème

J’en sais beaucoup sur ce sujet parce que je travaillais chez RealVNC. Nous avons travaillé avec tous les principaux fournisseurs de téléphones Android pour avoir access à ces API au niveau de la signature. Je ne saurais trop insister sur les nombreuses années de travail (commerciales et techniques) nécessaires pour y parvenir. Certains des équipementiers ont rendu public ce travail – par exemple 4 .

Je ne travaille plus chez RealVNC, donc je n’ai rien à gagner de la publicité de leurs logiciels. Mais si vous voulez vraiment pouvoir capturer l’écran sur plusieurs appareils Android, vous pouvez les contacter pour réutiliser leur service de contrôle à distance ou leur VNC SDK 5 . Ce n’est pas un logiciel libre, alors vous devriez vous attendre à payer, et croyez-moi, cela est assez juste compte tenu des efforts épiques à déployer pour travailler avec tous ces OEM Android.

Dans un souci d’équilibre, je dois souligner que d’autres fournisseurs ont également travaillé avec les fabricants de téléphones sur ce sujet, par exemple Soti. Mais je crois qu’ils offrent tous des solutions de gestion de périphériques spécifiques, plutôt qu’un kit de développement logiciel (SDK) à commande à distance / événement.

Sur USB

Une autre option – le démon adb qui écoute les débogages via USB a un peu plus de privilèges qu’une application normale, ce qui explique pourquoi il est capable de saisir l’écran (vous pouvez voir son image à l’aide de l’outil ddms ). Si vous êtes en mesure d’exécuter une commande en utilisant adb vous pouvez également obtenir ces privilèges (selon la bibliothèque android-screenshot liée précédemment).

Consortingbuer au projet open source Android

Finalement, ce problème m’a réduit à la poussière, et je suis parti pour des pâturages plus verts qui n’impliquaient pas d’essayer d’extraire les pixels des téléphones Android.

Avant de quitter RealVNC, nous avons essayé à nouveau de consortingbuer à ces API au projet open source Android. Cette fois, nous avons eu une réaction plus positive 6 . En bref, il a été suggéré que notre approche de la sécurité était presque correcte, mais que le système graphique était trop agité pour accepter nos correctifs. Eh bien, la bonne nouvelle est que le système graphique n’est plus dans la tourmente – en fait, il a maintenant cette API captureScreen ce qui signifie qu’aucune modification du système graphique n’est nécessaire. Il est donc possible de soumettre un nouveau mécanisme de sécurité à AOSP autour de cette API qui résout finalement ce problème.

Bonne chance!

Peut-être que la bibliothèque de capture d’écran Android peut aider. Mais bien dans leur page d’utilisation, il est écrit qu’il a besoin d’un service natif démarré avec adb (à partir du SDK Android).

PS: Rappelez-vous que Screenshot UX ne fonctionne pas pour chaque téléphone non raciné.

Je ne pense pas qu’Android vous permettra d’accéder au tampon d’images d’une autre application. Ceci est juste une partie de la sécurité d’Android. Chaque application doit conserver ses propres ressources.

Si vous avez vraiment besoin d’une capture d’écran de n’importe quelle application, je vous suggère d’utiliser le “geste” de capture d’écran natif. Par exemple, pour le Nexus 7 , il suffit de “maintenir le bouton d’alimentation et le bouton de volume enfoncés en même temps pendant environ 2 secondes.”

Une recherche Google trouvera généralement le truc avec votre appareil.