USB permission obtained via android.hardware.usb does not apply to NDK

Martin Marinov picture Martin Marinov · Dec 20, 2012 · Viewed 7.3k times · Source

I was able to obtain a permission to communicate with a device via Android's USB Host API.

private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

protected void execute(Context ctxt) {
    UsbManager manager = (UsbManager) viewer.getSystemService(Context.USB_SERVICE);
    HashMap<String, UsbDevice> deviceList = manager.getDeviceList();

    UsbDevice d = null;
    for (String s : deviceList.keySet()) {
        d = deviceList.get(s);
    }

    PendingIntent mPermissionIntent = PendingIntent.getBroadcast(ctxt, 0, new Intent(ACTION_USB_PERMISSION), 0);
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    viewer.registerReceiver(mUsbReceiver, filter);

    manager.requestPermission(d, mPermissionIntent);
}

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if(device != null){
                      Log.d(TAG, "Permission granted!");
                   }
                } 
                else {
                    Log.d(TAG, "permission denied for device " + device);
                }
            }
        }
    }
};

Unfortunately that doesn't give my NDK code permission to directly communicate with this device (which is needed for libusb). Is there any way to "transfer" the permissions from Java to NDK without root?

P.S. I ended up using UNIX sockets to transfer the original File Descirptor from Java to an Android native executable (I have GNU-ed the project at https://github.com/martinmarinov/rtl_tcp_andro- ). For some people it would be even easier since they might be using NDK to connect with the device directly (not a third party app) and therefore the pointer that they use in Java may be still accessible by the NDK without having to mess around with UNIX sockets.

Answer

Lester Buck picture Lester Buck · Dec 23, 2012

There is no "transfer" of permissions possible because the Android security model demands that each application statically declare its required permissions and the user approves the permission set at install time. No dynamic permissions are supported. Each app maps to a single UID, with its statically declared permissions in the manifest. Java is not a permission boundary, and the Dalvik VM is no barrier to running native code via NDK. All the permissions must be listed in the manifest, and the apk may contain no Java (dex) code at all.

http://developer.android.com/guide/topics/security/permissions.html

http://osdir.com/ml/android-ndk/2012-09/msg00094.html