nExtCamera / libuac

The USB Audio Class user-space driver
Apache License 2.0
3 stars 0 forks source link

Opens the audio device failed. Access denied (insufficient permissions) in libUSB #2

Open staneychan opened 4 months ago

staneychan commented 4 months ago

Platform: android 11 Arch: arm64-v8a libUSB version: 1.0.27 libuac version: Branches main

Hi , i had write a test app reference example code for my audio device which has both MIC and speaker. But it return fail (error: libusb_open() LIBUSB_ERROR_ACCESS) when i try to open the device. I had checked the libUSB error code and find out the result of insufficient permissions:

/** Access denied (insufficient permissions) */ LIBUSB_ERROR_ACCESS = -3 However, I have already added the corresponding authorization.

<uses-feature android:name="android.hardware.microphone" android:required="true" />
<uses-feature android:name="android.hardware.audio.output" android:required="true" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

private void requestRecordPermission(){
    ActivityCompat.requestPermissions(
            this,
            new String[]{Manifest.permission.RECORD_AUDIO},
            AUDIO_EFFECT_REQUEST);
}

But it woks fine when i use the android open source demo oboe Here is my audio device properties:

/proc/asound/card1 # cat stream0 Linux 4.4.143 with ff400000.usb audio A07 at usb-xhci-hcd.1.auto-1.3, high spe : USB Audio

Playback: Status: Stop Interface 2 Altset 1 Format: S16_LE Channels: 2 Endpoint: 4 OUT (ADAPTIVE) Rates: 48000 Data packet interval: 1000 us

Capture: Status: Stop Interface 3 Altset 1 Format: S16_LE Channels: 2 Endpoint: 3 IN (ASYNC) Rates: 48000 Data packet interval: 1000 us

This is the test source code:

define LOGV(format, ...) android_log_print(ANDROID_LOG_VERBOSE, "cjb", format, ##VA_ARGS__)

std::shared_ptr streamHandle;

static void cb(uint8_t *data, int size) { LOGV("PCM data:%d ->%08x", size, data); }

void initUac(int numChannels, int sampleRate){ std::shared_ptr ctx; try { ctx = uac::uac_context::create();

    std::vector<std::shared_ptr<uac::uac_device>> devices = ctx->query_all_devices();
    LOGV("Available UAC devices: %ld", devices.size());

    if (devices.empty()) {
        LOGV("No UAC device available!");
        goto cleanup;
    }
    for(auto device : devices){
        LOGV("AUDIO HW(vid:pid):%x:%x", device->get_vid(), device->get_pid());
    }
    auto dev = devices[0];
    auto routes = dev->query_audio_routes(uac::UAC_TERMINAL_EXTERNAL_UNDEFINED, uac::UAC_TERMINAL_USB_STREAMING);
    if (routes.empty()) {
        LOGV("No USB streaming output!");
        goto cleanup;
    }

    auto& route = routes[0];

    auto& streamIf = dev->get_stream_interface(route);

    auto audio_config = streamIf.query_config_uncompressed(uac::UAC_FORMAT_DATA_PCM, numChannels, sampleRate);
    if (!audio_config) {
        LOGV("Unable to select 48kHz 1-CH audio config");
        goto cleanup;
    }

    LOGV("Open device...");
    auto devHandle = dev->open();

    LOGV("Is Master Muted: %d",  devHandle->is_master_muted(route));
    LOGV("Master volume: %d",  devHandle->get_feature_master_volume(route));

    LOGV("Start streaming...");
    streamHandle = devHandle->start_streaming(streamIf, *audio_config, &cb);

} catch(const std::exception &e) {
    LOGV("error: %s", e.what());
}
cleanup:
LOGV("done cleanup");
streamHandle.reset();

}

extern "C" JNIEXPORT void JNICALL Java_com_test_uac_NativeLib_testUAC( JNIEnv env, jobject / this */) { initUac(2, 48000); }

jksiezni commented 4 months ago

Hello, on Android to open the USB device you would need a root permission. Instead, you should use uac_context::wrap() function to wrap an already opened usb connection. Also, see for more details: https://developer.android.com/develop/connectivity/usb/host

staneychan commented 4 months ago

Hello, on Android to open the USB device you would need a root permission. Instead, you should use uac_context::wrap() function to wrap an already opened usb connection. Also, see for more details: https://developer.android.com/develop/connectivity/usb/host

thanks a lot buddy~~ I use the libusb version of 1.0.19 and the demo app can access the audio device without 'root' permission. But the usb permission must be required via UsbManager.