Как предоставить разрешения /dev/bus/usb для приложений libusb для Android?

Я разрабатываю приложение, которое использует libusb через jni. это приложение в настоящее время предназначено только для рутированных машин Android 3+ с USB-хостом.

сценарий следующий:

<java Activity>
       loads <jni_wrapper.so>
               which wraps <my_main_lib.so>
                       that uses <libusb.so>
                               that needs rw access to: /dev/bus/usb/<device>

все нативные библиотеки .so являются частью инфраструктуры, которую я устанавливаю (как root) в /system/lib, которую затем можно использовать с помощью действий java, запускаемых простыми пользователями.

это означает, что вся связь через usb должна осуществляться с родной стороны.

у меня все работает нормально, за исключением одной проблемы - разрешения USB: разрешения по умолчанию для записей /dev/bus/usb/ (0660, uid= root, gid= usb).

очевидно, что стандартный процесс Java, выполняющий собственный код, не соответствует ни одному из вышеуказанных требований, что вынуждает меня выполнить «chmod 666» соответствующую запись /dev, чтобы это заработало.

это решение не так уж хорошо, потому что оно не выдерживает перезагрузки или отключения / повторного подключения устройства (разрешения возвращаются к 0660).

решение, которое я ищу, должно:

  • пережить перезагрузку/переподключение
  • быть установлен ~один раз~ пользователем root и не беспокоить пользователя каждый раз, чтобы получить разрешения
  • быть универсальным и работать на всех (/большинстве) машинах Android 3+
  • [не обязательно] дает минимальные необходимые учетные данные

направления, о которых я думал:

  • изменение разрешений в /init.rc или /ueventd.rc --> оба переопределяются при каждой перезагрузке
  • монтирование usbfs /proc/bus/usb с devmode=0666 --> выдерживает повторное подключение, но не перезагружается
  • заставить мой процесс присоединиться к группе «usb»? --> я пробовал android.permission.ACCESS_USB, но он не работает/поддерживается... :/

есть идеи? :-)

Спасибо!


person Nulldef    schedule 14.09.2011    source источник
comment
Та же проблема здесь. Очень интересует любое решение.   -  person Violet Giraffe    schedule 17.09.2011
comment
Привет ты заработал? Я делаю что-то подобное и использую нерутированный телефон.   -  person Anil Maddala    schedule 27.11.2014


Ответы (4)


У меня та же проблема, и я решаю ее, делая это в ndk, меняя /proc/bus/usb на то, где в вашем случае установлен usb. Надеюсь, поможет.

r = system("su -c \"chmod -R 777 /proc/bus/usb/\"");
if(r!=0) {
    LOGD("Could not grant permissions to USB\n");
    eturn CANT_GRAN_PERMISSION_USB;
}
person Pedro Fraca    schedule 28.10.2011

Есть некоторый метод от команды разработчиков libusb. для моего случая я выбираю первый метод.

из:https://github.com/libusb/libusb/blob/master/android/README

Разрешения во время выполнения:

Конфигурация системы по умолчанию на большинстве устройств Android не разрешает доступ к USB-устройствам. Есть несколько вариантов изменить это.

Если у вас есть контроль над образом системы, вы можете изменить ueventd.rc, используемый в образе, чтобы изменить разрешения на /dev/bus/usb//. При использовании этого подхода рекомендуется создать новое разрешение Android для защиты доступа к этим файлам. Не рекомендуется давать всем приложениям права на чтение и запись этих файлов.

Для корневых устройств код, использующий libusb, может быть выполнен от имени пользователя root с помощью команды «su». Альтернативой может быть использование команды «su» для изменения прав доступа к соответствующим файлам /dev/bus/usb/.

Пользователи сообщают об успешном использовании android.hardware.usb.UsbManager для запроса разрешения на использование UsbDevice и последующем открытии устройства. Сложность этого метода заключается в том, что нет гарантии, что он продолжит работать в будущих версиях Android, он требует вызова API-интерфейсов Java и запуска кода для сопоставления каждого android.hardware.usb.UsbDevice с libusb_device.

person kangear    schedule 11.02.2015

Изменить:

После повторного прочтения вопроса становится ясно, что я неправильно понял, что хост-компьютер работает под управлением Android. Поскольку udev не существует в Android, приведенный ниже ответ не отвечает на вопрос. Я оставляю этот ответ здесь на случай, если кто-то ищет информацию о том, как распознать устройства Android на хост-компьютере Linux, отличном от Android.

Завершить редактирование

Разрешения по умолчанию для этих драйверов (/dev/bus/usb/###/###) определяются udev. В частности, он анализирует файлы конфигурации в /etc/udev/rules.d и /lib/udev/rules.d в порядке номеров, чтобы определить значения по умолчанию.

Чтобы переопределить значения по умолчанию, вам потребуется создать собственный файл udev .rules. Для этого вам нужен идентификатор поставщика устройства, которому вы хотите предоставить разрешение. lsusb распечатает идентификатор устройства для любого конкретного устройства, и если вам нужен список всех поставщиков, вы можете попробовать это.

Итак, в вашем файле /etc/udev/rules.d/99-android.rules заполните следующую строку для каждого поставщика, которого вы хотите поддерживать:

SUBSYSTEM=="usb", ATTRS{idVendor}=="04e8", MODE:="0666"

Обратите внимание, что в приведенном выше примере они используют = вместо := и SYSFS вместо ATTRS. Не знаю почему, но я обнаружил, что этот файл не работает на моей машине дословно.

После записи файла

restart usbserial 

и снова подключите устройство. Теперь по умолчанию должны быть разрешения 666.

person Andres    schedule 06.12.2011
comment
Почему минус? Это не сработало? Не ответить на вопрос? Пожалуйста, оставьте комментарий. - person Andres; 23.01.2012
comment
Возможно, понижение голоса связано с тем, что usbserial предназначен для устройства преобразования USB в последовательный порт, и он говорит об использовании libusb более низкого уровня. Однако правила udev кажутся правильным местом для изменения прав и ... на самом деле это цель udev. использование su для изменения разрешений больше похоже на проблему безопасности. - person NickSoft; 12.02.2012
comment
Этот ответ не имеет значения, так как Android не использует udev. Это очень нетипичное пользовательское пространство Linux. - person Chris Stratton; 27.01.2014

Я нашел решение без рутирования устройства.

Протестировано на Android 4.2.2 Версия ядра 3.3.39

Все, что вам нужно сделать, это добавить свое приложение в группу «usb».

Без root вы можете использовать файл разрешений в /system/etc/permissions/platform.xml

Выберите одно разрешение, которое вы не используете, например «android.permission.CAMERA».

Измените /system/etc/permissions/platform.xml следующим образом:

<permissions>
...
    <permission name="android.permission.CAMERA" >
        <group gid="camera" />
    </permission>

    <permission name="android.permission.CAMERA" >
        <group gid="usb" />
    </permission>
...
</permissions>

Итак, добавьте <uses-permission android:name="android.permission.CAMERA" /> в файл манифеста вашего приложения и наслаждайтесь libusb доступным USB!

person user3706152    schedule 04.06.2014
comment
Choose one permission you don't use => Я не Android-разработчик, но мне кажется, что это ОЧЕНЬ ПЛОХАЯ практика... - person DrakaSAN; 04.06.2014
comment
Если у вас нет root, как вы можете изменить /system/etc/permissions/platform.xml? - person Julian Cerruti; 08.01.2015
comment
На самом деле, я думаю, что это хороший метод, если я изменю разрешение /dev/bus/usb, то любое приложение сможет читать/записывать его, это небезопасно, для меня, разработчика образа системы, это хороший способ. - person kangear; 12.02.2015