Check DeviceType before using them

This commit is contained in:
Chun-Min Chang 2019-05-01 08:49:48 -07:00
Родитель c3f669d354
Коммит 69b5b3d818
2 изменённых файлов: 69 добавлений и 50 удалений

Просмотреть файл

@ -46,12 +46,6 @@ use std::sync::{Arc, Mutex};
// They are actually same. Maybe it's better to use only one
// of them so code reader don't get confused about their types.
// 2. Maybe we can merge `io_side` and `DeviceType`.
// 3. Add assertions like:
// `assert!(devtype == DeviceType::INPUT || devtype == DeviceType::OUTPUT)`
// if the function is only called for either input or output. Then
// `if (devtype == DeviceType::INPUT) { ... } else { ... }`
// makes sense. In fact, for those variables depends on DeviceType, we can
// implement a `From` trait to get them.
const NO_ERR: OSStatus = 0;
@ -729,14 +723,13 @@ fn audiounit_get_acceptable_latency_range() -> Result<(AudioValueRange)> {
}
fn audiounit_get_default_device_id(devtype: DeviceType) -> AudioObjectID {
let adr;
if devtype == DeviceType::OUTPUT {
adr = &DEFAULT_OUTPUT_DEVICE_PROPERTY_ADDRESS;
} else if devtype == DeviceType::INPUT {
adr = &DEFAULT_INPUT_DEVICE_PROPERTY_ADDRESS;
assert!(devtype == DeviceType::INPUT || devtype == DeviceType::OUTPUT);
let adr = if devtype == DeviceType::OUTPUT {
&DEFAULT_OUTPUT_DEVICE_PROPERTY_ADDRESS
} else {
return kAudioObjectUnknown;
}
&DEFAULT_INPUT_DEVICE_PROPERTY_ADDRESS
};
let mut devid: AudioDeviceID = kAudioObjectUnknown;
let mut size = mem::size_of::<AudioDeviceID>();
@ -1882,12 +1875,16 @@ fn audiounit_get_device_presentation_latency(
dev + stream
}
// TODO: Put dev_info in Ok.
// TODO:
// 1. Put dev_info in Ok.
// 2. What if the device is a in-out device
fn audiounit_create_device_from_hwdev(
dev_info: &mut ffi::cubeb_device_info,
devid: AudioObjectID,
devtype: DeviceType,
) -> Result<()> {
assert!(devtype == DeviceType::INPUT || devtype == DeviceType::OUTPUT);
let mut adr = AudioObjectPropertyAddress {
mSelector: 0,
mScope: 0,
@ -1895,13 +1892,11 @@ fn audiounit_create_device_from_hwdev(
};
let mut size: usize = 0;
if devtype == DeviceType::OUTPUT {
adr.mScope = kAudioDevicePropertyScopeOutput;
} else if devtype == DeviceType::INPUT {
adr.mScope = kAudioDevicePropertyScopeInput;
adr.mScope = if devtype == DeviceType::OUTPUT {
kAudioDevicePropertyScopeOutput
} else {
return Err(Error::error());
}
kAudioDevicePropertyScopeInput
};
let ch = audiounit_get_channel_count(devid, adr.mScope);
if ch == 0 {
@ -1996,10 +1991,8 @@ fn audiounit_create_device_from_hwdev(
// `devtype.into()` to get `ffi::CUBEB_DEVICE_TYPE_*`.
dev_info.device_type = if devtype == DeviceType::OUTPUT {
ffi::CUBEB_DEVICE_TYPE_OUTPUT
} else if devtype == DeviceType::INPUT {
ffi::CUBEB_DEVICE_TYPE_INPUT
} else {
ffi::CUBEB_DEVICE_TYPE_UNKNOWN
ffi::CUBEB_DEVICE_TYPE_INPUT
};
dev_info.state = ffi::CUBEB_DEVICE_STATE_ENABLED;
dev_info.preferred = if devid == audiounit_get_default_device_id(devtype) {
@ -2075,6 +2068,8 @@ fn audiounit_device_destroy(device: &mut ffi::cubeb_device_info) {
}
fn audiounit_get_devices_of_type(devtype: DeviceType) -> Vec<AudioObjectID> {
assert!(devtype.intersects(DeviceType::INPUT | DeviceType::OUTPUT));
let mut size: usize = 0;
let mut ret = audio_object_get_property_data_size(
kAudioObjectSystemObject,
@ -2119,8 +2114,6 @@ fn audiounit_get_devices_of_type(devtype: DeviceType) -> Vec<AudioObjectID> {
return devices;
}
// FIXIT: This is wrong. We will use output scope when devtype
// is unknown. Change it after C version is updated!
let scope = if devtype == DeviceType::INPUT {
kAudioDevicePropertyScopeInput
} else {

Просмотреть файл

@ -634,16 +634,6 @@ fn test_get_acceptable_latency_range() {
// ------------------------------------
#[test]
fn test_get_default_device_id() {
// Invalid types:
assert_eq!(
audiounit_get_default_device_id(DeviceType::UNKNOWN),
kAudioObjectUnknown,
);
assert_eq!(
audiounit_get_default_device_id(DeviceType::INPUT | DeviceType::OUTPUT),
kAudioObjectUnknown,
);
if test_get_default_device(Scope::Input).is_some() {
assert_ne!(
audiounit_get_default_device_id(DeviceType::INPUT),
@ -659,6 +649,24 @@ fn test_get_default_device_id() {
}
}
#[test]
#[should_panic]
fn test_get_default_device_id_with_unknown_type() {
assert_eq!(
audiounit_get_default_device_id(DeviceType::UNKNOWN),
kAudioObjectUnknown,
);
}
#[test]
#[should_panic]
fn test_get_default_device_id_with_inout_type() {
assert_eq!(
audiounit_get_default_device_id(DeviceType::INPUT | DeviceType::OUTPUT),
kAudioObjectUnknown,
);
}
// convert_channel_layout
// ------------------------------------
#[test]
@ -2275,9 +2283,7 @@ fn test_create_device_from_hwdev() {
let is_input = test_device_in_scope(device, Scope::Input);
let is_output = test_device_in_scope(device, Scope::Output);
let mut results = test_create_device_from_hwdev_by_device(device);
assert_eq!(results.len(), 4);
// Unknown device type:
assert_eq!(results.pop_front().unwrap().unwrap_err(), Error::error());
assert_eq!(results.len(), 2);
// Input device type:
if is_input {
check_device_info_by_device(
@ -2298,9 +2304,6 @@ fn test_create_device_from_hwdev() {
} else {
assert_eq!(results.pop_front().unwrap().unwrap_err(), Error::error());
}
// In-out device type:
// FIXIT: What if the device is a in-out device ?
assert_eq!(results.pop_front().unwrap().unwrap_err(), Error::error());
} else {
println!("No device for {:?}.", scope);
}
@ -2309,12 +2312,7 @@ fn test_create_device_from_hwdev() {
fn test_create_device_from_hwdev_by_device(
id: AudioObjectID,
) -> VecDeque<std::result::Result<ffi::cubeb_device_info, Error>> {
let dev_types = [
DeviceType::UNKNOWN,
DeviceType::INPUT,
DeviceType::OUTPUT,
DeviceType::INPUT | DeviceType::OUTPUT,
];
let dev_types = [DeviceType::INPUT, DeviceType::OUTPUT];
let mut results = VecDeque::new();
for dev_type in dev_types.iter() {
let mut info = ffi::cubeb_device_info::default();
@ -2369,6 +2367,30 @@ fn test_create_device_from_hwdev() {
}
}
#[test]
#[should_panic]
fn test_create_device_from_hwdev_unknown_type() {
let mut info = ffi::cubeb_device_info::default();
assert!(audiounit_create_device_from_hwdev(
&mut info,
kAudioObjectUnknown,
DeviceType::UNKNOWN
)
.is_err());
}
#[test]
#[should_panic]
fn test_create_device_from_hwdev_inout_type() {
let mut info = ffi::cubeb_device_info::default();
assert!(audiounit_create_device_from_hwdev(
&mut info,
kAudioObjectUnknown,
DeviceType::INPUT | DeviceType::OUTPUT
)
.is_err());
}
// is_aggregate_device
// ------------------------------------
#[test]
@ -2457,9 +2479,6 @@ fn test_device_destroy_empty_device() {
fn test_get_devices_of_type() {
use std::collections::HashSet;
// FIXIT: Open this assertion after C version is updated.
// let no_devs = audiounit_get_devices_of_type(DeviceType::UNKNOWN);
// assert!(no_devs.is_empty());
let all_devices = audiounit_get_devices_of_type(DeviceType::INPUT | DeviceType::OUTPUT);
let input_devices = audiounit_get_devices_of_type(DeviceType::INPUT);
let output_devices = audiounit_get_devices_of_type(DeviceType::OUTPUT);
@ -2484,6 +2503,13 @@ fn test_get_devices_of_type() {
assert_eq!(all_devices, union_devices);
}
#[test]
#[should_panic]
fn test_get_devices_of_type_unknown() {
let no_devs = audiounit_get_devices_of_type(DeviceType::UNKNOWN);
assert!(no_devs.is_empty());
}
// add_devices_changed_listener
// ------------------------------------
#[test]