Как да дам разрешения на /dev/bus/usb за libusb приложения за Android?

Разработвам приложение, което използва libusb чрез jni. това приложение в момента е насочено само към вкоренени, usb-хост машини с 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, изпълнявани от обикновени потребители.

това означава, че цялата 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, той изисква извикване на Java API и изпълнение на код, за да съответства на всяко 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