2

У меня есть инструмент commad-line, который передает результаты трансляции и ожидания.Невозможно подключиться к локальному локальному гнезду на Android 5.1.

код сервера (обработка ошибок опущена):

int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen) 
    { 
     int nameLen = strlen(name); 
     pAddr->sun_path[0] = '\0'; 
     strcpy(pAddr->sun_path+1, name); 
     pAddr->sun_family = AF_LOCAL; 
     *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path); 
     return 0; 
    } 

    int main(int argc, char* argv[]) 
    { 
     //... 

     // Create socket in abstract namespace 
     struct sockaddr_un sockAddr = {0}; 
     socklen_t sockLen; 
     makeAddr("SOCKET_NAME", &sockAddr, &sockLen); 

     int serverFd = socket(AF_LOCAL, SOCK_STREAM, PF_UNIX)); 

     bind(serverFd, (const struct sockaddr*) &sockAddr, sockLen); 

     listen(serverFd, 5); 

     //set socket non-blocking 
     int flags = fcntl(serverFd, F_GETFL, 0); 
     fcntl(serverFd, F_SETFL, flags | O_NONBLOCK); 

     pollfd pollFd = {0}; 
     pollFd.fd = serverFd; 
     pollFd.events = POLLIN | POLLRDHUP; 

     // Send brodcast 
     system("am broadcast ..."); 

     for(;;) 
     { 
      // Wait result 
      int pollResult = poll(&pollFd, 1, timeout); 
     // Process result 

Java код клиента:

public class CommandReceiver extends BroadcastReceiver{ 

    @Override 
    public void onReceive(Context context, Intent intent) { 

      LocalSocket socket = new LocalSocket(); 
      LocalSocketAddress address = new LocalSocketAddress("SOCKET_NAME", LocalSocketAddress.Namespace.ABSTRACT); 
      socket.connect(address); 

      // Do something and send result asynchronously 

все это работает на андроид ранее 5.1.

На андроид 5.1 подключение() бросает исключение:

java.io.IOException: Permission denied

at android.net.LocalSocketImpl.connectLocal(Native Method)

at android.net.LocalSocketImpl.connect(LocalSocketImpl.java:290)

at android.net.LocalSocket.connect(LocalSocket.java:130)

В журнале есть ошибка:

07-27 09:56:08.179: W: type=1400 audit(0.0:3675): avc: denied { connectto } for path=00636F6D2E6B6173706572736B792E6B617368656C6C2E534F434B45542D36313838363731373231343337393833373637 scontext=u:r:untrusted_app:s0 tcontext=u:r:shell:s0 tclass=unix_stream_socket permissive=0

Я нашел относительный андроид исправление: https://android.googlesource.com/device/moto/shamu/+/b2db40f

Итак, это больше не будет работать с Android 5.1? Что я могу сделать (может быть, как-то установить разрешение)? Или есть другой механизм для отправки данных из встроенного инструмента командной строки и результата ожидания?

ответ

1

Используйте трубы вместо розетки: O_RDWR on named pipes with poll()

Создание трубы в процессе Java:

 mkfifo(cpath, 0); 
     chmod(cpath, S_IRWXU|S_IROTH|S_IRGRP); 

открытой трубы в процессе нативного:

int serverFd = open(PIPE_NAME, O_RDONLY | O_NONBLOCK); 
pollfd pollFd = {0}; 
pollFd.fd = serverFd.get(); 
pollFd.events = POLLIN | POLLRDHUP; 

// send command 
.... 

for(;;) 
{ 
    int pollResult = poll(&pollFd, 1, timeout); 
Смежные вопросы