void AudioInputCubeb::UpdateDeviceList() { cubeb* cubebContext = CubebUtils::GetCubebContext(); if (!cubebContext) { return; } cubeb_device_collection *devices = nullptr; if (CUBEB_OK != cubeb_enumerate_devices(cubebContext, CUBEB_DEVICE_TYPE_INPUT, &devices)) { return; } for (auto& device_index : (*mDeviceIndexes)) { device_index = -1; // unmapped } // We keep all the device names, but wipe the mappings and rebuild them // Calculate translation from existing mDevices to new devices. Note we // never end up with less devices than before, since people have // stashed indexes. // For some reason the "fake" device for automation is marked as DISABLED, // so white-list it. mDefaultDevice = -1; for (uint32_t i = 0; i < devices->count; i++) { if (devices->device[i]->type == CUBEB_DEVICE_TYPE_INPUT && // paranoia (devices->device[i]->state == CUBEB_DEVICE_STATE_ENABLED || (devices->device[i]->state == CUBEB_DEVICE_STATE_DISABLED && devices->device[i]->friendly_name && strcmp(devices->device[i]->friendly_name, "Sine source at 440 Hz") == 0))) { auto j = mDeviceNames->IndexOf(devices->device[i]->device_id); if (j != nsTArray<nsCString>::NoIndex) { // match! update the mapping (*mDeviceIndexes)[j] = i; } else { // new device, add to the array mDeviceIndexes->AppendElement(i); mDeviceNames->AppendElement(devices->device[i]->device_id); } if (devices->device[i]->preferred & CUBEB_DEVICE_PREF_VOICE) { // There can be only one... we hope NS_ASSERTION(mDefaultDevice == -1, "multiple default cubeb input devices!"); mDefaultDevice = i; } } } StaticMutexAutoLock lock(sMutex); // swap state if (mDevices) { cubeb_device_collection_destroy(mDevices); } mDevices = devices; }
TEST(cubeb, stable_devid) { /* Test that the devid field of cubeb_device_info is stable * (ie. compares equal) over two invocations of * cubeb_enumerate_devices(). */ int r; cubeb * ctx; cubeb_device_collection first; cubeb_device_collection second; cubeb_device_type all_devices = (cubeb_device_type) (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT); size_t n; r = common_init(&ctx, "test_sanity"); ASSERT_EQ(r, CUBEB_OK); ASSERT_NE(ctx, nullptr); r = cubeb_enumerate_devices(ctx, all_devices, &first); if (r == CUBEB_ERROR_NOT_SUPPORTED) return; ASSERT_EQ(r, CUBEB_OK); r = cubeb_enumerate_devices(ctx, all_devices, &second); ASSERT_EQ(r, CUBEB_OK); ASSERT_EQ(first.count, second.count); for (n = 0; n < first.count; n++) { ASSERT_EQ(first.device[n].devid, second.device[n].devid); } r = cubeb_device_collection_destroy(ctx, &first); ASSERT_EQ(r, CUBEB_OK); r = cubeb_device_collection_destroy(ctx, &second); ASSERT_EQ(r, CUBEB_OK); cubeb_destroy(ctx); }