2017-07-07 3 views
1

J'ai parcouru la plupart des réponses ici concernant l'accès socket via le code natif sur Android, et d'autres concernant l'accès socket pour les tests instrumentés "androidTest", mais aucun n'est en mesure d'expliquer complètement comportement étrange que je vois.Accès aux sockets raw dans les tests instrumentés Android

Android Studio 2.3.3 sur Windows 10, NDK 15.1.x, outils de construction 25.0.3. Construire avec Cmake. Je transfère du code natif à Android destiné à être distribué sous la forme d'une bibliothèque enveloppée dans une API Java JNI. Cette partie semble fonctionner correctement; Au moins, je peux déboguer et me connecter au code natif et voir où les choses vont mal. J'ai créé quelques tests instrumentés pour exercer l'interface JNI, mais il semble que le côté natif n'ait pas accès aux sockets, même si l'application de test qu'Android Studio termine pour vos tests intrumentés (c.-à-d. J'ai l'autorisation INTERNET appliquée, et je peux voir que cela fait partie du manifeste poussé de l'application de test.J'ai également appliqué le perm ACCESS_NETWORK_STATE dans un ajustement de pique.)

Ainsi, certaines parties de la bibliothèque savent comment configurer et utiliser les sockets TCP (datagramme et stream, dans ce cas) et résoudre DNS, qui échoue (Cela peut être un bogue dans mon port, puisque l'appareil semble toujours résoudre DNS basé sur la sortie shell ADB ci-dessous). Si je teste avec une adresse IP, il réessaie jusqu'à ce qu'il échoue. Chaque appel à socket() renvoie un ERRNO de 11 EAGAIN ("Réessayer"). Si j'utilise le shell ADB pour me connecter à l'appareil testé via USB, je peux utiliser ping et utiliser curl, etc. Mais, dès que je run-as comme application de test, je ne suis plus autorisé à utiliser un périphérique réseau .

[email protected]:/data/data/org.clvrmnky.library.test $ ping www.example.com 
PING www.example.com (93.184.216.34) 56(84) bytes of data. 
ping: sendmsg: Operation not permitted 
ping: sendmsg: Operation not permitted 
ping: sendmsg: Operation not permitted 
^C 
--- www.example.com ping statistics --- 
3 packets transmitted, 0 received, 100% packet loss, time 2004ms 

1|[email protected]:/data/data/org.clvrmnky.library.test $ ping -I wlan0 www.example.com 
ping: SO_BINDTODEVICE: Operation not permitted 
2|[email protected]:/data/data/org.clvrmnky.library.test $ curl -4 --verbose www.example.com/ 
* Trying 93.184.216.34... 
* connect to 93.184.216.34 port 80 failed: Connection timed out 
* Failed to connect to www.example.com port 80: Connection timed out 
* Closing connection 0 
curl: (7) Failed to connect to www.example.com port 80: Connection timed out 
7|[email protected]:/data/data/org.clvrmnky.library.test $ 

Je ne vais pas coller ici, mais wlan0 (et d'autres) existe et est avec une adresse IP valide, accessible. C'est "Link encap: UNSPEC" que j'avoue ne pas complètement grok. Je fais l'hypothèse que l'application échoue sur les appels de socket successifs et l'incapacité de se lier à un périphérique réseau et l'utiliser dans un shell adb sont liés d'une certaine manière, mais si quelqu'un a une raison pour laquelle cette peut-être pas, s'il vous plaît faites le moi savoir.

J'ai essayé:

  • Invoquer les méthodes d'essai dans un thread d'arrière-plan, juste au cas où les essais instrumentés en cours d'exécution dans l'application de test thread principal.
  • Définition de la stratégie de threads StrictMode à permitAll() dans la clause @Before de la classe de test.
  • Exécution avec et sans l'autorisation INTERNET définie dans le manifeste de test. Sans cette autorisation, il atteint le code natif, mais échoue beaucoup plus tôt dans l'initialisation. Je devrais fouiller dans mes notes pour aller chercher plus de détails à ce sujet. Je supposer que j'ai besoin de cette permission. (Note: si j'active INTERNET, le débogueur distant ne peut plus se connecter à l'appareil, donc je peux déboguer uniquement via les logs.)

Répondre

1

Il ressemble à des tests instrumentés, du moins à ce jour. prendre en charge l'accès aux connecteurs crus via le NDK. L'application .test créée automatiquement semblait avoir tout ce dont elle avait besoin dans le manifeste (j'ai vérifié base.apk directement à partir de l'appareil). Une fois qu'une DemoApp a été créée avec des paramètres de manifeste identiques, j'ai pu ouvrir des sockets, s'y connecter, faire des recherches de noms, etc. De plus, j'ai pu accéder au réseau via adb shell en cours d'exécution ("run-as") le DemoApp.

Il se passe toujours quelque chose d'étrange, car j'ai créé une application JNI séparée qui ouvre les sockets, et a piraté un test instrumenté contre cela. Au moins brièvement shell adb fonctionnant comme ext.other.app.test avait ont accès à Internet.