Как предоставить /dev/bus/usb разрешения для приложений libusb android?
Я разрабатываю приложение, использующее libusb через jni.
это приложение в настоящее время предназначено только для корневых, usb-host
Android 3+.
сценарий выглядит следующим образом:
<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 Activities, выполняемый простыми пользователями.
это означает, что вся коммуникация usb должна выполняться с внутренней стороны.
У меня есть все, чтобы работать нормально, за исключением одной проблемы - разрешения usb:
разрешения по умолчанию для /dev/bus/usb/entries (0660, uid = root, gid = usb).
очевидно, что стандартный java-процесс, выполняющий собственный код, не удовлетворяет ни одному из вышеуказанных требований, заставляя меня "chmod 666" использовать соответствующую запись /dev, чтобы эта работа работала.
это решение не так хорошо, хотя, потому что оно не выдерживает перезагрузки или отключает/переустанавливает устройство (разрешения возвращаются к 0660).
Решение, которое я ищу:
- пережить перезагрузку/перегрузку
- должен быть установлен ~ один раз корнем и не должен каждый раз беспокоить пользователя для получения разрешений
- быть общим и запускаться на всех (/most) машинах Android 3+.
- [не обязательно] предоставляет минимальные учетные данные
направления, о которых я думал:
- изменение разрешений в /init.rc или/ueventd.rc → при каждой перезагрузке обойдется
- установка usbfs/proc/bus/usb с devmode = 0666 → сохраняется при повторной загрузке, но не перезагружается
- чтобы мой процесс присоединился к группе "usb"? → Я пробовал android.permission.ACCESS_USB, но он не работает/поддерживается...:/
любые идеи?: -)
спасибо!
Ответы
Ответ 1
У меня такая же проблема, и я решаю, как это делается в 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;
}
Ответ 2
Есть некоторый метод от команды разработчиков libusb. для моего случая я выбираю первый метод.
from: https://github.com/libusb/libusb/blob/master/android/README
Разрешения времени выполнения:
Конфигурация системы по умолчанию на большинстве устройств Android не позволит доступ к USB-устройствам. Существует несколько вариантов изменения этого параметра.
Если у вас есть контроль над системным изображением, вы можете изменить ueventd.rc, используемый для изменения разрешений на /DEV/ автобус/USB//. При использовании этого подхода целесообразно создайте новое разрешение Android для защиты доступа к этим файлам. Это не рекомендуется предоставлять всем приложениям права на чтение и запись к этим файлам.
Для корневых устройств код с использованием libusb может выполняться как root используя команду "su". Альтернативой было бы использование "su", команду изменить разрешения на соответствующий /dev/bus/usb/ файлы.
Пользователи сообщили об успешном использовании android.hardware.usb.UsbManager запросить разрешение на использование UsbDevice, а затем открыть устройство. Трудности в этом методе заключаются в том, что нет гарантии что он будет продолжать работать в будущих версиях Android, он требует вызова Java API и кода для соответствия каждому android.hardware.usb.UsbDevice для libusb_device.
Ответ 3
Изменить:
После повторного чтения вопроса ясно, что я неправильно понял, что на хост-машине был Android. Поскольку udev не существует в Android, ответ ниже не отвечает на вопрос. Я оставляю этот ответ здесь, на случай, если кто-то ищет информацию о том, как распознавать Android-устройства на не-Android-хост-компьютере Linux.
Редактировать конец
Разрешения по умолчанию для этих драйверов (/dev/bus/usb/###/###) определяются udev. В частности, он анализирует конфигурационные файлы в /etc/udev/rules.d и/lib/udev/rules.d в числовом порядке, чтобы определить значения по умолчанию.
Чтобы переопределить значения по умолчанию, вам необходимо создать свой собственный файл udev.rules. Для этого вам потребуется идентификатор поставщика устройства, которому вы хотите предоставить разрешение. lsusb распечатает идентификатор устройства для любого конкретного устройства, и если вы хотите получить список всех поставщиков, вы можете попробовать this.
Итак, в файле /etc/udev/rules.d/99-android.rules введите следующую строку для каждого поставщика, которого вы хотите поддерживать:
SUBSYSTEM=="usb", ATTRS{idVendor}=="04e8", MODE:="0666"
Обратите внимание, что в приведенном выше примере они используют = вместо: = и SYSFS вместо ATTRS. Я не знаю почему, но я обнаружил, что этот файл не работает дословно на моей машине.
После записи файла
restart usbserial
и снова подключите устройство. Теперь он должен установить 666 разрешений.
Ответ 4
Я нашел решение без использования устройства.
Протестировано на 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!