Bug 1569090 - Vendor Rust after AudioIPC update. r=chunmin
☠☠ backed out by 6a96fdc69cc1 ☠ ☠
authorMatthew Gregan <kinetik@flim.org>
Fri, 26 Jul 2019 16:51:51 +0000
changeset 548743 6aa27e77e38f25d65fb4b534051765d03db5ed8b
parent 548742 5251efcd4ac146ad2291fe38bd67824033257d86
child 548744 d80347b0587968cc242368b124d88e7bc361a1e2
push id2165
push userffxbld-merge
push dateMon, 14 Oct 2019 16:30:58 +0000
treeherdermozilla-release@0eae18af659f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerschunmin
bugs1569090
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1569090 - Vendor Rust after AudioIPC update. r=chunmin Differential Revision: https://phabricator.services.mozilla.com/D39454
Cargo.lock
third_party/rust/cubeb-backend/.cargo-checksum.json
third_party/rust/cubeb-backend/Cargo.toml
third_party/rust/cubeb-backend/src/capi.rs
third_party/rust/cubeb-backend/src/traits.rs
third_party/rust/cubeb-core/.cargo-checksum.json
third_party/rust/cubeb-core/Cargo.toml
third_party/rust/cubeb-core/src/stream.rs
third_party/rust/cubeb-sys/.cargo-checksum.json
third_party/rust/cubeb-sys/Cargo.toml
third_party/rust/cubeb-sys/libcubeb/CMakeLists.txt
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/README.md
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindASan.cmake
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindMSan.cmake
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindSanitizers.cmake
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindTSan.cmake
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindUBSan.cmake
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/sanitize-helpers.cmake
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/tests/CMakeLists.txt
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/tests/asan_test.cpp
third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/tests/shortest.ext.test.cpp
third_party/rust/cubeb-sys/libcubeb/cmake/toolchain-cross-android.cmake
third_party/rust/cubeb-sys/libcubeb/cmake/toolchain-cross-mingw.cmake
third_party/rust/cubeb-sys/libcubeb/include/cubeb/cubeb.h
third_party/rust/cubeb-sys/libcubeb/src/android/sles_definitions.h
third_party/rust/cubeb-sys/libcubeb/src/cubeb.c
third_party/rust/cubeb-sys/libcubeb/src/cubeb_audiounit.cpp
third_party/rust/cubeb-sys/libcubeb/src/cubeb_mixer.cpp
third_party/rust/cubeb-sys/libcubeb/src/cubeb_opensl.c
third_party/rust/cubeb-sys/libcubeb/src/cubeb_pulse.c
third_party/rust/cubeb-sys/libcubeb/src/cubeb_resampler.cpp
third_party/rust/cubeb-sys/libcubeb/src/cubeb_sndio.c
third_party/rust/cubeb-sys/libcubeb/src/cubeb_sun.c
third_party/rust/cubeb-sys/libcubeb/src/cubeb_wasapi.cpp
third_party/rust/cubeb-sys/libcubeb/src/cubeb_winmm.c
third_party/rust/cubeb-sys/libcubeb/test/common.h
third_party/rust/cubeb-sys/libcubeb/test/test_audio.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_callback_ret.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_deadlock.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_device_changed_callback.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_devices.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_duplex.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_latency.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_loopback.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_overload_callback.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_record.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_ring_buffer.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_sanity.cpp
third_party/rust/cubeb-sys/libcubeb/test/test_tone.cpp
third_party/rust/cubeb-sys/libcubeb/tools/cubeb-test.cpp
third_party/rust/cubeb-sys/src/stream.rs
third_party/rust/cubeb/.cargo-checksum.json
third_party/rust/cubeb/Cargo.toml
third_party/rust/fs2/.cargo-checksum.json
third_party/rust/fs2/Cargo.toml
third_party/rust/fs2/LICENSE-APACHE
third_party/rust/fs2/LICENSE-MIT
third_party/rust/fs2/README.md
third_party/rust/fs2/src/lib.rs
third_party/rust/fs2/src/unix.rs
third_party/rust/fs2/src/windows.rs
third_party/rust/lazycell-0.4.0/.cargo-checksum.json
third_party/rust/lazycell-0.4.0/CHANGELOG.md
third_party/rust/lazycell-0.4.0/Cargo.toml
third_party/rust/lazycell-0.4.0/LICENSE-APACHE
third_party/rust/lazycell-0.4.0/LICENSE-MIT
third_party/rust/lazycell-0.4.0/README.md
third_party/rust/lazycell-0.4.0/src/lib.rs
third_party/rust/log-0.3.9/.cargo-checksum.json
third_party/rust/log-0.3.9/.travis.yml
third_party/rust/log-0.3.9/Cargo.toml
third_party/rust/log-0.3.9/LICENSE-APACHE
third_party/rust/log-0.3.9/LICENSE-MIT
third_party/rust/log-0.3.9/README.md
third_party/rust/log-0.3.9/appveyor.yml
third_party/rust/log-0.3.9/src/lib.rs
third_party/rust/log-0.3.9/src/macros.rs
third_party/rust/memmap-0.5.2/.appveyor.yml
third_party/rust/memmap-0.5.2/.cargo-checksum.json
third_party/rust/memmap-0.5.2/.travis.yml
third_party/rust/memmap-0.5.2/Cargo.toml
third_party/rust/memmap-0.5.2/LICENSE-APACHE
third_party/rust/memmap-0.5.2/LICENSE-MIT
third_party/rust/memmap-0.5.2/README.md
third_party/rust/memmap-0.5.2/ci/install.sh
third_party/rust/memmap-0.5.2/ci/script.sh
third_party/rust/memmap-0.5.2/examples/cat.rs
third_party/rust/memmap-0.5.2/src/lib.rs
third_party/rust/memmap-0.5.2/src/unix.rs
third_party/rust/memmap-0.5.2/src/windows.rs
third_party/rust/memmap-0.6.2/.cargo-checksum.json
third_party/rust/memmap-0.6.2/Cargo.toml
third_party/rust/memmap-0.6.2/LICENSE-APACHE
third_party/rust/memmap-0.6.2/LICENSE-MIT
third_party/rust/memmap-0.6.2/README.md
third_party/rust/memmap-0.6.2/ci/install.sh
third_party/rust/memmap-0.6.2/ci/script.sh
third_party/rust/memmap-0.6.2/examples/cat.rs
third_party/rust/memmap-0.6.2/src/lib.rs
third_party/rust/memmap-0.6.2/src/unix.rs
third_party/rust/memmap-0.6.2/src/windows.rs
third_party/rust/memmap/.cargo-checksum.json
third_party/rust/memmap/Cargo.toml
third_party/rust/memmap/ci/install.sh
third_party/rust/memmap/ci/script.sh
third_party/rust/memmap/examples/cat.rs
third_party/rust/memmap/src/lib.rs
third_party/rust/memmap/src/unix.rs
third_party/rust/memmap/src/windows.rs
third_party/rust/mio-named-pipes/.cargo-checksum.json
third_party/rust/mio-named-pipes/Cargo.toml
third_party/rust/mio-named-pipes/README.md
third_party/rust/mio-named-pipes/src/lib.rs
third_party/rust/mio-named-pipes/tests/smoke.rs
third_party/rust/mio/.cargo-checksum.json
third_party/rust/mio/CHANGELOG.md
third_party/rust/mio/Cargo.toml
third_party/rust/mio/README.md
third_party/rust/mio/appveyor.yml
third_party/rust/mio/azure-pipelines.yml
third_party/rust/mio/ci/azure-cross-compile.yml
third_party/rust/mio/ci/azure-deploy-docs.yml
third_party/rust/mio/ci/azure-install-rust.yml
third_party/rust/mio/ci/azure-test-stable.yml
third_party/rust/mio/ci/docker/aarch64-linux-android/Dockerfile
third_party/rust/mio/ci/docker/aarch64-linux-android/accept-licenses.sh
third_party/rust/mio/ci/docker/aarch64-linux-android/cargo_config
third_party/rust/mio/ci/docker/aarch64-linux-android/install-ndk.sh
third_party/rust/mio/ci/docker/aarch64-linux-android/install-sdk.sh
third_party/rust/mio/ci/docker/arm-linux-androideabi/Dockerfile
third_party/rust/mio/ci/docker/arm-linux-androideabi/accept-licenses.sh
third_party/rust/mio/ci/docker/arm-linux-androideabi/cargo_config
third_party/rust/mio/ci/docker/arm-linux-androideabi/install-ndk.sh
third_party/rust/mio/ci/docker/arm-linux-androideabi/install-sdk.sh
third_party/rust/mio/ci/run-docker.sh
third_party/rust/mio/ci/run.sh
third_party/rust/mio/ci/trust/install.sh
third_party/rust/mio/ci/trust/script.sh
third_party/rust/mio/src/channel.rs
third_party/rust/mio/src/deprecated/event_loop.rs
third_party/rust/mio/src/deprecated/unix.rs
third_party/rust/mio/src/event_imp.rs
third_party/rust/mio/src/lazycell.rs
third_party/rust/mio/src/lib.rs
third_party/rust/mio/src/net/tcp.rs
third_party/rust/mio/src/net/udp.rs
third_party/rust/mio/src/poll.rs
third_party/rust/mio/src/sys/unix/epoll.rs
third_party/rust/mio/src/sys/unix/eventedfd.rs
third_party/rust/mio/src/sys/unix/kqueue.rs
third_party/rust/mio/src/sys/unix/mod.rs
third_party/rust/mio/src/sys/unix/ready.rs
third_party/rust/mio/src/sys/unix/tcp.rs
third_party/rust/mio/src/sys/unix/udp.rs
third_party/rust/mio/src/sys/unix/uds.rs
third_party/rust/mio/src/sys/unix/uio.rs
third_party/rust/mio/src/sys/windows/tcp.rs
third_party/rust/mio/src/timer.rs
third_party/rust/mio/test/mod.rs
third_party/rust/mio/test/test_battery.rs
third_party/rust/mio/test/test_close_on_drop.rs
third_party/rust/mio/test/test_custom_evented.rs
third_party/rust/mio/test/test_echo_server.rs
third_party/rust/mio/test/test_multicast.rs
third_party/rust/mio/test/test_notify.rs
third_party/rust/mio/test/test_register_deregister.rs
third_party/rust/mio/test/test_tcp.rs
third_party/rust/mio/test/test_tcp_level.rs
third_party/rust/mio/test/test_tcp_shutdown.rs
third_party/rust/mio/test/test_tick.rs
third_party/rust/mio/test/test_udp_socket.rs
third_party/rust/mio/test/test_uds_shutdown.rs
third_party/rust/mio/test/test_unix_echo_server.rs
third_party/rust/mio/test/test_unix_pass_fd.rs
third_party/rust/mio/test/test_write_then_drop.rs
third_party/rust/miow-0.2.1/.cargo-checksum.json
third_party/rust/miow-0.2.1/Cargo.toml
third_party/rust/miow-0.2.1/LICENSE-APACHE
third_party/rust/miow-0.2.1/LICENSE-MIT
third_party/rust/miow-0.2.1/README.md
third_party/rust/miow-0.2.1/appveyor.yml
third_party/rust/miow-0.2.1/src/handle.rs
third_party/rust/miow-0.2.1/src/iocp.rs
third_party/rust/miow-0.2.1/src/lib.rs
third_party/rust/miow-0.2.1/src/net.rs
third_party/rust/miow-0.2.1/src/overlapped.rs
third_party/rust/miow-0.2.1/src/pipe.rs
third_party/rust/miow/.cargo-checksum.json
third_party/rust/miow/Cargo.toml
third_party/rust/miow/README.md
third_party/rust/miow/src/handle.rs
third_party/rust/miow/src/iocp.rs
third_party/rust/miow/src/lib.rs
third_party/rust/miow/src/net.rs
third_party/rust/miow/src/overlapped.rs
third_party/rust/miow/src/pipe.rs
third_party/rust/redox_syscall/.cargo-checksum.json
third_party/rust/redox_syscall/Cargo.toml
third_party/rust/redox_syscall/README.md
third_party/rust/redox_syscall/src/arch/aarch64.rs
third_party/rust/redox_syscall/src/arch/nonredox.rs
third_party/rust/redox_syscall/src/arch/x86_64.rs
third_party/rust/redox_syscall/src/call.rs
third_party/rust/redox_syscall/src/data.rs
third_party/rust/redox_syscall/src/error.rs
third_party/rust/redox_syscall/src/flag.rs
third_party/rust/redox_syscall/src/io/dma.rs
third_party/rust/redox_syscall/src/io/mmio.rs
third_party/rust/redox_syscall/src/lib.rs
third_party/rust/redox_syscall/src/number.rs
third_party/rust/redox_syscall/src/scheme.rs
third_party/rust/redox_syscall/src/scheme/generate.sh
third_party/rust/redox_syscall/src/scheme/mod.rs
third_party/rust/redox_syscall/src/scheme/scheme.rs
third_party/rust/redox_syscall/src/scheme/scheme_block.rs
third_party/rust/redox_syscall/src/scheme/scheme_block_mut.rs
third_party/rust/redox_syscall/src/scheme/scheme_mut.rs
third_party/rust/redox_syscall/src/tests.rs
third_party/rust/socket2/.cargo-checksum.json
third_party/rust/socket2/Cargo.toml
third_party/rust/socket2/LICENSE-APACHE
third_party/rust/socket2/LICENSE-MIT
third_party/rust/socket2/README.md
third_party/rust/socket2/src/lib.rs
third_party/rust/socket2/src/sockaddr.rs
third_party/rust/socket2/src/socket.rs
third_party/rust/socket2/src/sys/redox/mod.rs
third_party/rust/socket2/src/sys/unix.rs
third_party/rust/socket2/src/sys/windows.rs
third_party/rust/socket2/src/utils.rs
third_party/rust/tokio-core/.cargo-checksum.json
third_party/rust/tokio-core/Cargo.toml
third_party/rust/tokio-core/LICENSE-APACHE
third_party/rust/tokio-core/LICENSE-MIT
third_party/rust/tokio-core/README.md
third_party/rust/tokio-core/appveyor.yml
third_party/rust/tokio-core/benches/latency.rs
third_party/rust/tokio-core/benches/mio-ops.rs
third_party/rust/tokio-core/benches/tcp.rs
third_party/rust/tokio-core/examples/README.md
third_party/rust/tokio-core/examples/chat.rs
third_party/rust/tokio-core/examples/compress.rs
third_party/rust/tokio-core/examples/connect.rs
third_party/rust/tokio-core/examples/echo-threads.rs
third_party/rust/tokio-core/examples/echo-udp.rs
third_party/rust/tokio-core/examples/echo.rs
third_party/rust/tokio-core/examples/hello.rs
third_party/rust/tokio-core/examples/proxy.rs
third_party/rust/tokio-core/examples/sink.rs
third_party/rust/tokio-core/examples/tinydb.rs
third_party/rust/tokio-core/examples/tinyhttp.rs
third_party/rust/tokio-core/examples/udp-codec.rs
third_party/rust/tokio-core/src/channel.rs
third_party/rust/tokio-core/src/io/copy.rs
third_party/rust/tokio-core/src/io/flush.rs
third_party/rust/tokio-core/src/io/frame.rs
third_party/rust/tokio-core/src/io/mod.rs
third_party/rust/tokio-core/src/io/read.rs
third_party/rust/tokio-core/src/io/read_exact.rs
third_party/rust/tokio-core/src/io/read_to_end.rs
third_party/rust/tokio-core/src/io/read_until.rs
third_party/rust/tokio-core/src/io/split.rs
third_party/rust/tokio-core/src/io/window.rs
third_party/rust/tokio-core/src/io/write_all.rs
third_party/rust/tokio-core/src/lib.rs
third_party/rust/tokio-core/src/net/mod.rs
third_party/rust/tokio-core/src/net/tcp.rs
third_party/rust/tokio-core/src/net/udp/frame.rs
third_party/rust/tokio-core/src/net/udp/mod.rs
third_party/rust/tokio-core/src/reactor/interval.rs
third_party/rust/tokio-core/src/reactor/io_token.rs
third_party/rust/tokio-core/src/reactor/mod.rs
third_party/rust/tokio-core/src/reactor/poll_evented.rs
third_party/rust/tokio-core/src/reactor/poll_evented2.rs
third_party/rust/tokio-core/src/reactor/timeout.rs
third_party/rust/tokio-core/tests/buffered.rs
third_party/rust/tokio-core/tests/chain.rs
third_party/rust/tokio-core/tests/echo.rs
third_party/rust/tokio-core/tests/interval.rs
third_party/rust/tokio-core/tests/limit.rs
third_party/rust/tokio-core/tests/line-frames.rs
third_party/rust/tokio-core/tests/pipe-hup.rs
third_party/rust/tokio-core/tests/spawn.rs
third_party/rust/tokio-core/tests/stream-buffered.rs
third_party/rust/tokio-core/tests/tcp.rs
third_party/rust/tokio-core/tests/timeout.rs
third_party/rust/tokio-core/tests/udp.rs
third_party/rust/tokio-named-pipes/.cargo-checksum.json
third_party/rust/tokio-named-pipes/Cargo.toml
third_party/rust/tokio-named-pipes/LICENSE-APACHE
third_party/rust/tokio-named-pipes/LICENSE-MIT
third_party/rust/tokio-named-pipes/README.md
third_party/rust/tokio-named-pipes/appveyor.yml
third_party/rust/tokio-named-pipes/src/lib.rs
third_party/rust/tokio-uds-0.1.7/.cargo-checksum.json
third_party/rust/tokio-uds-0.1.7/Cargo.toml
third_party/rust/tokio-uds-0.1.7/LICENSE-APACHE
third_party/rust/tokio-uds-0.1.7/LICENSE-MIT
third_party/rust/tokio-uds-0.1.7/README.md
third_party/rust/tokio-uds-0.1.7/src/frame.rs
third_party/rust/tokio-uds-0.1.7/src/lib.rs
third_party/rust/tokio-uds-0.1.7/src/ucred.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -96,68 +96,63 @@ dependencies = [
 
 [[package]]
 name = "audioipc"
 version = "0.2.4"
 dependencies = [
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "cubeb 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio-named-pipes 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-named-pipes 0.1.6 (git+https://github.com/alexcrichton/mio-named-pipes)",
+ "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-named-pipes 0.2.0 (git+https://github.com/NikVolf/tokio-named-pipes?branch=stable)",
+ "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "audioipc-client"
 version = "0.4.0"
 dependencies = [
  "audio_thread_priority 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "audioipc 0.2.4",
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "cubeb-backend 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb-backend 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "audioipc-server"
 version = "0.2.3"
 dependencies = [
  "audio_thread_priority 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "audioipc 0.2.4",
- "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "cubeb-core 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb-core 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "authenticator"
 version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -792,65 +787,65 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cubeb"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cubeb-core 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cubeb-core 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cubeb-backend"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cubeb-core 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cubeb-core 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cubeb-core"
-version = "0.5.4"
+version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cubeb-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb-sys 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cubeb-coreaudio"
 version = "0.1.0"
 dependencies = [
  "atomic 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "coreaudio-sys-utils 0.1.0",
- "cubeb-backend 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb-backend 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cubeb-pulse"
 version = "0.2.0"
 dependencies = [
- "cubeb-backend 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb-backend 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulse 0.2.0",
  "pulse-ffi 0.1.0",
  "ringbuf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cubeb-sys"
-version = "0.5.4"
+version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "darling"
@@ -1123,25 +1118,16 @@ source = "registry+https://github.com/ru
 name = "freetype"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "fs2"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
-]
-
-[[package]]
 name = "fuchsia-cprng"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "fuchsia-zircon"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1259,17 +1245,17 @@ dependencies = [
  "audioipc-server 0.2.3",
  "authenticator 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitsdownload 0.1.0",
  "bookmark_sync 0.1.0",
  "cert_storage 0.0.1",
  "cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "cubeb-coreaudio 0.1.0",
  "cubeb-pulse 0.2.0",
- "cubeb-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb-sys 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding_c 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding_glue 0.1.0",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "geckoservo 0.0.1",
  "gkrust_utils 0.1.0",
  "jsrust_shared 0.1.0",
  "kvstore 0.1.0",
  "lmdb-rkv-sys 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1594,21 +1580,16 @@ dependencies = [
 
 [[package]]
 name = "lazy_static"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "lazycell"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "lazycell"
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libc"
 version = "0.2.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -1688,24 +1669,16 @@ name = "lock_api"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "log"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "log"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "lzw"
@@ -1770,28 +1743,26 @@ dependencies = [
 
 [[package]]
 name = "memchr"
 version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "memmap"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "memmap"
-version = "0.6.2"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "memoffset"
@@ -1834,77 +1805,84 @@ dependencies = [
  "cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
  "crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mio"
-version = "0.6.16"
+version = "0.6.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mio-extras"
 version = "2.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mio-named-pipes"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+version = "0.1.6"
+source = "git+https://github.com/alexcrichton/mio-named-pipes#2072ae0de5b3632dbb065fcd9c8be6c6a2fc39ae"
+dependencies = [
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "mio-uds"
 version = "0.6.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "miow"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "miow"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "socket2 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
+]
+
+[[package]]
 name = "moz_cbor"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "moz_task"
 version = "0.1.0"
 dependencies = [
@@ -2191,17 +2169,17 @@ dependencies = [
 name = "parking_lot_core"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "peek-poke"
 version = "0.2.0"
@@ -2523,36 +2501,36 @@ name = "rdrand"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.32"
+version = "0.1.56"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "redox_termios"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "redox_users"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2918,16 +2896,27 @@ name = "smallvec"
 version = "0.6.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "socket2"
+version = "0.3.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
+]
+
+[[package]]
 name = "stable_deref_trait"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "storage"
 version = "0.1.0"
 dependencies = [
@@ -3118,17 +3107,17 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
 version = "3.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
  "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "term_size"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3147,17 +3136,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "textwrap"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -3197,17 +3186,17 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "time"
 version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "to_shmem"
 version = "0.0.1"
 dependencies = [
  "cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3231,17 +3220,17 @@ dependencies = [
 
 [[package]]
 name = "tokio"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3256,34 +3245,16 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "tokio-core"
-version = "0.1.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
 name = "tokio-current-thread"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3312,37 +3283,49 @@ version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "tokio-named-pipes"
+version = "0.2.0"
+source = "git+https://github.com/NikVolf/tokio-named-pipes?branch=stable#0afa6247222a7aa6e8b370e949a0f4007f0018b6"
+dependencies = [
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-named-pipes 0.1.6 (git+https://github.com/alexcrichton/mio-named-pipes)",
+ "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "tokio-reactor"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "tokio-tcp"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "tokio-threadpool"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3371,49 +3354,33 @@ dependencies = [
 [[package]]
 name = "tokio-udp"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "tokio-uds"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "tokio-uds"
 version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "toml"
@@ -3826,17 +3793,17 @@ dependencies = [
 name = "ws"
 version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3990,20 +3957,20 @@ dependencies = [
 "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
 "checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4"
 "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
 "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
 "checksum cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a921abc45ea75c2c817d951caeda31b94539d09a6b5e8d58a857b3b35c9c3894"
 "checksum cssparser-macros 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b16e382d9b983fdb9ac6a36b37fdeb84ce3ea81f749febfee3463cfa7f24275e"
 "checksum cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b6557bdb1dc9647eae1cf7f5601b14cd45fc3c7ccf2df618387416fe542da6ea"
 "checksum cstr-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0f12dd847ec773fc98d75edba5394cb87d0f35e7ee548a4c81849ca6374b3d48"
-"checksum cubeb 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "db3f0df2ad5cb453126364a77921466ba6c1034e8bd9247f326cdb31430dbc2a"
-"checksum cubeb-backend 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "442cd5cfb980ff62730525278ce320d9b2ff635b725857ad3176832664262fec"
-"checksum cubeb-core 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0161f9327864922ba7a172c90bd86bc9094938433eca415e2c75629954045022"
-"checksum cubeb-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba7540c17b90159cf7d7854da370998ff0560d9b90e2c9290bb588afa0edf95"
+"checksum cubeb 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "50f6a746cc3a80bdc96203e617d3bfc8988169c012c85c4ca4f1bad7862441bc"
+"checksum cubeb-backend 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "54c14a298d865c7f454dd809b2feb1fdb361b0a143f8ed2ea0b3a9becfa0a2ea"
+"checksum cubeb-core 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "20c6cde72d3505dc4f2452e0378b970b03d1fddf3ad8ac1b98dcb65fc7721907"
+"checksum cubeb-sys 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "318d9b60d6d5de52f815882ab5405adedc0ac7e91414950eff27a440c2860a3b"
 "checksum darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6"
 "checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c"
 "checksum darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1"
 "checksum dbus 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e1b39f3f6aa3d4a1522c4f0f9f1e9e9167bd93740a8690874caa7cf8ce47d7"
 "checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86"
 "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
 "checksum devd-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d009f166c0d9e9f9909dc751630b3a6411ab7f85a153d32d01deb364ffe52a7"
 "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
@@ -4022,17 +3989,16 @@ dependencies = [
 "checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
 "checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
 "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 "checksum filetime_win 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c37abd4a58e0cb794bcae4a7dc4f02fff376949d8d1066d4c729e97bfb38ec"
 "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
 "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
 "checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"
 "checksum freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b659e75b7a7338fe75afd7f909fc2b71937845cffb6ebe54ba2e50f13d8e903d"
-"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
 "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "884dbe32a6ae4cd7da5c6db9b78114449df9953b8d490c9d7e1b51720b922c62"
 "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
 "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
 "checksum gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39a23d5e872a275135d66895d954269cf5e8661d234eb1c2480f4ce0d586acbd"
@@ -4056,47 +4022,46 @@ dependencies = [
 "checksum input_buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e1b822cc844905551931d6f81608ed5f50a79c1078a4e2b4d42dbc7c1eedfbf"
 "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
 "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"
 "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
 "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum khronos_api 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
 "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
-"checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"
 "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 "checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
 "checksum libdbus-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "18cb88963258d00f4962205dbb5933d82780d9962c8c8a064b651d2ad7189210"
 "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2"
 "checksum libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe"
 "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
 "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
 "checksum lmdb-rkv 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e25b4069789bf7ac069d6fd58229f18aec20c6f7cc9173cb731d11c10dbb6b6e"
 "checksum lmdb-rkv-sys 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4d7d61f709086e3efb2f7255ad01cf1d7f9e407b7dfe96d83cd15e76ee8283b4"
 "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
-"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
 "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
 "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
 "checksum mach 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9"
 "checksum malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35adee9ed962cf7d07d62cb58bc45029f3227f5b5b86246caa8632f06c187bc3"
 "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
 "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
 "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
-"checksum memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b"
 "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
+"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425"
 "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed"
 "checksum miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aaa2d3ad070f428fffbd7d3ca2ea20bb0d8cffe9024405c44e1840bc1418b398"
 "checksum miniz_oxide_c_api 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "92d98fdbd6145645828069b37ea92ca3de225e000d80702da25c20d3584b38a5"
-"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432"
+"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
 "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
-"checksum mio-named-pipes 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "82f43a815b57d2d652550f3d20cec88a495bb2d0956aa873dc43040278455677"
+"checksum mio-named-pipes 0.1.6 (git+https://github.com/alexcrichton/mio-named-pipes)" = "<none>"
 "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
 "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+"checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226"
 "checksum moz_cbor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20c82a57087fd5990d7122dbff1607c3b20c3d2958e9d9ad9765aab415e2c91c"
 "checksum mp4parse_fallible 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6626c2aef76eb8f984eef02e475883d3fe9112e114720446c5810fc5f045cd30"
 "checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729"
 "checksum murmurhash3 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
 "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
 "checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
 "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
 "checksum nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c349f68f25f596b9f44cf0e7c69752a5c633b0550c3ff849518bfba0233774a"
@@ -4142,17 +4107,17 @@ dependencies = [
 "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
 "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
 "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
 "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
 "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
 "checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4"
 "checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2"
 "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
-"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
+"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "214a97e49be64fd2c86f568dd0cb2c757d2cc53de95b273b6ad0a1c908482f26"
 "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
 "checksum regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d8c9f33201f46669484bacc312b00e7541bed6aaf296dffe2bb4e0ac6b8ce2a"
 "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
 "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
 "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
 "checksum ringbuf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "588456c74d5ff0a5806bc084818e043e767533f743c11ee6f3ccf298599c6847"
@@ -4187,16 +4152,17 @@ dependencies = [
 "checksum shift_or_euc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f930dea4685b9803954b9d74cdc175c6d946a22f2eafe5aa2e9a58cdcae7da8c"
 "checksum shift_or_euc_c 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c81ec08c8a68c45c48d8ef58b80ce038cc9945891c4a4996761e2ec5cba05abc"
 "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
 "checksum smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1764fe2b30ee783bfe3b9b37b2649d8d590b3148bb12e0079715d4d5c673562e"
 "checksum smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "622df2d454c29a4d89b30dc3b27b42d7d90d6b9e587dbf8f67652eb7514da484"
+"checksum socket2 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df028e0e632c2a1823d920ad74895e7f9128e6438cbc4bc6fd1f180e644767b9"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum svg_fmt 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c666f0fed8e1e20e057af770af9077d72f3d5a33157b8537c1475dd8ffd6d32b"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)" = "66c8865bf5a7cbb662d8b011950060b3c8743dca141b054bf7195b20d314d8e2"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
 "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
@@ -4209,27 +4175,26 @@ dependencies = [
 "checksum thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
 "checksum thin-vec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73fdf4b84c65a85168477b7fb6c498e0716bc9487fba24623389ea7f51708044"
 "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
 "checksum thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf947d192a9be60ef5131cc7a4648886ba89d712f16700ebbf80c8a69d05d48f"
 "checksum threadbound 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d23e87ee7a1ef5bd2d38cef24ff360f6e02beee13c6a7eb64dddde4a3da427a3"
 "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
 "checksum tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6e93c78d23cc61aa245a8acd2c4a79c4d7fa7fb5c3ca90d5737029f043a84895"
 "checksum tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb"
-"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71"
 "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
 "checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e"
 "checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135"
 "checksum tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a5c9635ee806f26d302b8baa1e145689a280d8f5aa8d0552e7344808da54cc21"
+"checksum tokio-named-pipes 0.2.0 (git+https://github.com/NikVolf/tokio-named-pipes?branch=stable)" = "<none>"
 "checksum tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8703a5762ff6913510dc64272c714c4389ffd8c4b3cf602879b8bd14ff06b604"
 "checksum tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565"
 "checksum tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "17465013014410310f9f61fa10bf4724803c149ea1d51efece131c38efca93aa"
 "checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e"
 "checksum tokio-udp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43eb534af6e8f37d43ab1b612660df14755c42bd003c5f8d2475ee78cc4600c0"
-"checksum tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "65ae5d255ce739e8537221ed2942e0445f4b3b813daebac1c0050ddaaa3587f9"
 "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
 "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
 "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
 "checksum tungstenite 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a9147f2f36ff21f9582ad10315172a14fdc3f3042ac12d302f61f7f2375926b"
 "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
 "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
 "checksum uluru 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2606e9192f308ddc4f0b3c5d1bf3400e28a70fff956e9d9f46d23b094746d9f"
 "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
--- a/third_party/rust/cubeb-backend/.cargo-checksum.json
+++ b/third_party/rust/cubeb-backend/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"1933f3fab97c50556ade6cc02e82b911aa7d7787be13501e9ea8dc09b85b2739","LICENSE":"8c044baa5d883274736eeece0b955249076c2697b826e576fce59496235b2cf5","src/capi.rs":"300e76bd3901de540b21a2cfc8d15dbcd1b2940d5fbb517fc5fe568af2ec2775","src/lib.rs":"94b80747ae1037423a2281f2572fc6d15cd7702417974ae3730adccd71c7a300","src/log.rs":"704faeb31934dad6bc6d02e01caa85118754209bd559d30d03fcfa5cb8c1603c","src/ops.rs":"55cbf9bdccdd854834eba72e8bde3e59a9a4193e65209769a1a6e0d8a320b8f6","src/traits.rs":"1a6e3401bb25088d355041704bd89099d62b51eda94da177e7e860646c52b955","tests/test_capi.rs":"9d949cbdb1c19e229ce4f652999a058c283cf7d5a882a669dbca08b71ac2fb62"},"package":"442cd5cfb980ff62730525278ce320d9b2ff635b725857ad3176832664262fec"}
\ No newline at end of file
+{"files":{"Cargo.toml":"4e854a5f7f2314ebf97a191a7de46c3e0e4264f5e8f5d48e41008201dd79f48e","LICENSE":"8c044baa5d883274736eeece0b955249076c2697b826e576fce59496235b2cf5","src/capi.rs":"2dafb53cf87041aea0ebe37fc38eac9653fa8382300df68ab51893fd1fe5614a","src/lib.rs":"94b80747ae1037423a2281f2572fc6d15cd7702417974ae3730adccd71c7a300","src/log.rs":"704faeb31934dad6bc6d02e01caa85118754209bd559d30d03fcfa5cb8c1603c","src/ops.rs":"55cbf9bdccdd854834eba72e8bde3e59a9a4193e65209769a1a6e0d8a320b8f6","src/traits.rs":"60bbb1b756e1576a691037e159f939e06b6d32c84b681cb6a1d0eaffd5205ae4","tests/test_capi.rs":"9d949cbdb1c19e229ce4f652999a058c283cf7d5a882a669dbca08b71ac2fb62"},"package":"54c14a298d865c7f454dd809b2feb1fdb361b0a143f8ed2ea0b3a9becfa0a2ea"}
\ No newline at end of file
--- a/third_party/rust/cubeb-backend/Cargo.toml
+++ b/third_party/rust/cubeb-backend/Cargo.toml
@@ -1,29 +1,29 @@
 # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
 #
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
+# to registry (e.g., crates.io) dependencies
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cubeb-backend"
-version = "0.5.4"
+version = "0.5.5"
 authors = ["Dan Glastonbury <dglastonbury@mozilla.com>"]
 description = "Bindings to libcubeb internals to facilitate implementing cubeb backends in rust.\n"
 homepage = "https://github.com/djg/cubeb-rs"
 keywords = ["cubeb"]
 categories = ["api-bindings"]
 license = "ISC"
 repository = "https://github.com/djg/cubeb-rs"
 [dependencies.cubeb-core]
-version = "0.5.4"
+version = "0.5.5"
 
 [features]
 gecko-in-tree = ["cubeb-core/gecko-in-tree"]
 [badges.circle-ci]
 repository = "djg/cubeb-rs"
--- a/third_party/rust/cubeb-backend/src/capi.rs
+++ b/third_party/rust/cubeb-backend/src/capi.rs
@@ -48,17 +48,18 @@ macro_rules! capi_new(
             stream_reset_default_device:
                 Some($crate::capi::capi_stream_reset_default_device::<$stm>),
             stream_get_position: Some($crate::capi::capi_stream_get_position::<$stm>),
             stream_get_latency: Some($crate::capi::capi_stream_get_latency::<$stm>),
             stream_set_volume: Some($crate::capi::capi_stream_set_volume::<$stm>),
             stream_set_panning: Some($crate::capi::capi_stream_set_panning::<$stm>),
             stream_get_current_device: Some($crate::capi::capi_stream_get_current_device::<$stm>),
             stream_device_destroy: Some($crate::capi::capi_stream_device_destroy::<$stm>),
-            stream_register_device_changed_callback: None,
+            stream_register_device_changed_callback:
+                Some($crate::capi::capi_stream_register_device_changed_callback::<$stm>),
             register_device_collection_changed:
                 Some($crate::capi::capi_register_device_collection_changed::<$ctx>)
         }));
 
 pub unsafe extern "C" fn capi_init<CTX: ContextOps>(
     c: *mut *mut ffi::cubeb,
     context_name: *const c_char,
 ) -> c_int {
@@ -120,17 +121,17 @@ pub unsafe extern "C" fn capi_enumerate_
 }
 
 pub unsafe extern "C" fn capi_device_collection_destroy<CTX: ContextOps>(
     c: *mut ffi::cubeb,
     collection: *mut ffi::cubeb_device_collection,
 ) -> c_int {
     let ctx = &mut *(c as *mut CTX);
     let collection = DeviceCollectionRef::from_ptr_mut(collection);
-    let _ = ctx.device_collection_destroy(collection);
+    _try!(ctx.device_collection_destroy(collection));
     ffi::CUBEB_OK
 }
 
 pub unsafe extern "C" fn capi_destroy<CTX>(c: *mut ffi::cubeb) {
     let _: Box<CTX> = Box::from_raw(c as *mut _);
 }
 
 pub unsafe extern "C" fn capi_stream_init<CTX: ContextOps>(
@@ -251,16 +252,26 @@ pub unsafe extern "C" fn capi_stream_dev
     device: *mut ffi::cubeb_device,
 ) -> c_int {
     let stm = &mut *(s as *mut STM);
     let device = DeviceRef::from_ptr(device);
     let _ = stm.device_destroy(device);
     ffi::CUBEB_OK
 }
 
+pub unsafe extern "C" fn capi_stream_register_device_changed_callback<STM: StreamOps>(
+    s: *mut ffi::cubeb_stream,
+    device_changed_callback: ffi::cubeb_device_changed_callback,
+) -> c_int {
+    let stm = &mut *(s as *mut STM);
+
+    _try!(stm.register_device_changed_callback(device_changed_callback));
+    ffi::CUBEB_OK
+}
+
 pub unsafe extern "C" fn capi_register_device_collection_changed<CTX: ContextOps>(
     c: *mut ffi::cubeb,
     devtype: ffi::cubeb_device_type,
     collection_changed_callback: ffi::cubeb_device_collection_changed_callback,
     user_ptr: *mut c_void,
 ) -> i32 {
     let ctx = &mut *(c as *mut CTX);
     let devtype = DeviceType::from_bits_truncate(devtype);
--- a/third_party/rust/cubeb-backend/src/traits.rs
+++ b/third_party/rust/cubeb-backend/src/traits.rs
@@ -6,17 +6,17 @@
 use cubeb_core::{Context, DeviceCollectionRef, DeviceId, DeviceRef, DeviceType, Result, Stream,
                  StreamParams, StreamParamsRef};
 use ffi;
 use std::ffi::CStr;
 use std::os::raw::c_void;
 
 pub trait ContextOps {
     fn init(context_name: Option<&CStr>) -> Result<Context>;
-    fn backend_id(&mut self) -> &'static CStr;
+    fn backend_id(&mut self) -> &CStr;
     fn max_channel_count(&mut self) -> Result<u32>;
     fn min_latency(&mut self, params: StreamParams) -> Result<u32>;
     fn preferred_sample_rate(&mut self) -> Result<u32>;
     fn enumerate_devices(
         &mut self,
         devtype: DeviceType,
         collection: &DeviceCollectionRef,
     ) -> Result<()>;
--- a/third_party/rust/cubeb-core/.cargo-checksum.json
+++ b/third_party/rust/cubeb-core/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"5606a2dfca9a44892ebfbc7caa0a96a50e8bb96676f7a9aaf584b3d459843d86","LICENSE":"8c044baa5d883274736eeece0b955249076c2697b826e576fce59496235b2cf5","src/builders.rs":"ca97e3a3d1f3fc451c17851c8538964ec67f3964dfe29e902d904ee7445becca","src/channel.rs":"c8d5a76ef3ecdd96cd4de516e3d4d139bbb83c4690d1c3f5fd07fffc47be51f1","src/context.rs":"09625b75070ec88d566a907ab2e574e2d85df4c6df295f798b3372df2cdc8f7a","src/device.rs":"490d2e94ecae1e149476c2e8d9aa03c4163987c3efccc962b2d3123e4c09dedf","src/device_collection.rs":"f6d0c1628cc34b524f86b84a1e1c79971c3f64ebc4ac64eeb10a1330bbe8c238","src/error.rs":"855ff3d3597753f832ecea00e403c71129afd80db3d39456cf3e23cb9aeb91e7","src/ffi_types.rs":"d815d7a80895b5e86907e708dc0219fca4ac4668cde114afee434e7d702a145d","src/format.rs":"5513c537a72af1c222ee7c30b26d4de9d368a69772688b95d88b1a99f6892d5c","src/lib.rs":"6010a5e20b836b8e5c9fba382fde819e6f3c18c0ec2016e6e7e118eabedbcd51","src/log.rs":"c46bae3472043fd076df3229c3421d948a87fae8495c1524b41ab2d8608f612a","src/stream.rs":"775b9af0e3d8c1a7a38f96b8365a632a9d52a43541d96ede9a4ed9688c2dc914","src/try_call.rs":"231bfa3f3448f7531427bb228beb2bcd4fd711f0b13d2d8f412af013470f40c7","src/util.rs":"308cfbaacd615ff600e74415c52daeef007fff34a4a0648a73c0042f6067f84f"},"package":"0161f9327864922ba7a172c90bd86bc9094938433eca415e2c75629954045022"}
\ No newline at end of file
+{"files":{"Cargo.toml":"f0fc91e3408113b5fcf54fda6ec59639f4501f083e6b17b7b1eecd9689e30502","LICENSE":"8c044baa5d883274736eeece0b955249076c2697b826e576fce59496235b2cf5","src/builders.rs":"ca97e3a3d1f3fc451c17851c8538964ec67f3964dfe29e902d904ee7445becca","src/channel.rs":"c8d5a76ef3ecdd96cd4de516e3d4d139bbb83c4690d1c3f5fd07fffc47be51f1","src/context.rs":"09625b75070ec88d566a907ab2e574e2d85df4c6df295f798b3372df2cdc8f7a","src/device.rs":"490d2e94ecae1e149476c2e8d9aa03c4163987c3efccc962b2d3123e4c09dedf","src/device_collection.rs":"f6d0c1628cc34b524f86b84a1e1c79971c3f64ebc4ac64eeb10a1330bbe8c238","src/error.rs":"855ff3d3597753f832ecea00e403c71129afd80db3d39456cf3e23cb9aeb91e7","src/ffi_types.rs":"d815d7a80895b5e86907e708dc0219fca4ac4668cde114afee434e7d702a145d","src/format.rs":"5513c537a72af1c222ee7c30b26d4de9d368a69772688b95d88b1a99f6892d5c","src/lib.rs":"6010a5e20b836b8e5c9fba382fde819e6f3c18c0ec2016e6e7e118eabedbcd51","src/log.rs":"c46bae3472043fd076df3229c3421d948a87fae8495c1524b41ab2d8608f612a","src/stream.rs":"95b8665fc860971250c28e7eba1f02759e83fdb8bae0b4ac7b615336cb87f758","src/try_call.rs":"231bfa3f3448f7531427bb228beb2bcd4fd711f0b13d2d8f412af013470f40c7","src/util.rs":"308cfbaacd615ff600e74415c52daeef007fff34a4a0648a73c0042f6067f84f"},"package":"20c6cde72d3505dc4f2452e0378b970b03d1fddf3ad8ac1b98dcb65fc7721907"}
\ No newline at end of file
--- a/third_party/rust/cubeb-core/Cargo.toml
+++ b/third_party/rust/cubeb-core/Cargo.toml
@@ -1,32 +1,32 @@
 # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
 #
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
+# to registry (e.g., crates.io) dependencies
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cubeb-core"
-version = "0.5.4"
+version = "0.5.5"
 authors = ["Dan Glastonbury <dglastonbury@mozilla.com>"]
 description = "Common types and definitions for cubeb rust and C bindings. Not intended for direct use.\n"
 homepage = "https://github.com/djg/cubeb-rs"
 keywords = ["cubeb"]
 categories = ["api-bindings"]
 license = "ISC"
 repository = "https://github.com/djg/cubeb-rs"
 [dependencies.bitflags]
 version = "1.0"
 
 [dependencies.cubeb-sys]
-version = "0.5.4"
+version = "0.5.5"
 
 [features]
 gecko-in-tree = ["cubeb-sys/gecko-in-tree"]
 [badges.circle-ci]
 repository = "djg/cubeb-rs"
--- a/third_party/rust/cubeb-core/src/stream.rs
+++ b/third_party/rust/cubeb-core/src/stream.rs
@@ -45,16 +45,18 @@ impl Into<ffi::cubeb_state> for State {
     }
 }
 
 /// Miscellaneous stream preferences.
 bitflags! {
     pub struct StreamPrefs: ffi::cubeb_stream_prefs {
         const NONE = ffi::CUBEB_STREAM_PREF_NONE;
         const LOOPBACK = ffi::CUBEB_STREAM_PREF_LOOPBACK;
+        const DISABLE_DEVICE_SWITCHING = ffi::CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING;
+        const VOICE = ffi::CUBEB_STREAM_PREF_VOICE;
     }
 }
 
 /// Stream format initialization parameters.
 ffi_type_stack!{
     type CType = ffi::cubeb_stream_params;
     #[derive(Debug)]
     pub struct StreamParams;
--- a/third_party/rust/cubeb-sys/.cargo-checksum.json
+++ b/third_party/rust/cubeb-sys/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"f3facab1f968b8c6bd6b3e2ebf88064bb3d6661a50080e753152b262fc96c4dc","LICENSE":"8c044baa5d883274736eeece0b955249076c2697b826e576fce59496235b2cf5","build.rs":"84f01f6c5f4559b87e348f6bc04d840a405889549dddf5e74cb486ad8b71bef2","libcubeb/AUTHORS":"829e45d138c7c8827799f302806fa4be8cd8bd4bad70a2fe26c3a27a5cf36948","libcubeb/CMakeLists.txt":"381886472be5fc0f925aa42268fd2df9f17f5613ee7db489849af474189f0358","libcubeb/Config.cmake.in":"88019286c96ef3d5d3a673b183c8655dfc97ceede07d3eb6c18f0c51bb896388","libcubeb/INSTALL.md":"7a84cdfbe86e7d3180e2203603b88571df61b369421fa97ee86740ffd4d4db8e","libcubeb/LICENSE":"44c6b5ae5ec3fe2fbc608b00e6f4896f4d2d5c7e525fcbaa3eaa3cf2f3d5a983","libcubeb/README.md":"aa417156dc65069264901b75fc3c792c73021ec61c909de04e109bd4184c07ab","libcubeb/TODO":"6f8065136e005d2becee810e3d8697a94f2c755f8c79687adfac7136ad165e80","libcubeb/appveyor.yml":"9a87fdc18b76fca1167289ecb2ec3a210b76984c1d7e92268b2cd36f1e00f541","libcubeb/cmake/sanitizers-cmake/CMakeLists.txt":"89b282c19b3897ff666f7847d5e679ae928ca7e76ffd0d23f7c58c9464048b61","libcubeb/cmake/sanitizers-cmake/LICENSE":"4b67e7ae8c91e68e1a929eb1cbaa4c773c6d19aa91aaa12c390cf9560d1c9799","libcubeb/cmake/sanitizers-cmake/README.md":"30ab1524618ac828b75f9b83c665a0bd50b839b42ce61519a8048d73f401da6e","libcubeb/cmake/sanitizers-cmake/cmake/FindASan.cmake":"cba07ffe438c57bef0840ed6a2d2890676530b66509da3c616438c53018baa4f","libcubeb/cmake/sanitizers-cmake/cmake/FindMSan.cmake":"1303aac5028fe9f64d42be0afd47f1291e679d74f8280b3dc5271f20ebf4d7a4","libcubeb/cmake/sanitizers-cmake/cmake/FindSanitizers.cmake":"ce1971b943bbef08fb9aba958cf28e3cbdff075406c85a3cfed22e00c9f8d9a8","libcubeb/cmake/sanitizers-cmake/cmake/FindTSan.cmake":"edca39b287312e9a8fc718f6ec791d2520515900b37426091310fe1bd52dc6a1","libcubeb/cmake/sanitizers-cmake/cmake/FindUBSan.cmake":"5b9d3621f629c807a1345a7cb053677a8bf25782a079e345dda53d04aecdc4b7","libcubeb/cmake/sanitizers-cmake/cmake/asan-wrapper":"4e543936e6374e24b80a0f92135c07c2e2101c0d110e51bddaf0e70ae8ec391e","libcubeb/cmake/sanitizers-cmake/cmake/sanitize-helpers.cmake":"282620734c2a8062f1280d0dde3121b8b01af26e5ecaa7d4308e145f80ecd115","libcubeb/cmake/sanitizers-cmake/tests/CMakeLists.txt":"fb983bab7040be002847db59c2493abfd249f67ad06e3a9270fbceb9fabda11c","libcubeb/cmake/sanitizers-cmake/tests/asan_test.cpp":"8b351c7c8668b4a2438286df426f0ad322cade6d1c6199a74668ccbd1c5204a4","libcubeb/cmake/toolchain-cross-android.cmake":"59d2355845a71647b353fb8b18fca630db8ffee7bb8500143e2d6fbc409cec97","libcubeb/cmake/toolchain-cross-mingw.cmake":"b09dc261981c0d4a0f8430f05aae9c8fc545651cd9cbfacd09754277b776b532","libcubeb/cubeb.supp":"19f33e59f8dc91a327c923e44c2c3f9af0a043ce1d6a8cac275ba094b4bfe0da","libcubeb/docs/Doxyfile.in":"0815f19789cedd310652a133bab260c27b57e95f7a65458df2dfca38ea4f1041","libcubeb/googletest/CHANGES":"72c8a289bfe4dd9160074a3a2238c8067a5bc7ca49fd87f70a134c3f373932a4","libcubeb/googletest/CMakeLists.txt":"cdf938ce79ea066866dc614de3925bfaa48d9e19e04049db2ec8c5443abaaa9b","libcubeb/googletest/CONTRIBUTORS":"4d911cd5e6d71f3f4bbcb2788b2f916df4b0ce1e088752a159457a1d936ae0ce","libcubeb/googletest/COPYING":"9702de7e4117a8e2b20dafab11ffda58c198aede066406496bef670d40a22138","libcubeb/googletest/Makefile.am":"a795e5a18e82ba06fd97509d92d773b7fafd0dd7086db8a1211fbd151b503bac","libcubeb/googletest/README":"484b19654362942fac9734c8fab0ed3d99249b81c69027bdb7de46054abada6b","libcubeb/googletest/cmake/internal_utils.cmake":"6f4670a5825cf8ae0415be9dd43d82a7f30316d75cab20a4c60afb6d9db2a01d","libcubeb/googletest/codegear/gtest.cbproj":"9fa07a66b8c01773256e508187775407c465ed9055651e93d390426d1888721a","libcubeb/googletest/codegear/gtest.groupproj":"76c001cb2ee0070e26d1570fb6db5250f2585179c707496c5ef6d12e582cf205","libcubeb/googletest/codegear/gtest_all.cc":"c8750dc2b7b3612edb60e8d23fc2f60ae264451916c4b15f81cbf60ea30eb75d","libcubeb/googletest/codegear/gtest_link.cc":"e5e47c086f932471e0ca748a62b3b1597e5e731f4d34fb8cb8b2ca2db7ba3ed0","libcubeb/googletest/codegear/gtest_main.cbproj":"056448ba7f41fae3f704b1001922d9f6e419cf8cbcf3a55bf0ecc59ece1fa9a1","libcubeb/googletest/codegear/gtest_unittest.cbproj":"2c48be90b0dbc3224a8bd6c4dc21f78dd1b08c81685e6bd4952bb6df6ee38701","libcubeb/googletest/configure.ac":"fadebffdaeaccebb60fbe4a501c1138c296e01348a5da45fabf5e4233248baa8","libcubeb/googletest/include/gtest/gtest-death-test.h":"fdd087f700cd04a3ce4bdd36f35769de52a44bfc0c5bae2dc9681d4cbcd3c44a","libcubeb/googletest/include/gtest/gtest-message.h":"eaf44df1284d94333507c47091c84eaaf43814e6a02a1b1c0061ca7b363e74d6","libcubeb/googletest/include/gtest/gtest-param-test.h":"f226f0a24c04cddbceaaa45d8a5e575ce18c3392349f9b8ba73317e37e62368d","libcubeb/googletest/include/gtest/gtest-param-test.h.pump":"17c65fd5cc5218279044a61f3873c9c952b0924a7ba5147d4999d400b122207f","libcubeb/googletest/include/gtest/gtest-printers.h":"7046f611398d63ee0f1c37bdb4fd08d9931979b2fedf13b781e6d85d4b3b5d60","libcubeb/googletest/include/gtest/gtest-spi.h":"560407dd45e8e57fa6927504c9e4a4cfdecf30f8cada975c1ffddce765e6a88a","libcubeb/googletest/include/gtest/gtest-test-part.h":"c4d6d840284728740c284646075e8ffc85b63b9f74f3ed488b18ef3c2c2b9005","libcubeb/googletest/include/gtest/gtest-typed-test.h":"1ec858bbb9ed8a8bb553232df016437c080b2670f00453b4de297c286eb78c21","libcubeb/googletest/include/gtest/gtest.h":"47433ca72a43bda7a380c34fe6d4ff451797c687e9bbd74d1f366bcdfa0cb013","libcubeb/googletest/include/gtest/gtest_pred_impl.h":"f03a3f77e3c231889c0ace6f63b2c4e410e4a9330287ea09443b23b9a3cf9092","libcubeb/googletest/include/gtest/gtest_prod.h":"4a99a3d986a45b4d6d9b3af54809f015c54aa98274793a4ae173f5010d0ad33c","libcubeb/googletest/include/gtest/internal/gtest-death-test-internal.h":"0b3abead866363f3e6b4201acc8d2763072e033826b22ae5ebffd790e1415235","libcubeb/googletest/include/gtest/internal/gtest-filepath.h":"638d2bb6c06a894513b03311a8e931ac835fc00afc4bd21fab3afc05732c23a0","libcubeb/googletest/include/gtest/internal/gtest-internal.h":"12c2c83df0a9dc5b46697ccd8271dfa34ee5f3d1972dcb56585bc1459d9583c9","libcubeb/googletest/include/gtest/internal/gtest-linked_ptr.h":"9bd319548dd073630dfd349c06a440c6a582feec47d4ff14f348ec32f8b4c1f3","libcubeb/googletest/include/gtest/internal/gtest-param-util-generated.h":"10db93fa7e98820192bae6f560664469dd33b265036fca64253c89b6801f96cb","libcubeb/googletest/include/gtest/internal/gtest-param-util-generated.h.pump":"abb72365d94d2811b34c195dc520fbf41c7dcb42aae5a1cfa0502cf619b21e70","libcubeb/googletest/include/gtest/internal/gtest-param-util.h":"7f9311f033ef6916217d87cef53b1db6c4e8733be930e4b48fe7e11d21b33da0","libcubeb/googletest/include/gtest/internal/gtest-port.h":"612932c2930a7cf2c3514d89a8d6b51a2c0030d251309b71765ed1c9954e20c5","libcubeb/googletest/include/gtest/internal/gtest-string.h":"a46aa36165c400d1e926f942be03fe04cd7ccb1e59f7a2a03b919c4eea05b997","libcubeb/googletest/include/gtest/internal/gtest-tuple.h":"43e7e3c92f8e4258cf3927a9204b214d4d03e6c796f88f3ad4e66b1ac20aa938","libcubeb/googletest/include/gtest/internal/gtest-tuple.h.pump":"16fa027ed3c5940699e0ac906815e66620993bcf75b0acaf826d4f09348d4b83","libcubeb/googletest/include/gtest/internal/gtest-type-util.h":"6d177af46a9b1e14b969972a8b886667f95e69037aba411433a44fb9b92e7037","libcubeb/googletest/include/gtest/internal/gtest-type-util.h.pump":"22092f44127af91651f57ce222e20914d5d32ae02f1c0964f6d5d7bc019af339","libcubeb/googletest/m4/acx_pthread.m4":"3326e3746b6b351d1671fe31f798269cda8de92c365b8a8305404ec0fa6c6b32","libcubeb/googletest/m4/gtest.m4":"d3c37ebd1aa792c967d4357755cc670bc6deb30091d9e6db498871d90a30ea4c","libcubeb/googletest/make/Makefile":"9b86e2a112dd55c6bf6a2b39e6f4078faf60cfecb8282ebf9b025167ed233420","libcubeb/googletest/msvc/gtest-md.sln":"0beab679b42cf0c431eaf4fe143bbf3b01fc064e20c74d9e33e7e437a70487d4","libcubeb/googletest/msvc/gtest-md.vcproj":"52e873e964daf9d5409b4e9bb471ddf2827be04985cd96c40620f9275d17a256","libcubeb/googletest/msvc/gtest.sln":"be21c2340650ec2259a2fbaeb8608ae6d3e982a0626a0f91128a771dc88e6bea","libcubeb/googletest/msvc/gtest.vcproj":"0064616c7d88a284c1b7c05baab038f239134ea9c6c563628f286f9600b3f921","libcubeb/googletest/msvc/gtest_main-md.vcproj":"f83a294a92b616bf34ccae6743ff916297bdba61d6125a9637a813d467a30372","libcubeb/googletest/msvc/gtest_main.vcproj":"9f03270a00896eab0c7015c6fb1a73818d024e462d3944ba1d3ceb313a051649","libcubeb/googletest/msvc/gtest_prod_test-md.vcproj":"7caa108733e2d5f140da004d2133e04a9a105811909c0e2d4ec06e2971983592","libcubeb/googletest/msvc/gtest_prod_test.vcproj":"cf5bfb7f3de9a59a0eba5535067845d12c33c3fd8fecc3d03aa702665db29578","libcubeb/googletest/msvc/gtest_unittest-md.vcproj":"e7949b21cf0418f2a7afe8aa94616e2c40e3ba0801c2f0826f3a3a3d2e6f48b0","libcubeb/googletest/msvc/gtest_unittest.vcproj":"5b097d596fbbc1c4090fd518008a0961b29661194e1c02d8a2d3daaa557e626f","libcubeb/googletest/samples/prime_tables.h":"2903df1d1e6643a5f624fe3ea3f931c3410eb1858ac347c5df278273c6c91ca4","libcubeb/googletest/samples/sample1.cc":"dc106c5940d87bb4bbef3d77815eab642ee173a3340b2b9c532b5c711c4c2d0e","libcubeb/googletest/samples/sample1.h":"7a7bf9a0fbd2401e8b2cb554bfcb9bd0ed228212f3b970675c1b1d38d4e188bb","libcubeb/googletest/samples/sample10_unittest.cc":"ccebb6393a5a8468399f7e511219b667a2233f82312ce59834a4bb0997d8700e","libcubeb/googletest/samples/sample1_unittest.cc":"904be0d4a095e74393515195392bd10e1e916bb2ca61f3f94b1bd6aebea29cb6","libcubeb/googletest/samples/sample2.cc":"f14b8a1e69d52eef1a70053fb256818c7eca64e8eda08de43cf46e896e57fcc2","libcubeb/googletest/samples/sample2.h":"df956ba520dafca068dbc1e28f36567db3cba36293e06762318af8cda6a12bd4","libcubeb/googletest/samples/sample2_unittest.cc":"abe7e0b253d328cb82ae67623fbe3c89eb94699102510c64a0b568eaca101e05","libcubeb/googletest/samples/sample3-inl.h":"3fe482bbd4f725f5820f5d6beab4d0d4a524be8addf4b344a9a470ec5aabc451","libcubeb/googletest/samples/sample3_unittest.cc":"252c06b4531dc35213ebdd7311700b9b4057bc1bdeeba0cd767b2bc86c456639","libcubeb/googletest/samples/sample4.cc":"b4260f5fa35d78ac114a9abb59fce12403faf0273df41f57e83c341ae7979222","libcubeb/googletest/samples/sample4.h":"604905cae7e5587805c3b884a36eda7a2bebdfedb53b24b0fd9a220eec0ef1a9","libcubeb/googletest/samples/sample4_unittest.cc":"6cfb4821d8cb1c77fbb5af4f8aec569948762d8ea314827e3ead967b5b6a223e","libcubeb/googletest/samples/sample5_unittest.cc":"73646d9038873a68bb2e56b12495d7f7b65b5c23901109701da446af454ba2ec","libcubeb/googletest/samples/sample6_unittest.cc":"833fee399954f908cf0f3b789832e505329787f4cf73607a7b31ca0f62f368d7","libcubeb/googletest/samples/sample7_unittest.cc":"8013ee68d61c181e4e936cdae3a9a635646274f8512033ef11bff7214e03e4a6","libcubeb/googletest/samples/sample8_unittest.cc":"7b7510fadf4955d2f934d23d652dbd35add832e50bdfcc98421fb9be4588d808","libcubeb/googletest/samples/sample9_unittest.cc":"8b827040dea37b460cbcaea0b255b98974a9840f6ef7bd82aaa7d4ad2c724335","libcubeb/googletest/scripts/fuse_gtest_files.py":"adecf64c6bab65b31740c321e568cf174f753d5617745aa5762d842339d68b53","libcubeb/googletest/scripts/gen_gtest_pred_impl.py":"78fb7e20a014c251d723186eb58040e4eb32405b73c9288d787ea0a0e4ff5183","libcubeb/googletest/scripts/gtest-config.in":"9a43978eeee88e188845d737c17f4d024d4e74feae09da7997e8fbe4ea6cc176","libcubeb/googletest/scripts/pump.py":"3856a3d7be37f78e0f214ee7d4f29d05f1ca14218b67539d67c9a16e992f670c","libcubeb/googletest/scripts/test/Makefile":"3576b257594a2d8e843b9e4de8c83353d837833bb86431fb1b4198022b1bcddc","libcubeb/googletest/scripts/upload.py":"f75d0712e3b13bebd8daa0a15e4eb32c9e3034a933f4fcccf65b1e999a7ae066","libcubeb/googletest/scripts/upload_gtest.py":"6e76fc0a7a3831c01cfffd18c220d44438073a66338d91ca61fc84b924021e61","libcubeb/googletest/src/gtest-all.cc":"568ac119f5e6418f1fbcfbdf185d724657d7f3539b47822da229ac5d015626b2","libcubeb/googletest/src/gtest-death-test.cc":"eec1b3c8252670c76acbbaf63483946897ce625139b53a566406b6313f023896","libcubeb/googletest/src/gtest-filepath.cc":"31b7fcda5d11346f8a487597c6a70ff057f1192e0cb11f27eb7841a9f3aa8b86","libcubeb/googletest/src/gtest-internal-inl.h":"c9d428a6b5990ace091e40c4ce8b7bf6c50c186a8314b1c4a4cdc988ca0ac1a4","libcubeb/googletest/src/gtest-port.cc":"95bcf473622d1b901c734e5c2aeb8efb058555ec924212a61bb04f049bb5a069","libcubeb/googletest/src/gtest-printers.cc":"6f191a7fc7f5a0a967fd11964057f2e2d2eaf2f37ccece16bd816531f52b3154","libcubeb/googletest/src/gtest-test-part.cc":"e489868b4cdc66f4fc33bc2326ac86bc1acc5808ab58bbb288c9dcfc330faddc","libcubeb/googletest/src/gtest-typed-test.cc":"ca9e819df728c25a6a1fc072806c22f3494e1dffe4bd0d48284f38dbdd3a0dd5","libcubeb/googletest/src/gtest.cc":"5cf9a3e897892c9f0e5c887f91d3c8c8c5665bd7348560441fc0b946c254873c","libcubeb/googletest/src/gtest_main.cc":"22fa1f77542b882d1798d7f696045c5895942a626e26200a175fa4382e1fa5b5","libcubeb/googletest/test/gtest-death-test_ex_test.cc":"613ccf50a3ff8f84c975a13e86ea01ea4e36933072388a3738b4acf9ed3ed7cf","libcubeb/googletest/test/gtest-death-test_test.cc":"df8384a847bdf889233c3d45d171f784991def7a9b6a08442138569fbae32b9d","libcubeb/googletest/test/gtest-filepath_test.cc":"49760f91723845b113bb60bb9b1a1426ed1da1f4ebfef2462128980ea5692cc9","libcubeb/googletest/test/gtest-linked_ptr_test.cc":"1b9cb4ff67475900db9de34ae9749b94193048a1f7a741091ba5a2dd7fc7a79b","libcubeb/googletest/test/gtest-listener_test.cc":"acf78f2c9a730525ea5adc93e9196a42de8fbfe488db1dfd02656bdbd477b2c0","libcubeb/googletest/test/gtest-message_test.cc":"b1fc68f8b75ce25fbd79b3f7d3c9c793381ef07b3203e1a2d9b610cb597542be","libcubeb/googletest/test/gtest-options_test.cc":"74e3ae0c310edb3139b0032266219d3ce7f386ded6feafa57fef03f4493ed7fa","libcubeb/googletest/test/gtest-param-test2_test.cc":"a0f1efbcab3f7e49df639383157626931f64756f7e738be081760f93f7308332","libcubeb/googletest/test/gtest-param-test_test.cc":"ef8bd344e959053f562b0c9e0d15e2fb6c1e534772a67aaf3f90bd6bad0bf99f","libcubeb/googletest/test/gtest-param-test_test.h":"9d7f47b79d54df7cc050aa6038b0464aa684dfca669a847bf70ea16e4a000628","libcubeb/googletest/test/gtest-port_test.cc":"1600f78ef0860a0f5b5525e5e5041ff32a216cc6ae948b1ea61fe04ec603f67d","libcubeb/googletest/test/gtest-printers_test.cc":"7898e4b4163ee0821fed248e1c75d9f4a0a511a2b4bbfad1ef2f4a11a099f6e7","libcubeb/googletest/test/gtest-test-part_test.cc":"62c8906bb0d12ea84d60217b3773cd8e1768db4aab934880db2316df7026cab8","libcubeb/googletest/test/gtest-tuple_test.cc":"2850dc1f73a3f8020d8a4d80688a28d9b736eae6d677222c3f871d8d33b25501","libcubeb/googletest/test/gtest-typed-test2_test.cc":"c52b65e7181610d6e577631cd50177399884913ff28d08aedfedc92f05185044","libcubeb/googletest/test/gtest-typed-test_test.cc":"c7daff5211028da79b3ca0473dca18ada9197f38e710f72d0493ad3332ce3ec9","libcubeb/googletest/test/gtest-typed-test_test.h":"3145698534d8869beb624c9c8ed114f75bead046b2eeb92ada5a724993ee7786","libcubeb/googletest/test/gtest-unittest-api_test.cc":"e3f54c28ef2849e8b12af666ed46aace50c3e047845072ee6f974ce4528bd297","libcubeb/googletest/test/gtest_all_test.cc":"db0c3c42b385570b1d517e3ee927671b8fad4e206247fca738ec477222ac3d97","libcubeb/googletest/test/gtest_break_on_failure_unittest.py":"11c91bc1c68cfdb913e2affb01261b55fb3b0c18773a45875e9c25cb330a4dcd","libcubeb/googletest/test/gtest_break_on_failure_unittest_.cc":"1da12e4bdda2a0bc7b59d4638fe34b2d3798134224fd9237eeebdd09c3326011","libcubeb/googletest/test/gtest_catch_exceptions_test.py":"305cef45c6dc034bdf72fd91aba1e89e1c6b5d222c3d6baffff5acdfd9b3873e","libcubeb/googletest/test/gtest_catch_exceptions_test_.cc":"b297a4f4d5bc0285ea9eb8869741631658305e49d4513bca904842aacb82128b","libcubeb/googletest/test/gtest_color_test.py":"c4cb006682a40f2d88759a4bcabf0d4be623720b135c71447f1788d17ea23d0f","libcubeb/googletest/test/gtest_color_test_.cc":"f263ba349afe58a558bf0fee98a98bb9207a648e7cd4f908a87799bd13d001ea","libcubeb/googletest/test/gtest_env_var_test.py":"79819598cd1e366eaa8f2a4fee2d638b6ef0686e490402fae792ccce58d876c0","libcubeb/googletest/test/gtest_env_var_test_.cc":"0eee5dfbb2a2598f4e76626346b921928ec1e052e38f254cc97c60d05611ab46","libcubeb/googletest/test/gtest_environment_test.cc":"a52a21ea29c2203b03fa93922733546d171f98d3b2fcd42972269e98fd124715","libcubeb/googletest/test/gtest_filter_unittest.py":"edc7d278803bba41626eacd050d91d7247f1c5999f9dceb99a8877e238bc73d6","libcubeb/googletest/test/gtest_filter_unittest_.cc":"996ac528ad75c293d8201ce28cf6acccee266286bd369b4cf43f05b8d67a4559","libcubeb/googletest/test/gtest_help_test.py":"b43ab690c08e4bffd84a47b361167496298697f9511bdf4a745bf305b5cfbdfc","libcubeb/googletest/test/gtest_help_test_.cc":"ff4b121098f0fe7cb4abf11fdd31f2fe7a477286ec9175482138bc038d61c807","libcubeb/googletest/test/gtest_list_tests_unittest.py":"7caebc175b44b3c727fc50420ada1a6a9500f3e4ce9e2839f69205437aa85e7a","libcubeb/googletest/test/gtest_list_tests_unittest_.cc":"d82d8b72914897232c2ff9fd091a7b0add68b7cf75f3f210d3a487ebeea84cfe","libcubeb/googletest/test/gtest_main_unittest.cc":"0f66f318809c88f0fbe034a340a75331720c4e33be5378022baffaf588ef1202","libcubeb/googletest/test/gtest_no_test_unittest.cc":"7cf487e07c3d27376c2cb8af33d02239b7966623875d37b7aa0259e927a9c2f6","libcubeb/googletest/test/gtest_output_test.py":"cf0dc1979572d94450a5e611b44f3fdb88d9cd980d669a723f0ed63057b5e2c4","libcubeb/googletest/test/gtest_output_test_.cc":"f69569374c2b3d06aa04a38ebc4f92ddc303e6af503f8b533cd8e6bf9f104899","libcubeb/googletest/test/gtest_output_test_golden_lin.txt":"4f3e49c10a524a99437cdcb5294e3335a7f3c07ea8462e65730f703a5fe4fec3","libcubeb/googletest/test/gtest_pred_impl_unittest.cc":"e406eccf75b6b58746a95d1c7ea7bc8e80ff974e438ef7c83074a46d4e62db9a","libcubeb/googletest/test/gtest_prod_test.cc":"b42ca1a6d0a1e43bc576b4ff7776c6d2c37234f6dc2a76f2735f261b4a47a526","libcubeb/googletest/test/gtest_repeat_test.cc":"e10abbb71595920aa3bb415029eed74106335fc9ea3d58c417ccfc7cba6a4cdb","libcubeb/googletest/test/gtest_shuffle_test.py":"12dd94eb5f30260ba37059fa74658bda57dffa821f3ba6a2a8b52ff14b1ad029","libcubeb/googletest/test/gtest_shuffle_test_.cc":"af1b2b01ae275f1a9fee7e7940c0f88f39ded063008994d585aad87e3ffadb39","libcubeb/googletest/test/gtest_sole_header_test.cc":"538414c27a593ab8dc34c37b5c877eb3a022d75d1b481ef14ceca00914929754","libcubeb/googletest/test/gtest_stress_test.cc":"0b02fc12f87944226915a999bdcc8a3eaafb34a1ea5bb0df128774abf8667f09","libcubeb/googletest/test/gtest_test_utils.py":"d4a76930aee6658ad8734981ca0c4ea14f34dbe8fdd31d5afe41f6d98f9779ee","libcubeb/googletest/test/gtest_throw_on_failure_ex_test.cc":"11ae790028da20bc7b7af1572eff3cfe8499be43ab64c110e18e1892612a183f","libcubeb/googletest/test/gtest_throw_on_failure_test.py":"ebe18ca0b07f90c53b9b3f9a54ed02df94facf8995cfa90dd41c6f5474537c13","libcubeb/googletest/test/gtest_throw_on_failure_test_.cc":"f8cbf75d8bf9e9ae068a17ff968434c3aec7b7f1137c994d8f14af1a84361aa9","libcubeb/googletest/test/gtest_uninitialized_test.py":"da8e6ce34930753e36fc1dfa2c3e20e48d02bda2a27d3d03a07364312c5f3bd9","libcubeb/googletest/test/gtest_uninitialized_test_.cc":"0b6a9d4983480f87352ca4da946089264b401f7a4a3b1282253fd6cc861bf483","libcubeb/googletest/test/gtest_unittest.cc":"c0c7d1f691ce1e10c3d1647ed5f7a66510725808ad58bb6da4bc03a7a08fb2fc","libcubeb/googletest/test/gtest_xml_outfile1_test_.cc":"29341d777a9c9d25f360d13ed966b30f0cbef1fc88aefe2f01bb88b82cf1ed93","libcubeb/googletest/test/gtest_xml_outfile2_test_.cc":"da7ab3cf0e9b2a293eceed7c5691233d6b61afb557e3c1176dfb75390f85be46","libcubeb/googletest/test/gtest_xml_outfiles_test.py":"b07927b43f44afbfd61761c2cc69f1b68c4fbdeddb992db03ff0c73052518cd4","libcubeb/googletest/test/gtest_xml_output_unittest.py":"b5ff0c0207238d01cada961b8f4656f2ec30a3e1e5bf9d22efdf1745af423031","libcubeb/googletest/test/gtest_xml_output_unittest_.cc":"ad0b9ebe63a146e386df3c5c51916869f6d4647b9832ceacc912fb1272d15f82","libcubeb/googletest/test/gtest_xml_test_utils.py":"ad89a39a6cd5b08e87082341f3e7800dbf1150ea0f1386e0b8cd374aa6832f00","libcubeb/googletest/test/production.cc":"56fef77c3a8e62073ec11653d740a8e534008a0d57925ab0877b843f4fdd6be8","libcubeb/googletest/test/production.h":"a36d10545d12ead5e93a3b0fdca6ff73405f29091cfe38164415e9038888ba8d","libcubeb/googletest/xcode/Config/DebugProject.xcconfig":"fb42302df29bd8e8b5237194c0c04941f0e578527037930d88469baeb7a7f62b","libcubeb/googletest/xcode/Config/FrameworkTarget.xcconfig":"9935ddabe221f074d2f3b969a137d12b0dc0f845a460f58b63232987cb0f37ff","libcubeb/googletest/xcode/Config/General.xcconfig":"0fb768924daba1048f8db28b3a1fbf915b6f788d49d9d37e85979aa4ee92e02d","libcubeb/googletest/xcode/Config/ReleaseProject.xcconfig":"a4878ddd1ed78fb411906623cb51bc0ab4aea1cc3feb5379d2ae2862d8bf3bf5","libcubeb/googletest/xcode/Config/StaticLibraryTarget.xcconfig":"5886291788b3e9d5aadcb979ff055fd26a2413be81016e7afffb813b627d177c","libcubeb/googletest/xcode/Config/TestTarget.xcconfig":"f074e6c2516a6063b253ec6b842d74f5c2abefc7bcf8d8da54097a7bfe016480","libcubeb/googletest/xcode/Resources/Info.plist":"5b7f78a6d5810ce5490649793175c8982d41e6b49af06bc0705bc061567cc9aa","libcubeb/googletest/xcode/Samples/FrameworkSample/Info.plist":"1c13d83e5eed45689d7fe4bf4681030366474bc40608e39e1623c1350513a0cd","libcubeb/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj":"1cf0e1b1abf84414372faf9c8bf634e01fe5750bb3ca769b1eb25fc530b21358","libcubeb/googletest/xcode/Samples/FrameworkSample/runtests.sh":"a587e5b00a8353dee0aca5a4c59b28301ccf7648dee8c79b62a9223f9fc3c8cf","libcubeb/googletest/xcode/Samples/FrameworkSample/widget.cc":"562a2bb615e93186012823c9b41761769638a11e38b54498ad5f699038c8fd32","libcubeb/googletest/xcode/Samples/FrameworkSample/widget.h":"0c7915e45cf7cb8d67db24e49cd0b277f23f967578f917f8e859a6adc4b156f9","libcubeb/googletest/xcode/Samples/FrameworkSample/widget_test.cc":"6a1a49d64912d9829ef3d991faf5a3f0e1e081126a1d8d387cdfa84fab70dc77","libcubeb/googletest/xcode/Scripts/runtests.sh":"1a0672a4151b16f3c797478ba26c534e82b2faa603f90b9aa14e785805f7683a","libcubeb/googletest/xcode/Scripts/versiongenerate.py":"4b9d5c0f4e1b556084109311d156bee6d781968dc5b1dfdc8702364508f1dd43","libcubeb/googletest/xcode/gtest.xcodeproj/project.pbxproj":"a1224decff058bfed01b8eefaee13cab0129492615548c6d0d878003a154f7ff","libcubeb/include/cubeb/cubeb.h":"a73748e7fafc73122a81f0639e9148179ca29b6582f225000a60283bf68417ab","libcubeb/scan-build-install.sh":"1ecf22aca367a4d02f810c4cb78db8636e08a12787e94e30c441ce439cf4a265","libcubeb/src/android/audiotrack_definitions.h":"0d5ec772f9ebf61333bc16e61a081a7e3b4cc02342ec4f8f417e220d032fbbc6","libcubeb/src/android/cubeb-output-latency.h":"000fb7bec38105f54b9d40fc436440c637d63390b219775d335216d29d767226","libcubeb/src/android/cubeb_media_library.h":"f67965fb2ea38f0023eb4c76024341ba9563ac1a135507b6f12a9aabd85e30a9","libcubeb/src/android/sles_definitions.h":"24e400ca2330ec16d3a37b69b74144697b51dce17f9ead763b1a6ffedc5633ac","libcubeb/src/cubeb-internal.h":"ef7e7e19c40f743c814a39b8a47b9f03df054894018ad88b49129ffad2564bfa","libcubeb/src/cubeb-jni-instances.h":"8195554372bf60dea569873c9e5fb1106a2cf5dedc66a13d2bc967da0ff48a12","libcubeb/src/cubeb-jni.cpp":"81f001720c41c69b5927e32bd19b9e8e7176d7c33d63c2a58bd0d695dace4fd2","libcubeb/src/cubeb-jni.h":"73f810a32087a6062fd49ba89542655a7e19cecac6f40f8411e1d77ce42a45d1","libcubeb/src/cubeb-sles.h":"dc84a01ba4de9db1ff108609930b36ba442020ccc3e3d6f16528f429426c430c","libcubeb/src/cubeb-speex-resampler.h":"dbf543eee4cc6e40ba3531a39d327e2cec884c19e26c570aa7eae0647e5f7420","libcubeb/src/cubeb.c":"2de6d02fefd308dcc755dc9009cdb42d2d60f900237b4eda305ddcaa180f13db","libcubeb/src/cubeb_alsa.c":"6c833e379eea5d64a65a209f8e60c2aa2d6e038ea855554cd3f2664c463abbcd","libcubeb/src/cubeb_array_queue.h":"5264ae02799c540ff73e8eb8efa55986772b22562a025ae227c2603b6b8d1036","libcubeb/src/cubeb_assert.h":"ab8ed4fe7070a3aed9419c5f9695fce2318c4dafd91213ae61cac476e64adaa7","libcubeb/src/cubeb_audiotrack.c":"fe66d36dfecbfaad164ee8c871b39fd6e708a2f8f1f8524a5c0148ab86bab467","libcubeb/src/cubeb_audiounit.cpp":"8c127f884bb773e3856cc7c1f74b85210d1c589b199b61a6d6322a9c0bc1fbd0","libcubeb/src/cubeb_jack.cpp":"129c011feb01e8c6d573862218c31a8bf90522539a28a5ece8bcf87867be9daf","libcubeb/src/cubeb_kai.c":"a71e1de94211ff0e5667a218d71588f1e74102ccf0140b80925c277949871095","libcubeb/src/cubeb_log.cpp":"74bdc0d92a31d6b4ce3c376c6d310db583b869d673e40e6bd0ea795a1e2f937a","libcubeb/src/cubeb_log.h":"ee05fd22ed9820bed79247b8603cdc64f67bcb145be47e78bf0a0e99fb6c0806","libcubeb/src/cubeb_mixer.cpp":"4fd0b0ba6bcf13ae9cede517e427eae38fd7bd6c373deac0d5856a8de65f6a92","libcubeb/src/cubeb_mixer.h":"e94205c1b98859e41eeab2cad53f635f34f57a2ae95aa23a36461a2619abf81b","libcubeb/src/cubeb_opensl.c":"d10d2d35667a48c8fc31f0ecdd47a8c62d7988bc83fb53d4186d0f37c0fc2ad3","libcubeb/src/cubeb_osx_run_loop.cpp":"13c029f7ea04808597b8841b13f248c4476fb7425762f01a59bc6c944cab3a78","libcubeb/src/cubeb_osx_run_loop.h":"ffe80df60b8ea3d0341715b72cc60aae2e0df45141887c01117df543260a0ef8","libcubeb/src/cubeb_panner.cpp":"405a115ff0eb5f00dbab6bc8f2999b02ee4ea4792a87bad7ebd7218ee7980438","libcubeb/src/cubeb_panner.h":"5679df1b9d138c91f6ea642d51e6230cdf3163bdd65db156ad45906916cb74b0","libcubeb/src/cubeb_pulse.c":"7ff5378b793f16fe3a238cff655ad464c94c7a7fc86258bc6588fc3f429e281f","libcubeb/src/cubeb_resampler.cpp":"2d5f5f4ff242d61897b62b4aeaeee85633be54c1eb155c9e35a2c67d8d5b7043","libcubeb/src/cubeb_resampler.h":"ad9800a40c0272fb2a451c02367cc5a516a3067d4acf963d35eb31be367f9224","libcubeb/src/cubeb_resampler_internal.h":"4b4eb6aee343b9c1f73cf17b201329d3714ba44b06ecb1cebf950fdf93a9dfe6","libcubeb/src/cubeb_ring_array.h":"db8dec7a6d778a424045e5ac61c2bc3a3cec8c4fe8e4780f383db4b6f1b2438c","libcubeb/src/cubeb_ringbuffer.h":"2296255ca7835a3ace2fe1852054f43428b677f432b4174bd832ad0224a409eb","libcubeb/src/cubeb_sndio.c":"d64d6ed34987d89a3041988274834a8346c3af6f08e3dd641a0cef2c71eab6c3","libcubeb/src/cubeb_strings.c":"60f2b8c03a5a01925f9777eec0ab84b0e704b40c03e0d6b9c0e7a16246c81fde","libcubeb/src/cubeb_strings.h":"00e5dc97cf16e28cfb53aaae50ac0e3c0ae8a82aad0720ab6842ce5d9785c39f","libcubeb/src/cubeb_utils.cpp":"5bd7de8bbf7bbdc3a275525edd92bad590fb90fb4d35e77017fdd5d25a5769e6","libcubeb/src/cubeb_utils.h":"27baa42747771bf9232741382b83722f5c731e5dcd4dc2e9b595aca91c5647a5","libcubeb/src/cubeb_utils_unix.h":"2a48bd2aefa1b4e4e4968121512bcaaa6be3bca6597ea390b8203c338f5c49b5","libcubeb/src/cubeb_utils_win.h":"74658b6266a8a223c681b0fd06fcc9c891c7b0b95377635c6f1763b240c2ab27","libcubeb/src/cubeb_wasapi.cpp":"4a734b57d344b7cd6e430fe4e4fe42a673a7a4815fa569296d2f9faf5a833e15","libcubeb/src/cubeb_winmm.c":"3f59675847c8ff899d34898616d813b12bd3b6c925cb32fb43f6f9357d0cced5","libcubeb/src/speex/arch.h":"2300bce68c588270cdc684dc7f01377e5e251529f4545d93771e111c56d51b0f","libcubeb/src/speex/fixed_generic.h":"306ee7453677fa6067f16c79d358c6c90a9d3d008850b493cdaa59c07e6375c1","libcubeb/src/speex/resample.c":"9c3a1c64ecf3750af82c980d01ea73d3682f73c332a580465d1e787e5c54cd00","libcubeb/src/speex/resample_neon.h":"7d3fd7af9a1ddde22518b9c7b4419073b72b2dfa5be4c3bc8796992bc87b3da0","libcubeb/src/speex/resample_sse.h":"5a196d8e2d8ab5c956f5252f09f5ddc55aee1f99b1341af3fa54a1f4c2157924","libcubeb/src/speex/speex_config_types.h":"24e3ffbf29e5519611a48e5acb959645b01d166dcb4369380d5f776c3f53d4cd","libcubeb/src/speex/speex_resampler.h":"7e439ec0dd30c32216b3ced17135f8992e5aaf53389d3f5996a7d900c453e65f","libcubeb/src/speex/stack_alloc.h":"e8a2fc0874942d2c7177475fcc141fdd0c0156200b8a4e7656d4a20313e2e569","libcubeb/test/README.md":"1c11b038f87daf10ea78abc17bdbdd157940c241df548c24d5872d142a98c1af","libcubeb/test/common.h":"45eccf0f0c506f2f424149bc434180e296f85ed682b3ffca78cd53f91487d210","libcubeb/test/test_audio.cpp":"c10a9f438d8667153cde2ca13e4b2eebda22d0db93a045299fdbd8c924c44c6c","libcubeb/test/test_callback_ret.cpp":"fdcd25f6da30f2e1dba147d2a790994737d61afbaa30e0e0e9bf41dd5fa41953","libcubeb/test/test_deadlock.cpp":"c311519f30c05300715e91b529685a0c61b8e6b67161fa1f4aeb7030587d86f9","libcubeb/test/test_devices.cpp":"eec312a08667d053216a4266ef9e2b04dcdfa487cc4d34a811bb64cb33ed2937","libcubeb/test/test_duplex.cpp":"add22390fe2dbba09def4cece9a0a6a8e69b24a97f874312b931ece43b1ec4c3","libcubeb/test/test_latency.cpp":"0ace31644f499d69adcfa0aa3bad8c859ad51e97b622e2fa6d26374b8af12894","libcubeb/test/test_loopback.cpp":"e5dfcd868b25468a43dd4d8482702b9494e807db05c041b6fdcb295c59f1f01c","libcubeb/test/test_overload_callback.cpp":"8a05771e5bedfabf9f8a2e5a9266df90f5e964ead3b07782e2e435d7b69b0beb","libcubeb/test/test_record.cpp":"76d5b4f738ca7c30836ef6cc5851f3e04e396b21cf26511e0eeb7a616049fa04","libcubeb/test/test_resampler.cpp":"ca4bc0493ce0c3a5f02f389ac6e37bc2cdb9a752faad2b6fbc5af0a2223ef645","libcubeb/test/test_ring_array.cpp":"27836d716616abf8b020a710659c10ac5e1d4b64149d22cb89bd7a7a5a5669d1","libcubeb/test/test_ring_buffer.cpp":"f6e5a9f552f15808eb8ac3405559bf0ea61e7da4219cd14ac49fff3bfbf49ca7","libcubeb/test/test_sanity.cpp":"f978de12e7046518fbf848fcb5dbb2b5033c7624d5f4b59c0f3e02e7155c3884","libcubeb/test/test_tone.cpp":"3938250700c708c9c742ec8d0c9c2984f3e11860ff8dcacdf0ce785d4668f789","libcubeb/test/test_utils.cpp":"e8d7a02a9096dbc0fd15d71f9849415d52958d2ed82cbc7b8507d3228e08d382","src/callbacks.rs":"b4b4eb3f370475488d7c77b338b0bceee94ef59ede8ff41fa797a3d35ea98b5d","src/channel.rs":"555bc8d5257496cf6e5b4c786df84755327d88a9dc07202746e35f3b7b7e4e0b","src/context.rs":"96bf3442b1dd40262d3088dbb6c473f5451fd91320cef93c522b40f284599803","src/device.rs":"5b65e1c1fdd53fa5208f20bfb809475cbb3c434e02db7d0e4771d13c86f8e369","src/error.rs":"406e3b843ed2d263fe677c4b34fb96a6d780a68bcb56a6f85f041d20d70227bd","src/format.rs":"d4d27790c20eab0b16592f60d5e487425a45a268cf4c74cf843c10ac91bbff4c","src/internal.rs":"c3af5f53dc7957860bf3bc0cd9737d094fb8ac000e7b40c569304cfa76a43145","src/lib.rs":"cb49a3dd8782369172a2f8a61d5c74b4615bfb5fba3677af7d5c149e47d71815","src/log.rs":"6694178177775f2ce5449435d00609e9361c836e23119c07d04892000587dc55","src/macros.rs":"caef13f5d23f7a3ec1a54ec3ca2390ac4ad89d521893f1d0864daf70d57a20aa","src/mixer.rs":"e72e92855614da187da6419ed0a115062a05670cb73443b2ea4313d8f5108a68","src/panner.rs":"341af4b5a5331a3c1a4ab5396125a3600945e588ea33350431dfe6f1a9a0bd80","src/resampler.rs":"762070f8afde2256715b8764380cdfa1204a1a39d98a9da0b2efe88699792f2c","src/stream.rs":"ea3080b6225949938098e3ac38c42939c49a91b322b327ea66e959fe41f51763"},"package":"3ba7540c17b90159cf7d7854da370998ff0560d9b90e2c9290bb588afa0edf95"}
\ No newline at end of file
+{"files":{"Cargo.toml":"ed3411a6a717d7a7565cce826b14c7d0071bbce82a5323cc4d5bdaab71696400","LICENSE":"8c044baa5d883274736eeece0b955249076c2697b826e576fce59496235b2cf5","build.rs":"84f01f6c5f4559b87e348f6bc04d840a405889549dddf5e74cb486ad8b71bef2","libcubeb/AUTHORS":"829e45d138c7c8827799f302806fa4be8cd8bd4bad70a2fe26c3a27a5cf36948","libcubeb/CMakeLists.txt":"e050a0d22384d05452a2e2a4fa774cec0135b149f2b6cc4d5002ac38802a20d2","libcubeb/Config.cmake.in":"88019286c96ef3d5d3a673b183c8655dfc97ceede07d3eb6c18f0c51bb896388","libcubeb/INSTALL.md":"7a84cdfbe86e7d3180e2203603b88571df61b369421fa97ee86740ffd4d4db8e","libcubeb/LICENSE":"44c6b5ae5ec3fe2fbc608b00e6f4896f4d2d5c7e525fcbaa3eaa3cf2f3d5a983","libcubeb/README.md":"aa417156dc65069264901b75fc3c792c73021ec61c909de04e109bd4184c07ab","libcubeb/TODO":"6f8065136e005d2becee810e3d8697a94f2c755f8c79687adfac7136ad165e80","libcubeb/appveyor.yml":"9a87fdc18b76fca1167289ecb2ec3a210b76984c1d7e92268b2cd36f1e00f541","libcubeb/cmake/sanitizers-cmake/CMakeLists.txt":"89b282c19b3897ff666f7847d5e679ae928ca7e76ffd0d23f7c58c9464048b61","libcubeb/cmake/sanitizers-cmake/LICENSE":"4b67e7ae8c91e68e1a929eb1cbaa4c773c6d19aa91aaa12c390cf9560d1c9799","libcubeb/cmake/sanitizers-cmake/README.md":"f3b85a594e1601ae65bb09393c56fbc8a98e3f3f49234e56f86bd78803c3544e","libcubeb/cmake/sanitizers-cmake/cmake/FindASan.cmake":"bd30b1c3cb0682b8a2b0b599f6c51fbf99ef4908b00eba8826f0d484c623b01b","libcubeb/cmake/sanitizers-cmake/cmake/FindMSan.cmake":"55e40f0994b47f8e779622af2007c69252d9456be99f4aa4fba7dd49c23d5580","libcubeb/cmake/sanitizers-cmake/cmake/FindSanitizers.cmake":"2ffd9717a49e3e9de848ec0d91097bdbab3f75a7866211d902f9659f59271ffc","libcubeb/cmake/sanitizers-cmake/cmake/FindTSan.cmake":"ceace234abd5a463ad1b8134ad06c4c8004895b2e8fc9edb67e64620ea97ca47","libcubeb/cmake/sanitizers-cmake/cmake/FindUBSan.cmake":"4720ec96ea42a2a9c07d887c1fc5562ed3e8c222f5778a18b78c46678b23f156","libcubeb/cmake/sanitizers-cmake/cmake/asan-wrapper":"4e543936e6374e24b80a0f92135c07c2e2101c0d110e51bddaf0e70ae8ec391e","libcubeb/cmake/sanitizers-cmake/cmake/sanitize-helpers.cmake":"c0c225f22bebd27eb68b807b2a61962d28afc61609735fe652c2fde6aa6a005b","libcubeb/cmake/sanitizers-cmake/tests/CMakeLists.txt":"64b7aea469a043f27414e3d652aaa89a03a11843d152c4cd42f30561e6ef51bc","libcubeb/cmake/sanitizers-cmake/tests/asan_test.cpp":"a25de95282aaee22d977d0b474468b946c1422b80b15424c04266dba038eba2e","libcubeb/cmake/sanitizers-cmake/tests/shortest.ext.test.cpp":"a25de95282aaee22d977d0b474468b946c1422b80b15424c04266dba038eba2e","libcubeb/cmake/toolchain-cross-mingw.cmake":"1c26749465364061ddf37aaa00f363eaf057c4b6a70181086e13b0a4d09bd376","libcubeb/cubeb.supp":"19f33e59f8dc91a327c923e44c2c3f9af0a043ce1d6a8cac275ba094b4bfe0da","libcubeb/docs/Doxyfile.in":"0815f19789cedd310652a133bab260c27b57e95f7a65458df2dfca38ea4f1041","libcubeb/googletest/CHANGES":"72c8a289bfe4dd9160074a3a2238c8067a5bc7ca49fd87f70a134c3f373932a4","libcubeb/googletest/CMakeLists.txt":"cdf938ce79ea066866dc614de3925bfaa48d9e19e04049db2ec8c5443abaaa9b","libcubeb/googletest/CONTRIBUTORS":"4d911cd5e6d71f3f4bbcb2788b2f916df4b0ce1e088752a159457a1d936ae0ce","libcubeb/googletest/COPYING":"9702de7e4117a8e2b20dafab11ffda58c198aede066406496bef670d40a22138","libcubeb/googletest/Makefile.am":"a795e5a18e82ba06fd97509d92d773b7fafd0dd7086db8a1211fbd151b503bac","libcubeb/googletest/README":"484b19654362942fac9734c8fab0ed3d99249b81c69027bdb7de46054abada6b","libcubeb/googletest/cmake/internal_utils.cmake":"6f4670a5825cf8ae0415be9dd43d82a7f30316d75cab20a4c60afb6d9db2a01d","libcubeb/googletest/codegear/gtest.cbproj":"9fa07a66b8c01773256e508187775407c465ed9055651e93d390426d1888721a","libcubeb/googletest/codegear/gtest.groupproj":"76c001cb2ee0070e26d1570fb6db5250f2585179c707496c5ef6d12e582cf205","libcubeb/googletest/codegear/gtest_all.cc":"c8750dc2b7b3612edb60e8d23fc2f60ae264451916c4b15f81cbf60ea30eb75d","libcubeb/googletest/codegear/gtest_link.cc":"e5e47c086f932471e0ca748a62b3b1597e5e731f4d34fb8cb8b2ca2db7ba3ed0","libcubeb/googletest/codegear/gtest_main.cbproj":"056448ba7f41fae3f704b1001922d9f6e419cf8cbcf3a55bf0ecc59ece1fa9a1","libcubeb/googletest/codegear/gtest_unittest.cbproj":"2c48be90b0dbc3224a8bd6c4dc21f78dd1b08c81685e6bd4952bb6df6ee38701","libcubeb/googletest/configure.ac":"fadebffdaeaccebb60fbe4a501c1138c296e01348a5da45fabf5e4233248baa8","libcubeb/googletest/include/gtest/gtest-death-test.h":"fdd087f700cd04a3ce4bdd36f35769de52a44bfc0c5bae2dc9681d4cbcd3c44a","libcubeb/googletest/include/gtest/gtest-message.h":"eaf44df1284d94333507c47091c84eaaf43814e6a02a1b1c0061ca7b363e74d6","libcubeb/googletest/include/gtest/gtest-param-test.h":"f226f0a24c04cddbceaaa45d8a5e575ce18c3392349f9b8ba73317e37e62368d","libcubeb/googletest/include/gtest/gtest-param-test.h.pump":"17c65fd5cc5218279044a61f3873c9c952b0924a7ba5147d4999d400b122207f","libcubeb/googletest/include/gtest/gtest-printers.h":"7046f611398d63ee0f1c37bdb4fd08d9931979b2fedf13b781e6d85d4b3b5d60","libcubeb/googletest/include/gtest/gtest-spi.h":"560407dd45e8e57fa6927504c9e4a4cfdecf30f8cada975c1ffddce765e6a88a","libcubeb/googletest/include/gtest/gtest-test-part.h":"c4d6d840284728740c284646075e8ffc85b63b9f74f3ed488b18ef3c2c2b9005","libcubeb/googletest/include/gtest/gtest-typed-test.h":"1ec858bbb9ed8a8bb553232df016437c080b2670f00453b4de297c286eb78c21","libcubeb/googletest/include/gtest/gtest.h":"47433ca72a43bda7a380c34fe6d4ff451797c687e9bbd74d1f366bcdfa0cb013","libcubeb/googletest/include/gtest/gtest_pred_impl.h":"f03a3f77e3c231889c0ace6f63b2c4e410e4a9330287ea09443b23b9a3cf9092","libcubeb/googletest/include/gtest/gtest_prod.h":"4a99a3d986a45b4d6d9b3af54809f015c54aa98274793a4ae173f5010d0ad33c","libcubeb/googletest/include/gtest/internal/gtest-death-test-internal.h":"0b3abead866363f3e6b4201acc8d2763072e033826b22ae5ebffd790e1415235","libcubeb/googletest/include/gtest/internal/gtest-filepath.h":"638d2bb6c06a894513b03311a8e931ac835fc00afc4bd21fab3afc05732c23a0","libcubeb/googletest/include/gtest/internal/gtest-internal.h":"12c2c83df0a9dc5b46697ccd8271dfa34ee5f3d1972dcb56585bc1459d9583c9","libcubeb/googletest/include/gtest/internal/gtest-linked_ptr.h":"9bd319548dd073630dfd349c06a440c6a582feec47d4ff14f348ec32f8b4c1f3","libcubeb/googletest/include/gtest/internal/gtest-param-util-generated.h":"10db93fa7e98820192bae6f560664469dd33b265036fca64253c89b6801f96cb","libcubeb/googletest/include/gtest/internal/gtest-param-util-generated.h.pump":"abb72365d94d2811b34c195dc520fbf41c7dcb42aae5a1cfa0502cf619b21e70","libcubeb/googletest/include/gtest/internal/gtest-param-util.h":"7f9311f033ef6916217d87cef53b1db6c4e8733be930e4b48fe7e11d21b33da0","libcubeb/googletest/include/gtest/internal/gtest-port.h":"612932c2930a7cf2c3514d89a8d6b51a2c0030d251309b71765ed1c9954e20c5","libcubeb/googletest/include/gtest/internal/gtest-string.h":"a46aa36165c400d1e926f942be03fe04cd7ccb1e59f7a2a03b919c4eea05b997","libcubeb/googletest/include/gtest/internal/gtest-tuple.h":"43e7e3c92f8e4258cf3927a9204b214d4d03e6c796f88f3ad4e66b1ac20aa938","libcubeb/googletest/include/gtest/internal/gtest-tuple.h.pump":"16fa027ed3c5940699e0ac906815e66620993bcf75b0acaf826d4f09348d4b83","libcubeb/googletest/include/gtest/internal/gtest-type-util.h":"6d177af46a9b1e14b969972a8b886667f95e69037aba411433a44fb9b92e7037","libcubeb/googletest/include/gtest/internal/gtest-type-util.h.pump":"22092f44127af91651f57ce222e20914d5d32ae02f1c0964f6d5d7bc019af339","libcubeb/googletest/m4/acx_pthread.m4":"3326e3746b6b351d1671fe31f798269cda8de92c365b8a8305404ec0fa6c6b32","libcubeb/googletest/m4/gtest.m4":"d3c37ebd1aa792c967d4357755cc670bc6deb30091d9e6db498871d90a30ea4c","libcubeb/googletest/make/Makefile":"9b86e2a112dd55c6bf6a2b39e6f4078faf60cfecb8282ebf9b025167ed233420","libcubeb/googletest/msvc/gtest-md.sln":"0beab679b42cf0c431eaf4fe143bbf3b01fc064e20c74d9e33e7e437a70487d4","libcubeb/googletest/msvc/gtest-md.vcproj":"52e873e964daf9d5409b4e9bb471ddf2827be04985cd96c40620f9275d17a256","libcubeb/googletest/msvc/gtest.sln":"be21c2340650ec2259a2fbaeb8608ae6d3e982a0626a0f91128a771dc88e6bea","libcubeb/googletest/msvc/gtest.vcproj":"0064616c7d88a284c1b7c05baab038f239134ea9c6c563628f286f9600b3f921","libcubeb/googletest/msvc/gtest_main-md.vcproj":"f83a294a92b616bf34ccae6743ff916297bdba61d6125a9637a813d467a30372","libcubeb/googletest/msvc/gtest_main.vcproj":"9f03270a00896eab0c7015c6fb1a73818d024e462d3944ba1d3ceb313a051649","libcubeb/googletest/msvc/gtest_prod_test-md.vcproj":"7caa108733e2d5f140da004d2133e04a9a105811909c0e2d4ec06e2971983592","libcubeb/googletest/msvc/gtest_prod_test.vcproj":"cf5bfb7f3de9a59a0eba5535067845d12c33c3fd8fecc3d03aa702665db29578","libcubeb/googletest/msvc/gtest_unittest-md.vcproj":"e7949b21cf0418f2a7afe8aa94616e2c40e3ba0801c2f0826f3a3a3d2e6f48b0","libcubeb/googletest/msvc/gtest_unittest.vcproj":"5b097d596fbbc1c4090fd518008a0961b29661194e1c02d8a2d3daaa557e626f","libcubeb/googletest/samples/prime_tables.h":"2903df1d1e6643a5f624fe3ea3f931c3410eb1858ac347c5df278273c6c91ca4","libcubeb/googletest/samples/sample1.cc":"dc106c5940d87bb4bbef3d77815eab642ee173a3340b2b9c532b5c711c4c2d0e","libcubeb/googletest/samples/sample1.h":"7a7bf9a0fbd2401e8b2cb554bfcb9bd0ed228212f3b970675c1b1d38d4e188bb","libcubeb/googletest/samples/sample10_unittest.cc":"ccebb6393a5a8468399f7e511219b667a2233f82312ce59834a4bb0997d8700e","libcubeb/googletest/samples/sample1_unittest.cc":"904be0d4a095e74393515195392bd10e1e916bb2ca61f3f94b1bd6aebea29cb6","libcubeb/googletest/samples/sample2.cc":"f14b8a1e69d52eef1a70053fb256818c7eca64e8eda08de43cf46e896e57fcc2","libcubeb/googletest/samples/sample2.h":"df956ba520dafca068dbc1e28f36567db3cba36293e06762318af8cda6a12bd4","libcubeb/googletest/samples/sample2_unittest.cc":"abe7e0b253d328cb82ae67623fbe3c89eb94699102510c64a0b568eaca101e05","libcubeb/googletest/samples/sample3-inl.h":"3fe482bbd4f725f5820f5d6beab4d0d4a524be8addf4b344a9a470ec5aabc451","libcubeb/googletest/samples/sample3_unittest.cc":"252c06b4531dc35213ebdd7311700b9b4057bc1bdeeba0cd767b2bc86c456639","libcubeb/googletest/samples/sample4.cc":"b4260f5fa35d78ac114a9abb59fce12403faf0273df41f57e83c341ae7979222","libcubeb/googletest/samples/sample4.h":"604905cae7e5587805c3b884a36eda7a2bebdfedb53b24b0fd9a220eec0ef1a9","libcubeb/googletest/samples/sample4_unittest.cc":"6cfb4821d8cb1c77fbb5af4f8aec569948762d8ea314827e3ead967b5b6a223e","libcubeb/googletest/samples/sample5_unittest.cc":"73646d9038873a68bb2e56b12495d7f7b65b5c23901109701da446af454ba2ec","libcubeb/googletest/samples/sample6_unittest.cc":"833fee399954f908cf0f3b789832e505329787f4cf73607a7b31ca0f62f368d7","libcubeb/googletest/samples/sample7_unittest.cc":"8013ee68d61c181e4e936cdae3a9a635646274f8512033ef11bff7214e03e4a6","libcubeb/googletest/samples/sample8_unittest.cc":"7b7510fadf4955d2f934d23d652dbd35add832e50bdfcc98421fb9be4588d808","libcubeb/googletest/samples/sample9_unittest.cc":"8b827040dea37b460cbcaea0b255b98974a9840f6ef7bd82aaa7d4ad2c724335","libcubeb/googletest/scripts/fuse_gtest_files.py":"adecf64c6bab65b31740c321e568cf174f753d5617745aa5762d842339d68b53","libcubeb/googletest/scripts/gen_gtest_pred_impl.py":"78fb7e20a014c251d723186eb58040e4eb32405b73c9288d787ea0a0e4ff5183","libcubeb/googletest/scripts/gtest-config.in":"9a43978eeee88e188845d737c17f4d024d4e74feae09da7997e8fbe4ea6cc176","libcubeb/googletest/scripts/pump.py":"3856a3d7be37f78e0f214ee7d4f29d05f1ca14218b67539d67c9a16e992f670c","libcubeb/googletest/scripts/test/Makefile":"3576b257594a2d8e843b9e4de8c83353d837833bb86431fb1b4198022b1bcddc","libcubeb/googletest/scripts/upload.py":"f75d0712e3b13bebd8daa0a15e4eb32c9e3034a933f4fcccf65b1e999a7ae066","libcubeb/googletest/scripts/upload_gtest.py":"6e76fc0a7a3831c01cfffd18c220d44438073a66338d91ca61fc84b924021e61","libcubeb/googletest/src/gtest-all.cc":"568ac119f5e6418f1fbcfbdf185d724657d7f3539b47822da229ac5d015626b2","libcubeb/googletest/src/gtest-death-test.cc":"eec1b3c8252670c76acbbaf63483946897ce625139b53a566406b6313f023896","libcubeb/googletest/src/gtest-filepath.cc":"31b7fcda5d11346f8a487597c6a70ff057f1192e0cb11f27eb7841a9f3aa8b86","libcubeb/googletest/src/gtest-internal-inl.h":"c9d428a6b5990ace091e40c4ce8b7bf6c50c186a8314b1c4a4cdc988ca0ac1a4","libcubeb/googletest/src/gtest-port.cc":"95bcf473622d1b901c734e5c2aeb8efb058555ec924212a61bb04f049bb5a069","libcubeb/googletest/src/gtest-printers.cc":"6f191a7fc7f5a0a967fd11964057f2e2d2eaf2f37ccece16bd816531f52b3154","libcubeb/googletest/src/gtest-test-part.cc":"e489868b4cdc66f4fc33bc2326ac86bc1acc5808ab58bbb288c9dcfc330faddc","libcubeb/googletest/src/gtest-typed-test.cc":"ca9e819df728c25a6a1fc072806c22f3494e1dffe4bd0d48284f38dbdd3a0dd5","libcubeb/googletest/src/gtest.cc":"5cf9a3e897892c9f0e5c887f91d3c8c8c5665bd7348560441fc0b946c254873c","libcubeb/googletest/src/gtest_main.cc":"22fa1f77542b882d1798d7f696045c5895942a626e26200a175fa4382e1fa5b5","libcubeb/googletest/test/gtest-death-test_ex_test.cc":"613ccf50a3ff8f84c975a13e86ea01ea4e36933072388a3738b4acf9ed3ed7cf","libcubeb/googletest/test/gtest-death-test_test.cc":"df8384a847bdf889233c3d45d171f784991def7a9b6a08442138569fbae32b9d","libcubeb/googletest/test/gtest-filepath_test.cc":"49760f91723845b113bb60bb9b1a1426ed1da1f4ebfef2462128980ea5692cc9","libcubeb/googletest/test/gtest-linked_ptr_test.cc":"1b9cb4ff67475900db9de34ae9749b94193048a1f7a741091ba5a2dd7fc7a79b","libcubeb/googletest/test/gtest-listener_test.cc":"acf78f2c9a730525ea5adc93e9196a42de8fbfe488db1dfd02656bdbd477b2c0","libcubeb/googletest/test/gtest-message_test.cc":"b1fc68f8b75ce25fbd79b3f7d3c9c793381ef07b3203e1a2d9b610cb597542be","libcubeb/googletest/test/gtest-options_test.cc":"74e3ae0c310edb3139b0032266219d3ce7f386ded6feafa57fef03f4493ed7fa","libcubeb/googletest/test/gtest-param-test2_test.cc":"a0f1efbcab3f7e49df639383157626931f64756f7e738be081760f93f7308332","libcubeb/googletest/test/gtest-param-test_test.cc":"ef8bd344e959053f562b0c9e0d15e2fb6c1e534772a67aaf3f90bd6bad0bf99f","libcubeb/googletest/test/gtest-param-test_test.h":"9d7f47b79d54df7cc050aa6038b0464aa684dfca669a847bf70ea16e4a000628","libcubeb/googletest/test/gtest-port_test.cc":"1600f78ef0860a0f5b5525e5e5041ff32a216cc6ae948b1ea61fe04ec603f67d","libcubeb/googletest/test/gtest-printers_test.cc":"7898e4b4163ee0821fed248e1c75d9f4a0a511a2b4bbfad1ef2f4a11a099f6e7","libcubeb/googletest/test/gtest-test-part_test.cc":"62c8906bb0d12ea84d60217b3773cd8e1768db4aab934880db2316df7026cab8","libcubeb/googletest/test/gtest-tuple_test.cc":"2850dc1f73a3f8020d8a4d80688a28d9b736eae6d677222c3f871d8d33b25501","libcubeb/googletest/test/gtest-typed-test2_test.cc":"c52b65e7181610d6e577631cd50177399884913ff28d08aedfedc92f05185044","libcubeb/googletest/test/gtest-typed-test_test.cc":"c7daff5211028da79b3ca0473dca18ada9197f38e710f72d0493ad3332ce3ec9","libcubeb/googletest/test/gtest-typed-test_test.h":"3145698534d8869beb624c9c8ed114f75bead046b2eeb92ada5a724993ee7786","libcubeb/googletest/test/gtest-unittest-api_test.cc":"e3f54c28ef2849e8b12af666ed46aace50c3e047845072ee6f974ce4528bd297","libcubeb/googletest/test/gtest_all_test.cc":"db0c3c42b385570b1d517e3ee927671b8fad4e206247fca738ec477222ac3d97","libcubeb/googletest/test/gtest_break_on_failure_unittest.py":"11c91bc1c68cfdb913e2affb01261b55fb3b0c18773a45875e9c25cb330a4dcd","libcubeb/googletest/test/gtest_break_on_failure_unittest_.cc":"1da12e4bdda2a0bc7b59d4638fe34b2d3798134224fd9237eeebdd09c3326011","libcubeb/googletest/test/gtest_catch_exceptions_test.py":"305cef45c6dc034bdf72fd91aba1e89e1c6b5d222c3d6baffff5acdfd9b3873e","libcubeb/googletest/test/gtest_catch_exceptions_test_.cc":"b297a4f4d5bc0285ea9eb8869741631658305e49d4513bca904842aacb82128b","libcubeb/googletest/test/gtest_color_test.py":"c4cb006682a40f2d88759a4bcabf0d4be623720b135c71447f1788d17ea23d0f","libcubeb/googletest/test/gtest_color_test_.cc":"f263ba349afe58a558bf0fee98a98bb9207a648e7cd4f908a87799bd13d001ea","libcubeb/googletest/test/gtest_env_var_test.py":"79819598cd1e366eaa8f2a4fee2d638b6ef0686e490402fae792ccce58d876c0","libcubeb/googletest/test/gtest_env_var_test_.cc":"0eee5dfbb2a2598f4e76626346b921928ec1e052e38f254cc97c60d05611ab46","libcubeb/googletest/test/gtest_environment_test.cc":"a52a21ea29c2203b03fa93922733546d171f98d3b2fcd42972269e98fd124715","libcubeb/googletest/test/gtest_filter_unittest.py":"edc7d278803bba41626eacd050d91d7247f1c5999f9dceb99a8877e238bc73d6","libcubeb/googletest/test/gtest_filter_unittest_.cc":"996ac528ad75c293d8201ce28cf6acccee266286bd369b4cf43f05b8d67a4559","libcubeb/googletest/test/gtest_help_test.py":"b43ab690c08e4bffd84a47b361167496298697f9511bdf4a745bf305b5cfbdfc","libcubeb/googletest/test/gtest_help_test_.cc":"ff4b121098f0fe7cb4abf11fdd31f2fe7a477286ec9175482138bc038d61c807","libcubeb/googletest/test/gtest_list_tests_unittest.py":"7caebc175b44b3c727fc50420ada1a6a9500f3e4ce9e2839f69205437aa85e7a","libcubeb/googletest/test/gtest_list_tests_unittest_.cc":"d82d8b72914897232c2ff9fd091a7b0add68b7cf75f3f210d3a487ebeea84cfe","libcubeb/googletest/test/gtest_main_unittest.cc":"0f66f318809c88f0fbe034a340a75331720c4e33be5378022baffaf588ef1202","libcubeb/googletest/test/gtest_no_test_unittest.cc":"7cf487e07c3d27376c2cb8af33d02239b7966623875d37b7aa0259e927a9c2f6","libcubeb/googletest/test/gtest_output_test.py":"cf0dc1979572d94450a5e611b44f3fdb88d9cd980d669a723f0ed63057b5e2c4","libcubeb/googletest/test/gtest_output_test_.cc":"f69569374c2b3d06aa04a38ebc4f92ddc303e6af503f8b533cd8e6bf9f104899","libcubeb/googletest/test/gtest_output_test_golden_lin.txt":"4f3e49c10a524a99437cdcb5294e3335a7f3c07ea8462e65730f703a5fe4fec3","libcubeb/googletest/test/gtest_pred_impl_unittest.cc":"e406eccf75b6b58746a95d1c7ea7bc8e80ff974e438ef7c83074a46d4e62db9a","libcubeb/googletest/test/gtest_prod_test.cc":"b42ca1a6d0a1e43bc576b4ff7776c6d2c37234f6dc2a76f2735f261b4a47a526","libcubeb/googletest/test/gtest_repeat_test.cc":"e10abbb71595920aa3bb415029eed74106335fc9ea3d58c417ccfc7cba6a4cdb","libcubeb/googletest/test/gtest_shuffle_test.py":"12dd94eb5f30260ba37059fa74658bda57dffa821f3ba6a2a8b52ff14b1ad029","libcubeb/googletest/test/gtest_shuffle_test_.cc":"af1b2b01ae275f1a9fee7e7940c0f88f39ded063008994d585aad87e3ffadb39","libcubeb/googletest/test/gtest_sole_header_test.cc":"538414c27a593ab8dc34c37b5c877eb3a022d75d1b481ef14ceca00914929754","libcubeb/googletest/test/gtest_stress_test.cc":"0b02fc12f87944226915a999bdcc8a3eaafb34a1ea5bb0df128774abf8667f09","libcubeb/googletest/test/gtest_test_utils.py":"d4a76930aee6658ad8734981ca0c4ea14f34dbe8fdd31d5afe41f6d98f9779ee","libcubeb/googletest/test/gtest_throw_on_failure_ex_test.cc":"11ae790028da20bc7b7af1572eff3cfe8499be43ab64c110e18e1892612a183f","libcubeb/googletest/test/gtest_throw_on_failure_test.py":"ebe18ca0b07f90c53b9b3f9a54ed02df94facf8995cfa90dd41c6f5474537c13","libcubeb/googletest/test/gtest_throw_on_failure_test_.cc":"f8cbf75d8bf9e9ae068a17ff968434c3aec7b7f1137c994d8f14af1a84361aa9","libcubeb/googletest/test/gtest_uninitialized_test.py":"da8e6ce34930753e36fc1dfa2c3e20e48d02bda2a27d3d03a07364312c5f3bd9","libcubeb/googletest/test/gtest_uninitialized_test_.cc":"0b6a9d4983480f87352ca4da946089264b401f7a4a3b1282253fd6cc861bf483","libcubeb/googletest/test/gtest_unittest.cc":"c0c7d1f691ce1e10c3d1647ed5f7a66510725808ad58bb6da4bc03a7a08fb2fc","libcubeb/googletest/test/gtest_xml_outfile1_test_.cc":"29341d777a9c9d25f360d13ed966b30f0cbef1fc88aefe2f01bb88b82cf1ed93","libcubeb/googletest/test/gtest_xml_outfile2_test_.cc":"da7ab3cf0e9b2a293eceed7c5691233d6b61afb557e3c1176dfb75390f85be46","libcubeb/googletest/test/gtest_xml_outfiles_test.py":"b07927b43f44afbfd61761c2cc69f1b68c4fbdeddb992db03ff0c73052518cd4","libcubeb/googletest/test/gtest_xml_output_unittest.py":"b5ff0c0207238d01cada961b8f4656f2ec30a3e1e5bf9d22efdf1745af423031","libcubeb/googletest/test/gtest_xml_output_unittest_.cc":"ad0b9ebe63a146e386df3c5c51916869f6d4647b9832ceacc912fb1272d15f82","libcubeb/googletest/test/gtest_xml_test_utils.py":"ad89a39a6cd5b08e87082341f3e7800dbf1150ea0f1386e0b8cd374aa6832f00","libcubeb/googletest/test/production.cc":"56fef77c3a8e62073ec11653d740a8e534008a0d57925ab0877b843f4fdd6be8","libcubeb/googletest/test/production.h":"a36d10545d12ead5e93a3b0fdca6ff73405f29091cfe38164415e9038888ba8d","libcubeb/googletest/xcode/Config/DebugProject.xcconfig":"fb42302df29bd8e8b5237194c0c04941f0e578527037930d88469baeb7a7f62b","libcubeb/googletest/xcode/Config/FrameworkTarget.xcconfig":"9935ddabe221f074d2f3b969a137d12b0dc0f845a460f58b63232987cb0f37ff","libcubeb/googletest/xcode/Config/General.xcconfig":"0fb768924daba1048f8db28b3a1fbf915b6f788d49d9d37e85979aa4ee92e02d","libcubeb/googletest/xcode/Config/ReleaseProject.xcconfig":"a4878ddd1ed78fb411906623cb51bc0ab4aea1cc3feb5379d2ae2862d8bf3bf5","libcubeb/googletest/xcode/Config/StaticLibraryTarget.xcconfig":"5886291788b3e9d5aadcb979ff055fd26a2413be81016e7afffb813b627d177c","libcubeb/googletest/xcode/Config/TestTarget.xcconfig":"f074e6c2516a6063b253ec6b842d74f5c2abefc7bcf8d8da54097a7bfe016480","libcubeb/googletest/xcode/Resources/Info.plist":"5b7f78a6d5810ce5490649793175c8982d41e6b49af06bc0705bc061567cc9aa","libcubeb/googletest/xcode/Samples/FrameworkSample/Info.plist":"1c13d83e5eed45689d7fe4bf4681030366474bc40608e39e1623c1350513a0cd","libcubeb/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj":"1cf0e1b1abf84414372faf9c8bf634e01fe5750bb3ca769b1eb25fc530b21358","libcubeb/googletest/xcode/Samples/FrameworkSample/runtests.sh":"a587e5b00a8353dee0aca5a4c59b28301ccf7648dee8c79b62a9223f9fc3c8cf","libcubeb/googletest/xcode/Samples/FrameworkSample/widget.cc":"562a2bb615e93186012823c9b41761769638a11e38b54498ad5f699038c8fd32","libcubeb/googletest/xcode/Samples/FrameworkSample/widget.h":"0c7915e45cf7cb8d67db24e49cd0b277f23f967578f917f8e859a6adc4b156f9","libcubeb/googletest/xcode/Samples/FrameworkSample/widget_test.cc":"6a1a49d64912d9829ef3d991faf5a3f0e1e081126a1d8d387cdfa84fab70dc77","libcubeb/googletest/xcode/Scripts/runtests.sh":"1a0672a4151b16f3c797478ba26c534e82b2faa603f90b9aa14e785805f7683a","libcubeb/googletest/xcode/Scripts/versiongenerate.py":"4b9d5c0f4e1b556084109311d156bee6d781968dc5b1dfdc8702364508f1dd43","libcubeb/googletest/xcode/gtest.xcodeproj/project.pbxproj":"a1224decff058bfed01b8eefaee13cab0129492615548c6d0d878003a154f7ff","libcubeb/include/cubeb/cubeb.h":"7fde26ac5d7b1754369abbe66b4bed148e0ce5af17304cb869a85fe427e558f2","libcubeb/scan-build-install.sh":"1ecf22aca367a4d02f810c4cb78db8636e08a12787e94e30c441ce439cf4a265","libcubeb/src/android/audiotrack_definitions.h":"0d5ec772f9ebf61333bc16e61a081a7e3b4cc02342ec4f8f417e220d032fbbc6","libcubeb/src/android/cubeb-output-latency.h":"000fb7bec38105f54b9d40fc436440c637d63390b219775d335216d29d767226","libcubeb/src/android/cubeb_media_library.h":"f67965fb2ea38f0023eb4c76024341ba9563ac1a135507b6f12a9aabd85e30a9","libcubeb/src/android/sles_definitions.h":"66d10b157e463ee106236736b0338d1ec512d66d577ecafda56427bf14658443","libcubeb/src/cubeb-internal.h":"ef7e7e19c40f743c814a39b8a47b9f03df054894018ad88b49129ffad2564bfa","libcubeb/src/cubeb-jni-instances.h":"8195554372bf60dea569873c9e5fb1106a2cf5dedc66a13d2bc967da0ff48a12","libcubeb/src/cubeb-jni.cpp":"81f001720c41c69b5927e32bd19b9e8e7176d7c33d63c2a58bd0d695dace4fd2","libcubeb/src/cubeb-jni.h":"73f810a32087a6062fd49ba89542655a7e19cecac6f40f8411e1d77ce42a45d1","libcubeb/src/cubeb-sles.h":"dc84a01ba4de9db1ff108609930b36ba442020ccc3e3d6f16528f429426c430c","libcubeb/src/cubeb-speex-resampler.h":"dbf543eee4cc6e40ba3531a39d327e2cec884c19e26c570aa7eae0647e5f7420","libcubeb/src/cubeb.c":"537d418a17c85c855dfd559e07d2593b09489ed51fd3e8b2e08586c1c9a54288","libcubeb/src/cubeb_alsa.c":"6c833e379eea5d64a65a209f8e60c2aa2d6e038ea855554cd3f2664c463abbcd","libcubeb/src/cubeb_array_queue.h":"5264ae02799c540ff73e8eb8efa55986772b22562a025ae227c2603b6b8d1036","libcubeb/src/cubeb_assert.h":"ab8ed4fe7070a3aed9419c5f9695fce2318c4dafd91213ae61cac476e64adaa7","libcubeb/src/cubeb_audiotrack.c":"fe66d36dfecbfaad164ee8c871b39fd6e708a2f8f1f8524a5c0148ab86bab467","libcubeb/src/cubeb_audiounit.cpp":"9b869e260c32f0fad7b1f05803efcaa0a9afabf6cddf118e0be678424bc1be48","libcubeb/src/cubeb_jack.cpp":"129c011feb01e8c6d573862218c31a8bf90522539a28a5ece8bcf87867be9daf","libcubeb/src/cubeb_kai.c":"a71e1de94211ff0e5667a218d71588f1e74102ccf0140b80925c277949871095","libcubeb/src/cubeb_log.cpp":"74bdc0d92a31d6b4ce3c376c6d310db583b869d673e40e6bd0ea795a1e2f937a","libcubeb/src/cubeb_log.h":"ee05fd22ed9820bed79247b8603cdc64f67bcb145be47e78bf0a0e99fb6c0806","libcubeb/src/cubeb_mixer.cpp":"061427a06516792ead3936a643224c3d275913410f67765cc24e1b8699e8d99d","libcubeb/src/cubeb_mixer.h":"e94205c1b98859e41eeab2cad53f635f34f57a2ae95aa23a36461a2619abf81b","libcubeb/src/cubeb_opensl.c":"973389c53f0d8524ed2d2a64e66c942fbe5365b75eaa65ccd4b20cc12e66f96f","libcubeb/src/cubeb_osx_run_loop.cpp":"13c029f7ea04808597b8841b13f248c4476fb7425762f01a59bc6c944cab3a78","libcubeb/src/cubeb_osx_run_loop.h":"ffe80df60b8ea3d0341715b72cc60aae2e0df45141887c01117df543260a0ef8","libcubeb/src/cubeb_panner.cpp":"405a115ff0eb5f00dbab6bc8f2999b02ee4ea4792a87bad7ebd7218ee7980438","libcubeb/src/cubeb_panner.h":"5679df1b9d138c91f6ea642d51e6230cdf3163bdd65db156ad45906916cb74b0","libcubeb/src/cubeb_pulse.c":"281d8115f0e6759ecc5a323c8d61f70eb27e339539946253a773924c2fd9c491","libcubeb/src/cubeb_resampler.cpp":"f58deac4d17f004e8b31773335bb0cafbde08494cbda8453fa39a36617e47337","libcubeb/src/cubeb_resampler.h":"ad9800a40c0272fb2a451c02367cc5a516a3067d4acf963d35eb31be367f9224","libcubeb/src/cubeb_resampler_internal.h":"4b4eb6aee343b9c1f73cf17b201329d3714ba44b06ecb1cebf950fdf93a9dfe6","libcubeb/src/cubeb_ring_array.h":"db8dec7a6d778a424045e5ac61c2bc3a3cec8c4fe8e4780f383db4b6f1b2438c","libcubeb/src/cubeb_ringbuffer.h":"2296255ca7835a3ace2fe1852054f43428b677f432b4174bd832ad0224a409eb","libcubeb/src/cubeb_sndio.c":"6613d8555b4faf1f047d706ae37473effaa645d9846458eac24ae0973432ce61","libcubeb/src/cubeb_strings.c":"60f2b8c03a5a01925f9777eec0ab84b0e704b40c03e0d6b9c0e7a16246c81fde","libcubeb/src/cubeb_strings.h":"00e5dc97cf16e28cfb53aaae50ac0e3c0ae8a82aad0720ab6842ce5d9785c39f","libcubeb/src/cubeb_sun.c":"b0269c4b9fccaa44a11ccee9afa074659710591aa99e75e0d2e33724f20414c6","libcubeb/src/cubeb_utils.cpp":"5bd7de8bbf7bbdc3a275525edd92bad590fb90fb4d35e77017fdd5d25a5769e6","libcubeb/src/cubeb_utils.h":"27baa42747771bf9232741382b83722f5c731e5dcd4dc2e9b595aca91c5647a5","libcubeb/src/cubeb_utils_unix.h":"2a48bd2aefa1b4e4e4968121512bcaaa6be3bca6597ea390b8203c338f5c49b5","libcubeb/src/cubeb_utils_win.h":"74658b6266a8a223c681b0fd06fcc9c891c7b0b95377635c6f1763b240c2ab27","libcubeb/src/cubeb_wasapi.cpp":"ab8cd5c8aa5dbd0f9180697d17df4bb00c0c61319d464154d37a368971163ef9","libcubeb/src/cubeb_winmm.c":"4f3d2b1e51b45f75e524a74d5b0adecc47db39a1204cf2bfa46741169f73d121","libcubeb/src/speex/arch.h":"2300bce68c588270cdc684dc7f01377e5e251529f4545d93771e111c56d51b0f","libcubeb/src/speex/fixed_generic.h":"306ee7453677fa6067f16c79d358c6c90a9d3d008850b493cdaa59c07e6375c1","libcubeb/src/speex/resample.c":"9c3a1c64ecf3750af82c980d01ea73d3682f73c332a580465d1e787e5c54cd00","libcubeb/src/speex/resample_neon.h":"7d3fd7af9a1ddde22518b9c7b4419073b72b2dfa5be4c3bc8796992bc87b3da0","libcubeb/src/speex/resample_sse.h":"5a196d8e2d8ab5c956f5252f09f5ddc55aee1f99b1341af3fa54a1f4c2157924","libcubeb/src/speex/speex_config_types.h":"24e3ffbf29e5519611a48e5acb959645b01d166dcb4369380d5f776c3f53d4cd","libcubeb/src/speex/speex_resampler.h":"7e439ec0dd30c32216b3ced17135f8992e5aaf53389d3f5996a7d900c453e65f","libcubeb/src/speex/stack_alloc.h":"e8a2fc0874942d2c7177475fcc141fdd0c0156200b8a4e7656d4a20313e2e569","libcubeb/test/README.md":"1c11b038f87daf10ea78abc17bdbdd157940c241df548c24d5872d142a98c1af","libcubeb/test/common.h":"968144634f3ce627d7f6cb91d48ddc6f1fa89f481ae63f80a7cbe743989e449c","libcubeb/test/test_audio.cpp":"95337fd7f55c91af5ab0988a727566ecb04314979094834624d5c10cb206e0b1","libcubeb/test/test_callback_ret.cpp":"f2d190ec14b2da927bb4cd759f775cd3b7f38df3cd2984862b346f7c37eb9ca8","libcubeb/test/test_deadlock.cpp":"0e28e59f360e27241536879d9e02e4e05291db252f66fd601577aaf723e06543","libcubeb/test/test_device_changed_callback.cpp":"c30bcd2ec4348f56c520952cef18a47c430f121cad59d64d648498c14e79f080","libcubeb/test/test_devices.cpp":"8c61e4319af2af5a59103fccd216c666424d42b859b8719166513e26eebd39c3","libcubeb/test/test_duplex.cpp":"fa9944a3d7975b21ad0b61690f2ab40c4ed16a4c3f2758d7b6ad0df60cbb0768","libcubeb/test/test_latency.cpp":"dc5af071df0ff0c4b2f6cf7b37438ac8ed9f18cc0fafffb2c685b1e82201c9f5","libcubeb/test/test_loopback.cpp":"f67c2828e2e238f07a0d1371d42ae916b9d7decfc4233fcf4d632346ef98871d","libcubeb/test/test_overload_callback.cpp":"f3ffa014a0e6f7871a023b46733f93d992ddc9b41e0974cc22a365979b6d989e","libcubeb/test/test_record.cpp":"89a884872b780005b2fb29d106b6f33ddd76b2fcae381395e17d3413153b3b89","libcubeb/test/test_resampler.cpp":"ca4bc0493ce0c3a5f02f389ac6e37bc2cdb9a752faad2b6fbc5af0a2223ef645","libcubeb/test/test_ring_array.cpp":"27836d716616abf8b020a710659c10ac5e1d4b64149d22cb89bd7a7a5a5669d1","libcubeb/test/test_ring_buffer.cpp":"4ca684e38f1d34bb1f625ce2a2a730e5b24e09d1107f108e8b80731e55315861","libcubeb/test/test_sanity.cpp":"509cfaa6ad932e47861c00236ae27b59056547355bde78707dbe34a17a5005a6","libcubeb/test/test_tone.cpp":"02de19023d203e2d538c4f8ae23574153a4df6ada1d06fb83af2d51603b61669","libcubeb/test/test_utils.cpp":"e8d7a02a9096dbc0fd15d71f9849415d52958d2ed82cbc7b8507d3228e08d382","libcubeb/tools/cubeb-test.cpp":"10adb630fc1d0ab965e689c571ea2bdbef50006fd32521e224e16309737e2537","src/callbacks.rs":"b4b4eb3f370475488d7c77b338b0bceee94ef59ede8ff41fa797a3d35ea98b5d","src/channel.rs":"555bc8d5257496cf6e5b4c786df84755327d88a9dc07202746e35f3b7b7e4e0b","src/context.rs":"96bf3442b1dd40262d3088dbb6c473f5451fd91320cef93c522b40f284599803","src/device.rs":"5b65e1c1fdd53fa5208f20bfb809475cbb3c434e02db7d0e4771d13c86f8e369","src/error.rs":"406e3b843ed2d263fe677c4b34fb96a6d780a68bcb56a6f85f041d20d70227bd","src/format.rs":"d4d27790c20eab0b16592f60d5e487425a45a268cf4c74cf843c10ac91bbff4c","src/internal.rs":"c3af5f53dc7957860bf3bc0cd9737d094fb8ac000e7b40c569304cfa76a43145","src/lib.rs":"cb49a3dd8782369172a2f8a61d5c74b4615bfb5fba3677af7d5c149e47d71815","src/log.rs":"6694178177775f2ce5449435d00609e9361c836e23119c07d04892000587dc55","src/macros.rs":"caef13f5d23f7a3ec1a54ec3ca2390ac4ad89d521893f1d0864daf70d57a20aa","src/mixer.rs":"e72e92855614da187da6419ed0a115062a05670cb73443b2ea4313d8f5108a68","src/panner.rs":"341af4b5a5331a3c1a4ab5396125a3600945e588ea33350431dfe6f1a9a0bd80","src/resampler.rs":"762070f8afde2256715b8764380cdfa1204a1a39d98a9da0b2efe88699792f2c","src/stream.rs":"7ca9f271b4556f31f6576edfc48a23af3e63dbfba3c5dd42f864e54a0e0a4d42"},"package":"318d9b60d6d5de52f815882ab5405adedc0ac7e91414950eff27a440c2860a3b"}
\ No newline at end of file
--- a/third_party/rust/cubeb-sys/Cargo.toml
+++ b/third_party/rust/cubeb-sys/Cargo.toml
@@ -1,23 +1,23 @@
 # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
 #
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
+# to registry (e.g., crates.io) dependencies
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cubeb-sys"
-version = "0.5.4"
+version = "0.5.5"
 authors = ["Dan Glastonbury <dglastonbury@mozilla.com>"]
 build = "build.rs"
 links = "cubeb"
 description = "Native bindings to the cubeb library"
 license = "ISC"
 repository = "https://github.com/djg/cubeb-rs"
 [build-dependencies.cmake]
 version = "0.1.2"
--- a/third_party/rust/cubeb-sys/libcubeb/CMakeLists.txt
+++ b/third_party/rust/cubeb-sys/libcubeb/CMakeLists.txt
@@ -2,16 +2,18 @@
 # - backend selection via command line, rather than simply detecting headers.
 
 cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
 project(cubeb
   VERSION 0.0.0)
 
 option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
 option(BUILD_TESTS "Build tests" ON)
+option(BUILD_RUST_LIBS "Build rust backends" OFF)
+option(BUILD_TOOLS "Build tools" ON)
 
 if(NOT CMAKE_BUILD_TYPE)
   set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
       "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
 endif()
 
 if(POLICY CMP0063)
   cmake_policy(SET CMP0063 NEW)
@@ -34,16 +36,25 @@ if(BUILD_TESTS)
       message(FATAL_ERROR "Could not find googletest: run\n\tgit submodule update --init --recursive\nin base git checkout")
     endif()
     add_definitions(-DGTEST_HAS_TR1_TUPLE=0)
     set(gtest_force_shared_crt ON CACHE BOOL "")
     add_subdirectory(googletest)
   endif()
 endif()
 
+if (BUILD_RUST_LIBS)
+  if(EXISTS "${PROJECT_SOURCE_DIR}/src/cubeb-pulse-rs")
+    set(USE_PULSE_RUST 1)
+  endif()
+  if(EXISTS "${PROJECT_SOURCE_DIR}/src/cubeb-coreaudio-rs")
+    set(USE_AUDIOUNIT_RUST 1)
+  endif()
+endif()
+
 # On OS/2, visibility attribute is not supported.
 if(NOT OS2)
   set(CMAKE_C_VISIBILITY_PRESET hidden)
   set(CMAKE_CXX_VISIBILITY_PRESET hidden)
   set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
 endif()
 
 set(CMAKE_CXX_WARNING_LEVEL 4)
@@ -73,47 +84,57 @@ target_compile_definitions(cubeb PRIVATE
 add_sanitizers(cubeb)
 
 include(GenerateExportHeader)
 generate_export_header(cubeb EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/exports/cubeb_export.h)
 target_include_directories(cubeb
   PUBLIC $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/exports>
 )
 
-install(DIRECTORY ${CMAKE_SOURCE_DIR}/include DESTINATION ${CMAKE_INSTALL_PREFIX})
-install(DIRECTORY ${CMAKE_BINARY_DIR}/exports/ DESTINATION ${CMAKE_INSTALL_PREFIX}/include/cubeb)
+if(UNIX)
+  include(GNUInstallDirs)
+else()
+  set(CMAKE_INSTALL_LIBDIR "lib")
+  set(CMAKE_INSTALL_BINDIR "bin")
+  set(CMAKE_INSTALL_DATADIR "share")
+  set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATADIR}/doc")
+  set(CMAKE_INSTALL_INCLUDEDIR "include")
+endif()
+
+install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+install(DIRECTORY ${CMAKE_BINARY_DIR}/exports/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
 
 include(CMakePackageConfigHelpers)
 write_basic_package_version_file(
   "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
   COMPATIBILITY SameMajorVersion
 )
 
 configure_package_config_file(
   "Config.cmake.in"
   "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
-  INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}"
+  INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
 )
 
 install(TARGETS cubeb
   EXPORT "${PROJECT_NAME}Targets"
   DESTINATION ${CMAKE_INSTALL_PREFIX}
-  LIBRARY DESTINATION "lib"
-  ARCHIVE DESTINATION "lib"
-  RUNTIME DESTINATION "bin"
-  INCLUDES DESTINATION "include"
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+  INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
 )
 install(
   FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
-  DESTINATION "lib/cmake/${PROJECT_NAME}"
+  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
 )
 install(
   EXPORT "${PROJECT_NAME}Targets"
   NAMESPACE "${PROJECT_NAME}::"
-  DESTINATION "lib/cmake/${PROJECT_NAME}"
+  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
 )
 
 add_library(speex OBJECT
   src/speex/resample.c)
 set_target_properties(speex PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
 target_compile_definitions(speex PRIVATE OUTSIDE_SPEEX)
 target_compile_definitions(speex PRIVATE FLOATING_POINT)
 target_compile_definitions(speex PRIVATE EXPORT=)
@@ -163,17 +184,17 @@ if(USE_JACK)
   endif()
 endif()
 
 check_include_files(audioclient.h USE_WASAPI)
 if(USE_WASAPI)
   target_sources(cubeb PRIVATE
     src/cubeb_wasapi.cpp)
   target_compile_definitions(cubeb PRIVATE USE_WASAPI)
-  target_link_libraries(cubeb PRIVATE avrt)
+  target_link_libraries(cubeb PRIVATE avrt ole32)
 endif()
 
 check_include_files("windows.h;mmsystem.h" USE_WINMM)
 if(USE_WINMM)
   target_sources(cubeb PRIVATE
     src/cubeb_winmm.c)
   target_compile_definitions(cubeb PRIVATE USE_WINMM)
   target_link_libraries(cubeb PRIVATE winmm)
@@ -199,24 +220,68 @@ endif()
 check_include_files(sndio.h USE_SNDIO)
 if(USE_SNDIO)
   target_sources(cubeb PRIVATE
     src/cubeb_sndio.c)
   target_compile_definitions(cubeb PRIVATE USE_SNDIO)
   target_link_libraries(cubeb PRIVATE sndio)
 endif()
 
+check_include_files(sys/audioio.h USE_SUN)
+if(USE_SUN)
+  target_sources(cubeb PRIVATE
+    src/cubeb_sun.c)
+  target_compile_definitions(cubeb PRIVATE USE_SUN)
+  target_link_libraries(cubeb PRIVATE pthread)
+endif()
+
 check_include_files(kai.h USE_KAI)
 if(USE_KAI)
   target_sources(cubeb PRIVATE
     src/cubeb_kai.c)
   target_compile_definitions(cubeb PRIVATE USE_KAI)
   target_link_libraries(cubeb PRIVATE kai)
 endif()
 
+if(USE_PULSE_RUST)
+  include(ExternalProject)
+  set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/rust)
+  ExternalProject_Add(
+    cubeb_pulse_rs
+    DOWNLOAD_COMMAND ""
+    CONFIGURE_COMMAND ""
+    BUILD_COMMAND cargo build COMMAND cargo build --release
+    BINARY_DIR "${CMAKE_SOURCE_DIR}/src/cubeb-pulse-rs"
+    INSTALL_COMMAND ""
+    LOG_BUILD ON)
+  add_dependencies(cubeb cubeb_pulse_rs)
+  target_compile_definitions(cubeb PRIVATE USE_PULSE_RUST)
+  target_link_libraries(cubeb PRIVATE
+    debug "${CMAKE_SOURCE_DIR}/src/cubeb-pulse-rs/target/debug/libcubeb_pulse.a"
+    optimized "${CMAKE_SOURCE_DIR}/src/cubeb-pulse-rs/target/release/libcubeb_pulse.a")
+endif()
+
+if(USE_AUDIOUNIT_RUST)
+  include(ExternalProject)
+  set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/rust)
+  ExternalProject_Add(
+    cubeb_coreaudio_rs
+    DOWNLOAD_COMMAND ""
+    CONFIGURE_COMMAND ""
+    BUILD_COMMAND cargo build COMMAND cargo build --release
+    BINARY_DIR "${CMAKE_SOURCE_DIR}/src/cubeb-coreaudio-rs"
+    INSTALL_COMMAND ""
+    LOG_BUILD ON)
+  add_dependencies(cubeb cubeb_coreaudio_rs)
+  target_compile_definitions(cubeb PRIVATE USE_AUDIOUNIT_RUST)
+  target_link_libraries(cubeb PRIVATE
+    debug "${CMAKE_SOURCE_DIR}/src/cubeb-coreaudio-rs/target/debug/libcubeb_coreaudio.a"
+    optimized "${CMAKE_SOURCE_DIR}/src/cubeb-coreaudio-rs/target/release/libcubeb_coreaudio.a")
+endif()
+
 find_package(Doxygen)
 if(DOXYGEN_FOUND)
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile @ONLY)
   add_custom_target(doc ALL
     ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile
     WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs
     COMMENT "Generating API documentation with Doxygen" VERBATIM)
 endif()
@@ -226,17 +291,17 @@ if(BUILD_TESTS)
 
   macro(cubeb_add_test NAME)
     add_executable(test_${NAME} test/test_${NAME}.cpp)
     target_include_directories(test_${NAME} PRIVATE ${gtest_SOURCE_DIR}/include)
     target_include_directories(test_${NAME} PRIVATE src)
     target_link_libraries(test_${NAME} PRIVATE cubeb gtest_main)
     add_test(${NAME} test_${NAME})
     add_sanitizers(test_${NAME})
-    install(TARGETS test_${NAME} DESTINATION ${CMAKE_INSTALL_PREFIX})
+    install(TARGETS test_${NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR})
   endmacro(cubeb_add_test)
 
   cubeb_add_test(sanity)
   cubeb_add_test(tone)
   cubeb_add_test(audio)
   cubeb_add_test(record)
   cubeb_add_test(devices)
   cubeb_add_test(callback_ret)
@@ -246,23 +311,32 @@ if(BUILD_TESTS)
   target_include_directories(test_resampler PRIVATE src)
   target_compile_definitions(test_resampler PRIVATE OUTSIDE_SPEEX)
   target_compile_definitions(test_resampler PRIVATE FLOATING_POINT)
   target_compile_definitions(test_resampler PRIVATE EXPORT=)
   target_compile_definitions(test_resampler PRIVATE RANDOM_PREFIX=speex)
   target_link_libraries(test_resampler PRIVATE cubeb gtest_main)
   add_test(resampler test_resampler)
   add_sanitizers(test_resampler)
-  install(TARGETS test_resampler DESTINATION ${CMAKE_INSTALL_PREFIX})
+  install(TARGETS test_resampler DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR})
 
   cubeb_add_test(duplex)
 
   if (USE_WASAPI)
     cubeb_add_test(overload_callback)
     cubeb_add_test(loopback)
   endif()
 
   cubeb_add_test(latency test_latency)
   cubeb_add_test(ring_array)
 
   cubeb_add_test(utils)
   cubeb_add_test(ring_buffer)
+  cubeb_add_test(device_changed_callback)
 endif()
+
+if(BUILD_TOOLS)
+  add_executable(cubeb-test tools/cubeb-test.cpp)
+  target_include_directories(cubeb-test PRIVATE src)
+  target_link_libraries(cubeb-test PRIVATE cubeb)
+  add_sanitizers(cubeb-test)
+  install(TARGETS cubeb-test DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR})
+endif()
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/README.md
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/README.md
@@ -37,21 +37,21 @@ If sanitizers are supported by your comp
 Different compilers may be using different implementations for sanitizers. If you'll try to sanitize targets with C and Fortran code but don't use gcc & gfortran but clang & gfortran, this will cause linking problems. To avoid this, such problems will be detected and sanitizing will be disabled for these targets.
 
 Even C only targets may cause problems in certain situations. Some problems have been seen with AddressSanitizer for preloading or dynamic linking. In such cases you may try the ``SANITIZE_LINK_STATIC`` to link sanitizers for gcc static.
 
 
 
 ## Build targets with sanitizer support
 
-To enable sanitizer support you simply have to add ``add_sanitizers(<TARGET>)`` after defining your target. To provide a sanitizer blacklist file you can use the ``add_sanitizer_blacklist(<FILE>)`` function:
+To enable sanitizer support you simply have to add ``add_sanitizers(<TARGET>)`` after defining your target. To provide a sanitizer blacklist file you can use the ``sanitizer_add_blacklist_file(<FILE>)`` function:
 ```CMake
 find_package(Sanitizers)
 
-add_sanitizer_blacklist("blacklist.txt")
+sanitizer_add_blacklist_file("blacklist.txt")
 
 add_executable(some_exe foo.c bar.c)
 add_sanitizers(some_exe)
 
 add_library(some_lib foo.c bar.c)
 add_sanitizers(some_lib)
 ```
 
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindASan.cmake
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindASan.cmake
@@ -50,10 +50,10 @@ if (SANITIZE_ADDRESS)
 	mark_as_advanced(ASan_WRAPPER)
 endif ()
 
 function (add_sanitize_address TARGET)
     if (NOT SANITIZE_ADDRESS)
         return()
     endif ()
 
-    saitizer_add_flags(${TARGET} "AddressSanitizer" "ASan")
+    sanitizer_add_flags(${TARGET} "AddressSanitizer" "ASan")
 endfunction ()
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindMSan.cmake
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindMSan.cmake
@@ -48,10 +48,10 @@ if (SANITIZE_MEMORY)
     endif ()
 endif ()
 
 function (add_sanitize_memory TARGET)
     if (NOT SANITIZE_MEMORY)
         return()
     endif ()
 
-    saitizer_add_flags(${TARGET} "MemorySanitizer" "MSan")
+    sanitizer_add_flags(${TARGET} "MemorySanitizer" "MSan")
 endfunction ()
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindSanitizers.cmake
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindSanitizers.cmake
@@ -57,29 +57,36 @@ function(add_sanitizers ...)
     if (NOT (SANITIZE_ADDRESS OR SANITIZE_MEMORY OR SANITIZE_THREAD OR
         SANITIZE_UNDEFINED))
         return()
     endif ()
 
     foreach (TARGET ${ARGV})
         # Check if this target will be compiled by exactly one compiler. Other-
         # wise sanitizers can't be used and a warning should be printed once.
+        get_target_property(TARGET_TYPE ${TARGET} TYPE)
+        if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
+            message(WARNING "Can't use any sanitizers for target ${TARGET}, "
+                    "because it is an interface library and cannot be "
+                    "compiled directly.")
+            return()
+        endif ()
         sanitizer_target_compilers(${TARGET} TARGET_COMPILER)
         list(LENGTH TARGET_COMPILER NUM_COMPILERS)
         if (NUM_COMPILERS GREATER 1)
             message(WARNING "Can't use any sanitizers for target ${TARGET}, "
                     "because it will be compiled by incompatible compilers. "
-                    "Target will be compiled without sanitzers.")
+                    "Target will be compiled without sanitizers.")
             return()
 
         # If the target is compiled by no known compiler, ignore it.
         elseif (NUM_COMPILERS EQUAL 0)
             message(WARNING "Can't use any sanitizers for target ${TARGET}, "
                     "because it uses an unknown compiler. Target will be "
-                    "compiled without sanitzers.")
+                    "compiled without sanitizers.")
             return()
         endif ()
 
         # Add sanitizers for target.
         add_sanitize_address(${TARGET})
         add_sanitize_thread(${TARGET})
         add_sanitize_memory(${TARGET})
         add_sanitize_undefined(${TARGET})
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindTSan.cmake
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindTSan.cmake
@@ -34,19 +34,20 @@ if (SANITIZE_THREAD AND SANITIZE_MEMORY)
     message(FATAL_ERROR "ThreadSanitizer is not compatible with "
         "MemorySanitizer.")
 endif ()
 
 
 include(sanitize-helpers)
 
 if (SANITIZE_THREAD)
-    if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND
+      NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
         message(WARNING "ThreadSanitizer disabled for target ${TARGET} because "
-            "ThreadSanitizer is supported for Linux systems only.")
+          "ThreadSanitizer is supported for Linux systems and macOS only.")
         set(SANITIZE_THREAD Off CACHE BOOL
             "Enable ThreadSanitizer for sanitized targets." FORCE)
     elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8)
         message(WARNING "ThreadSanitizer disabled for target ${TARGET} because "
             "ThreadSanitizer is supported for 64bit systems only.")
         set(SANITIZE_THREAD Off CACHE BOOL
             "Enable ThreadSanitizer for sanitized targets." FORCE)
     else ()
@@ -55,10 +56,10 @@ if (SANITIZE_THREAD)
     endif ()
 endif ()
 
 function (add_sanitize_thread TARGET)
     if (NOT SANITIZE_THREAD)
         return()
     endif ()
 
-    saitizer_add_flags(${TARGET} "ThreadSanitizer" "TSan")
+    sanitizer_add_flags(${TARGET} "ThreadSanitizer" "TSan")
 endfunction ()
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindUBSan.cmake
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/FindUBSan.cmake
@@ -37,10 +37,10 @@ if (SANITIZE_UNDEFINED)
         "UndefinedBehaviorSanitizer" "UBSan")
 endif ()
 
 function (add_sanitize_undefined TARGET)
     if (NOT SANITIZE_UNDEFINED)
         return()
     endif ()
 
-    saitizer_add_flags(${TARGET} "UndefinedBehaviorSanitizer" "UBSan")
+    sanitizer_add_flags(${TARGET} "UndefinedBehaviorSanitizer" "UBSan")
 endfunction ()
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/sanitize-helpers.cmake
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/cmake/sanitize-helpers.cmake
@@ -19,17 +19,19 @@
 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
 # Helper function to get the language of a source file.
 function (sanitizer_lang_of_source FILE RETURN_VAR)
-    get_filename_component(FILE_EXT "${FILE}" EXT)
+    get_filename_component(LONGEST_EXT "${FILE}" EXT)
+    # Get shortest extension as some files can have dot in their names
+    string(REGEX REPLACE "^.*(\\.[^.]+)$" "\\1" FILE_EXT ${LONGEST_EXT})
     string(TOLOWER "${FILE_EXT}" FILE_EXT)
     string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT)
 
     get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
     foreach (LANG ${ENABLED_LANGUAGES})
         list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP)
         if (NOT ${TEMP} EQUAL -1)
             set(${RETURN_VAR} "${LANG}" PARENT_SCOPE)
@@ -145,17 +147,17 @@ function (sanitizer_check_compiler_flags
                         "compiled without ${NAME}.")
             endif ()
         endif ()
     endforeach ()
 endfunction ()
 
 
 # Helper to assign sanitizer flags for TARGET.
-function (saitizer_add_flags TARGET NAME PREFIX)
+function (sanitizer_add_flags TARGET NAME PREFIX)
     # Get list of compilers used by target and check, if sanitizer is available
     # for this target. Other compiler checks like check for conflicting
     # compilers will be done in add_sanitizers function.
     sanitizer_target_compilers(${TARGET} TARGET_COMPILER)
     list(LENGTH TARGET_COMPILER NUM_COMPILERS)
     if ("${${PREFIX}_${TARGET_COMPILER}_FLAGS}" STREQUAL "")
         return()
     endif()
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/tests/CMakeLists.txt
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/tests/CMakeLists.txt
@@ -26,27 +26,42 @@
 
 # Function to add testcases.
 function(add_testcase TESTNAME SOURCEFILES)
 	# remove ${TESTNAME} from ${ARGV} to use ${ARGV} as ${SOURCEFILES}
 	list(REMOVE_AT ARGV 0)
 
 	# add a new executable
 	add_executable(${TESTNAME} ${ARGV})
-	add_sanitizers(${TESTNAME})
 
 	# add a testcase for executable
 	add_test(${TESTNAME} ${TESTNAME})
 endfunction(add_testcase)
 
+# Function to add testcases with asan enabled.
+function(add_sanitized_testcase TESTNAME SOURCEFILES)
+	add_testcase(${TESTNAME} ${SOURCEFILES})
+	add_sanitizers(${TESTNAME})
+endfunction(add_sanitized_testcase)
 
 
+
+set(SANITIZE_ADDRESS TRUE)
+
 #
 # search for sanitizers
 #
 find_package(Sanitizers)
 
 
-
 #
 # add testcases
 #
-add_testcase("asan_test_cpp" asan_test.cpp)
+add_sanitized_testcase("asan_test_cpp" asan_test.cpp)
+add_sanitized_testcase("shortest_ext_test_cpp" shortest.ext.test.cpp)
+
+set_tests_properties(
+	"asan_test_cpp"
+	"shortest_ext_test_cpp"
+PROPERTIES
+	WILL_FAIL TRUE
+)
+
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/tests/asan_test.cpp
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/tests/asan_test.cpp
@@ -24,16 +24,17 @@
  *  2015      RWTH Aachen University, Federal Republic of Germany
  */
 
 
 int
 main(int argc, char **argv)
 {
 	// Allocate a new array and delete it.
-	int *array = new int[argc];
+	int *array = new int[argc + 1];
+	array[argc] = 0;
 	delete[] array;
 
 	/* Access element of the deleted array. This will cause an memory error with
 	 * address sanitizer.
 	 */
 	return array[argc];
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/tests/shortest.ext.test.cpp
@@ -0,0 +1,40 @@
+/* This file is part of CMake-sanitizers.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ * Copyright (c)
+ *  2013-2015 Matt Arsenault
+ *  2015      RWTH Aachen University, Federal Republic of Germany
+ */
+
+
+int
+main(int argc, char **argv)
+{
+	// Allocate a new array and delete it.
+	int *array = new int[argc + 1];
+	array[argc] = 0;
+	delete[] array;
+
+	/* Access element of the deleted array. This will cause an memory error with
+	 * address sanitizer.
+	 */
+	return array[argc];
+}
deleted file mode 100644
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/toolchain-cross-android.cmake
+++ /dev/null
@@ -1,1693 +0,0 @@
-# Copyright (c) 2010-2011, Ethan Rublee
-# Copyright (c) 2011-2014, Andrey Kamaev
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1.  Redistributions of source code must retain the above copyright notice,
-#     this list of conditions and the following disclaimer.
-#
-# 2.  Redistributions in binary form must reproduce the above copyright notice,
-#     this list of conditions and the following disclaimer in the documentation
-#     and/or other materials provided with the distribution.
-#
-# 3.  Neither the name of the copyright holder nor the names of its
-#     contributors may be used to endorse or promote products derived from this
-#     software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-# ------------------------------------------------------------------------------
-#  Android CMake toolchain file, for use with the Android NDK r5-r10d
-#  Requires cmake 2.6.3 or newer (2.8.9 or newer is recommended).
-#  See home page: https://github.com/taka-no-me/android-cmake
-#
-#  Usage Linux:
-#   $ export ANDROID_NDK=/absolute/path/to/the/android-ndk
-#   $ mkdir build && cd build
-#   $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake ..
-#   $ make -j8
-#
-#  Usage Windows:
-#     You need native port of make to build your project.
-#     Android NDK r7 (and newer) already has make.exe on board.
-#     For older NDK you have to install it separately.
-#     For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm
-#
-#   $ SET ANDROID_NDK=C:\absolute\path\to\the\android-ndk
-#   $ mkdir build && cd build
-#   $ cmake.exe -G"MinGW Makefiles"
-#       -DCMAKE_TOOLCHAIN_FILE=path\to\the\android.toolchain.cmake
-#       -DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%\prebuilt\windows\bin\make.exe" ..
-#   $ cmake.exe --build .
-#
-#
-#  Options (can be set as cmake parameters: -D<option_name>=<value>):
-#    ANDROID_NDK=/opt/android-ndk - path to the NDK root.
-#      Can be set as environment variable. Can be set only at first cmake run.
-#
-#    ANDROID_ABI=armeabi-v7a - specifies the target Application Binary
-#      Interface (ABI). This option nearly matches to the APP_ABI variable
-#      used by ndk-build tool from Android NDK.
-#
-#      Possible targets are:
-#        "armeabi" - ARMv5TE based CPU with software floating point operations
-#        "armeabi-v7a" - ARMv7 based devices with hardware FPU instructions
-#            this ABI target is used by default
-#        "armeabi-v7a with NEON" - same as armeabi-v7a, but
-#            sets NEON as floating-point unit
-#        "armeabi-v7a with VFPV3" - same as armeabi-v7a, but
-#            sets VFPV3 as floating-point unit (has 32 registers instead of 16)
-#        "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP
-#        "x86" - IA-32 instruction set
-#        "mips" - MIPS32 instruction set
-#
-#      64-bit ABIs for NDK r10 and newer:
-#        "arm64-v8a" - ARMv8 AArch64 instruction set
-#        "x86_64" - Intel64 instruction set (r1)
-#        "mips64" - MIPS64 instruction set (r6)
-#
-#    ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for.
-#      Option is read-only when standalone toolchain is used.
-#      Note: building for "android-L" requires explicit configuration.
-#
-#    ANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 - the name of compiler
-#      toolchain to be used. The list of possible values depends on the NDK
-#      version. For NDK r10c the possible values are:
-#
-#        * aarch64-linux-android-4.9
-#        * aarch64-linux-android-clang3.4
-#        * aarch64-linux-android-clang3.5
-#        * arm-linux-androideabi-4.6
-#        * arm-linux-androideabi-4.8
-#        * arm-linux-androideabi-4.9 (default)
-#        * arm-linux-androideabi-clang3.4
-#        * arm-linux-androideabi-clang3.5
-#        * mips64el-linux-android-4.9
-#        * mips64el-linux-android-clang3.4
-#        * mips64el-linux-android-clang3.5
-#        * mipsel-linux-android-4.6
-#        * mipsel-linux-android-4.8
-#        * mipsel-linux-android-4.9
-#        * mipsel-linux-android-clang3.4
-#        * mipsel-linux-android-clang3.5
-#        * x86-4.6
-#        * x86-4.8
-#        * x86-4.9
-#        * x86-clang3.4
-#        * x86-clang3.5
-#        * x86_64-4.9
-#        * x86_64-clang3.4
-#        * x86_64-clang3.5
-#
-#    ANDROID_FORCE_ARM_BUILD=OFF - set ON to generate 32-bit ARM instructions
-#      instead of Thumb. Is not available for "armeabi-v6 with VFP"
-#      (is forced to be ON) ABI.
-#
-#    ANDROID_NO_UNDEFINED=ON - set ON to show all undefined symbols as linker
-#      errors even if they are not used.
-#
-#    ANDROID_SO_UNDEFINED=OFF - set ON to allow undefined symbols in shared
-#      libraries. Automatically turned for NDK r5x and r6x due to GLESv2
-#      problems.
-#
-#    ANDROID_STL=gnustl_static - specify the runtime to use.
-#
-#      Possible values are:
-#        none           -> Do not configure the runtime.
-#        system         -> Use the default minimal system C++ runtime library.
-#                          Implies -fno-rtti -fno-exceptions.
-#                          Is not available for standalone toolchain.
-#        system_re      -> Use the default minimal system C++ runtime library.
-#                          Implies -frtti -fexceptions.
-#                          Is not available for standalone toolchain.
-#        gabi++_static  -> Use the GAbi++ runtime as a static library.
-#                          Implies -frtti -fno-exceptions.
-#                          Available for NDK r7 and newer.
-#                          Is not available for standalone toolchain.
-#        gabi++_shared  -> Use the GAbi++ runtime as a shared library.
-#                          Implies -frtti -fno-exceptions.
-#                          Available for NDK r7 and newer.
-#                          Is not available for standalone toolchain.
-#        stlport_static -> Use the STLport runtime as a static library.
-#                          Implies -fno-rtti -fno-exceptions for NDK before r7.
-#                          Implies -frtti -fno-exceptions for NDK r7 and newer.
-#                          Is not available for standalone toolchain.
-#        stlport_shared -> Use the STLport runtime as a shared library.
-#                          Implies -fno-rtti -fno-exceptions for NDK before r7.
-#                          Implies -frtti -fno-exceptions for NDK r7 and newer.
-#                          Is not available for standalone toolchain.
-#        gnustl_static  -> Use the GNU STL as a static library.
-#                          Implies -frtti -fexceptions.
-#        gnustl_shared  -> Use the GNU STL as a shared library.
-#                          Implies -frtti -fno-exceptions.
-#                          Available for NDK r7b and newer.
-#                          Silently degrades to gnustl_static if not available.
-#
-#    ANDROID_STL_FORCE_FEATURES=ON - turn rtti and exceptions support based on
-#      chosen runtime. If disabled, then the user is responsible for settings
-#      these options.
-#
-#  What?:
-#    android-cmake toolchain searches for NDK/toolchain in the following order:
-#      ANDROID_NDK - cmake parameter
-#      ANDROID_NDK - environment variable
-#      ANDROID_STANDALONE_TOOLCHAIN - cmake parameter
-#      ANDROID_STANDALONE_TOOLCHAIN - environment variable
-#      ANDROID_NDK - default locations
-#      ANDROID_STANDALONE_TOOLCHAIN - default locations
-#
-#    Make sure to do the following in your scripts:
-#      SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}" )
-#      SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}" )
-#    The flags will be prepopulated with critical flags, so don't loose them.
-#    Also be aware that toolchain also sets configuration-specific compiler
-#    flags and linker flags.
-#
-#    ANDROID and BUILD_ANDROID will be set to true, you may test any of these
-#    variables to make necessary Android-specific configuration changes.
-#
-#    Also ARMEABI or ARMEABI_V7A or X86 or MIPS or ARM64_V8A or X86_64 or MIPS64
-#    will be set true, mutually exclusive. NEON option will be set true
-#    if VFP is set to NEON.
-#
-# ------------------------------------------------------------------------------
-
-cmake_minimum_required( VERSION 2.6.3 )
-
-if( DEFINED CMAKE_CROSSCOMPILING )
- # subsequent toolchain loading is not really needed
- return()
-endif()
-
-if( CMAKE_TOOLCHAIN_FILE )
- # touch toolchain variable to suppress "unused variable" warning
-endif()
-
-# inherit settings in recursive loads
-get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
-if( _CMAKE_IN_TRY_COMPILE )
- include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL )
-endif()
-
-# this one is important
-if( CMAKE_VERSION VERSION_GREATER "3.0.99" )
- set( CMAKE_SYSTEM_NAME Android )
-else()
- set( CMAKE_SYSTEM_NAME Linux )
-endif()
-
-# this one not so much
-set( CMAKE_SYSTEM_VERSION 1 )
-
-# rpath makes low sense for Android
-set( CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "" )
-set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." )
-
-# NDK search paths
-set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r10d -r10c -r10b -r10 -r9d -r9c -r9b -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
-if( NOT DEFINED ANDROID_NDK_SEARCH_PATHS )
- if( CMAKE_HOST_WIN32 )
-  file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
-  set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}" "$ENV{SystemDrive}/NVPACK" )
- else()
-  file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS )
-  set( ANDROID_NDK_SEARCH_PATHS /opt "${ANDROID_NDK_SEARCH_PATHS}/NVPACK" )
- endif()
-endif()
-if( NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH )
- set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain )
-endif()
-
-# known ABIs
-set( ANDROID_SUPPORTED_ABIS_arm "armeabi-v7a;armeabi;armeabi-v7a with NEON;armeabi-v7a with VFPV3;armeabi-v6 with VFP" )
-set( ANDROID_SUPPORTED_ABIS_arm64 "arm64-v8a" )
-set( ANDROID_SUPPORTED_ABIS_x86 "x86" )
-set( ANDROID_SUPPORTED_ABIS_x86_64 "x86_64" )
-set( ANDROID_SUPPORTED_ABIS_mips "mips" )
-set( ANDROID_SUPPORTED_ABIS_mips64 "mips64" )
-
-# API level defaults
-set( ANDROID_DEFAULT_NDK_API_LEVEL 8 )
-set( ANDROID_DEFAULT_NDK_API_LEVEL_arm64 21 )
-set( ANDROID_DEFAULT_NDK_API_LEVEL_x86 9 )
-set( ANDROID_DEFAULT_NDK_API_LEVEL_x86_64 21 )
-set( ANDROID_DEFAULT_NDK_API_LEVEL_mips 9 )
-set( ANDROID_DEFAULT_NDK_API_LEVEL_mips64 21 )
-
-
-macro( __LIST_FILTER listvar regex )
-  if( ${listvar} )
-    foreach( __val ${${listvar}} )
-      if( __val MATCHES "${regex}" )
-        list( REMOVE_ITEM ${listvar} "${__val}" )
-      endif()
-    endforeach()
-  endif()
-endmacro()
-
-macro( __INIT_VARIABLE var_name )
-  set( __test_path 0 )
-  foreach( __var ${ARGN} )
-    if( __var STREQUAL "PATH" )
-      set( __test_path 1 )
-      break()
-    endif()
-  endforeach()
-
-  if( __test_path AND NOT EXISTS "${${var_name}}" )
-    unset( ${var_name} CACHE )
-  endif()
-
-  if( " ${${var_name}}" STREQUAL " " )
-    set( __values 0 )
-    foreach( __var ${ARGN} )
-      if( __var STREQUAL "VALUES" )
-        set( __values 1 )
-      elseif( NOT __var STREQUAL "PATH" )
-        if( __var MATCHES "^ENV_.*$" )
-          string( REPLACE "ENV_" "" __var "${__var}" )
-          set( __value "$ENV{${__var}}" )
-        elseif( DEFINED ${__var} )
-          set( __value "${${__var}}" )
-        elseif( __values )
-          set( __value "${__var}" )
-        else()
-          set( __value "" )
-        endif()
-
-        if( NOT " ${__value}" STREQUAL " " AND (NOT __test_path OR EXISTS "${__value}") )
-          set( ${var_name} "${__value}" )
-          break()
-        endif()
-      endif()
-    endforeach()
-    unset( __value )
-    unset( __values )
-  endif()
-
-  if( __test_path )
-    file( TO_CMAKE_PATH "${${var_name}}" ${var_name} )
-  endif()
-  unset( __test_path )
-endmacro()
-
-macro( __DETECT_NATIVE_API_LEVEL _var _path )
-  set( __ndkApiLevelRegex "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*.*$" )
-  file( STRINGS ${_path} __apiFileContent REGEX "${__ndkApiLevelRegex}" )
-  if( NOT __apiFileContent )
-    message( SEND_ERROR "Could not get Android native API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken." )
-  endif()
-  string( REGEX REPLACE "${__ndkApiLevelRegex}" "\\1" ${_var} "${__apiFileContent}" )
-  unset( __apiFileContent )
-  unset( __ndkApiLevelRegex )
-endmacro()
-
-macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root )
- if( EXISTS "${_root}" )
-    file( GLOB __gccExePath RELATIVE "${_root}/bin/" "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" )
-    __LIST_FILTER( __gccExePath "^[.].*" )
-    list( LENGTH __gccExePath __gccExePathsCount )
-    if( NOT __gccExePathsCount EQUAL 1  AND NOT _CMAKE_IN_TRY_COMPILE )
-      message( WARNING "Could not determine machine name for compiler from ${_root}" )
-      set( ${_var} "" )
-    else()
-      get_filename_component( __gccExeName "${__gccExePath}" NAME_WE )
-      string( REPLACE "-gcc" "" ${_var} "${__gccExeName}" )
-    endif()
-    unset( __gccExePath )
-    unset( __gccExePathsCount )
-    unset( __gccExeName )
-  else()
-    set( ${_var} "" )
-  endif()
-endmacro()
-
-
-# fight against cygwin
-set( ANDROID_FORBID_SYGWIN TRUE CACHE BOOL "Prevent cmake from working under cygwin and using cygwin tools")
-mark_as_advanced( ANDROID_FORBID_SYGWIN )
-if( ANDROID_FORBID_SYGWIN )
- if( CYGWIN )
-  message( FATAL_ERROR "Android NDK and android-cmake toolchain are not welcome Cygwin. It is unlikely that this cmake toolchain will work under cygwin. But if you want to try then you can set cmake variable ANDROID_FORBID_SYGWIN to FALSE and rerun cmake." )
- endif()
-
- if( CMAKE_HOST_WIN32 )
-  # remove cygwin from PATH
-  set( __new_path "$ENV{PATH}")
-  __LIST_FILTER( __new_path "cygwin" )
-  set(ENV{PATH} "${__new_path}")
-  unset(__new_path)
- endif()
-endif()
-
-
-# detect current host platform
-if( NOT DEFINED ANDROID_NDK_HOST_X64 AND (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64" OR CMAKE_HOST_APPLE) )
- set( ANDROID_NDK_HOST_X64 1 CACHE BOOL "Try to use 64-bit compiler toolchain" )
- mark_as_advanced( ANDROID_NDK_HOST_X64 )
-endif()
-
-set( TOOL_OS_SUFFIX "" )
-if( CMAKE_HOST_APPLE )
- set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86_64" )
- set( ANDROID_NDK_HOST_SYSTEM_NAME2 "darwin-x86" )
-elseif( CMAKE_HOST_WIN32 )
- set( ANDROID_NDK_HOST_SYSTEM_NAME "windows-x86_64" )
- set( ANDROID_NDK_HOST_SYSTEM_NAME2 "windows" )
- set( TOOL_OS_SUFFIX ".exe" )
-elseif( CMAKE_HOST_UNIX )
- set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86_64" )
- set( ANDROID_NDK_HOST_SYSTEM_NAME2 "linux-x86" )
-else()
- message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" )
-endif()
-
-if( NOT ANDROID_NDK_HOST_X64 )
- set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} )
-endif()
-
-# see if we have path to Android NDK
-if( NOT ANDROID_NDK AND NOT ANDROID_STANDALONE_TOOLCHAIN )
-  __INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK )
-endif()
-if( NOT ANDROID_NDK )
- # see if we have path to Android standalone toolchain
- __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN )
-
- if( NOT ANDROID_STANDALONE_TOOLCHAIN )
-  #try to find Android NDK in one of the the default locations
-  set( __ndkSearchPaths )
-  foreach( __ndkSearchPath ${ANDROID_NDK_SEARCH_PATHS} )
-   foreach( suffix ${ANDROID_SUPPORTED_NDK_VERSIONS} )
-    list( APPEND __ndkSearchPaths "${__ndkSearchPath}/android-ndk${suffix}" )
-   endforeach()
-  endforeach()
-  __INIT_VARIABLE( ANDROID_NDK PATH VALUES ${__ndkSearchPaths} )
-  unset( __ndkSearchPaths )
-
-  if( ANDROID_NDK )
-   message( STATUS "Using default path for Android NDK: ${ANDROID_NDK}" )
-   message( STATUS "  If you prefer to use a different location, please define a cmake or environment variable: ANDROID_NDK" )
-  else()
-   #try to find Android standalone toolchain in one of the the default locations
-   __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH )
-
-   if( ANDROID_STANDALONE_TOOLCHAIN )
-    message( STATUS "Using default path for standalone toolchain ${ANDROID_STANDALONE_TOOLCHAIN}" )
-    message( STATUS "  If you prefer to use a different location, please define the variable: ANDROID_STANDALONE_TOOLCHAIN" )
-   endif( ANDROID_STANDALONE_TOOLCHAIN )
-  endif( ANDROID_NDK )
- endif( NOT ANDROID_STANDALONE_TOOLCHAIN )
-endif( NOT ANDROID_NDK )
-
-# remember found paths
-if( ANDROID_NDK )
- get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE )
- set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" FORCE )
- set( BUILD_WITH_ANDROID_NDK True )
- if( EXISTS "${ANDROID_NDK}/RELEASE.TXT" )
-  file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX "r[0-9]+[a-z]?" )
-  string( REGEX MATCH "r([0-9]+)([a-z]?)" ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" )
- else()
-  set( ANDROID_NDK_RELEASE "r1x" )
-  set( ANDROID_NDK_RELEASE_FULL "unreleased" )
- endif()
- string( REGEX REPLACE "r([0-9]+)([a-z]?)" "\\1*1000" ANDROID_NDK_RELEASE_NUM "${ANDROID_NDK_RELEASE}" )
- string( FIND " abcdefghijklmnopqastuvwxyz" "${CMAKE_MATCH_2}" __ndkReleaseLetterNum )
- math( EXPR ANDROID_NDK_RELEASE_NUM "${ANDROID_NDK_RELEASE_NUM}+${__ndkReleaseLetterNum}" )
-elseif( ANDROID_STANDALONE_TOOLCHAIN )
- get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE )
- # try to detect change
- if( CMAKE_AR )
-  string( LENGTH "${ANDROID_STANDALONE_TOOLCHAIN}" __length )
-  string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidStandaloneToolchainPreviousPath )
-  if( NOT __androidStandaloneToolchainPreviousPath STREQUAL ANDROID_STANDALONE_TOOLCHAIN )
-   message( FATAL_ERROR "It is not possible to change path to the Android standalone toolchain on subsequent run." )
-  endif()
-  unset( __androidStandaloneToolchainPreviousPath )
-  unset( __length )
- endif()
- set( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" CACHE INTERNAL "Path of the Android standalone toolchain" FORCE )
- set( BUILD_WITH_STANDALONE_TOOLCHAIN True )
-else()
- list(GET ANDROID_NDK_SEARCH_PATHS 0 ANDROID_NDK_SEARCH_PATH)
- message( FATAL_ERROR "Could not find neither Android NDK nor Android standalone toolchain.
-    You should either set an environment variable:
-      export ANDROID_NDK=~/my-android-ndk
-    or
-      export ANDROID_STANDALONE_TOOLCHAIN=~/my-android-toolchain
-    or put the toolchain or NDK in the default path:
-      sudo ln -s ~/my-android-ndk ${ANDROID_NDK_SEARCH_PATH}/android-ndk
-      sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" )
-endif()
-
-# android NDK layout
-if( BUILD_WITH_ANDROID_NDK )
- if( NOT DEFINED ANDROID_NDK_LAYOUT )
-  # try to automatically detect the layout
-  if( EXISTS "${ANDROID_NDK}/RELEASE.TXT")
-   set( ANDROID_NDK_LAYOUT "RELEASE" )
-  elseif( EXISTS "${ANDROID_NDK}/../../linux-x86/toolchain/" )
-   set( ANDROID_NDK_LAYOUT "LINARO" )
-  elseif( EXISTS "${ANDROID_NDK}/../../gcc/" )
-   set( ANDROID_NDK_LAYOUT "ANDROID" )
-  endif()
- endif()
- set( ANDROID_NDK_LAYOUT "${ANDROID_NDK_LAYOUT}" CACHE STRING "The inner layout of NDK" )
- mark_as_advanced( ANDROID_NDK_LAYOUT )
- if( ANDROID_NDK_LAYOUT STREQUAL "LINARO" )
-  set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
-  set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../${ANDROID_NDK_HOST_SYSTEM_NAME}/toolchain" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
- elseif( ANDROID_NDK_LAYOUT STREQUAL "ANDROID" )
-  set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
-  set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../gcc/${ANDROID_NDK_HOST_SYSTEM_NAME}/arm" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
- else() # ANDROID_NDK_LAYOUT STREQUAL "RELEASE"
-  set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/toolchains" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME2}" )
- endif()
- get_filename_component( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK_TOOLCHAINS_PATH}" ABSOLUTE )
-
- # try to detect change of NDK
- if( CMAKE_AR )
-  string( LENGTH "${ANDROID_NDK_TOOLCHAINS_PATH}" __length )
-  string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath )
-  if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK_TOOLCHAINS_PATH )
-   message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first.
-   " )
-  endif()
-  unset( __androidNdkPreviousPath )
-  unset( __length )
- endif()
-endif()
-
-
-# get all the details about standalone toolchain
-if( BUILD_WITH_STANDALONE_TOOLCHAIN )
- __DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" )
- set( ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
- set( __availableToolchains "standalone" )
- __DETECT_TOOLCHAIN_MACHINE_NAME( __availableToolchainMachines "${ANDROID_STANDALONE_TOOLCHAIN}" )
- if( NOT __availableToolchainMachines )
-  message( FATAL_ERROR "Could not determine machine name of your toolchain. Probably your Android standalone toolchain is broken." )
- endif()
- if( __availableToolchainMachines MATCHES x86_64 )
-  set( __availableToolchainArchs "x86_64" )
- elseif( __availableToolchainMachines MATCHES i686 )
-  set( __availableToolchainArchs "x86" )
- elseif( __availableToolchainMachines MATCHES aarch64 )
-  set( __availableToolchainArchs "arm64" )
- elseif( __availableToolchainMachines MATCHES arm )
-  set( __availableToolchainArchs "arm" )
- elseif( __availableToolchainMachines MATCHES mips64el )
-  set( __availableToolchainArchs "mips64" )
- elseif( __availableToolchainMachines MATCHES mipsel )
-  set( __availableToolchainArchs "mips" )
- endif()
- execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" -dumpversion
-                  OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE )
- string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" )
- if( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/bin/clang${TOOL_OS_SUFFIX}" )
-  list( APPEND __availableToolchains "standalone-clang" )
-  list( APPEND __availableToolchainMachines ${__availableToolchainMachines} )
-  list( APPEND __availableToolchainArchs ${__availableToolchainArchs} )
-  list( APPEND __availableToolchainCompilerVersions ${__availableToolchainCompilerVersions} )
- endif()
-endif()
-
-macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath )
- foreach( __toolchain ${${__availableToolchainsLst}} )
-  if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" )
-   SET( __toolchainVersionRegex "^TOOLCHAIN_VERSION[\t ]+:=[\t ]+(.*)$" )
-   FILE( STRINGS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}/setup.mk" __toolchainVersionStr REGEX "${__toolchainVersionRegex}" )
-   if( __toolchainVersionStr )
-    string( REGEX REPLACE "${__toolchainVersionRegex}" "\\1" __toolchainVersionStr "${__toolchainVersionStr}" )
-    string( REGEX REPLACE "-clang3[.][0-9]$" "-${__toolchainVersionStr}" __gcc_toolchain "${__toolchain}" )
-   else()
-    string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" )
-   endif()
-   unset( __toolchainVersionStr )
-   unset( __toolchainVersionRegex )
-  else()
-   set( __gcc_toolchain "${__toolchain}" )
-  endif()
-  __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" )
-  if( __machine )
-   string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" )
-   if( __machine MATCHES x86_64 )
-    set( __arch "x86_64" )
-   elseif( __machine MATCHES i686 )
-    set( __arch "x86" )
-   elseif( __machine MATCHES aarch64 )
-    set( __arch "arm64" )
-   elseif( __machine MATCHES arm )
-    set( __arch "arm" )
-   elseif( __machine MATCHES mips64el )
-    set( __arch "mips64" )
-   elseif( __machine MATCHES mipsel )
-    set( __arch "mips" )
-   else()
-    set( __arch "" )
-   endif()
-   #message("machine: !${__machine}!\narch: !${__arch}!\nversion: !${__version}!\ntoolchain: !${__toolchain}!\n")
-   if (__arch)
-    list( APPEND __availableToolchainMachines "${__machine}" )
-    list( APPEND __availableToolchainArchs "${__arch}" )
-    list( APPEND __availableToolchainCompilerVersions "${__version}" )
-    list( APPEND ${__availableToolchainsVar} "${__toolchain}" )
-   endif()
-  endif()
-  unset( __gcc_toolchain )
- endforeach()
-endmacro()
-
-# get all the details about NDK
-if( BUILD_WITH_ANDROID_NDK )
- file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" )
- string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" )
- set( __availableToolchains "" )
- set( __availableToolchainMachines "" )
- set( __availableToolchainArchs "" )
- set( __availableToolchainCompilerVersions "" )
- if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_TOOLCHAIN_NAME}/" )
-  # do not go through all toolchains if we know the name
-  set( __availableToolchainsLst "${ANDROID_TOOLCHAIN_NAME}" )
-  __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
-  if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
-   __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
-   if( __availableToolchains )
-    set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
-   endif()
-  endif()
- endif()
- if( NOT __availableToolchains )
-  file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" )
-  if( __availableToolchainsLst )
-   list(SORT __availableToolchainsLst) # we need clang to go after gcc
-  endif()
-  __LIST_FILTER( __availableToolchainsLst "^[.]" )
-  __LIST_FILTER( __availableToolchainsLst "llvm" )
-  __LIST_FILTER( __availableToolchainsLst "renderscript" )
-  __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
-  if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
-   __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
-   if( __availableToolchains )
-    set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
-   endif()
-  endif()
- endif()
- if( NOT __availableToolchains )
-  message( FATAL_ERROR "Could not find any working toolchain in the NDK. Probably your Android NDK is broken." )
- endif()
-endif()
-
-# build list of available ABIs
-set( ANDROID_SUPPORTED_ABIS "" )
-set( __uniqToolchainArchNames ${__availableToolchainArchs} )
-list( REMOVE_DUPLICATES __uniqToolchainArchNames )
-list( SORT __uniqToolchainArchNames )
-foreach( __arch ${__uniqToolchainArchNames} )
- list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
-endforeach()
-unset( __uniqToolchainArchNames )
-if( NOT ANDROID_SUPPORTED_ABIS )
- message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
-endif()
-
-# choose target ABI
-__INIT_VARIABLE( ANDROID_ABI VALUES ${ANDROID_SUPPORTED_ABIS} )
-# verify that target ABI is supported
-list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx )
-if( __androidAbiIdx EQUAL -1 )
- string( REPLACE ";" "\", \"" PRINTABLE_ANDROID_SUPPORTED_ABIS  "${ANDROID_SUPPORTED_ABIS}" )
- message( FATAL_ERROR "Specified ANDROID_ABI = \"${ANDROID_ABI}\" is not supported by this cmake toolchain or your NDK/toolchain.
-   Supported values are: \"${PRINTABLE_ANDROID_SUPPORTED_ABIS}\"
-   " )
-endif()
-unset( __androidAbiIdx )
-
-# set target ABI options
-if( ANDROID_ABI STREQUAL "x86" )
- set( X86 true )
- set( ANDROID_NDK_ABI_NAME "x86" )
- set( ANDROID_ARCH_NAME "x86" )
- set( ANDROID_LLVM_TRIPLE "i686-none-linux-android" )
- set( CMAKE_SYSTEM_PROCESSOR "i686" )
-elseif( ANDROID_ABI STREQUAL "x86_64" )
- set( X86 true )
- set( X86_64 true )
- set( ANDROID_NDK_ABI_NAME "x86_64" )
- set( ANDROID_ARCH_NAME "x86_64" )
- set( CMAKE_SYSTEM_PROCESSOR "x86_64" )
- set( ANDROID_LLVM_TRIPLE "x86_64-none-linux-android" )
-elseif( ANDROID_ABI STREQUAL "mips64" )
- set( MIPS64 true )
- set( ANDROID_NDK_ABI_NAME "mips64" )
- set( ANDROID_ARCH_NAME "mips64" )
- set( ANDROID_LLVM_TRIPLE "mips64el-none-linux-android" )
- set( CMAKE_SYSTEM_PROCESSOR "mips64" )
-elseif( ANDROID_ABI STREQUAL "mips" )
- set( MIPS true )
- set( ANDROID_NDK_ABI_NAME "mips" )
- set( ANDROID_ARCH_NAME "mips" )
- set( ANDROID_LLVM_TRIPLE "mipsel-none-linux-android" )
- set( CMAKE_SYSTEM_PROCESSOR "mips" )
-elseif( ANDROID_ABI STREQUAL "arm64-v8a" )
- set( ARM64_V8A true )
- set( ANDROID_NDK_ABI_NAME "arm64-v8a" )
- set( ANDROID_ARCH_NAME "arm64" )
- set( ANDROID_LLVM_TRIPLE "aarch64-none-linux-android" )
- set( CMAKE_SYSTEM_PROCESSOR "aarch64" )
- set( VFPV3 true )
- set( NEON true )
-elseif( ANDROID_ABI STREQUAL "armeabi" )
- set( ARMEABI true )
- set( ANDROID_NDK_ABI_NAME "armeabi" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv5te" )
-elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" )
- set( ARMEABI_V6 true )
- set( ANDROID_NDK_ABI_NAME "armeabi" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv6" )
- # need always fallback to older platform
- set( ARMEABI true )
-elseif( ANDROID_ABI STREQUAL "armeabi-v7a")
- set( ARMEABI_V7A true )
- set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
-elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" )
- set( ARMEABI_V7A true )
- set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
- set( VFPV3 true )
-elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" )
- set( ARMEABI_V7A true )
- set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
- set( VFPV3 true )
- set( NEON true )
-else()
- message( SEND_ERROR "Unknown ANDROID_ABI=\"${ANDROID_ABI}\" is specified." )
-endif()
-
-if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" )
- # really dirty hack
- # it is not possible to change CMAKE_SYSTEM_PROCESSOR after the first run...
- file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" )
-endif()
-
-if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 )
- __INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD VALUES OFF )
- set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE )
- mark_as_advanced( ANDROID_FORCE_ARM_BUILD )
-else()
- unset( ANDROID_FORCE_ARM_BUILD CACHE )
-endif()
-
-# choose toolchain
-if( ANDROID_TOOLCHAIN_NAME )
- list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx )
- if( __toolchainIdx EQUAL -1 )
-  list( SORT __availableToolchains )
-  string( REPLACE ";" "\n  * " toolchains_list "${__availableToolchains}" )
-  set( toolchains_list "  * ${toolchains_list}")
-  message( FATAL_ERROR "Specified toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing in your NDK or broken. Please verify that your NDK is working or select another compiler toolchain.
-To configure the toolchain set CMake variable ANDROID_TOOLCHAIN_NAME to one of the following values:\n${toolchains_list}\n" )
- endif()
- list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch )
- if( NOT __toolchainArch STREQUAL ANDROID_ARCH_NAME )
-  message( SEND_ERROR "Selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." )
- endif()
-else()
- set( __toolchainIdx -1 )
- set( __applicableToolchains "" )
- set( __toolchainMaxVersion "0.0.0" )
- list( LENGTH __availableToolchains __availableToolchainsCount )
- math( EXPR __availableToolchainsCount "${__availableToolchainsCount}-1" )
- foreach( __idx RANGE ${__availableToolchainsCount} )
-  list( GET __availableToolchainArchs ${__idx} __toolchainArch )
-  if( __toolchainArch STREQUAL ANDROID_ARCH_NAME )
-   list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion )
-   string( REPLACE "x" "99" __toolchainVersion "${__toolchainVersion}")
-   if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion )
-    set( __toolchainMaxVersion "${__toolchainVersion}" )
-    set( __toolchainIdx ${__idx} )
-   endif()
-  endif()
- endforeach()
- unset( __availableToolchainsCount )
- unset( __toolchainMaxVersion )
- unset( __toolchainVersion )
-endif()
-unset( __toolchainArch )
-if( __toolchainIdx EQUAL -1 )
- message( FATAL_ERROR "No one of available compiler toolchains is able to compile for ${ANDROID_ARCH_NAME} platform." )
-endif()
-list( GET __availableToolchains ${__toolchainIdx} ANDROID_TOOLCHAIN_NAME )
-list( GET __availableToolchainMachines ${__toolchainIdx} ANDROID_TOOLCHAIN_MACHINE_NAME )
-list( GET __availableToolchainCompilerVersions ${__toolchainIdx} ANDROID_COMPILER_VERSION )
-
-unset( __toolchainIdx )
-unset( __availableToolchains )
-unset( __availableToolchainMachines )
-unset( __availableToolchainArchs )
-unset( __availableToolchainCompilerVersions )
-
-# choose native API level
-__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL )
-string( REPLACE "android-" "" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" )
-string( STRIP "${ANDROID_NATIVE_API_LEVEL}" ANDROID_NATIVE_API_LEVEL )
-# adjust API level
-set( __real_api_level ${ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME}} )
-foreach( __level ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
- if( (__level LESS ANDROID_NATIVE_API_LEVEL OR __level STREQUAL ANDROID_NATIVE_API_LEVEL) AND NOT __level LESS __real_api_level )
-  set( __real_api_level ${__level} )
- endif()
-endforeach()
-if( __real_api_level AND NOT ANDROID_NATIVE_API_LEVEL STREQUAL __real_api_level )
- message( STATUS "Adjusting Android API level 'android-${ANDROID_NATIVE_API_LEVEL}' to 'android-${__real_api_level}'")
- set( ANDROID_NATIVE_API_LEVEL ${__real_api_level} )
-endif()
-unset(__real_api_level)
-# validate
-list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx )
-if( __levelIdx EQUAL -1 )
- message( SEND_ERROR "Specified Android native API level 'android-${ANDROID_NATIVE_API_LEVEL}' is not supported by your NDK/toolchain." )
-else()
- if( BUILD_WITH_ANDROID_NDK )
-  __DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" )
-  if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL AND NOT __realApiLevel GREATER 9000 )
-   message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." )
-  endif()
-  unset( __realApiLevel )
- endif()
- set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE )
- set( CMAKE_ANDROID_API ${ANDROID_NATIVE_API_LEVEL} )
- if( CMAKE_VERSION VERSION_GREATER "2.8" )
-  list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS )
-  set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
- endif()
-endif()
-unset( __levelIdx )
-
-
-# remember target ABI
-set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE )
-if( CMAKE_VERSION VERSION_GREATER "2.8" )
- list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME} )
- set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME}} )
-endif()
-
-
-# runtime choice (STL, rtti, exceptions)
-if( NOT ANDROID_STL )
-  set( ANDROID_STL gnustl_static )
-endif()
-set( ANDROID_STL "${ANDROID_STL}" CACHE STRING "C++ runtime" )
-set( ANDROID_STL_FORCE_FEATURES ON CACHE BOOL "automatically configure rtti and exceptions support based on C++ runtime" )
-mark_as_advanced( ANDROID_STL ANDROID_STL_FORCE_FEATURES )
-
-if( BUILD_WITH_ANDROID_NDK )
- if( NOT "${ANDROID_STL}" MATCHES "^(none|system|system_re|gabi\\+\\+_static|gabi\\+\\+_shared|stlport_static|stlport_shared|gnustl_static|gnustl_shared)$")
-  message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\".
-The possible values are:
-  none           -> Do not configure the runtime.
-  system         -> Use the default minimal system C++ runtime library.
-  system_re      -> Same as system but with rtti and exceptions.
-  gabi++_static  -> Use the GAbi++ runtime as a static library.
-  gabi++_shared  -> Use the GAbi++ runtime as a shared library.
-  stlport_static -> Use the STLport runtime as a static library.
-  stlport_shared -> Use the STLport runtime as a shared library.
-  gnustl_static  -> (default) Use the GNU STL as a static library.
-  gnustl_shared  -> Use the GNU STL as a shared library.
-" )
- endif()
-elseif( BUILD_WITH_STANDALONE_TOOLCHAIN )
- if( NOT "${ANDROID_STL}" MATCHES "^(none|gnustl_static|gnustl_shared)$")
-  message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\".
-The possible values are:
-  none           -> Do not configure the runtime.
-  gnustl_static  -> (default) Use the GNU STL as a static library.
-  gnustl_shared  -> Use the GNU STL as a shared library.
-" )
- endif()
-endif()
-
-unset( ANDROID_RTTI )
-unset( ANDROID_EXCEPTIONS )
-unset( ANDROID_STL_INCLUDE_DIRS )
-unset( __libstl )
-unset( __libsupcxx )
-
-if( NOT _CMAKE_IN_TRY_COMPILE AND ANDROID_NDK_RELEASE STREQUAL "r7b" AND ARMEABI_V7A AND NOT VFPV3 AND ANDROID_STL MATCHES "gnustl" )
- message( WARNING  "The GNU STL armeabi-v7a binaries from NDK r7b can crash non-NEON devices. The files provided with NDK r7b were not configured properly, resulting in crashes on Tegra2-based devices and others when trying to use certain floating-point functions (e.g., cosf, sinf, expf).
-You are strongly recommended to switch to another NDK release.
-" )
-endif()
-
-if( NOT _CMAKE_IN_TRY_COMPILE AND X86 AND ANDROID_STL MATCHES "gnustl" AND ANDROID_NDK_RELEASE STREQUAL "r6" )
-  message( WARNING  "The x86 system header file from NDK r6 has incorrect definition for ptrdiff_t. You are recommended to upgrade to a newer NDK release or manually patch the header:
-See https://android.googlesource.com/platform/development.git f907f4f9d4e56ccc8093df6fee54454b8bcab6c2
-  diff --git a/ndk/platforms/android-9/arch-x86/include/machine/_types.h b/ndk/platforms/android-9/arch-x86/include/machine/_types.h
-  index 5e28c64..65892a1 100644
-  --- a/ndk/platforms/android-9/arch-x86/include/machine/_types.h
-  +++ b/ndk/platforms/android-9/arch-x86/include/machine/_types.h
-  @@ -51,7 +51,11 @@ typedef long int       ssize_t;
-   #endif
-   #ifndef _PTRDIFF_T
-   #define _PTRDIFF_T
-  -typedef long           ptrdiff_t;
-  +#  ifdef __ANDROID__
-  +     typedef int            ptrdiff_t;
-  +#  else
-  +     typedef long           ptrdiff_t;
-  +#  endif
-   #endif
-" )
-endif()
-
-
-# setup paths and STL for standalone toolchain
-if( BUILD_WITH_STANDALONE_TOOLCHAIN )
- set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
- set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
- set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" )
-
- if( NOT ANDROID_STL STREQUAL "none" )
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/include/c++/${ANDROID_COMPILER_VERSION}" )
-  if( NOT EXISTS "${ANDROID_STL_INCLUDE_DIRS}" )
-   # old location ( pre r8c )
-   set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" )
-  endif()
-  if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" )
-   list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" )
-  elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" )
-   list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb" )
-  else()
-   list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" )
-  endif()
-  # always search static GNU STL to get the location of libsupc++.a
-  if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" )
-   set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb" )
-  elseif( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" )
-   set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}" )
-  elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libstdc++.a" )
-   set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb" )
-  elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libstdc++.a" )
-   set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib" )
-  endif()
-  if( __libstl )
-   set( __libsupcxx "${__libstl}/libsupc++.a" )
-   set( __libstl    "${__libstl}/libstdc++.a" )
-  endif()
-  if( NOT EXISTS "${__libsupcxx}" )
-   message( FATAL_ERROR "The required libstdsupc++.a is missing in your standalone toolchain.
- Usually it happens because of bug in make-standalone-toolchain.sh script from NDK r7, r7b and r7c.
- You need to either upgrade to newer NDK or manually copy
-     $ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a
- to
-     ${__libsupcxx}
-   " )
-  endif()
-  if( ANDROID_STL STREQUAL "gnustl_shared" )
-   if( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" )
-    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" )
-   elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" )
-    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" )
-   elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" )
-    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" )
-   endif()
-  endif()
- endif()
-endif()
-
-# clang
-if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" )
- set( ANDROID_COMPILER_IS_CLANG 1 )
- execute_process( COMMAND "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/clang${TOOL_OS_SUFFIX}" --version OUTPUT_VARIABLE ANDROID_CLANG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE )
- string( REGEX MATCH "[0-9]+[.][0-9]+" ANDROID_CLANG_VERSION "${ANDROID_CLANG_VERSION}")
-elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" )
- string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}")
- string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-${ANDROID_COMPILER_VERSION}" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
- if( NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}/bin/clang${TOOL_OS_SUFFIX}" )
-  message( FATAL_ERROR "Could not find the Clang compiler driver" )
- endif()
- set( ANDROID_COMPILER_IS_CLANG 1 )
- set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
-else()
- set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
- unset( ANDROID_COMPILER_IS_CLANG CACHE )
-endif()
-
-string( REPLACE "." "" _clang_name "clang${ANDROID_CLANG_VERSION}" )
-if( NOT EXISTS "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" )
- set( _clang_name "clang" )
-endif()
-
-
-# setup paths and STL for NDK
-if( BUILD_WITH_ANDROID_NDK )
- set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
- set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" )
-
- if( ANDROID_STL STREQUAL "none" )
-  # do nothing
- elseif( ANDROID_STL STREQUAL "system" )
-  set( ANDROID_RTTI             OFF )
-  set( ANDROID_EXCEPTIONS       OFF )
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
- elseif( ANDROID_STL STREQUAL "system_re" )
-  set( ANDROID_RTTI             ON )
-  set( ANDROID_EXCEPTIONS       ON )
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
- elseif( ANDROID_STL MATCHES "gabi" )
-  if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7
-   message( FATAL_ERROR "gabi++ is not available in your NDK. You have to upgrade to NDK r7 or newer to use gabi++.")
-  endif()
-  set( ANDROID_RTTI             ON )
-  set( ANDROID_EXCEPTIONS       OFF )
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/gabi++/include" )
-  set( __libstl                 "${ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${ANDROID_NDK_ABI_NAME}/libgabi++_static.a" )
- elseif( ANDROID_STL MATCHES "stlport" )
-  if( NOT ANDROID_NDK_RELEASE_NUM LESS 8004 ) # before r8d
-   set( ANDROID_EXCEPTIONS       ON )
-  else()
-   set( ANDROID_EXCEPTIONS       OFF )
-  endif()
-  if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7
-   set( ANDROID_RTTI            OFF )
-  else()
-   set( ANDROID_RTTI            ON )
-  endif()
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" )
-  set( __libstl                 "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
- elseif( ANDROID_STL MATCHES "gnustl" )
-  set( ANDROID_EXCEPTIONS       ON )
-  set( ANDROID_RTTI             ON )
-  if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
-   if( ARMEABI_V7A AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.7" AND ANDROID_NDK_RELEASE STREQUAL "r8d" )
-    # gnustl binary for 4.7 compiler is buggy :(
-    # TODO: look for right fix
-    set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.6" )
-   else()
-    set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
-   endif()
-  else()
-   set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++" )
-  endif()
-  set( ANDROID_STL_INCLUDE_DIRS "${__libstl}/include" "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/include" "${__libstl}/include/backward" )
-  if( EXISTS "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
-   set( __libstl                "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
-  else()
-   set( __libstl                "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
-  endif()
- else()
-  message( FATAL_ERROR "Unknown runtime: ${ANDROID_STL}" )
- endif()
- # find libsupc++.a - rtti & exceptions
- if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" )
-  set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r8b or newer
-  if( NOT EXISTS "${__libsupcxx}" )
-   set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r7-r8
-  endif()
-  if( NOT EXISTS "${__libsupcxx}" ) # before r7
-   if( ARMEABI_V7A )
-    if( ANDROID_FORCE_ARM_BUILD )
-     set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" )
-    else()
-     set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" )
-    endif()
-   elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD )
-    set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" )
-   else()
-    set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" )
-   endif()
-  endif()
-  if( NOT EXISTS "${__libsupcxx}")
-   message( ERROR "Could not find libsupc++.a for a chosen platform. Either your NDK is not supported or is broken.")
-  endif()
- endif()
-endif()
-
-
-# case of shared STL linkage
-if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl )
- string( REPLACE "_static.a" "_shared.so" __libstl "${__libstl}" )
- # TODO: check if .so file exists before the renaming
-endif()
-
-
-# ccache support
-__INIT_VARIABLE( _ndk_ccache NDK_CCACHE ENV_NDK_CCACHE )
-if( _ndk_ccache )
- if( DEFINED NDK_CCACHE AND NOT EXISTS NDK_CCACHE )
-  unset( NDK_CCACHE CACHE )
- endif()
- find_program( NDK_CCACHE "${_ndk_ccache}" DOC "The path to ccache binary")
-else()
- unset( NDK_CCACHE CACHE )
-endif()
-unset( _ndk_ccache )
-
-
-# setup the cross-compiler
-if( NOT CMAKE_C_COMPILER )
- if( NDK_CCACHE AND NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
-  set( CMAKE_C_COMPILER   "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" )
-  set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" )
-  if( ANDROID_COMPILER_IS_CLANG )
-   set( CMAKE_C_COMPILER_ARG1   "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}"   CACHE PATH "C compiler")
-   set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
-  else()
-   set( CMAKE_C_COMPILER_ARG1   "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler")
-   set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
-  endif()
- else()
-  if( ANDROID_COMPILER_IS_CLANG )
-   set( CMAKE_C_COMPILER   "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}"   CACHE PATH "C compiler")
-   set( CMAKE_CXX_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
-  else()
-   set( CMAKE_C_COMPILER   "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}"    CACHE PATH "C compiler" )
-   set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}"    CACHE PATH "C++ compiler" )
-  endif()
- endif()
- set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}"     CACHE PATH "assembler" )
- set( CMAKE_STRIP        "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}"   CACHE PATH "strip" )
- if( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc-ar${TOOL_OS_SUFFIX}" )
-  # Use gcc-ar if we have it for better LTO support.
-  set( CMAKE_AR           "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc-ar${TOOL_OS_SUFFIX}"      CACHE PATH "archive" )
- else()
-  set( CMAKE_AR           "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}"      CACHE PATH "archive" )
- endif()
- set( CMAKE_LINKER       "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}"      CACHE PATH "linker" )
- set( CMAKE_NM           "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}"      CACHE PATH "nm" )
- set( CMAKE_OBJCOPY      "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" )
- set( CMAKE_OBJDUMP      "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" )
- set( CMAKE_RANLIB       "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ranlib${TOOL_OS_SUFFIX}"  CACHE PATH "ranlib" )
-endif()
-
-set( _CMAKE_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_MACHINE_NAME}-" )
-if( CMAKE_VERSION VERSION_LESS 2.8.5 )
- set( CMAKE_ASM_COMPILER_ARG1 "-c" )
-endif()
-if( APPLE )
- find_program( CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool )
- if( NOT CMAKE_INSTALL_NAME_TOOL )
-  message( FATAL_ERROR "Could not find install_name_tool, please check your installation." )
- endif()
- mark_as_advanced( CMAKE_INSTALL_NAME_TOOL )
-endif()
-
-# Force set compilers because standard identification works badly for us
-include( CMakeForceCompiler )
-CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU )
-if( ANDROID_COMPILER_IS_CLANG )
- set( CMAKE_C_COMPILER_ID Clang )
-endif()
-set( CMAKE_C_PLATFORM_ID Linux )
-if( X86_64 OR MIPS64 OR ARM64_V8A )
- set( CMAKE_C_SIZEOF_DATA_PTR 8 )
-else()
- set( CMAKE_C_SIZEOF_DATA_PTR 4 )
-endif()
-set( CMAKE_C_HAS_ISYSROOT 1 )
-set( CMAKE_C_COMPILER_ABI ELF )
-CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU )
-if( ANDROID_COMPILER_IS_CLANG )
- set( CMAKE_CXX_COMPILER_ID Clang)
-endif()
-set( CMAKE_CXX_PLATFORM_ID Linux )
-set( CMAKE_CXX_SIZEOF_DATA_PTR ${CMAKE_C_SIZEOF_DATA_PTR} )
-set( CMAKE_CXX_HAS_ISYSROOT 1 )
-set( CMAKE_CXX_COMPILER_ABI ELF )
-set( CMAKE_CXX_SOURCE_FILE_EXTENSIONS cc cp cxx cpp CPP c++ C )
-# force ASM compiler (required for CMake < 2.8.5)
-set( CMAKE_ASM_COMPILER_ID_RUN TRUE )
-set( CMAKE_ASM_COMPILER_ID GNU )
-set( CMAKE_ASM_COMPILER_WORKS TRUE )
-set( CMAKE_ASM_COMPILER_FORCED TRUE )
-set( CMAKE_COMPILER_IS_GNUASM 1)
-set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm )
-
-foreach( lang C CXX ASM )
- if( ANDROID_COMPILER_IS_CLANG )
-  set( CMAKE_${lang}_COMPILER_VERSION ${ANDROID_CLANG_VERSION} )
- else()
-  set( CMAKE_${lang}_COMPILER_VERSION ${ANDROID_COMPILER_VERSION} )
- endif()
-endforeach()
-
-# flags and definitions
-remove_definitions( -DANDROID )
-add_definitions( -DANDROID )
-
-if( ANDROID_SYSROOT MATCHES "[ ;\"]" )
- if( CMAKE_HOST_WIN32 )
-  # try to convert path to 8.3 form
-  file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "@echo %~s1" )
-  execute_process( COMMAND "$ENV{ComSpec}" /c "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "${ANDROID_SYSROOT}"
-                   OUTPUT_VARIABLE __path OUTPUT_STRIP_TRAILING_WHITESPACE
-                   RESULT_VARIABLE __result ERROR_QUIET )
-  if( __result EQUAL 0 )
-   file( TO_CMAKE_PATH "${__path}" ANDROID_SYSROOT )
-   set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
-  else()
-   set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" )
-  endif()
- else()
-  set( ANDROID_CXX_FLAGS "'--sysroot=${ANDROID_SYSROOT}'" )
- endif()
- if( NOT _CMAKE_IN_TRY_COMPILE )
-  # quotes can break try_compile and compiler identification
-  message(WARNING "Path to your Android NDK (or toolchain) has non-alphanumeric symbols.\nThe build might be broken.\n")
- endif()
-else()
- set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
-endif()
-
-# NDK flags
-if (ARM64_V8A )
- set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS} -funwind-tables" )
- set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
- set( ANDROID_CXX_FLAGS_DEBUG   "-fno-omit-frame-pointer -fno-strict-aliasing" )
- if( NOT ANDROID_COMPILER_IS_CLANG )
-  set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" )
- endif()
-elseif( ARMEABI OR ARMEABI_V7A)
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
- if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 )
-  set( ANDROID_CXX_FLAGS_RELEASE "-mthumb -fomit-frame-pointer -fno-strict-aliasing" )
-  set( ANDROID_CXX_FLAGS_DEBUG   "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
-  if( NOT ANDROID_COMPILER_IS_CLANG )
-   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -finline-limit=64" )
-  endif()
- else()
-  # always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI
-  set( ANDROID_CXX_FLAGS_RELEASE "-marm -fomit-frame-pointer -fstrict-aliasing" )
-  set( ANDROID_CXX_FLAGS_DEBUG   "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
-  if( NOT ANDROID_COMPILER_IS_CLANG )
-   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
-  endif()
- endif()
-elseif( X86 OR X86_64 )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
- if( NOT ANDROID_COMPILER_IS_CLANG )
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
- endif()
- set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
- set( ANDROID_CXX_FLAGS_DEBUG   "-fno-omit-frame-pointer -fno-strict-aliasing" )
-elseif( MIPS OR MIPS64 )
- set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS} -fno-strict-aliasing -finline-functions -funwind-tables -fmessage-length=0" )
- set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer" )
- set( ANDROID_CXX_FLAGS_DEBUG   "-fno-omit-frame-pointer" )
- if( NOT ANDROID_COMPILER_IS_CLANG )
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" )
-  set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" )
- endif()
-elseif()
- set( ANDROID_CXX_FLAGS_RELEASE "" )
- set( ANDROID_CXX_FLAGS_DEBUG   "" )
-endif()
-
-set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) # good/necessary when porting desktop libraries
-
-if( NOT X86 AND NOT ANDROID_COMPILER_IS_CLANG )
- set( ANDROID_CXX_FLAGS "-Wno-psabi ${ANDROID_CXX_FLAGS}" )
-endif()
-
-if( NOT ANDROID_COMPILER_VERSION VERSION_LESS "4.6" )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -no-canonical-prefixes" ) # see https://android-review.googlesource.com/#/c/47564/
-endif()
-
-# ABI-specific flags
-if( ARMEABI_V7A )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mfloat-abi=softfp" )
- if( NEON )
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=neon" )
- elseif( VFPV3 )
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3" )
- else()
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3-d16" )
- endif()
-elseif( ARMEABI_V6 )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) # vfp == vfpv2
-elseif( ARMEABI )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" )
-endif()
-
-if( ANDROID_STL MATCHES "gnustl" AND (EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}") )
- set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
- set( CMAKE_CXX_CREATE_SHARED_MODULE  "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
- set( CMAKE_CXX_LINK_EXECUTABLE       "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
-else()
- set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
- set( CMAKE_CXX_CREATE_SHARED_MODULE  "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
- set( CMAKE_CXX_LINK_EXECUTABLE       "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
-endif()
-
-# STL
-if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" )
- if( EXISTS "${__libstl}" )
-  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libstl}\"" )
-  set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libstl}\"" )
-  set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} \"${__libstl}\"" )
- endif()
- if( EXISTS "${__libsupcxx}" )
-  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libsupcxx}\"" )
-  set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libsupcxx}\"" )
-  set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} \"${__libsupcxx}\"" )
-  # C objects:
-  set( CMAKE_C_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
-  set( CMAKE_C_CREATE_SHARED_MODULE  "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
-  set( CMAKE_C_LINK_EXECUTABLE       "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
-  set( CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY} \"${__libsupcxx}\"" )
-  set( CMAKE_C_CREATE_SHARED_MODULE  "${CMAKE_C_CREATE_SHARED_MODULE} \"${__libsupcxx}\"" )
-  set( CMAKE_C_LINK_EXECUTABLE       "${CMAKE_C_LINK_EXECUTABLE} \"${__libsupcxx}\"" )
- endif()
- if( ANDROID_STL MATCHES "gnustl" )
-  if( NOT EXISTS "${ANDROID_LIBM_PATH}" )
-   set( ANDROID_LIBM_PATH -lm )
-  endif()
-  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} ${ANDROID_LIBM_PATH}" )
-  set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} ${ANDROID_LIBM_PATH}" )
-  set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} ${ANDROID_LIBM_PATH}" )
- endif()
-endif()
-
-# variables controlling optional build flags
-if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7
- # libGLESv2.so in NDK's prior to r7 refers to missing external symbols.
- # So this flag option is required for all projects using OpenGL from native.
- __INIT_VARIABLE( ANDROID_SO_UNDEFINED                      VALUES ON )
-else()
- __INIT_VARIABLE( ANDROID_SO_UNDEFINED                      VALUES OFF )
-endif()
-__INIT_VARIABLE( ANDROID_NO_UNDEFINED                       VALUES ON )
-__INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING             VALUES ON )
-__INIT_VARIABLE( ANDROID_GOLD_LINKER                        VALUES ON )
-__INIT_VARIABLE( ANDROID_NOEXECSTACK                        VALUES ON )
-__INIT_VARIABLE( ANDROID_RELRO                              VALUES ON )
-
-set( ANDROID_NO_UNDEFINED           ${ANDROID_NO_UNDEFINED}           CACHE BOOL "Show all undefined symbols as linker errors" )
-set( ANDROID_SO_UNDEFINED           ${ANDROID_SO_UNDEFINED}           CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
-set( ANDROID_FUNCTION_LEVEL_LINKING ${ANDROID_FUNCTION_LEVEL_LINKING} CACHE BOOL "Put each function in separate section and enable garbage collection of unused input sections at link time" )
-set( ANDROID_GOLD_LINKER            ${ANDROID_GOLD_LINKER}            CACHE BOOL "Enables gold linker" )
-set( ANDROID_NOEXECSTACK            ${ANDROID_NOEXECSTACK}            CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
-set( ANDROID_RELRO                  ${ANDROID_RELRO}                  CACHE BOOL "Enables RELRO - a memory corruption mitigation technique" )
-mark_as_advanced( ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_FUNCTION_LEVEL_LINKING ANDROID_GOLD_LINKER ANDROID_NOEXECSTACK ANDROID_RELRO )
-
-# linker flags
-set( ANDROID_LINKER_FLAGS "" )
-
-if( ARMEABI_V7A )
- # this is *required* to use the following linker flags that routes around
- # a CPU bug in some Cortex-A8 implementations:
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--fix-cortex-a8" )
-endif()
-
-if( ANDROID_NO_UNDEFINED )
- if( MIPS )
-  # there is some sysroot-related problem in mips linker...
-  if( NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
-   set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib" )
-  endif()
- else()
-  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" )
- endif()
-endif()
-
-if( ANDROID_SO_UNDEFINED )
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-allow-shlib-undefined" )
-endif()
-
-if( ANDROID_FUNCTION_LEVEL_LINKING )
- set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" )
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" )
-endif()
-
-if( ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" )
- if( ANDROID_GOLD_LINKER AND (CMAKE_HOST_UNIX OR ANDROID_NDK_RELEASE_NUM GREATER 8002) AND (ARMEABI OR ARMEABI_V7A OR X86) )
-  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold" )
- elseif( ANDROID_NDK_RELEASE_NUM GREATER 8002 ) # after r8b
-  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=bfd" )
- elseif( ANDROID_NDK_RELEASE STREQUAL "r8b" AND ARMEABI AND NOT _CMAKE_IN_TRY_COMPILE )
-  message( WARNING "The default bfd linker from arm GCC 4.6 toolchain can fail with 'unresolvable R_ARM_THM_CALL relocation' error message. See https://code.google.com/p/android/issues/detail?id=35342
-  On Linux and OS X host platform you can workaround this problem using gold linker (default).
-  Rerun cmake with -DANDROID_GOLD_LINKER=ON option in case of problems.
-" )
- endif()
-endif() # version 4.6
-
-if( ANDROID_NOEXECSTACK )
- if( ANDROID_COMPILER_IS_CLANG )
-  set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -Xclang -mnoexecstack" )
- else()
-  set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -Wa,--noexecstack" )
- endif()
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,noexecstack" )
-endif()
-
-if( ANDROID_RELRO )
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now" )
-endif()
-
-if( ANDROID_COMPILER_IS_CLANG )
- set( ANDROID_CXX_FLAGS "-target ${ANDROID_LLVM_TRIPLE} -Qunused-arguments ${ANDROID_CXX_FLAGS}" )
- if( BUILD_WITH_ANDROID_NDK )
-  set( ANDROID_CXX_FLAGS "-gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT} ${ANDROID_CXX_FLAGS}" )
- endif()
-endif()
-
-# cache flags
-set( CMAKE_CXX_FLAGS           ""                        CACHE STRING "c++ flags" )
-set( CMAKE_C_FLAGS             ""                        CACHE STRING "c flags" )
-set( CMAKE_CXX_FLAGS_RELEASE   "-O3 -DNDEBUG"            CACHE STRING "c++ Release flags" )
-set( CMAKE_C_FLAGS_RELEASE     "-O3 -DNDEBUG"            CACHE STRING "c Release flags" )
-set( CMAKE_CXX_FLAGS_DEBUG     "-O0 -g -DDEBUG -D_DEBUG" CACHE STRING "c++ Debug flags" )
-set( CMAKE_C_FLAGS_DEBUG       "-O0 -g -DDEBUG -D_DEBUG" CACHE STRING "c Debug flags" )
-set( CMAKE_SHARED_LINKER_FLAGS ""                        CACHE STRING "shared linker flags" )
-set( CMAKE_MODULE_LINKER_FLAGS ""                        CACHE STRING "module linker flags" )
-set( CMAKE_EXE_LINKER_FLAGS    "-Wl,-z,nocopyreloc"      CACHE STRING "executable linker flags" )
-
-# put flags to cache (for debug purpose only)
-set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS}"         CACHE INTERNAL "Android specific c/c++ flags" )
-set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE}" CACHE INTERNAL "Android specific c/c++ Release flags" )
-set( ANDROID_CXX_FLAGS_DEBUG   "${ANDROID_CXX_FLAGS_DEBUG}"   CACHE INTERNAL "Android specific c/c++ Debug flags" )
-set( ANDROID_LINKER_FLAGS      "${ANDROID_LINKER_FLAGS}"      CACHE INTERNAL "Android specific c/c++ linker flags" )
-
-# finish flags
-set( CMAKE_CXX_FLAGS           "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
-set( CMAKE_C_FLAGS             "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
-set( CMAKE_CXX_FLAGS_RELEASE   "${ANDROID_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}" )
-set( CMAKE_C_FLAGS_RELEASE     "${ANDROID_CXX_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}" )
-set( CMAKE_CXX_FLAGS_DEBUG     "${ANDROID_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}" )
-set( CMAKE_C_FLAGS_DEBUG       "${ANDROID_CXX_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}" )
-set( CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" )
-set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" )
-set( CMAKE_EXE_LINKER_FLAGS    "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
-
-if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" )
- set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
- set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
- set( CMAKE_EXE_LINKER_FLAGS    "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
-endif()
-
-# pie/pic
-if( NOT (ANDROID_NATIVE_API_LEVEL LESS 16) AND (NOT DEFINED ANDROID_APP_PIE OR ANDROID_APP_PIE) AND (CMAKE_VERSION VERSION_GREATER 2.8.8) )
- set( CMAKE_POSITION_INDEPENDENT_CODE TRUE )
- set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie")
-else()
- set( CMAKE_POSITION_INDEPENDENT_CODE FALSE )
- set( CMAKE_CXX_FLAGS "-fpic ${CMAKE_CXX_FLAGS}" )
- set( CMAKE_C_FLAGS   "-fpic ${CMAKE_C_FLAGS}" )
-endif()
-
-# configure rtti
-if( DEFINED ANDROID_RTTI AND ANDROID_STL_FORCE_FEATURES )
- if( ANDROID_RTTI )
-  set( CMAKE_CXX_FLAGS "-frtti ${CMAKE_CXX_FLAGS}" )
- else()
-  set( CMAKE_CXX_FLAGS "-fno-rtti ${CMAKE_CXX_FLAGS}" )
- endif()
-endif()
-
-# configure exceptios
-if( DEFINED ANDROID_EXCEPTIONS AND ANDROID_STL_FORCE_FEATURES )
- if( ANDROID_EXCEPTIONS )
-  set( CMAKE_CXX_FLAGS "-fexceptions ${CMAKE_CXX_FLAGS}" )
-  set( CMAKE_C_FLAGS "-fexceptions ${CMAKE_C_FLAGS}" )
- else()
-  set( CMAKE_CXX_FLAGS "-fno-exceptions ${CMAKE_CXX_FLAGS}" )
-  set( CMAKE_C_FLAGS "-fno-exceptions ${CMAKE_C_FLAGS}" )
- endif()
-endif()
-
-# global includes and link directories
-include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} )
-get_filename_component(__android_install_path "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ABSOLUTE) # avoid CMP0015 policy warning
-link_directories( "${__android_install_path}" )
-
-# detect if need link crtbegin_so.o explicitly
-if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK )
- set( __cmd "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" )
- string( REPLACE "<CMAKE_CXX_COMPILER>" "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" __cmd "${__cmd}" )
- string( REPLACE "<CMAKE_C_COMPILER>"   "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"   __cmd "${__cmd}" )
- string( REPLACE "<CMAKE_SHARED_LIBRARY_CXX_FLAGS>" "${CMAKE_CXX_FLAGS}" __cmd "${__cmd}" )
- string( REPLACE "<LANGUAGE_COMPILE_FLAGS>" "" __cmd "${__cmd}" )
- string( REPLACE "<LINK_FLAGS>" "${CMAKE_SHARED_LINKER_FLAGS}" __cmd "${__cmd}" )
- string( REPLACE "<CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS>" "-shared" __cmd "${__cmd}" )
- string( REPLACE "<CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG>" "" __cmd "${__cmd}" )
- string( REPLACE "<TARGET_SONAME>" "" __cmd "${__cmd}" )
- string( REPLACE "<TARGET>" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain_crtlink_test.so" __cmd "${__cmd}" )
- string( REPLACE "<OBJECTS>" "\"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" __cmd "${__cmd}" )
- string( REPLACE "<LINK_LIBRARIES>" "" __cmd "${__cmd}" )
- separate_arguments( __cmd )
- foreach( __var ANDROID_NDK ANDROID_NDK_TOOLCHAINS_PATH ANDROID_STANDALONE_TOOLCHAIN )
-  if( ${__var} )
-   set( __tmp "${${__var}}" )
-   separate_arguments( __tmp )
-   string( REPLACE "${__tmp}" "${${__var}}" __cmd "${__cmd}")
-  endif()
- endforeach()
- string( REPLACE "'" "" __cmd "${__cmd}" )
- string( REPLACE "\"" "" __cmd "${__cmd}" )
- execute_process( COMMAND ${__cmd} RESULT_VARIABLE __cmd_result OUTPUT_QUIET ERROR_QUIET )
- if( __cmd_result EQUAL 0 )
-  set( ANDROID_EXPLICIT_CRT_LINK ON )
- else()
-  set( ANDROID_EXPLICIT_CRT_LINK OFF )
- endif()
-endif()
-
-if( ANDROID_EXPLICIT_CRT_LINK )
- set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
- set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
-endif()
-
-# setup output directories
-set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
-
-if( DEFINED LIBRARY_OUTPUT_PATH_ROOT
-      OR EXISTS "${CMAKE_SOURCE_DIR}/AndroidManifest.xml"
-      OR (EXISTS "${CMAKE_SOURCE_DIR}/../AndroidManifest.xml" AND EXISTS "${CMAKE_SOURCE_DIR}/../jni/") )
-  set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "Root for binaries output, set this to change where Android libs are installed to" )
-  if( NOT _CMAKE_IN_TRY_COMPILE )
-    if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
-      set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
-    else()
-      set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
-    endif()
-    set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for Android libs" )
-  endif()
-endif()
-
-# copy shaed stl library to build directory
-if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" AND DEFINED LIBRARY_OUTPUT_PATH )
-  get_filename_component( __libstlname "${__libstl}" NAME )
-  execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess )
-  if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}")
-    message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" )
-  endif()
-  unset( __fileCopyProcess )
-  unset( __libstlname )
-endif()
-
-
-# set these global flags for cmake client scripts to change behavior
-set( ANDROID True )
-set( BUILD_ANDROID True )
-
-# where is the target environment
-set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin" "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" "${ANDROID_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share" )
-
-# only search for libraries and includes in the ndk toolchain
-set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
-set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
-set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
-
-
-# macro to find packages on the host OS
-macro( find_host_package )
- set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
- set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
- set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
- if( CMAKE_HOST_WIN32 )
-  SET( WIN32 1 )
-  SET( UNIX )
- elseif( CMAKE_HOST_APPLE )
-  SET( APPLE 1 )
-  SET( UNIX )
- endif()
- find_package( ${ARGN} )
- SET( WIN32 )
- SET( APPLE )
- SET( UNIX 1 )
- set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
- set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
- set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
-endmacro()
-
-
-# macro to find programs on the host OS
-macro( find_host_program )
- set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
- set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
- set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
- if( CMAKE_HOST_WIN32 )
-  SET( WIN32 1 )
-  SET( UNIX )
- elseif( CMAKE_HOST_APPLE )
-  SET( APPLE 1 )
-  SET( UNIX )
- endif()
- find_program( ${ARGN} )
- SET( WIN32 )
- SET( APPLE )
- SET( UNIX 1 )
- set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
- set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
- set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
-endmacro()
-
-
-# export toolchain settings for the try_compile() command
-if( NOT _CMAKE_IN_TRY_COMPILE )
- set( __toolchain_config "")
- foreach( __var NDK_CCACHE  LIBRARY_OUTPUT_PATH_ROOT  ANDROID_FORBID_SYGWIN
-                ANDROID_NDK_HOST_X64
-                ANDROID_NDK
-                ANDROID_NDK_LAYOUT
-                ANDROID_STANDALONE_TOOLCHAIN
-                ANDROID_TOOLCHAIN_NAME
-                ANDROID_ABI
-                ANDROID_NATIVE_API_LEVEL
-                ANDROID_STL
-                ANDROID_STL_FORCE_FEATURES
-                ANDROID_FORCE_ARM_BUILD
-                ANDROID_NO_UNDEFINED
-                ANDROID_SO_UNDEFINED
-                ANDROID_FUNCTION_LEVEL_LINKING
-                ANDROID_GOLD_LINKER
-                ANDROID_NOEXECSTACK
-                ANDROID_RELRO
-                ANDROID_LIBM_PATH
-                ANDROID_EXPLICIT_CRT_LINK
-                ANDROID_APP_PIE
-                )
-  if( DEFINED ${__var} )
-   if( ${__var} MATCHES " ")
-    set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" )
-   else()
-    set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" )
-   endif()
-  endif()
- endforeach()
- file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/android.toolchain.config.cmake" "${__toolchain_config}" )
- unset( __toolchain_config )
-endif()
-
-
-# force cmake to produce / instead of \ in build commands for Ninja generator
-if( CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_HOST_WIN32 )
- # it is a bad hack after all
- # CMake generates Ninja makefiles with UNIX paths only if it thinks that we are going to build with MinGW
- set( CMAKE_COMPILER_IS_MINGW TRUE ) # tell CMake that we are MinGW
- set( CMAKE_CROSSCOMPILING TRUE )    # stop recursion
- enable_language( C )
- enable_language( CXX )
- # unset( CMAKE_COMPILER_IS_MINGW ) # can't unset because CMake does not convert back-slashes in response files without it
- unset( MINGW )
-endif()
-
-
-# Variables controlling behavior or set by cmake toolchain:
-#   ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips", "arm64-v8a", "x86_64", "mips64"
-#   ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14,15,16,17,18,19,21 (depends on NDK version)
-#   ANDROID_STL : gnustl_static/gnustl_shared/stlport_static/stlport_shared/gabi++_static/gabi++_shared/system_re/system/none
-#   ANDROID_FORBID_SYGWIN : ON/OFF
-#   ANDROID_NO_UNDEFINED : ON/OFF
-#   ANDROID_SO_UNDEFINED : OFF/ON  (default depends on NDK version)
-#   ANDROID_FUNCTION_LEVEL_LINKING : ON/OFF
-#   ANDROID_GOLD_LINKER : ON/OFF
-#   ANDROID_NOEXECSTACK : ON/OFF
-#   ANDROID_RELRO : ON/OFF
-#   ANDROID_FORCE_ARM_BUILD : ON/OFF
-#   ANDROID_STL_FORCE_FEATURES : ON/OFF
-#   ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product/<product_name>/obj/lib/libm.so) to workaround unresolved `sincos`
-# Can be set only at the first run:
-#   ANDROID_NDK : path to your NDK install
-#   NDK_CCACHE : path to your ccache executable
-#   ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain
-#   ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems)
-#   ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID)
-#   LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
-#   ANDROID_STANDALONE_TOOLCHAIN
-#
-# Primary read-only variables:
-#   ANDROID : always TRUE
-#   ARMEABI : TRUE for arm v6 and older devices
-#   ARMEABI_V6 : TRUE for arm v6
-#   ARMEABI_V7A : TRUE for arm v7a
-#   ARM64_V8A : TRUE for arm64-v8a
-#   NEON : TRUE if NEON unit is enabled
-#   VFPV3 : TRUE if VFP version 3 is enabled
-#   X86 : TRUE if configured for x86
-#   X86_64 : TRUE if configured for x86_64
-#   MIPS : TRUE if configured for mips
-#   MIPS64 : TRUE if configured for mips64
-#   BUILD_WITH_ANDROID_NDK : TRUE if NDK is used
-#   BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used
-#   ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform
-#   ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86", "mips", "arm64-v8a", "x86_64", "mips64" depending on ANDROID_ABI
-#   ANDROID_NDK_RELEASE : from r5 to r10d; set only for NDK
-#   ANDROID_NDK_RELEASE_NUM : numeric ANDROID_NDK_RELEASE version (1000*major+minor)
-#   ANDROID_ARCH_NAME : "arm", "x86", "mips", "arm64", "x86_64", "mips64" depending on ANDROID_ABI
-#   ANDROID_SYSROOT : path to the compiler sysroot
-#   TOOL_OS_SUFFIX : "" or ".exe" depending on host platform
-#   ANDROID_COMPILER_IS_CLANG : TRUE if clang compiler is used
-#
-# Secondary (less stable) read-only variables:
-#   ANDROID_COMPILER_VERSION : GCC version used (not Clang version)
-#   ANDROID_CLANG_VERSION : version of clang compiler if clang is used
-#   ANDROID_CXX_FLAGS : C/C++ compiler flags required by Android platform
-#   ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI
-#   ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux"
-#   ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK)
-#   ANDROID_CLANG_TOOLCHAIN_ROOT : path to clang tools
-#   ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK
-#   ANDROID_STL_INCLUDE_DIRS : stl include paths
-#   ANDROID_RTTI : if rtti is enabled by the runtime
-#   ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime
-#   ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used
-#
-# Defaults:
-#   ANDROID_DEFAULT_NDK_API_LEVEL
-#   ANDROID_DEFAULT_NDK_API_LEVEL_${ARCH}
-#   ANDROID_NDK_SEARCH_PATHS
-#   ANDROID_SUPPORTED_ABIS_${ARCH}
-#   ANDROID_SUPPORTED_NDK_VERSIONS
--- a/third_party/rust/cubeb-sys/libcubeb/cmake/toolchain-cross-mingw.cmake
+++ b/third_party/rust/cubeb-sys/libcubeb/cmake/toolchain-cross-mingw.cmake
@@ -1,14 +1,14 @@
 SET(CMAKE_SYSTEM_NAME Windows)
 
 set(COMPILER_PREFIX "i686-w64-mingw32")
 
 find_program(CMAKE_RC_COMPILER NAMES ${COMPILER_PREFIX}-windres)
-find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc)
-find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++)
+find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc-posix)
+find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++-posix)
 
 SET(CMAKE_FIND_ROOT_PATH /usr/${COMPILER_PREFIX})
 
 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
 set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
 
--- a/third_party/rust/cubeb-sys/libcubeb/include/cubeb/cubeb.h
+++ b/third_party/rust/cubeb-sys/libcubeb/include/cubeb/cubeb.h
@@ -48,22 +48,24 @@ extern "C" {
       fprintf(stderr, "Could not get preferred sample-rate");
       return rv;
     }
 
     cubeb_stream_params output_params;
     output_params.format = CUBEB_SAMPLE_FLOAT32NE;
     output_params.rate = rate;
     output_params.channels = 2;
+    output_params.layout = CUBEB_LAYOUT_UNDEFINED;
     output_params.prefs = CUBEB_STREAM_PREF_NONE;
 
     cubeb_stream_params input_params;
     input_params.format = CUBEB_SAMPLE_FLOAT32NE;
     input_params.rate = rate;
     input_params.channels = 1;
+    input_params.layout = CUBEB_LAYOUT_UNDEFINED;
     input_params.prefs = CUBEB_STREAM_PREF_NONE;
 
     cubeb_stream * stm;
     rv = cubeb_stream_init(app_ctx, &stm, "Example Stream 1",
                            NULL, &input_params,
                            NULL, &output_params,
                            latency_frames,
                            data_cb, state_cb,
@@ -97,17 +99,17 @@ extern "C" {
     long data_cb(cubeb_stream * stm, void * user,
                  void * input_buffer, void * output_buffer, long nframes)
     {
       float * in  = input_buffer;
       float * out = output_buffer;
 
       for (i = 0; i < nframes; ++i) {
         for (c = 0; c < 2; ++c) {
-          buf[i][c] = in[i];
+          out[i][c] = in[i];
         }
       }
       return nframes;
     }
     @endcode
 
     @code
     void state_cb(cubeb_stream * stm, void * user, cubeb_state state)
@@ -216,20 +218,29 @@ enum {
                          CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
                          CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
                          CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
 };
 
 /** Miscellaneous stream preferences. */
 typedef enum {
   CUBEB_STREAM_PREF_NONE     = 0x00, /**< No stream preferences are requested. */
-  CUBEB_STREAM_PREF_LOOPBACK = 0x01 /**< Request a loopback stream. Should be
+  CUBEB_STREAM_PREF_LOOPBACK = 0x01, /**< Request a loopback stream. Should be
                                          specified on the input params and an
                                          output device to loopback from should
                                          be passed in place of an input device. */
+  CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING = 0x02, /**< Disable switching
+                                                          default device on OS
+                                                          changes. */
+  CUBEB_STREAM_PREF_VOICE = 0x04  /**< This stream is going to transport voice data.
+                                       Depending on the backend and platform, this can
+                                       change the audio input or output devices
+                                       selected, as well as the quality of the stream,
+                                       for example to accomodate bluetooth SCO modes on
+                                       bluetooth devices. */
 } cubeb_stream_prefs;
 
 /** Stream format initialization parameters. */
 typedef struct {
   cubeb_sample_format format;   /**< Requested sample format.  One of
                                      #cubeb_sample_format. */
   uint32_t rate;                /**< Requested sample rate.  Valid range is [1000, 192000]. */
   uint32_t channels;            /**< Requested channel count.  Valid range is [1, 8]. */
@@ -623,19 +634,23 @@ CUBEB_EXPORT int cubeb_enumerate_devices
     @retval CUBEB_OK
     @retval CUBEB_ERROR_INVALID_PARAMETER if collection is an invalid pointer */
 CUBEB_EXPORT int cubeb_device_collection_destroy(cubeb * context,
                                                  cubeb_device_collection * collection);
 
 /** Registers a callback which is called when the system detects
     a new device or a device is removed.
     @param context
-    @param devtype device type to include
+    @param devtype device type to include. Different callbacks and user pointers
+           can be registered for each devtype. The hybrid devtype
+           `CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT` is also valid
+           and will register the provided callback and user pointer in both sides.
     @param callback a function called whenever the system device list changes.
-           Passing NULL allow to unregister a function
+           Passing NULL allow to unregister a function. You have to unregister
+           first before you register a new callback.
     @param user_ptr pointer to user specified data which will be present in
            subsequent callbacks.
     @retval CUBEB_ERROR_NOT_SUPPORTED */
 CUBEB_EXPORT int cubeb_register_device_collection_changed(cubeb * context,
                                                           cubeb_device_type devtype,
                                                           cubeb_device_collection_changed_callback callback,
                                                           void * user_ptr);
 
--- a/third_party/rust/cubeb-sys/libcubeb/src/android/sles_definitions.h
+++ b/third_party/rust/cubeb-sys/libcubeb/src/android/sles_definitions.h
@@ -38,20 +38,19 @@
 #define SL_ANDROID_RECORDING_PRESET_GENERIC             ((SLuint32) 0x00000001)
 /**   uses the microphone audio source with the same orientation as the camera
  *     if available, the main device microphone otherwise */
 #define SL_ANDROID_RECORDING_PRESET_CAMCORDER           ((SLuint32) 0x00000002)
 /**   uses the main microphone tuned for voice recognition */
 #define SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION   ((SLuint32) 0x00000003)
 /**   uses the main microphone tuned for audio communications */
 #define SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION ((SLuint32) 0x00000004)
+/**   uses the main microphone unprocessed */
+#define SL_ANDROID_RECORDING_PRESET_UNPROCESSED         ((SLuint32) 0x00000005)
 
-/** Audio recording get session ID (read only) */
-/** Audio recording get session ID key */
-#define SL_ANDROID_KEY_RECORDING_SESSION_ID ((const SLchar*) "androidRecordingSessionId")
 
 /*---------------------------------------------------------------------------*/
 /* Android AudioPlayer configuration                                         */
 /*---------------------------------------------------------------------------*/
 
 /** Audio playback stream type */
 /** Audio playback stream type key */
 #define SL_ANDROID_KEY_STREAM_TYPE ((const SLchar*) "androidPlaybackStreamType")
@@ -64,14 +63,40 @@
 /*      same as android.media.AudioManager.STREAM_RING */
 #define SL_ANDROID_STREAM_RING         ((SLint32) 0x00000002)
 /*      same as android.media.AudioManager.STREAM_MUSIC */
 #define SL_ANDROID_STREAM_MEDIA        ((SLint32) 0x00000003)
 /*      same as android.media.AudioManager.STREAM_ALARM */
 #define SL_ANDROID_STREAM_ALARM        ((SLint32) 0x00000004)
 /*      same as android.media.AudioManager.STREAM_NOTIFICATION */
 #define SL_ANDROID_STREAM_NOTIFICATION ((SLint32) 0x00000005)
-/*      same as android.media.AudioManager.STREAM_BLUETOOTH_SCO */
-#define SL_ANDROID_STREAM_BLUETOOTH_SCO ((SLint32) 0x00000006)
-/*      same as android.media.AudioManager.STREAM_SYSTEM_ENFORCED */
-#define SL_ANDROID_STREAM_SYSTEM_ENFORCED ((SLint32) 0x00000007)
+
+
+/*---------------------------------------------------------------------------*/
+/* Android AudioPlayer and AudioRecorder configuration                       */
+/*---------------------------------------------------------------------------*/
+
+/** Audio Performance mode.
+ * Performance mode tells the framework how to configure the audio path
+ * for a player or recorder according to application performance and
+ * functional requirements.
+ * It affects the output or input latency based on acceptable tradeoffs on
+ * battery drain and use of pre or post processing effects.
+ * Performance mode should be set before realizing the object and should be
+ * read after realizing the object to check if the requested mode could be
+ * granted or not.
+ */
+/** Audio Performance mode key */
+#define SL_ANDROID_KEY_PERFORMANCE_MODE ((const SLchar*) "androidPerformanceMode")
+
+/** Audio performance values */
+/*      No specific performance requirement. Allows HW and SW pre/post processing. */
+#define SL_ANDROID_PERFORMANCE_NONE ((SLuint32) 0x00000000)
+/*      Priority given to latency. No HW or software pre/post processing.
+ *      This is the default if no performance mode is specified. */
+#define SL_ANDROID_PERFORMANCE_LATENCY ((SLuint32) 0x00000001)
+/*      Priority given to latency while still allowing HW pre and post processing. */
+#define SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS ((SLuint32) 0x00000002)
+/*      Priority given to power saving if latency is not a concern.
+ *      Allows HW and SW pre/post processing. */
+#define SL_ANDROID_PERFORMANCE_POWER_SAVING ((SLuint32) 0x00000003)
 
 #endif /* OPENSL_ES_ANDROIDCONFIGURATION_H_ */
--- a/third_party/rust/cubeb-sys/libcubeb/src/cubeb.c
+++ b/third_party/rust/cubeb-sys/libcubeb/src/cubeb.c
@@ -37,25 +37,31 @@ int pulse_rust_init(cubeb ** contet, cha
 int jack_init (cubeb ** context, char const * context_name);
 #endif
 #if defined(USE_ALSA)
 int alsa_init(cubeb ** context, char const * context_name);
 #endif
 #if defined(USE_AUDIOUNIT)
 int audiounit_init(cubeb ** context, char const * context_name);
 #endif
+#if defined(USE_AUDIOUNIT_RUST)
+int audiounit_rust_init(cubeb ** contet, char const * context_name);
+#endif
 #if defined(USE_WINMM)
 int winmm_init(cubeb ** context, char const * context_name);
 #endif
 #if defined(USE_WASAPI)
 int wasapi_init(cubeb ** context, char const * context_name);
 #endif
 #if defined(USE_SNDIO)
 int sndio_init(cubeb ** context, char const * context_name);
 #endif
+#if defined(USE_SUN)
+int sun_init(cubeb ** context, char const * context_name);
+#endif
 #if defined(USE_OPENSL)
 int opensl_init(cubeb ** context, char const * context_name);
 #endif
 #if defined(USE_AUDIOTRACK)
 int audiotrack_init(cubeb ** context, char const * context_name);
 #endif
 #if defined(USE_KAI)
 int kai_init(cubeb ** context, char const * context_name);
@@ -63,17 +69,17 @@ int kai_init(cubeb ** context, char cons
 
 static int
 validate_stream_params(cubeb_stream_params * input_stream_params,
                        cubeb_stream_params * output_stream_params)
 {
   XASSERT(input_stream_params || output_stream_params);
   if (output_stream_params) {
     if (output_stream_params->rate < 1000 || output_stream_params->rate > 192000 ||
-        output_stream_params->channels < 1 || output_stream_params->channels > 8) {
+        output_stream_params->channels < 1) {
       return CUBEB_ERROR_INVALID_FORMAT;
     }
   }
   if (input_stream_params) {
     if (input_stream_params->rate < 1000 || input_stream_params->rate > 192000 ||
         input_stream_params->channels < 1 || input_stream_params->channels > 8) {
       return CUBEB_ERROR_INVALID_FORMAT;
     }
@@ -131,28 +137,36 @@ cubeb_init(cubeb ** context, char const 
     } else if (!strcmp(backend_name, "alsa")) {
 #if defined(USE_ALSA)
       init_oneshot = alsa_init;
 #endif
     } else if (!strcmp(backend_name, "audiounit")) {
 #if defined(USE_AUDIOUNIT)
       init_oneshot = audiounit_init;
 #endif
+    } else if (!strcmp(backend_name, "audiounit-rust")) {
+#if defined(USE_AUDIOUNIT_RUST)
+      init_oneshot = audiounit_rust_init;
+#endif
     } else if (!strcmp(backend_name, "wasapi")) {
 #if defined(USE_WASAPI)
       init_oneshot = wasapi_init;
 #endif
     } else if (!strcmp(backend_name, "winmm")) {
 #if defined(USE_WINMM)
       init_oneshot = winmm_init;
 #endif
     } else if (!strcmp(backend_name, "sndio")) {
 #if defined(USE_SNDIO)
       init_oneshot = sndio_init;
 #endif
+    } else if (!strcmp(backend_name, "sun")) {
+#if defined(USE_SUN)
+      init_oneshot = sun_init;
+#endif
     } else if (!strcmp(backend_name, "opensl")) {
 #if defined(USE_OPENSL)
       init_oneshot = opensl_init;
 #endif
     } else if (!strcmp(backend_name, "audiotrack")) {
 #if defined(USE_AUDIOTRACK)
       init_oneshot = audiotrack_init;
 #endif
@@ -166,37 +180,46 @@ cubeb_init(cubeb ** context, char const 
   }
 
   int (* default_init[])(cubeb **, char const *) = {
     /*
      * init_oneshot must be at the top to allow user
      * to override all other choices
      */
     init_oneshot,
+#if defined(USE_PULSE_RUST)
+    pulse_rust_init,
+#endif
 #if defined(USE_PULSE)
     pulse_init,
 #endif
 #if defined(USE_JACK)
     jack_init,
 #endif
 #if defined(USE_ALSA)
     alsa_init,
 #endif
 #if defined(USE_AUDIOUNIT)
     audiounit_init,
 #endif
+#if defined(USE_AUDIOUNIT_RUST)
+    audiounit_rust_init,
+#endif
 #if defined(USE_WASAPI)
     wasapi_init,
 #endif
 #if defined(USE_WINMM)
     winmm_init,
 #endif
 #if defined(USE_SNDIO)
     sndio_init,
 #endif
+#if defined(USE_SUN)
+    sun_init,
+#endif
 #if defined(USE_OPENSL)
     opensl_init,
 #endif
 #if defined(USE_AUDIOTRACK)
     audiotrack_init,
 #endif
 #if defined(USE_KAI)
     kai_init,
@@ -295,17 +318,17 @@ cubeb_stream_init(cubeb * context, cubeb
                   cubeb_stream_params * output_stream_params,
                   unsigned int latency,
                   cubeb_data_callback data_callback,
                   cubeb_state_callback state_callback,
                   void * user_ptr)
 {
   int r;
 
-  if (!context || !stream) {
+  if (!context || !stream || !data_callback || !state_callback) {
     return CUBEB_ERROR_INVALID_PARAMETER;
   }
 
   if ((r = validate_stream_params(input_stream_params, output_stream_params)) != CUBEB_OK ||
       (r = validate_latency(latency)) != CUBEB_OK) {
     return r;
   }
 
--- a/third_party/rust/cubeb-sys/libcubeb/src/cubeb_audiounit.cpp
+++ b/third_party/rust/cubeb-sys/libcubeb/src/cubeb_audiounit.cpp
@@ -59,82 +59,145 @@ const char * PRIVATE_AGGREGATE_DEVICE_NA
 #define ALOG(msg, ...) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{LOG(msg, ##__VA_ARGS__);})
 
 /* Testing empirically, some headsets report a minimal latency that is very
  * low, but this does not work in practice. Lie and say the minimum is 256
  * frames. */
 const uint32_t SAFE_MIN_LATENCY_FRAMES = 256;
 const uint32_t SAFE_MAX_LATENCY_FRAMES = 512;
 
+const AudioObjectPropertyAddress DEFAULT_INPUT_DEVICE_PROPERTY_ADDRESS = {
+  kAudioHardwarePropertyDefaultInputDevice,
+  kAudioObjectPropertyScopeGlobal,
+  kAudioObjectPropertyElementMaster
+};
+
+const AudioObjectPropertyAddress DEFAULT_OUTPUT_DEVICE_PROPERTY_ADDRESS = {
+  kAudioHardwarePropertyDefaultOutputDevice,
+  kAudioObjectPropertyScopeGlobal,
+  kAudioObjectPropertyElementMaster
+};
+
+const AudioObjectPropertyAddress DEVICE_IS_ALIVE_PROPERTY_ADDRESS = {
+  kAudioDevicePropertyDeviceIsAlive,
+  kAudioObjectPropertyScopeGlobal,
+  kAudioObjectPropertyElementMaster
+};
+
+const AudioObjectPropertyAddress DEVICES_PROPERTY_ADDRESS = {
+  kAudioHardwarePropertyDevices,
+  kAudioObjectPropertyScopeGlobal,
+  kAudioObjectPropertyElementMaster
+};
+
+const AudioObjectPropertyAddress INPUT_DATA_SOURCE_PROPERTY_ADDRESS = {
+  kAudioDevicePropertyDataSource,
+  kAudioDevicePropertyScopeInput,
+  kAudioObjectPropertyElementMaster
+};
+
+const AudioObjectPropertyAddress OUTPUT_DATA_SOURCE_PROPERTY_ADDRESS = {
+  kAudioDevicePropertyDataSource,
+  kAudioDevicePropertyScopeOutput,
+  kAudioObjectPropertyElementMaster
+};
+
+typedef uint32_t device_flags_value;
+
+enum device_flags {
+  DEV_UNKNOWN           = 0x00, /* Unknown */
+  DEV_INPUT             = 0x01, /* Record device like mic */
+  DEV_OUTPUT            = 0x02, /* Playback device like speakers */
+  DEV_SYSTEM_DEFAULT    = 0x04, /* System default device */
+  DEV_SELECTED_DEFAULT  = 0x08, /* User selected to use the system default device */
+};
+
 void audiounit_stream_stop_internal(cubeb_stream * stm);
-void audiounit_stream_start_internal(cubeb_stream * stm);
+static int audiounit_stream_start_internal(cubeb_stream * stm);
 static void audiounit_close_stream(cubeb_stream *stm);
 static int audiounit_setup_stream(cubeb_stream *stm);
 static vector<AudioObjectID>
 audiounit_get_devices_of_type(cubeb_device_type devtype);
+static UInt32 audiounit_get_device_presentation_latency(AudioObjectID devid, AudioObjectPropertyScope scope);
+
+#if !TARGET_OS_IPHONE
+static AudioObjectID audiounit_get_default_device_id(cubeb_device_type type);
+static int audiounit_uninstall_device_changed_callback(cubeb_stream * stm);
+static int audiounit_uninstall_system_changed_callback(cubeb_stream * stm);
+static void audiounit_reinit_stream_async(cubeb_stream * stm, device_flags_value flags);
+#endif
 
 extern cubeb_ops const audiounit_ops;
 
 struct cubeb {
   cubeb_ops const * ops = &audiounit_ops;
   owned_critical_section mutex;
-  atomic<int> active_streams{ 0 };
+  int active_streams = 0;
   uint32_t global_latency_frames = 0;
-  cubeb_device_collection_changed_callback collection_changed_callback = nullptr;
-  void * collection_changed_user_ptr = nullptr;
-  /* Differentiate input from output devices. */
-  cubeb_device_type collection_changed_devtype = CUBEB_DEVICE_TYPE_UNKNOWN;
-  vector<AudioObjectID> devtype_device_array;
-  // The queue is asynchronously deallocated once all references to it are released
+  cubeb_device_collection_changed_callback input_collection_changed_callback = nullptr;
+  void * input_collection_changed_user_ptr = nullptr;
+  cubeb_device_collection_changed_callback output_collection_changed_callback = nullptr;
+  void * output_collection_changed_user_ptr = nullptr;
+  // Store list of devices to detect changes
+  vector<AudioObjectID> input_device_array;
+  vector<AudioObjectID> output_device_array;
+  // The queue should be released when it’s no longer needed.
   dispatch_queue_t serial_queue = dispatch_queue_create(DISPATCH_QUEUE_LABEL, DISPATCH_QUEUE_SERIAL);
   // Current used channel layout
   atomic<cubeb_channel_layout> layout{ CUBEB_LAYOUT_UNDEFINED };
   uint32_t channels = 0;
 };
 
 static unique_ptr<AudioChannelLayout, decltype(&free)>
 make_sized_audio_channel_layout(size_t sz)
 {
     assert(sz >= sizeof(AudioChannelLayout));
     AudioChannelLayout * acl = reinterpret_cast<AudioChannelLayout *>(calloc(1, sz));
     assert(acl); // Assert the allocation works.
     return unique_ptr<AudioChannelLayout, decltype(&free)>(acl, free);
 }
 
-enum io_side {
+enum class io_side {
   INPUT,
   OUTPUT,
 };
 
 static char const *
 to_string(io_side side)
 {
   switch (side) {
-  case INPUT:
+  case io_side::INPUT:
     return "input";
-  case OUTPUT:
+  case io_side::OUTPUT:
     return "output";
   }
 }
 
-typedef uint32_t device_flags_value;
-
-enum device_flags {
-  DEV_UNKNOWN           = 0x00, /* Unknown */
-  DEV_INPUT             = 0x01, /* Record device like mic */
-  DEV_OUTPUT            = 0x02, /* Playback device like speakers */
-  DEV_SYSTEM_DEFAULT    = 0x04, /* System default device */
-  DEV_SELECTED_DEFAULT  = 0x08, /* User selected to use the system default device */
-};
-
 struct device_info {
   AudioDeviceID id = kAudioObjectUnknown;
   device_flags_value flags = DEV_UNKNOWN;
 };
 
+struct property_listener {
+  AudioDeviceID device_id;
+  const AudioObjectPropertyAddress * property_address;
+  AudioObjectPropertyListenerProc callback;
+  cubeb_stream * stream;
+
+  property_listener(AudioDeviceID id,
+                    const AudioObjectPropertyAddress * address,
+                    AudioObjectPropertyListenerProc proc,
+                    cubeb_stream * stm)
+    : device_id(id)
+    , property_address(address)
+    , callback(proc)
+    , stream(stm)
+  {}
+};
+
 struct cubeb_stream {
   explicit cubeb_stream(cubeb * context);
 
   /* Note: Must match cubeb_stream layout in cubeb.c. */
   cubeb * context;
   void * user_ptr = nullptr;
   /**/
 
@@ -155,49 +218,53 @@ struct cubeb_stream {
   AudioUnit output_unit = nullptr;
   /* I/O device sample rate */
   Float64 input_hw_rate = 0;
   Float64 output_hw_rate = 0;
   /* Expected I/O thread interleave,
    * calculated from I/O hw rate. */
   int expected_output_callbacks_in_a_row = 0;
   owned_critical_section mutex;
-  /* Hold the input samples in every
-   * input callback iteration */
+  // Hold the input samples in every input callback iteration.
+  // Only accessed on input/output callback thread and during initial configure.
   unique_ptr<auto_array_wrapper> input_linear_buffer;
-  owned_critical_section input_linear_buffer_lock;
-  // After the resampling some input data remains stored inside
-  // the resampler. This number is used in order to calculate
-  // the number of extra silence frames in input.
-  atomic<uint32_t> available_input_frames{ 0 };
-  /* Frames on input buffer */
-  atomic<uint32_t> input_buffer_frames{ 0 };
   /* Frame counters */
   atomic<uint64_t> frames_played{ 0 };
   uint64_t frames_queued = 0;
+  // How many frames got read from the input since the stream started (includes
+  // padded silence)
   atomic<int64_t> frames_read{ 0 };
+  // How many frames got written to the output device since the stream started
+  atomic<int64_t> frames_written{ 0 };
   atomic<bool> shutdown{ true };
   atomic<bool> draining{ false };
+  atomic<bool> reinit_pending { false };
+  atomic<bool> destroy_pending{ false };
   /* Latency requested by the user. */
   uint32_t latency_frames = 0;
-  atomic<uint64_t> current_latency_frames{ 0 };
-  uint64_t hw_latency_frames = UINT64_MAX;
+  atomic<uint32_t> current_latency_frames{ 0 };
   atomic<float> panning{ 0 };
   unique_ptr<cubeb_resampler, decltype(&cubeb_resampler_destroy)> resampler;
   /* This is true if a device change callback is currently running.  */
   atomic<bool> switching_device{ false };
   atomic<bool> buffer_size_change_state{ false };
-  AudioDeviceID aggregate_device_id = 0;    // the aggregate device id
-  AudioObjectID plugin_id = 0;              // used to create aggregate device
+  AudioDeviceID aggregate_device_id = kAudioObjectUnknown;  // the aggregate device id
+  AudioObjectID plugin_id = kAudioObjectUnknown;            // used to create aggregate device
   /* Mixer interface */
   unique_ptr<cubeb_mixer, decltype(&cubeb_mixer_destroy)> mixer;
   /* Buffer where remixing/resampling will occur when upmixing is required */
   /* Only accessed from callback thread */
   unique_ptr<uint8_t[]> temp_buffer;
   size_t temp_buffer_size = 0; // size in bytes.
+  /* Listeners indicating what system events are monitored. */
+  unique_ptr<property_listener> default_input_listener;
+  unique_ptr<property_listener> default_output_listener;
+  unique_ptr<property_listener> input_alive_listener;
+  unique_ptr<property_listener> input_source_listener;
+  unique_ptr<property_listener> output_source_listener;
 };
 
 bool has_input(cubeb_stream * stm)
 {
   return stm->input_stream_params.rate != 0;
 }
 
 bool has_output(cubeb_stream * stm)
@@ -286,17 +353,17 @@ cubeb_channel_to_channel_label(cubeb_cha
       return kAudioChannelLabel_VerticalHeightRight;
     case CHANNEL_TOP_BACK_LEFT:
       return kAudioChannelLabel_TopBackLeft;
     case CHANNEL_TOP_BACK_CENTER:
       return kAudioChannelLabel_TopBackCenter;
     case CHANNEL_TOP_BACK_RIGHT:
       return kAudioChannelLabel_TopBackRight;
     default:
-      return CHANNEL_UNKNOWN;
+      return kAudioChannelLabel_Unknown;
   }
 }
 
 #if TARGET_OS_IPHONE
 typedef UInt32 AudioDeviceID;
 typedef UInt32 AudioObjectID;
 
 #define AudioGetCurrentHostTime mach_absolute_time
@@ -315,35 +382,43 @@ AudioConvertHostTimeToNanos(uint64_t hos
   if (timebase_info.numer != timebase_info.denom) {
     answer *= timebase_info.numer;
     answer /= timebase_info.denom;
   }
   return (uint64_t)answer;
 }
 #endif
 
-static int64_t
-audiotimestamp_to_latency(AudioTimeStamp const * tstamp, cubeb_stream * stream)
+static void
+audiounit_increment_active_streams(cubeb * ctx)
 {
-  if (!(tstamp->mFlags & kAudioTimeStampHostTimeValid)) {
-    return 0;
-  }
-
-  uint64_t pres = AudioConvertHostTimeToNanos(tstamp->mHostTime);
-  uint64_t now = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
-
-  return ((pres - now) * stream->output_desc.mSampleRate) / 1000000000LL;
+  ctx->mutex.assert_current_thread_owns();
+  ctx->active_streams += 1;
 }
 
 static void
-audiounit_set_global_latency(cubeb_stream * stm, uint32_t latency_frames)
+audiounit_decrement_active_streams(cubeb * ctx)
+{
+  ctx->mutex.assert_current_thread_owns();
+  ctx->active_streams -= 1;
+}
+
+static int
+audiounit_active_streams(cubeb * ctx)
 {
-  stm->mutex.assert_current_thread_owns();
-  assert(stm->context->active_streams == 1);
-  stm->context->global_latency_frames = latency_frames;
+  ctx->mutex.assert_current_thread_owns();
+  return ctx->active_streams;
+}
+
+static void
+audiounit_set_global_latency(cubeb * ctx, uint32_t latency_frames)
+{
+  ctx->mutex.assert_current_thread_owns();
+  assert(audiounit_active_streams(ctx) == 1);
+  ctx->global_latency_frames = latency_frames;
 }
 
 static void
 audiounit_make_silent(AudioBuffer * ioData)
 {
   assert(ioData);
   assert(ioData->mData);
   memset(ioData->mData, 0, ioData->mDataByteSize);
@@ -369,38 +444,46 @@ audiounit_render_input(cubeb_stream * st
                                flags,
                                tstamp,
                                bus,
                                input_frames,
                                &input_buffer_list);
 
   if (r != noErr) {
     LOG("AudioUnitRender rv=%d", r);
-    return r;
-  }
-
-  /* Copy input data in linear buffer. */
-  {
-    auto_lock l(stm->input_linear_buffer_lock);
+    if (r != kAudioUnitErr_CannotDoInCurrentContext) {
+      return r;
+    }
+    if (stm->output_unit) {
+      // kAudioUnitErr_CannotDoInCurrentContext is returned when using a BT
+      // headset and the profile is changed from A2DP to HFP/HSP. The previous
+      // output device is no longer valid and must be reset.
+      audiounit_reinit_stream_async(stm, DEV_INPUT | DEV_OUTPUT);
+    }
+    // For now state that no error occurred and feed silence, stream will be
+    // resumed once reinit has completed.
+    ALOGV("(%p) input: reinit pending feeding silence instead", stm);
+    stm->input_linear_buffer->push_silence(input_frames * stm->input_desc.mChannelsPerFrame);
+  } else {
+    /* Copy input data in linear buffer. */
     stm->input_linear_buffer->push(input_buffer_list.mBuffers[0].mData,
                                    input_frames * stm->input_desc.mChannelsPerFrame);
   }
 
   /* Advance input frame counter. */
   assert(input_frames > 0);
   stm->frames_read += input_frames;
-  stm->available_input_frames += input_frames;
-
-  ALOGV("(%p) input: buffers %u, size %u, channels %u, rendered frames %d, total frames %d.",
-       stm,
-       (unsigned int) input_buffer_list.mNumberBuffers,
-       (unsigned int) input_buffer_list.mBuffers[0].mDataByteSize,
-       (unsigned int) input_buffer_list.mBuffers[0].mNumberChannels,
-       (unsigned int) input_frames,
-        stm->available_input_frames.load());
+
+  ALOGV("(%p) input: buffers %u, size %u, channels %u, rendered frames %d, total frames %lu.",
+        stm,
+        (unsigned int) input_buffer_list.mNumberBuffers,
+        (unsigned int) input_buffer_list.mBuffers[0].mDataByteSize,
+        (unsigned int) input_buffer_list.mBuffers[0].mNumberChannels,
+        (unsigned int) input_frames,
+        stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame);
 
   return noErr;
 }
 
 static OSStatus
 audiounit_input_callback(void * user_ptr,
                          AudioUnitRenderActionFlags * flags,
                          AudioTimeStamp const * tstamp,
@@ -425,58 +508,36 @@ audiounit_input_callback(void * user_ptr
 
   // Full Duplex. We'll call data_callback in the AudioUnit output callback.
   if (stm->output_unit != NULL) {
     return noErr;
   }
 
   /* Input only. Call the user callback through resampler.
      Resampler will deliver input buffer in the correct rate. */
-  {
-    auto_lock l(stm->input_linear_buffer_lock);
-    assert(input_frames <= stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame);
-    long total_input_frames = stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame;
-    long outframes = cubeb_resampler_fill(stm->resampler.get(),
-                                          stm->input_linear_buffer->data(),
-                                          &total_input_frames,
-                                          NULL,
-                                          0);
-    if (outframes < total_input_frames) {
-      OSStatus r = AudioOutputUnitStop(stm->input_unit);
-      assert(r == 0);
-      stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
-      return noErr;
-    }
-    assert(outframes >= 0);
-
-    // Reset input buffer
-    stm->input_linear_buffer->clear();
+  assert(input_frames <= stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame);
+  long total_input_frames = stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame;
+  long outframes = cubeb_resampler_fill(stm->resampler.get(),
+                                        stm->input_linear_buffer->data(),
+                                        &total_input_frames,
+                                        NULL,
+                                        0);
+  if (outframes < total_input_frames) {
+    OSStatus r = AudioOutputUnitStop(stm->input_unit);
+    assert(r == 0);
+    stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
+    return noErr;
   }
 
+  // Reset input buffer
+  stm->input_linear_buffer->clear();
+
   return noErr;
 }
 
-static uint32_t
-minimum_resampling_input_frames(cubeb_stream *stm)
-{
-  return ceilf(stm->input_hw_rate / stm->output_hw_rate * stm->input_buffer_frames);
-}
-
-static bool
-is_extra_input_needed(cubeb_stream * stm)
-{
-  /* If the output callback came first and this is a duplex stream, we need to
-    * fill in some additional silence in the resampler.
-    * Otherwise, if we had more than expected callbacks in a row, or we're currently
-    * switching, we add some silence as well to compensate for the fact that
-    * we're lacking some input data. */
-  return stm->frames_read == 0 ||
-         stm->available_input_frames.load() < minimum_resampling_input_frames(stm);
-}
-
 static void
 audiounit_mix_output_buffer(cubeb_stream * stm,
                             size_t output_frames,
                             void * input_buffer,
                             size_t input_buffer_size,
                             void * output_buffer,
                             size_t output_buffer_size)
 {
@@ -491,47 +552,59 @@ audiounit_mix_output_buffer(cubeb_stream
                           input_buffer_size,
                           output_buffer,
                           output_buffer_size);
   if (r != 0) {
     LOG("Remix error = %d", r);
   }
 }
 
+// Return how many input frames (sampled at input_hw_rate) are needed to provide
+// output_frames (sampled at output_stream_params.rate)
+static int64_t
+minimum_resampling_input_frames(cubeb_stream * stm, uint32_t output_frames)
+{
+  if (stm->input_hw_rate == stm->output_stream_params.rate) {
+    // Fast path.
+    return output_frames;
+  }
+  return ceil(stm->input_hw_rate * output_frames /
+              stm->output_stream_params.rate);
+}
+
 static OSStatus
 audiounit_output_callback(void * user_ptr,
                           AudioUnitRenderActionFlags * /* flags */,
                           AudioTimeStamp const * tstamp,
                           UInt32 bus,
                           UInt32 output_frames,
                           AudioBufferList * outBufferList)
 {
   assert(AU_OUT_BUS == bus);
   assert(outBufferList->mNumberBuffers == 1);
 
   cubeb_stream * stm = static_cast<cubeb_stream *>(user_ptr);
 
-  ALOGV("(%p) output: buffers %u, size %u, channels %u, frames %u, total input frames %d.",
+  ALOGV("(%p) output: buffers %u, size %u, channels %u, frames %u, total input frames %lu.",
         stm,
         (unsigned int) outBufferList->mNumberBuffers,
         (unsigned int) outBufferList->mBuffers[0].mDataByteSize,
         (unsigned int) outBufferList->mBuffers[0].mNumberChannels,
         (unsigned int) output_frames,
-        stm->available_input_frames.load());
-
-  long input_frames = 0, input_frames_before_fill = 0;
+        has_input(stm) ? stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame : 0);
+
+  long input_frames = 0;
   void * output_buffer = NULL, * input_buffer = NULL;
 
   if (stm->shutdown) {
     ALOG("(%p) output shutdown.", stm);
     audiounit_make_silent(&outBufferList->mBuffers[0]);
     return noErr;
   }
 
-  stm->current_latency_frames = audiotimestamp_to_latency(tstamp, stm);
   if (stm->draining) {
     OSStatus r = AudioOutputUnitStop(stm->output_unit);
     assert(r == 0);
     if (stm->input_unit) {
       r = AudioOutputUnitStop(stm->input_unit);
       assert(r == 0);
     }
     stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
@@ -549,51 +622,51 @@ audiounit_output_callback(void * user_pt
       stm->temp_buffer.reset(new uint8_t[size_needed]);
       stm->temp_buffer_size = size_needed;
     }
     output_buffer = stm->temp_buffer.get();
   } else {
     output_buffer = outBufferList->mBuffers[0].mData;
   }
 
+  stm->frames_written += output_frames;
+
   /* If Full duplex get also input buffer */
   if (stm->input_unit != NULL) {
-    if (is_extra_input_needed(stm)) {
-      uint32_t min_input_frames = minimum_resampling_input_frames(stm);
-      {
-        auto_lock l(stm->input_linear_buffer_lock);
-        stm->input_linear_buffer->push_silence(min_input_frames * stm->input_desc.mChannelsPerFrame);
-      }
-      stm->available_input_frames += min_input_frames;
-
-      ALOG("(%p) %s pushed %u frames of input silence.", stm, stm->frames_read == 0 ? "Input hasn't started," :
-           stm->switching_device ? "Device switching," : "Drop out,", min_input_frames);
+    /* If the output callback came first and this is a duplex stream, we need to
+     * fill in some additional silence in the resampler.
+     * Otherwise, if we had more than expected callbacks in a row, or we're
+     * currently switching, we add some silence as well to compensate for the
+     * fact that we're lacking some input data. */
+    uint32_t input_frames_needed =
+      minimum_resampling_input_frames(stm, stm->frames_written);
+    long missing_frames = input_frames_needed - stm->frames_read;
+    if (missing_frames > 0) {
+      stm->input_linear_buffer->push_silence(missing_frames * stm->input_desc.mChannelsPerFrame);
+      stm->frames_read = input_frames_needed;
+
+      ALOG("(%p) %s pushed %ld frames of input silence.", stm, stm->frames_read == 0 ? "Input hasn't started," :
+           stm->switching_device ? "Device switching," : "Drop out,", missing_frames);
     }
     input_buffer = stm->input_linear_buffer->data();
     // Number of input frames in the buffer. It will change to actually used frames
     // inside fill
     input_frames = stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame;
-    // Number of input frames pushed inside resampler.
-    input_frames_before_fill = input_frames;
   }
 
   /* Call user callback through resampler. */
   long outframes = cubeb_resampler_fill(stm->resampler.get(),
                                         input_buffer,
                                         input_buffer ? &input_frames : NULL,
                                         output_buffer,
                                         output_frames);
 
   if (input_buffer) {
-    // Decrease counter by the number of frames used by resampler
-    stm->available_input_frames -= input_frames;
-    assert(stm->available_input_frames.load() >= 0);
-    // Pop from the buffer the frames pushed to the resampler.
-    auto_lock l(stm->input_linear_buffer_lock);
-    stm->input_linear_buffer->pop(input_frames_before_fill * stm->input_desc.mChannelsPerFrame);
+    // Pop from the buffer the frames used by the the resampler.
+    stm->input_linear_buffer->pop(input_frames * stm->input_desc.mChannelsPerFrame);
   }
 
   if (outframes < 0 || outframes > output_frames) {
     stm->shutdown = true;
     OSStatus r = AudioOutputUnitStop(stm->output_unit);
     assert(r == 0);
     if (stm->input_unit) {
       r = AudioOutputUnitStop(stm->input_unit);
@@ -661,40 +734,38 @@ audiounit_get_backend_id(cubeb * /* ctx 
 {
   return "audiounit";
 }
 
 #if !TARGET_OS_IPHONE
 
 static int audiounit_stream_get_volume(cubeb_stream * stm, float * volume);
 static int audiounit_stream_set_volume(cubeb_stream * stm, float volume);
-static int audiounit_uninstall_device_changed_callback(cubeb_stream * stm);
-static AudioObjectID audiounit_get_default_device_id(cubeb_device_type type);
 
 static int
 audiounit_set_device_info(cubeb_stream * stm, AudioDeviceID id, io_side side)
 {
   assert(stm);
 
   device_info * info = nullptr;
   cubeb_device_type type = CUBEB_DEVICE_TYPE_UNKNOWN;
 
-  if (side == INPUT) {
+  if (side == io_side::INPUT) {
     info = &stm->input_device;
     type = CUBEB_DEVICE_TYPE_INPUT;
-  } else if (side == OUTPUT) {
+  } else if (side == io_side::OUTPUT) {
     info = &stm->output_device;
     type = CUBEB_DEVICE_TYPE_OUTPUT;
   }
   memset(info, 0, sizeof(device_info));
   info->id = id;
 
-  if (side == INPUT) {
+  if (side == io_side::INPUT) {
     info->flags |= DEV_INPUT;
-  } else if (side == OUTPUT) {
+  } else if (side == io_side::OUTPUT) {
     info->flags |= DEV_OUTPUT;
   }
 
   AudioDeviceID default_device_id = audiounit_get_default_device_id(type);
   if (default_device_id == kAudioObjectUnknown) {
     return CUBEB_ERROR;
   }
   if (id == kAudioObjectUnknown) {
@@ -734,56 +805,98 @@ audiounit_reinit_stream(cubeb_stream * s
     float volume = 0.0;
     int vol_rv = CUBEB_ERROR;
     if (stm->output_unit) {
       vol_rv = audiounit_stream_get_volume(stm, &volume);
     }
 
     audiounit_close_stream(stm);
 
-    /* Reinit occurs in 2 cases. When the device is not alive any more and when the
-     * default system device change. In both cases cubeb switch on the new default
-     * device. This is considered the most expected behavior for the user. */
+    /* Reinit occurs in one of the following case:
+     * - When the device is not alive any more
+     * - When the default system device change.
+     * - The bluetooth device changed from A2DP to/from HFP/HSP profile
+     * We first attempt to re-use the same device id, should that fail we will
+     * default to the (potentially new) default device. */
+    AudioDeviceID input_device = flags & DEV_INPUT ? stm->input_device.id : kAudioObjectUnknown;
     if (flags & DEV_INPUT) {
-      r = audiounit_set_device_info(stm, 0, INPUT);
+      r = audiounit_set_device_info(stm, input_device, io_side::INPUT);
       if (r != CUBEB_OK) {
         LOG("(%p) Set input device info failed. This can happen when last media device is unplugged", stm);
         return CUBEB_ERROR;
       }
     }
-    /* Always use the default output on reinit. This is not correct in every case
-     * but it is sufficient for Firefox and prevent reinit from reporting failures.
-     * It will change soon when reinit mechanism will be updated. */
-    r = audiounit_set_device_info(stm, 0, OUTPUT);
+
+    /* Always use the default output on reinit. This is not correct in every
+     * case but it is sufficient for Firefox and prevent reinit from reporting
+     * failures. It will change soon when reinit mechanism will be updated. */
+    r = audiounit_set_device_info(stm, kAudioObjectUnknown, io_side::OUTPUT);
     if (r != CUBEB_OK) {
       LOG("(%p) Set output device info failed. This can happen when last media device is unplugged", stm);
       return CUBEB_ERROR;
     }
 
     if (audiounit_setup_stream(stm) != CUBEB_OK) {
       LOG("(%p) Stream reinit failed.", stm);
-      return CUBEB_ERROR;
+      if (flags & DEV_INPUT && input_device != kAudioObjectUnknown) {
+        // Attempt to re-use the same device-id failed, so attempt again with
+        // default input device.
+        audiounit_close_stream(stm);
+        if (audiounit_set_device_info(stm, kAudioObjectUnknown, io_side::INPUT) != CUBEB_OK ||
+            audiounit_setup_stream(stm) != CUBEB_OK) {
+          LOG("(%p) Second stream reinit failed.", stm);
+          return CUBEB_ERROR;
+        }
+      }
     }
 
     if (vol_rv == CUBEB_OK) {
       audiounit_stream_set_volume(stm, volume);
     }
 
-    // Reset input frames to force new stream pre-buffer
-    // silence if needed, check `is_extra_input_needed()`
-    stm->frames_read = 0;
-
     // If the stream was running, start it again.
     if (!stm->shutdown) {
-      audiounit_stream_start_internal(stm);
+      r = audiounit_stream_start_internal(stm);
+      if (r != CUBEB_OK) {
+        return CUBEB_ERROR;
+      }
     }
   }
   return CUBEB_OK;
 }
 
+static void
+audiounit_reinit_stream_async(cubeb_stream * stm, device_flags_value flags)
+{
+  if (std::atomic_exchange(&stm->reinit_pending, true)) {
+    // A reinit task is already pending, nothing more to do.
+    ALOG("(%p) re-init stream task already pending, cancelling request", stm);
+    return;
+  }
+
+  // Use a new thread, through the queue, to avoid deadlock when calling
+  // Get/SetProperties method from inside notify callback
+  dispatch_async(stm->context->serial_queue, ^() {
+    if (stm->destroy_pending) {
+      ALOG("(%p) stream pending destroy, cancelling reinit task", stm);
+      return;
+    }
+
+    if (audiounit_reinit_stream(stm, flags) != CUBEB_OK) {
+      if (audiounit_uninstall_system_changed_callback(stm) != CUBEB_OK) {
+        LOG("(%p) Could not uninstall system changed callback", stm);
+      }
+      stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
+      LOG("(%p) Could not reopen the stream after switching.", stm);
+    }
+    stm->switching_device = false;
+    stm->reinit_pending = false;
+  });
+}
+
 static char const *
 event_addr_to_string(AudioObjectPropertySelector selector)
 {
   switch(selector) {
     case kAudioHardwarePropertyDefaultOutputDevice:
       return "kAudioHardwarePropertyDefaultOutputDevice";
     case kAudioHardwarePropertyDefaultInputDevice:
       return "kAudioHardwarePropertyDefaultInputDevice";
@@ -791,18 +904,16 @@ event_addr_to_string(AudioObjectProperty
       return "kAudioDevicePropertyDeviceIsAlive";
     case kAudioDevicePropertyDataSource:
       return "kAudioDevicePropertyDataSource";
     default:
       return "Unknown";
   }
 }
 
-static int audiounit_uninstall_system_changed_callback(cubeb_stream * stm);
-
 static OSStatus
 audiounit_property_listener_callback(AudioObjectID id, UInt32 address_count,
                                      const AudioObjectPropertyAddress * addresses,
                                      void * user)
 {
   cubeb_stream * stm = (cubeb_stream*) user;
   if (stm->switching_device) {
     LOG("Switching is already taking place. Skip Event %s for id=%d", event_addr_to_string(addresses[0].mSelector), id);
@@ -828,17 +939,17 @@ audiounit_property_listener_callback(Aud
           if (stm->input_device.flags & DEV_SYSTEM_DEFAULT) {
             LOG("It's the default input device, ignore the event");
             stm->switching_device = false;
             return noErr;
           }
         }
         break;
       case kAudioDevicePropertyDataSource: {
-          LOG("Event[%u] - mSelector == kAudioHardwarePropertyDataSource for id=%d", (unsigned int) i, id);
+          LOG("Event[%u] - mSelector == kAudioDevicePropertyDataSource for id=%d", (unsigned int) i, id);
         }
         break;
       default:
         LOG("Event[%u] - mSelector == Unexpected Event id %d, return", (unsigned int) i, addresses[i].mSelector);
         stm->switching_device = false;
         return noErr;
     }
   }
@@ -863,91 +974,81 @@ audiounit_property_listener_callback(Aud
         if (stm->device_changed_callback) {
           stm->device_changed_callback(stm->user_ptr);
         }
         break;
       }
     }
   }
 
-  // Use a new thread, through the queue, to avoid deadlock when calling
-  // Get/SetProperties method from inside notify callback
-  dispatch_async(stm->context->serial_queue, ^() {
-    if (audiounit_reinit_stream(stm, switch_side) != CUBEB_OK) {
-      if (audiounit_uninstall_system_changed_callback(stm) != CUBEB_OK) {
-        LOG("(%p) Could not uninstall system changed callback", stm);
-      }
-      stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
-      LOG("(%p) Could not reopen the stream after switching.", stm);
-    }
-    stm->switching_device = false;
-  });
+  audiounit_reinit_stream_async(stm, switch_side);
 
   return noErr;
 }
 
 OSStatus
-audiounit_add_listener(cubeb_stream * stm, AudioDeviceID id, AudioObjectPropertySelector selector,
-    AudioObjectPropertyScope scope, AudioObjectPropertyListenerProc listener)
+audiounit_add_listener(const property_listener * listener)
 {
-  AudioObjectPropertyAddress address = {
-      selector,
-      scope,
-      kAudioObjectPropertyElementMaster
-  };
-
-  return AudioObjectAddPropertyListener(id, &address, listener, stm);
+  assert(listener);
+  return AudioObjectAddPropertyListener(listener->device_id,
+                                        listener->property_address,
+                                        listener->callback,
+                                        listener->stream);
 }
 
 OSStatus
-audiounit_remove_listener(cubeb_stream * stm, AudioDeviceID id,
-                          AudioObjectPropertySelector selector,
-                          AudioObjectPropertyScope scope,
-                          AudioObjectPropertyListenerProc listener)
+audiounit_remove_listener(const property_listener * listener)
 {
-  AudioObjectPropertyAddress address = {
-      selector,
-      scope,
-      kAudioObjectPropertyElementMaster
-  };
-
-  return AudioObjectRemovePropertyListener(id, &address, listener, stm);
+  assert(listener);
+  return AudioObjectRemovePropertyListener(listener->device_id,
+                                           listener->property_address,
+                                           listener->callback,
+                                           listener->stream);
 }
 
 static int
 audiounit_install_device_changed_callback(cubeb_stream * stm)
 {
   OSStatus rv;
   int r = CUBEB_OK;
 
   if (stm->output_unit) {
     /* This event will notify us when the data source on the same device changes,
      * for example when the user plugs in a normal (non-usb) headset in the
      * headphone jack. */
-    rv = audiounit_add_listener(stm, stm->output_device.id, kAudioDevicePropertyDataSource,
-        kAudioDevicePropertyScopeOutput, &audiounit_property_listener_callback);
+    stm->output_source_listener.reset(new property_listener(
+      stm->output_device.id, &OUTPUT_DATA_SOURCE_PROPERTY_ADDRESS,
+      &audiounit_property_listener_callback, stm));
+    rv = audiounit_add_listener(stm->output_source_listener.get());
     if (rv != noErr) {
+      stm->output_source_listener.reset();
       LOG("AudioObjectAddPropertyListener/output/kAudioDevicePropertyDataSource rv=%d, device id=%d", rv, stm->output_device.id);
       r = CUBEB_ERROR;
     }
   }
 
   if (stm->input_unit) {
     /* This event will notify us when the data source on the input device changes. */
-    rv = audiounit_add_listener(stm, stm->input_device.id, kAudioDevicePropertyDataSource,
-        kAudioDevicePropertyScopeInput, &audiounit_property_listener_callback);
+    stm->input_source_listener.reset(new property_listener(
+      stm->input_device.id, &INPUT_DATA_SOURCE_PROPERTY_ADDRESS,
+      &audiounit_property_listener_callback, stm));
+    rv = audiounit_add_listener(stm->input_source_listener.get());
     if (rv != noErr) {
+      stm->input_source_listener.reset();
       LOG("AudioObjectAddPropertyListener/input/kAudioDevicePropertyDataSource rv=%d, device id=%d", rv, stm->input_device.id);
       r = CUBEB_ERROR;
     }
 
     /* Event to notify when the input is going away. */
-    rv = audiounit_add_listener(stm, stm->input_device.id, kAudioDevicePropertyDeviceIsAlive,
-        kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+    stm->input_alive_listener.reset(new property_listener(
+      stm->input_device.id, &DEVICE_IS_ALIVE_PROPERTY_ADDRESS,
+      &audiounit_property_listener_callback, stm));
+    rv = audiounit_add_listener(stm->input_alive_listener.get());
     if (rv != noErr) {
+      stm->input_alive_listener.reset();
       LOG("AudioObjectAddPropertyListener/input/kAudioDevicePropertyDeviceIsAlive rv=%d, device id =%d", rv, stm->input_device.id);
       r = CUBEB_ERROR;
     }
   }
 
   return r;
 }
 
@@ -956,90 +1057,99 @@ audiounit_install_system_changed_callbac
 {
   OSStatus r;
 
   if (stm->output_unit) {
     /* This event will notify us when the default audio device changes,
      * for example when the user plugs in a USB headset and the system chooses it
      * automatically as the default, or when another device is chosen in the
      * dropdown list. */
-    r = audiounit_add_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultOutputDevice,
-                               kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+    stm->default_output_listener.reset(new property_listener(
+      kAudioObjectSystemObject, &DEFAULT_OUTPUT_DEVICE_PROPERTY_ADDRESS,
+      &audiounit_property_listener_callback, stm));
+    r = audiounit_add_listener(stm->default_output_listener.get());
     if (r != noErr) {
+      stm->default_output_listener.reset();
       LOG("AudioObjectAddPropertyListener/output/kAudioHardwarePropertyDefaultOutputDevice rv=%d", r);
       return CUBEB_ERROR;
     }
   }
 
   if (stm->input_unit) {
     /* This event will notify us when the default input device changes. */
-    r = audiounit_add_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultInputDevice,
-                               kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+    stm->default_input_listener.reset(new property_listener(
+      kAudioObjectSystemObject, &DEFAULT_INPUT_DEVICE_PROPERTY_ADDRESS,
+      &audiounit_property_listener_callback, stm));
+    r = audiounit_add_listener(stm->default_input_listener.get());
     if (r != noErr) {
+      stm->default_input_listener.reset();
       LOG("AudioObjectAddPropertyListener/input/kAudioHardwarePropertyDefaultInputDevice rv=%d", r);
       return CUBEB_ERROR;
     }
   }
 
   return CUBEB_OK;
 }
 
 static int
 audiounit_uninstall_device_changed_callback(cubeb_stream * stm)
 {
   OSStatus rv;
   // Failing to uninstall listeners is not a fatal error.
   int r = CUBEB_OK;
 
-  if (stm->output_unit) {
-    rv = audiounit_remove_listener(stm, stm->output_device.id, kAudioDevicePropertyDataSource,
-        kAudioDevicePropertyScopeOutput, &audiounit_property_listener_callback);
+  if (stm->output_source_listener) {
+    rv = audiounit_remove_listener(stm->output_source_listener.get());
     if (rv != noErr) {
       LOG("AudioObjectRemovePropertyListener/output/kAudioDevicePropertyDataSource rv=%d, device id=%d", rv, stm->output_device.id);
       r = CUBEB_ERROR;
     }
+    stm->output_source_listener.reset();
   }
 
-  if (stm->input_unit) {
-    rv = audiounit_remove_listener(stm, stm->input_device.id, kAudioDevicePropertyDataSource,
-        kAudioDevicePropertyScopeInput, &audiounit_property_listener_callback);
+  if (stm->input_source_listener) {
+    rv = audiounit_remove_listener(stm->input_source_listener.get());
     if (rv != noErr) {
       LOG("AudioObjectRemovePropertyListener/input/kAudioDevicePropertyDataSource rv=%d, device id=%d", rv, stm->input_device.id);
       r = CUBEB_ERROR;
     }
-
-    rv = audiounit_remove_listener(stm, stm->input_device.id, kAudioDevicePropertyDeviceIsAlive,
-                                  kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+    stm->input_source_listener.reset();
+  }
+
+  if (stm->input_alive_listener) {
+    rv = audiounit_remove_listener(stm->input_alive_listener.get());
     if (rv != noErr) {
       LOG("AudioObjectRemovePropertyListener/input/kAudioDevicePropertyDeviceIsAlive rv=%d, device id=%d", rv, stm->input_device.id);
       r = CUBEB_ERROR;
     }
+    stm->input_alive_listener.reset();
   }
+
   return r;
 }
 
 static int
 audiounit_uninstall_system_changed_callback(cubeb_stream * stm)
 {
   OSStatus r;
 
-  if (has_output(stm)) {
-    r = audiounit_remove_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultOutputDevice,
-                                  kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+  if (stm->default_output_listener) {
+    r = audiounit_remove_listener(stm->default_output_listener.get());
     if (r != noErr) {
       return CUBEB_ERROR;
     }
+    stm->default_output_listener.reset();
   }
 
-  if (has_input(stm)) {
-    r = audiounit_remove_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultInputDevice,
-                                  kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
+  if (stm->default_input_listener) {
+    r = audiounit_remove_listener(stm->default_input_listener.get());
     if (r != noErr) {
       return CUBEB_ERROR;
     }
+    stm->default_input_listener.reset();
   }
   return CUBEB_OK;
 }
 
 /* Get the acceptable buffer size (in frames) that this device can work with. */
 static int
 audiounit_get_acceptable_latency_range(AudioValueRange * latency_range)
 {
@@ -1074,30 +1184,29 @@ audiounit_get_acceptable_latency_range(A
 
   return CUBEB_OK;
 }
 #endif /* !TARGET_OS_IPHONE */
 
 static AudioObjectID
 audiounit_get_default_device_id(cubeb_device_type type)
 {
-  AudioObjectPropertyAddress adr = { 0, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
-  AudioDeviceID devid;
-  UInt32 size;
-
+  const AudioObjectPropertyAddress * adr;
   if (type == CUBEB_DEVICE_TYPE_OUTPUT) {
-    adr.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+    adr = &DEFAULT_OUTPUT_DEVICE_PROPERTY_ADDRESS;
   } else if (type == CUBEB_DEVICE_TYPE_INPUT) {
-    adr.mSelector = kAudioHardwarePropertyDefaultInputDevice;
+    adr = &DEFAULT_INPUT_DEVICE_PROPERTY_ADDRESS;
   } else {
     return kAudioObjectUnknown;
   }
 
-  size = sizeof(AudioDeviceID);
-  if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &adr, 0, NULL, &size, &devid) != noErr) {
+  AudioDeviceID devid;
+  UInt32 size = sizeof(AudioDeviceID);
+  if (AudioObjectGetPropertyData(kAudioObjectSystemObject,
+                                 adr, 0, NULL, &size, &devid) != noErr) {
     return kAudioObjectUnknown;
   }
 
   return devid;
 }
 
 int
 audiounit_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
@@ -1200,19 +1309,19 @@ audiounit_get_preferred_sample_rate(cube
   *rate = static_cast<uint32_t>(fsamplerate);
 #endif
   return CUBEB_OK;
 }
 
 static cubeb_channel_layout
 audiounit_convert_channel_layout(AudioChannelLayout * layout)
 {
-  // When having on or two channel, force mono or stereo. Some devices (namely,
-  //  Bose QC35, mark 1 and 2), expose a single channel mapped to the right for
-  //  some reason.
+  // When having one or two channel, force mono or stereo. Some devices (namely,
+  // Bose QC35, mark 1 and 2), expose a single channel mapped to the right for
+  // some reason.
   if (layout->mNumberChannelDescriptions == 1) {
     return CUBEB_LAYOUT_MONO;
   } else if (layout->mNumberChannelDescriptions == 2) {
     return CUBEB_LAYOUT_STEREO;
   }
 
   if (layout->mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions) {
     // kAudioChannelLayoutTag_UseChannelBitmap
@@ -1220,37 +1329,74 @@ audiounit_convert_channel_layout(AudioCh
     // kAudioChannelLayoutTag_Stereo
     // ....
     LOG("Only handle UseChannelDescriptions for now.\n");
     return CUBEB_LAYOUT_UNDEFINED;
   }
 
   cubeb_channel_layout cl = 0;
   for (UInt32 i = 0; i < layout->mNumberChannelDescriptions; ++i) {
-    cl |= channel_label_to_cubeb_channel(
+    cubeb_channel cc = channel_label_to_cubeb_channel(
       layout->mChannelDescriptions[i].mChannelLabel);
+    if (cc == CHANNEL_UNKNOWN) {
+      return CUBEB_LAYOUT_UNDEFINED;
+    }
+    cl |= cc;
   }
 
   return cl;
 }
 
 static cubeb_channel_layout
+audiounit_get_preferred_channel_layout(AudioUnit output_unit)
+{
+  OSStatus rv = noErr;
+  UInt32 size = 0;
+  rv = AudioUnitGetPropertyInfo(output_unit,
+                                kAudioDevicePropertyPreferredChannelLayout,
+                                kAudioUnitScope_Output,
+                                AU_OUT_BUS,
+                                &size,
+                                nullptr);
+  if (rv != noErr) {
+    LOG("AudioUnitGetPropertyInfo/kAudioDevicePropertyPreferredChannelLayout rv=%d", rv);
+    return CUBEB_LAYOUT_UNDEFINED;
+  }
+  assert(size > 0);
+
+  auto layout = make_sized_audio_channel_layout(size);
+  rv = AudioUnitGetProperty(output_unit,
+                            kAudioDevicePropertyPreferredChannelLayout,
+                            kAudioUnitScope_Output,
+                            AU_OUT_BUS,
+                            layout.get(),
+                            &size);
+  if (rv != noErr) {
+    LOG("AudioUnitGetProperty/kAudioDevicePropertyPreferredChannelLayout rv=%d", rv);
+    return CUBEB_LAYOUT_UNDEFINED;
+  }
+
+  return audiounit_convert_channel_layout(layout.get());
+}
+
+static cubeb_channel_layout
 audiounit_get_current_channel_layout(AudioUnit output_unit)
 {
   OSStatus rv = noErr;
   UInt32 size = 0;
   rv = AudioUnitGetPropertyInfo(output_unit,
                                 kAudioUnitProperty_AudioChannelLayout,
                                 kAudioUnitScope_Output,
                                 AU_OUT_BUS,
                                 &size,
                                 nullptr);
   if (rv != noErr) {
     LOG("AudioUnitGetPropertyInfo/kAudioUnitProperty_AudioChannelLayout rv=%d", rv);
-    return CUBEB_LAYOUT_UNDEFINED;
+    // This property isn't known before macOS 10.12, attempt another method.
+    return audiounit_get_preferred_channel_layout(output_unit);
   }
   assert(size > 0);
 
   auto layout = make_sized_audio_channel_layout(size);
   rv = AudioUnitGetProperty(output_unit,
                             kAudioUnitProperty_AudioChannelLayout,
                             kAudioUnitScope_Output,
                             AU_OUT_BUS,
@@ -1261,35 +1407,41 @@ audiounit_get_current_channel_layout(Aud
     return CUBEB_LAYOUT_UNDEFINED;
   }
 
   return audiounit_convert_channel_layout(layout.get());
 }
 
 static int audiounit_create_unit(AudioUnit * unit, device_info * device);
 
-static OSStatus audiounit_remove_device_listener(cubeb * context);
+static OSStatus audiounit_remove_device_listener(cubeb * context, cubeb_device_type devtype);
 
 static void
 audiounit_destroy(cubeb * ctx)
 {
-  // Disabling this assert for bug 1083664 -- we seem to leak a stream
-  // assert(ctx->active_streams == 0);
-  if (ctx->active_streams > 0) {
-    LOG("(%p) API misuse, %d streams active when context destroyed!", ctx, ctx->active_streams.load());
-  }
-
   {
     auto_lock lock(ctx->mutex);
+
+    // Disabling this assert for bug 1083664 -- we seem to leak a stream
+    // assert(ctx->active_streams == 0);
+    if (audiounit_active_streams(ctx) > 0) {
+      LOG("(%p) API misuse, %d streams active when context destroyed!", ctx, audiounit_active_streams(ctx));
+    }
+
     /* Unregister the callback if necessary. */
-    if (ctx->collection_changed_callback) {
-      audiounit_remove_device_listener(ctx);
+    if (ctx->input_collection_changed_callback) {
+      audiounit_remove_device_listener(ctx, CUBEB_DEVICE_TYPE_INPUT);
+    }
+    if (ctx->output_collection_changed_callback) {
+      audiounit_remove_device_listener(ctx, CUBEB_DEVICE_TYPE_OUTPUT);
     }
   }
 
+  dispatch_release(ctx->serial_queue);
+
   delete ctx;
 }
 
 static void audiounit_stream_destroy(cubeb_stream * stm);
 
 static int
 audio_stream_desc_init(AudioStreamBasicDescription * ss,
                        const cubeb_stream_params * stream_params)
@@ -1345,45 +1497,46 @@ audiounit_init_mixer(cubeb_stream * stm)
   assert(stm->mixer);
 }
 
 static int
 audiounit_set_channel_layout(AudioUnit unit,
                              io_side side,
                              cubeb_channel_layout layout)
 {
-  if (side != OUTPUT) {
+  if (side != io_side::OUTPUT) {
     return CUBEB_ERROR;
   }
 
   if (layout == CUBEB_LAYOUT_UNDEFINED) {
     // We leave everything as-is...
     return CUBEB_OK;
   }
 
 
   OSStatus r;
-  int channels = cubeb_channel_layout_nb_channels(layout);
+  uint32_t nb_channels = cubeb_channel_layout_nb_channels(layout);
 
   // We do not use CoreAudio standard layout for lack of documentation on what
   // the actual channel orders are. So we set a custom layout.
-  size_t size = offsetof(AudioChannelLayout, mChannelDescriptions[channels]);
+  size_t size = offsetof(AudioChannelLayout, mChannelDescriptions[nb_channels]);
   auto au_layout = make_sized_audio_channel_layout(size);
   au_layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
-  au_layout->mNumberChannelDescriptions = channels;
+  au_layout->mNumberChannelDescriptions = nb_channels;
+
+  uint32_t channels = 0;
   cubeb_channel_layout channelMap = layout;
-  int i = 0;
-  while (channelMap != 0) {
-    XASSERT(i < channels);
+  for (uint32_t i = 0; channelMap != 0; ++i) {
+    XASSERT(channels < nb_channels);
     uint32_t channel = (channelMap & 1) << i;
     if (channel != 0) {
-      au_layout->mChannelDescriptions[i].mChannelLabel =
+      au_layout->mChannelDescriptions[channels].mChannelLabel =
         cubeb_channel_to_channel_label(static_cast<cubeb_channel>(channel));
-      au_layout->mChannelDescriptions[i].mChannelFlags = kAudioChannelFlags_AllOff;
-      i += 1;
+      au_layout->mChannelDescriptions[channels].mChannelFlags = kAudioChannelFlags_AllOff;
+      channels++;
     }
     channelMap = channelMap >> 1;
   }
 
   r = AudioUnitSetProperty(unit,
                            kAudioUnitProperty_AudioChannelLayout,
                            kAudioUnitScope_Input,
                            AU_OUT_BUS,
@@ -1396,23 +1549,23 @@ audiounit_set_channel_layout(AudioUnit u
 
   return CUBEB_OK;
 }
 
 void
 audiounit_layout_init(cubeb_stream * stm, io_side side)
 {
   // We currently don't support the input layout setting.
-  if (side == INPUT) {
+  if (side == io_side::INPUT) {
     return;
   }
 
   stm->context->layout = audiounit_get_current_channel_layout(stm->output_unit);
 
-  audiounit_set_channel_layout(stm->output_unit, OUTPUT, stm->context->layout);
+  audiounit_set_channel_layout(stm->output_unit, io_side::OUTPUT, stm->context->layout);
 }
 
 static vector<AudioObjectID>
 audiounit_get_sub_devices(AudioDeviceID device_id)
 {
   vector<AudioDeviceID> sub_devices;
   AudioObjectPropertyAddress property_address = { kAudioAggregateDevicePropertyActiveSubDeviceList,
                                                   kAudioObjectPropertyScopeGlobal,
@@ -1453,17 +1606,17 @@ audiounit_create_blank_aggregate_device(
                                                           kAudioObjectPropertyScopeGlobal,
                                                           kAudioObjectPropertyElementMaster };
   UInt32 size = 0;
   OSStatus r = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
                                               &address_plugin_bundle_id,
                                               0, NULL,
                                               &size);
   if (r != noErr) {
-    LOG("AudioHardwareGetPropertyInfo/kAudioHardwarePropertyPlugInForBundleID, rv=%d", r);
+    LOG("AudioObjectGetPropertyDataSize/kAudioHardwarePropertyPlugInForBundleID, rv=%d", r);
     return CUBEB_ERROR;
   }
 
   AudioValueTranslation translation_value;
   CFStringRef in_bundle_ref = CFSTR("com.apple.audio.CoreAudio");
   translation_value.mInputData = &in_bundle_ref;
   translation_value.mInputDataSize = sizeof(in_bundle_ref);
   translation_value.mOutputData = plugin_id;
@@ -1471,17 +1624,17 @@ audiounit_create_blank_aggregate_device(
 
   r = AudioObjectGetPropertyData(kAudioObjectSystemObject,
                                  &address_plugin_bundle_id,
                                  0,
                                  nullptr,
                                  &size,
                                  &translation_value);
   if (r != noErr) {
-    LOG("AudioHardwareGetProperty/kAudioHardwarePropertyPlugInForBundleID, rv=%d", r);
+    LOG("AudioObjectGetPropertyData/kAudioHardwarePropertyPlugInForBundleID, rv=%d", r);
     return CUBEB_ERROR;
   }
 
   AudioObjectPropertyAddress create_aggregate_device_address = { kAudioPlugInCreateAggregateDevice,
                                                                  kAudioObjectPropertyScopeGlobal,
                                                                  kAudioObjectPropertyElementMaster };
   r = AudioObjectGetPropertyDataSize(*plugin_id,
                                      &create_aggregate_device_address,
@@ -1528,21 +1681,24 @@ audiounit_create_blank_aggregate_device(
     LOG("AudioObjectGetPropertyData/kAudioPlugInCreateAggregateDevice, rv=%d", r);
     return CUBEB_ERROR;
   }
   LOG("New aggregate device %u", *aggregate_device_id);
 
   return CUBEB_OK;
 }
 
+// The returned CFStringRef object needs to be released (via CFRelease)
+// if it's not NULL, since the reference count of the returned CFStringRef
+// object is increased.
 static CFStringRef
 get_device_name(AudioDeviceID id)
 {
   UInt32 size = sizeof(CFStringRef);
-  CFStringRef UIname;
+  CFStringRef UIname = nullptr;
   AudioObjectPropertyAddress address_uuid = { kAudioDevicePropertyDeviceUID,
                                               kAudioObjectPropertyScopeGlobal,
                                               kAudioObjectPropertyElementMaster };
   OSStatus err = AudioObjectGetPropertyData(id, &address_uuid, 0, nullptr, &size, &UIname);
   return (err == noErr) ? UIname : NULL;
 }
 
 static int
@@ -1560,24 +1716,26 @@ audiounit_set_aggregate_sub_device_list(
      of the AudioAggregateDevice. */
   for (UInt32 i = 0; i < output_sub_devices.size(); i++) {
     CFStringRef ref = get_device_name(output_sub_devices[i]);
     if (ref == NULL) {
       CFRelease(aggregate_sub_devices_array);
       return CUBEB_ERROR;
     }
     CFArrayAppendValue(aggregate_sub_devices_array, ref);
+    CFRelease(ref);
   }
   for (UInt32 i = 0; i < input_sub_devices.size(); i++) {
     CFStringRef ref = get_device_name(input_sub_devices[i]);
     if (ref == NULL) {
       CFRelease(aggregate_sub_devices_array);
       return CUBEB_ERROR;
     }
     CFArrayAppendValue(aggregate_sub_devices_array, ref);
+    CFRelease(ref);
   }
 
   AudioObjectPropertyAddress aggregate_sub_device_list = { kAudioAggregateDevicePropertyFullSubDeviceList,
                                                            kAudioObjectPropertyScopeGlobal,
                                                            kAudioObjectPropertyElementMaster };
   UInt32 size = sizeof(CFMutableArrayRef);
   OSStatus rv = AudioObjectSetPropertyData(aggregate_device_id,
                                            &aggregate_sub_device_list,
@@ -1592,45 +1750,48 @@ audiounit_set_aggregate_sub_device_list(
   }
 
   return CUBEB_OK;
 }
 
 static int
 audiounit_set_master_aggregate_device(const AudioDeviceID aggregate_device_id)
 {
-  assert(aggregate_device_id);
+  assert(aggregate_device_id != kAudioObjectUnknown);
   AudioObjectPropertyAddress master_aggregate_sub_device =  { kAudioAggregateDevicePropertyMasterSubDevice,
                                                               kAudioObjectPropertyScopeGlobal,
                                                               kAudioObjectPropertyElementMaster };
 
   // Master become the 1st output sub device
   AudioDeviceID output_device_id = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_OUTPUT);
   const vector<AudioDeviceID> output_sub_devices = audiounit_get_sub_devices(output_device_id);
   CFStringRef master_sub_device = get_device_name(output_sub_devices[0]);
 
   UInt32 size = sizeof(CFStringRef);
   OSStatus rv = AudioObjectSetPropertyData(aggregate_device_id,
                                            &master_aggregate_sub_device,
                                            0,
                                            NULL,
                                            size,
                                            &master_sub_device);
+  if (master_sub_device) {
+    CFRelease(master_sub_device);
+  }
   if (rv != noErr) {
     LOG("AudioObjectSetPropertyData/kAudioAggregateDevicePropertyMasterSubDevice, rv=%d", rv);
     return CUBEB_ERROR;
   }
 
   return CUBEB_OK;
 }
 
 static int
 audiounit_activate_clock_drift_compensation(const AudioDeviceID aggregate_device_id)
 {
-  assert(aggregate_device_id);
+  assert(aggregate_device_id != kAudioObjectUnknown);
   AudioObjectPropertyAddress address_owned = { kAudioObjectPropertyOwnedObjects,
                                                kAudioObjectPropertyScopeGlobal,
                                                kAudioObjectPropertyElementMaster };
 
   UInt32 qualifier_data_size = sizeof(AudioObjectID);
   AudioClassID class_id = kAudioSubDeviceClassID;
   void * qualifier_data = &class_id;
   UInt32 size = 0;
@@ -1680,32 +1841,33 @@ audiounit_activate_clock_drift_compensat
   }
   return CUBEB_OK;
 }
 
 static int audiounit_destroy_aggregate_device(AudioObjectID plugin_id, AudioDeviceID * aggregate_device_id);
 static void audiounit_get_available_samplerate(AudioObjectID devid, AudioObjectPropertyScope scope,
                                    uint32_t * min, uint32_t * max, uint32_t * def);
 static int
-audiounit_create_device_from_hwdev(cubeb_device_info * ret, AudioObjectID devid, cubeb_device_type type);
+audiounit_create_device_from_hwdev(cubeb_device_info * dev_info, AudioObjectID devid, cubeb_device_type type);
+static void audiounit_device_destroy(cubeb_device_info * device);
 
 static void
 audiounit_workaround_for_airpod(cubeb_stream * stm)
 {
   cubeb_device_info input_device_info;
   audiounit_create_device_from_hwdev(&input_device_info, stm->input_device.id, CUBEB_DEVICE_TYPE_INPUT);
 
   cubeb_device_info output_device_info;
   audiounit_create_device_from_hwdev(&output_device_info, stm->output_device.id, CUBEB_DEVICE_TYPE_OUTPUT);
 
   std::string input_name_str(input_device_info.friendly_name);
   std::string output_name_str(output_device_info.friendly_name);
 
-  if( input_name_str.find("AirPods") != std::string::npos
-    && output_name_str.find("AirPods") != std::string::npos ) {
+  if(input_name_str.find("AirPods") != std::string::npos &&
+     output_name_str.find("AirPods") != std::string::npos) {
     uint32_t input_min_rate = 0;
     uint32_t input_max_rate = 0;
     uint32_t input_nominal_rate = 0;
     audiounit_get_available_samplerate(stm->input_device.id, kAudioObjectPropertyScopeGlobal,
                                        &input_min_rate, &input_max_rate, &input_nominal_rate);
     LOG("(%p) Input device %u, name: %s, min: %u, max: %u, nominal rate: %u", stm, stm->input_device.id
     , input_device_info.friendly_name, input_min_rate, input_max_rate, input_nominal_rate);
     uint32_t output_min_rate = 0;
@@ -1726,16 +1888,18 @@ audiounit_workaround_for_airpod(cubeb_st
                                              0,
                                              nullptr,
                                              sizeof(Float64),
                                              &rate);
     if (rv != noErr) {
       LOG("Non fatal error, AudioObjectSetPropertyData/kAudioDevicePropertyNominalSampleRate, rv=%d", rv);
     }
   }
+  audiounit_device_destroy(&input_device_info);
+  audiounit_device_destroy(&output_device_info);
 }
 
 /*
  * Aggregate Device is a virtual audio interface which utilizes inputs and outputs
  * of one or more physical audio interfaces. It is possible to use the clock of
  * one of the devices as a master clock for all the combined devices and enable
  * drift compensation for the devices that are not designated clock master.
  *
@@ -1753,17 +1917,16 @@ audiounit_workaround_for_airpod(cubeb_st
  * [2] CoreAudio.framework/Headers/AudioHardware.h
  * */
 static int
 audiounit_create_aggregate_device(cubeb_stream * stm)
 {
   int r = audiounit_create_blank_aggregate_device(&stm->plugin_id, &stm->aggregate_device_id);
   if (r != CUBEB_OK) {
     LOG("(%p) Failed to create blank aggregate device", stm);
-    audiounit_destroy_aggregate_device(stm->plugin_id, &stm->aggregate_device_id);
     return CUBEB_ERROR;
   }
 
   r = audiounit_set_aggregate_sub_device_list(stm->aggregate_device_id, stm->input_device.id, stm->output_device.id);
   if (r != CUBEB_OK) {
     LOG("(%p) Failed to set aggregate sub-device list", stm);
     audiounit_destroy_aggregate_device(stm->plugin_id, &stm->aggregate_device_id);
     return CUBEB_ERROR;
@@ -1815,17 +1978,17 @@ audiounit_destroy_aggregate_device(Audio
                                   &size,
                                   aggregate_device_id);
   if (rv != noErr) {
     LOG("AudioObjectGetPropertyData/kAudioPlugInDestroyAggregateDevice, rv=%d", rv);
     return CUBEB_ERROR;
   }
 
   LOG("Destroyed aggregate device %d", *aggregate_device_id);
-  *aggregate_device_id = 0;
+  *aggregate_device_id = kAudioObjectUnknown;
   return CUBEB_OK;
 }
 
 static int
 audiounit_new_unit_instance(AudioUnit * unit, device_info * device)
 {
   AudioComponentDescription desc;
   AudioComponent comp;
@@ -1834,18 +1997,18 @@ audiounit_new_unit_instance(AudioUnit * 
   desc.componentType = kAudioUnitType_Output;
 #if TARGET_OS_IPHONE
   desc.componentSubType = kAudioUnitSubType_RemoteIO;
 #else
   // Use the DefaultOutputUnit for output when no device is specified
   // so we retain automatic output device switching when the default
   // changes.  Once we have complete support for device notifications
   // and switching, we can use the AUHAL for everything.
-  if ((device->flags & DEV_SYSTEM_DEFAULT)
-      && (device->flags & DEV_OUTPUT)) {
+  if ((device->flags & DEV_SYSTEM_DEFAULT) &&
+      (device->flags & DEV_OUTPUT)) {
     desc.componentSubType = kAudioUnitSubType_DefaultOutput;
   } else {
     desc.componentSubType = kAudioUnitSubType_HALOutput;
   }
 #endif
   desc.componentManufacturer = kAudioUnitManufacturer_Apple;
   desc.componentFlags = 0;
   desc.componentFlagsMask = 0;
@@ -1869,18 +2032,18 @@ enum enable_state {
 };
 
 static int
 audiounit_enable_unit_scope(AudioUnit * unit, io_side side, enable_state state)
 {
   OSStatus rv;
   UInt32 enable = state;
   rv = AudioUnitSetProperty(*unit, kAudioOutputUnitProperty_EnableIO,
-                            (side == INPUT) ? kAudioUnitScope_Input : kAudioUnitScope_Output,
-                            (side == INPUT) ? AU_IN_BUS : AU_OUT_BUS,
+                            (side == io_side::INPUT) ? kAudioUnitScope_Input : kAudioUnitScope_Output,
+                            (side == io_side::INPUT) ? AU_IN_BUS : AU_OUT_BUS,
                             &enable,
                             sizeof(UInt32));
   if (rv != noErr) {
     LOG("AudioUnitSetProperty/kAudioOutputUnitProperty_EnableIO rv=%d", rv);
     return CUBEB_ERROR;
   }
   return CUBEB_OK;
 }
@@ -1895,42 +2058,42 @@ audiounit_create_unit(AudioUnit * unit, 
   int r;
 
   r = audiounit_new_unit_instance(unit, device);
   if (r != CUBEB_OK) {
     return r;
   }
   assert(*unit);
 
-  if ((device->flags & DEV_SYSTEM_DEFAULT)
-      && (device->flags & DEV_OUTPUT)) {
+  if ((device->flags & DEV_SYSTEM_DEFAULT) &&
+      (device->flags & DEV_OUTPUT)) {
     return CUBEB_OK;
   }
 
 
   if (device->flags & DEV_INPUT) {
-    r = audiounit_enable_unit_scope(unit, INPUT, ENABLE);
+    r = audiounit_enable_unit_scope(unit, io_side::INPUT, ENABLE);
     if (r != CUBEB_OK) {
-      LOG("Failed to enable audiounit input scope ");
+      LOG("Failed to enable audiounit input scope");
       return r;
     }
-    r = audiounit_enable_unit_scope(unit, OUTPUT, DISABLE);
+    r = audiounit_enable_unit_scope(unit, io_side::OUTPUT, DISABLE);
     if (r != CUBEB_OK) {
-      LOG("Failed to disable audiounit output scope ");
+      LOG("Failed to disable audiounit output scope");
       return r;
     }
   } else if (device->flags & DEV_OUTPUT) {
-    r = audiounit_enable_unit_scope(unit, OUTPUT, ENABLE);
+    r = audiounit_enable_unit_scope(unit, io_side::OUTPUT, ENABLE);
     if (r != CUBEB_OK) {
-      LOG("Failed to enable audiounit output scope ");
+      LOG("Failed to enable audiounit output scope");
       return r;
     }
-    r = audiounit_enable_unit_scope(unit, INPUT, DISABLE);
+    r = audiounit_enable_unit_scope(unit, io_side::INPUT, DISABLE);
     if (r != CUBEB_OK) {
-      LOG("Failed to disable audiounit input scope ");
+      LOG("Failed to disable audiounit input scope");
       return r;
     }
   } else {
     assert(false);
   }
 
   rv = AudioUnitSetProperty(*unit,
                             kAudioOutputUnitProperty_CurrentDevice,
@@ -1943,33 +2106,33 @@ audiounit_create_unit(AudioUnit * unit, 
   }
 
   return CUBEB_OK;
 }
 
 static int
 audiounit_init_input_linear_buffer(cubeb_stream * stream, uint32_t capacity)
 {
-  uint32_t size = capacity * stream->input_buffer_frames * stream->input_desc.mChannelsPerFrame;
+  uint32_t size = capacity * stream->latency_frames * stream->input_desc.mChannelsPerFrame;
   if (stream->input_desc.mFormatFlags & kAudioFormatFlagIsSignedInteger) {
     stream->input_linear_buffer.reset(new auto_array_wrapper_impl<short>(size));
   } else {
     stream->input_linear_buffer.reset(new auto_array_wrapper_impl<float>(size));
   }
   assert(stream->input_linear_buffer->length() == 0);
 
   return CUBEB_OK;
 }
 
 static uint32_t
 audiounit_clamp_latency(cubeb_stream * stm, uint32_t latency_frames)
 {
   // For the 1st stream set anything within safe min-max
-  assert(stm->context->active_streams > 0);
-  if (stm->context->active_streams == 1) {
+  assert(audiounit_active_streams(stm->context) > 0);
+  if (audiounit_active_streams(stm->context) == 1) {
     return max(min<uint32_t>(latency_frames, SAFE_MAX_LATENCY_FRAMES),
                     SAFE_MIN_LATENCY_FRAMES);
   }
   assert(stm->output_unit);
 
   // If more than one stream operates in parallel
   // allow only lower values of latency
   int r;
@@ -2079,17 +2242,17 @@ buffer_size_changed_callback(void * inCl
 
 static int
 audiounit_set_buffer_size(cubeb_stream * stm, uint32_t new_size_frames, io_side side)
 {
   AudioUnit au = stm->output_unit;
   AudioUnitScope au_scope = kAudioUnitScope_Input;
   AudioUnitElement au_element = AU_OUT_BUS;
 
-  if (side == INPUT) {
+  if (side == io_side::INPUT) {
     au = stm->input_unit;
     au_scope = kAudioUnitScope_Output;
     au_element = AU_IN_BUS;
   }
 
   uint32_t buffer_frames = 0;
   UInt32 size = sizeof(buffer_frames);
   int r = AudioUnitGetProperty(au,
@@ -2200,18 +2363,17 @@ audiounit_configure_input(cubeb_stream *
   /* Set format description according to the input params. */
   r = audio_stream_desc_init(&stm->input_desc, &stm->input_stream_params);
   if (r != CUBEB_OK) {
     LOG("(%p) Setting format description for input failed.", stm);
     return r;
   }
 
   // Use latency to set buffer size
-  stm->input_buffer_frames = stm->latency_frames;
-  r = audiounit_set_buffer_size(stm, stm->input_buffer_frames, INPUT);
+  r = audiounit_set_buffer_size(stm, stm->latency_frames, io_side::INPUT);
   if (r != CUBEB_OK) {
     LOG("(%p) Error in change input buffer size.", stm);
     return CUBEB_ERROR;
   }
 
   AudioStreamBasicDescription src_desc = stm->input_desc;
   /* Input AudioUnit must be configured with device's sample rate.
      we will resample inside input callback. */
@@ -2228,17 +2390,17 @@ audiounit_configure_input(cubeb_stream *
     return CUBEB_ERROR;
   }
 
   /* Frames per buffer in the input callback. */
   r = AudioUnitSetProperty(stm->input_unit,
                            kAudioUnitProperty_MaximumFramesPerSlice,
                            kAudioUnitScope_Global,
                            AU_IN_BUS,
-                           &stm->input_buffer_frames,
+                           &stm->latency_frames,
                            sizeof(UInt32));
   if (r != noErr) {
     LOG("AudioUnitSetProperty/input/kAudioUnitProperty_MaximumFramesPerSlice rv=%d", r);
     return CUBEB_ERROR;
   }
 
   // Input only capacity
   unsigned int array_capacity = 1;
@@ -2259,16 +2421,18 @@ audiounit_configure_input(cubeb_stream *
                            AU_OUT_BUS,
                            &aurcbs_in,
                            sizeof(aurcbs_in));
   if (r != noErr) {
     LOG("AudioUnitSetProperty/input/kAudioOutputUnitProperty_SetInputCallback rv=%d", r);
     return CUBEB_ERROR;
   }
 
+  stm->frames_read = 0;
+
   LOG("(%p) Input audiounit init successfully.", stm);
 
   return CUBEB_OK;
 }
 
 static int
 audiounit_configure_output(cubeb_stream * stm)
 {
@@ -2303,17 +2467,17 @@ audiounit_configure_output(cubeb_stream 
     LOG("AudioUnitGetProperty/output/kAudioUnitProperty_StreamFormat rv=%d", r);
     return CUBEB_ERROR;
   }
   stm->output_hw_rate = output_hw_desc.mSampleRate;
   LOG("(%p) Output device sampling rate: %.2f", stm, output_hw_desc.mSampleRate);
   stm->context->channels = output_hw_desc.mChannelsPerFrame;
 
   // Set the input layout to match the output device layout.
-  audiounit_layout_init(stm, OUTPUT);
+  audiounit_layout_init(stm, io_side::OUTPUT);
   if (stm->context->channels != stm->output_stream_params.channels ||
       stm->context->layout != stm->output_stream_params.layout) {
     LOG("Incompatible channel layouts detected, setting up remixer");
     audiounit_init_mixer(stm);
     // We will be remixing the data before it reaches the output device.
     // We need to adjust the number of channels and other
     // AudioStreamDescription details.
     stm->output_desc.mChannelsPerFrame = stm->context->channels;
@@ -2331,17 +2495,17 @@ audiounit_configure_output(cubeb_stream 
                            AU_OUT_BUS,
                            &stm->output_desc,
                            sizeof(AudioStreamBasicDescription));
   if (r != noErr) {
     LOG("AudioUnitSetProperty/output/kAudioUnitProperty_StreamFormat rv=%d", r);
     return CUBEB_ERROR;
   }
 
-  r = audiounit_set_buffer_size(stm, stm->latency_frames, OUTPUT);
+  r = audiounit_set_buffer_size(stm, stm->latency_frames, io_side::OUTPUT);
   if (r != CUBEB_OK) {
     LOG("(%p) Error in change output buffer size.", stm);
     return CUBEB_ERROR;
   }
 
   /* Frames per buffer in the input callback. */
   r = AudioUnitSetProperty(stm->output_unit,
                            kAudioUnitProperty_MaximumFramesPerSlice,
@@ -2362,16 +2526,18 @@ audiounit_configure_output(cubeb_stream 
                            AU_OUT_BUS,
                            &aurcbs_out,
                            sizeof(aurcbs_out));
   if (r != noErr) {
     LOG("AudioUnitSetProperty/output/kAudioUnitProperty_SetRenderCallback rv=%d", r);
     return CUBEB_ERROR;
   }
 
+  stm->frames_written = 0;
+
   LOG("(%p) Output audiounit init successfully.", stm);
   return CUBEB_OK;
 }
 
 static int
 audiounit_setup_stream(cubeb_stream * stm)
 {
   stm->mutex.assert_current_thread_owns();
@@ -2386,17 +2552,17 @@ audiounit_setup_stream(cubeb_stream * st
 
   device_info in_dev_info = stm->input_device;
   device_info out_dev_info = stm->output_device;
 
   if (has_input(stm) && has_output(stm) &&
       stm->input_device.id != stm->output_device.id) {
     r = audiounit_create_aggregate_device(stm);
     if (r != CUBEB_OK) {
-      stm->aggregate_device_id = 0;
+      stm->aggregate_device_id = kAudioObjectUnknown;
       LOG("(%p) Create aggregate devices failed.", stm);
       // !!!NOTE: It is not necessary to return here. If it does not
       // return it will fallback to the old implementation. The intention
       // is to investigate how often it fails. I plan to remove
       // it after a couple of weeks.
       return r;
     } else {
       in_dev_info.id = out_dev_info.id = stm->aggregate_device_id;
@@ -2417,27 +2583,27 @@ audiounit_setup_stream(cubeb_stream * st
     r = audiounit_create_unit(&stm->output_unit, &out_dev_info);
     if (r != CUBEB_OK) {
       LOG("(%p) AudioUnit creation for output failed.", stm);
       return r;
     }
   }
 
   /* Latency cannot change if another stream is operating in parallel. In this case
-  * latecy is set to the other stream value. */
-  if (stm->context->active_streams > 1) {
+   * latency is set to the other stream value. */
+  if (audiounit_active_streams(stm->context) > 1) {
     LOG("(%p) More than one active stream, use global latency.", stm);
     stm->latency_frames = stm->context->global_latency_frames;
   } else {
     /* Silently clamp the latency down to the platform default, because we
-    * synthetize the clock from the callbacks, and we want the clock to update
-    * often. */
+     * synthetize the clock from the callbacks, and we want the clock to update
+     * often. */
     stm->latency_frames = audiounit_clamp_latency(stm, stm->latency_frames);
-    assert(stm->latency_frames); // Ungly error check
-    audiounit_set_global_latency(stm, stm->latency_frames);
+    assert(stm->latency_frames); // Ugly error check
+    audiounit_set_global_latency(stm->context, stm->latency_frames);
   }
 
   /* Configure I/O stream */
   if (has_input(stm)) {
     r = audiounit_configure_input(stm);
     if (r != CUBEB_OK) {
       LOG("(%p) Configure audiounit input failed.", stm);
       return r;
@@ -2536,16 +2702,24 @@ audiounit_setup_stream(cubeb_stream * st
   }
 
   if (stm->output_unit != NULL) {
     r = AudioUnitInitialize(stm->output_unit);
     if (r != noErr) {
       LOG("AudioUnitInitialize/output rv=%d", r);
       return CUBEB_ERROR;
     }
+
+    stm->current_latency_frames = audiounit_get_device_presentation_latency(stm->output_device.id, kAudioDevicePropertyScopeOutput);
+
+    Float64 unit_s;
+    UInt32 size = sizeof(unit_s);
+    if (AudioUnitGetProperty(stm->output_unit, kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0, &unit_s, &size) == noErr) {
+      stm->current_latency_frames += static_cast<uint32_t>(unit_s * stm->output_desc.mSampleRate);
+    }
   }
 
   if (stm->input_unit && stm->output_unit) {
     // According to the I/O hardware rate it is expected a specific pattern of callbacks
     // for example is input is 44100 and output is 48000 we expected no more than 2
     // out callback in a row.
     stm->expected_output_callbacks_in_a_row = ceilf(stm->output_hw_rate / stm->input_hw_rate);
   }
@@ -2563,66 +2737,68 @@ cubeb_stream::cubeb_stream(cubeb * conte
   : context(context)
   , resampler(nullptr, cubeb_resampler_destroy)
   , mixer(nullptr, cubeb_mixer_destroy)
 {
   PodZero(&input_desc, 1);
   PodZero(&output_desc, 1);
 }
 
+static void audiounit_stream_destroy_internal(cubeb_stream * stm);
+
 static int
 audiounit_stream_init(cubeb * context,
                       cubeb_stream ** stream,
                       char const * /* stream_name */,
                       cubeb_devid input_device,
                       cubeb_stream_params * input_stream_params,
                       cubeb_devid output_device,
                       cubeb_stream_params * output_stream_params,
                       unsigned int latency_frames,
                       cubeb_data_callback data_callback,
                       cubeb_state_callback state_callback,
                       void * user_ptr)
 {
+  assert(context);
+  auto_lock context_lock(context->mutex);
+  audiounit_increment_active_streams(context);
   unique_ptr<cubeb_stream, decltype(&audiounit_stream_destroy)> stm(new cubeb_stream(context),
-                                                                    audiounit_stream_destroy);
-  context->active_streams += 1;
+                                                                    audiounit_stream_destroy_internal);
   int r;
-
-  assert(context);
   *stream = NULL;
   assert(latency_frames > 0);
-  if ((input_device && !input_stream_params) ||
-      (output_device && !output_stream_params)) {
-    return CUBEB_ERROR_INVALID_PARAMETER;
-  }
 
   /* These could be different in the future if we have both
    * full-duplex stream and different devices for input vs output. */
   stm->data_callback = data_callback;
   stm->state_callback = state_callback;
   stm->user_ptr = user_ptr;
   stm->latency_frames = latency_frames;
+
+  if ((input_device && !input_stream_params) ||
+      (output_device && !output_stream_params)) {
+    return CUBEB_ERROR_INVALID_PARAMETER;
+  }
   if (input_stream_params) {
     stm->input_stream_params = *input_stream_params;
-    r = audiounit_set_device_info(stm.get(), reinterpret_cast<uintptr_t>(input_device), INPUT);
+    r = audiounit_set_device_info(stm.get(), reinterpret_cast<uintptr_t>(input_device), io_side::INPUT);
     if (r != CUBEB_OK) {
       LOG("(%p) Fail to set device info for input.", stm.get());
       return r;
     }
   }
   if (output_stream_params) {
     stm->output_stream_params = *output_stream_params;
-    r = audiounit_set_device_info(stm.get(), reinterpret_cast<uintptr_t>(output_device), OUTPUT);
+    r = audiounit_set_device_info(stm.get(), reinterpret_cast<uintptr_t>(output_device), io_side::OUTPUT);
     if (r != CUBEB_OK) {
       LOG("(%p) Fail to set device info for output.", stm.get());
       return r;
     }
   }
 
-  auto_lock context_lock(context->mutex);
   {
     // It's not critical to lock here, because no other thread has been started
     // yet, but it allows to assert that the lock has been taken in
     // `audiounit_setup_stream`.
     auto_lock lock(stm->mutex);
     r = audiounit_setup_stream(stm.get());
   }
 
@@ -2659,77 +2835,95 @@ audiounit_close_stream(cubeb_stream *stm
     AudioUnitUninitialize(stm->output_unit);
     AudioComponentInstanceDispose(stm->output_unit);
     stm->output_unit = nullptr;
   }
 
   stm->resampler.reset();
   stm->mixer.reset();
 
-  if (stm->aggregate_device_id) {
+  if (stm->aggregate_device_id != kAudioObjectUnknown) {
     audiounit_destroy_aggregate_device(stm->plugin_id, &stm->aggregate_device_id);
-    stm->aggregate_device_id = 0;
+    stm->aggregate_device_id = kAudioObjectUnknown;
   }
 }
 
 static void
-audiounit_stream_destroy(cubeb_stream * stm)
+audiounit_stream_destroy_internal(cubeb_stream *stm)
 {
-  stm->shutdown = true;
+  stm->context->mutex.assert_current_thread_owns();
 
   int r = audiounit_uninstall_system_changed_callback(stm);
   if (r != CUBEB_OK) {
     LOG("(%p) Could not uninstall the device changed callback", stm);
   }
-
   r = audiounit_uninstall_device_changed_callback(stm);
   if (r != CUBEB_OK) {
     LOG("(%p) Could not uninstall all device change listeners", stm);
   }
 
-  {
+  auto_lock lock(stm->mutex);
+  audiounit_close_stream(stm);
+  assert(audiounit_active_streams(stm->context) >= 1);
+  audiounit_decrement_active_streams(stm->context);
+}
+
+static void
+audiounit_stream_destroy(cubeb_stream * stm)
+{
+  if (!stm->shutdown.load()){
     auto_lock context_lock(stm->context->mutex);
     audiounit_stream_stop_internal(stm);
+    stm->shutdown = true;
   }
 
+  stm->destroy_pending = true;
   // Execute close in serial queue to avoid collision
   // with reinit when un/plug devices
   dispatch_sync(stm->context->serial_queue, ^() {
-    auto_lock lock(stm->mutex);
-    audiounit_close_stream(stm);
-    assert(stm->context->active_streams >= 1);
-    stm->context->active_streams -= 1;
+    auto_lock context_lock(stm->context->mutex);
+    audiounit_stream_destroy_internal(stm);
   });
 
   LOG("Cubeb stream (%p) destroyed successful.", stm);
   delete stm;
 }
 
-void
+static int
 audiounit_stream_start_internal(cubeb_stream * stm)
 {
   OSStatus r;
   if (stm->input_unit != NULL) {
     r = AudioOutputUnitStart(stm->input_unit);
-    assert(r == 0);
+    if (r != noErr) {
+      LOG("AudioOutputUnitStart (input) rv=%d", r);
+      return CUBEB_ERROR;
+    }
   }
   if (stm->output_unit != NULL) {
     r = AudioOutputUnitStart(stm->output_unit);
-    assert(r == 0);
+    if (r != noErr) {
+      LOG("AudioOutputUnitStart (output) rv=%d", r);
+      return CUBEB_ERROR;
+    }
   }
+  return CUBEB_OK;
 }
 
 static int
 audiounit_stream_start(cubeb_stream * stm)
 {
   auto_lock context_lock(stm->context->mutex);
   stm->shutdown = false;
   stm->draining = false;
 
-  audiounit_stream_start_internal(stm);
+  int r = audiounit_stream_start_internal(stm);
+  if (r != CUBEB_OK) {
+    return r;
+  }
 
   stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STARTED);
 
   LOG("Cubeb stream (%p) started successfully.", stm);
   return CUBEB_OK;
 }
 
 void
@@ -2759,95 +2953,32 @@ audiounit_stream_stop(cubeb_stream * stm
   LOG("Cubeb stream (%p) stopped successfully.", stm);
   return CUBEB_OK;
 }
 
 static int
 audiounit_stream_get_position(cubeb_stream * stm, uint64_t * position)
 {
   assert(stm);
-  *position = stm->frames_played;
+  if (stm->current_latency_frames > stm->frames_played) {
+    *position = 0;
+  } else {
+    *position = stm->frames_played - stm->current_latency_frames;
+  }
   return CUBEB_OK;
 }
 
 int
 audiounit_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
 {
 #if TARGET_OS_IPHONE
   //TODO
   return CUBEB_ERROR_NOT_SUPPORTED;
 #else
-  auto_lock lock(stm->mutex);
-  if (stm->hw_latency_frames == UINT64_MAX) {
-    UInt32 size;
-    uint32_t device_latency_frames, device_safety_offset;
-    double unit_latency_sec;
-    AudioDeviceID output_device_id;
-    OSStatus r;
-    AudioObjectPropertyAddress latency_address = {
-      kAudioDevicePropertyLatency,
-      kAudioDevicePropertyScopeOutput,
-      kAudioObjectPropertyElementMaster
-    };
-    AudioObjectPropertyAddress safety_offset_address = {
-      kAudioDevicePropertySafetyOffset,
-      kAudioDevicePropertyScopeOutput,
-      kAudioObjectPropertyElementMaster
-    };
-
-    output_device_id = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_OUTPUT);
-    if (output_device_id == kAudioObjectUnknown) {
-      return CUBEB_ERROR;
-    }
-
-    size = sizeof(unit_latency_sec);
-    r = AudioUnitGetProperty(stm->output_unit,
-                             kAudioUnitProperty_Latency,
-                             kAudioUnitScope_Global,
-                             0,
-                             &unit_latency_sec,
-                             &size);
-    if (r != noErr) {
-      LOG("AudioUnitGetProperty/kAudioUnitProperty_Latency rv=%d", r);
-      return CUBEB_ERROR;
-    }
-
-    size = sizeof(device_latency_frames);
-    r = AudioObjectGetPropertyData(output_device_id,
-                                   &latency_address,
-                                   0,
-                                   NULL,
-                                   &size,
-                                   &device_latency_frames);
-    if (r != noErr) {
-      LOG("AudioUnitGetPropertyData/latency_frames rv=%d", r);
-      return CUBEB_ERROR;
-    }
-
-    size = sizeof(device_safety_offset);
-    r = AudioObjectGetPropertyData(output_device_id,
-                                   &safety_offset_address,
-                                   0,
-                                   NULL,
-                                   &size,
-                                   &device_safety_offset);
-    if (r != noErr) {
-      LOG("AudioUnitGetPropertyData/safety_offset rv=%d", r);
-      return CUBEB_ERROR;
-    }
-
-    /* This part is fixed and depend on the stream parameter and the hardware. */
-    stm->hw_latency_frames =
-      static_cast<uint32_t>(unit_latency_sec * stm->output_desc.mSampleRate)
-      + device_latency_frames
-      + device_safety_offset;
-  }
-
-  *latency = stm->hw_latency_frames + stm->current_latency_frames;
-
+  *latency = stm->current_latency_frames;
   return CUBEB_OK;
 #endif
 }
 
 static int
 audiounit_stream_get_volume(cubeb_stream * stm, float * volume)
 {
   assert(stm->output_unit);
@@ -2884,106 +3015,104 @@ int audiounit_stream_set_panning(cubeb_s
   if (stm->output_desc.mChannelsPerFrame > 2) {
     return CUBEB_ERROR_INVALID_PARAMETER;
   }
 
   stm->panning.store(panning, memory_order_relaxed);
   return CUBEB_OK;
 }
 
+unique_ptr<char[]> convert_uint32_into_string(UInt32 data)
+{
+  // Simply create an empty string if no data.
+  size_t size = data == 0 ? 0 : 4; // 4 bytes for uint32.
+  auto str = unique_ptr<char[]> { new char[size + 1] }; // + 1 for '\0'.
+  str[size] = '\0';
+  if (size < 4) {
+    return str;
+  }
+
+  // Reverse 0xWXYZ into 0xZYXW.
+  str[0] = (char)(data >> 24);
+  str[1] = (char)(data >> 16);
+  str[2] = (char)(data >> 8);
+  str[3] = (char)(data);
+  return str;
+}
+
+int audiounit_get_default_device_datasource(cubeb_device_type type,
+                                            UInt32 * data)
+{
+  AudioDeviceID id = audiounit_get_default_device_id(type);
+  if (id == kAudioObjectUnknown) {
+    return CUBEB_ERROR;
+  }
+
+  UInt32 size = sizeof(*data);
+  /* This fails with some USB headsets (e.g., Plantronic .Audio 628). */
+  OSStatus r = AudioObjectGetPropertyData(id,
+                                          type == CUBEB_DEVICE_TYPE_INPUT ?
+                                            &INPUT_DATA_SOURCE_PROPERTY_ADDRESS :
+                                            &OUTPUT_DATA_SOURCE_PROPERTY_ADDRESS,
+                                          0, NULL, &size, data);
+  if (r != noErr) {
+    *data = 0;
+  }
+
+  return CUBEB_OK;
+}
+
+int audiounit_get_default_device_name(cubeb_stream * stm,
+                                      cubeb_device * const device,
+                                      cubeb_device_type type)
+{
+  assert(stm);
+  assert(device);
+
+  UInt32 data;
+  int r = audiounit_get_default_device_datasource(type, &data);
+  if (r != CUBEB_OK) {
+    return r;
+  }
+  char ** name = type == CUBEB_DEVICE_TYPE_INPUT ?
+    &device->input_name : &device->output_name;
+  *name = convert_uint32_into_string(data).release();
+  if (!strlen(*name)) { // empty string.
+    LOG("(%p) name of %s device is empty!", stm,
+        type == CUBEB_DEVICE_TYPE_INPUT ? "input" : "output");
+  }
+  return CUBEB_OK;
+}
+
+
 int audiounit_stream_get_current_device(cubeb_stream * stm,
                                         cubeb_device ** const device)
 {
 #if TARGET_OS_IPHONE
   //TODO
   return CUBEB_ERROR_NOT_SUPPORTED;
 #else
-  OSStatus r;
-  UInt32 size;
-  UInt32 data;
-  char strdata[4];
-  AudioDeviceID output_device_id;
-  AudioDeviceID input_device_id;
-
-  AudioObjectPropertyAddress datasource_address = {
-    kAudioDevicePropertyDataSource,
-    kAudioDevicePropertyScopeOutput,
-    kAudioObjectPropertyElementMaster
-  };
-
-  AudioObjectPropertyAddress datasource_address_input = {
-    kAudioDevicePropertyDataSource,
-    kAudioDevicePropertyScopeInput,
-    kAudioObjectPropertyElementMaster
-  };
-
-  *device = NULL;
-
-  output_device_id = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_OUTPUT);
-  if (output_device_id == kAudioObjectUnknown) {
-    return CUBEB_ERROR;
-  }
-
   *device = new cubeb_device;
   if (!*device) {
     return CUBEB_ERROR;
   }
   PodZero(*device, 1);
 
-  size = sizeof(UInt32);
-  /* This fails with some USB headset, so simply return an empty string. */
-  r = AudioObjectGetPropertyData(output_device_id,
-                                 &datasource_address,
-                                 0, NULL, &size, &data);
-  if (r != noErr) {
-    size = 0;
-    data = 0;
-  }
-
-  (*device)->output_name = new char[size + 1];
-  if (!(*device)->output_name) {
-    return CUBEB_ERROR;
+  int r = audiounit_get_default_device_name(stm, *device,
+                                            CUBEB_DEVICE_TYPE_OUTPUT);
+  if (r != CUBEB_OK) {
+    return r;
   }
 
-  // Turn the four chars packed into a uint32 into a string
-  strdata[0] = (char)(data >> 24);
-  strdata[1] = (char)(data >> 16);
-  strdata[2] = (char)(data >> 8);
-  strdata[3] = (char)(data);
-
-  memcpy((*device)->output_name, strdata, size);
-  (*device)->output_name[size] = '\0';
-
-  input_device_id = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT);
-  if (input_device_id == kAudioObjectUnknown) {
-    return CUBEB_ERROR;
+  r = audiounit_get_default_device_name(stm, *device,
+                                        CUBEB_DEVICE_TYPE_INPUT);
+  if (r != CUBEB_OK) {
+    return r;
   }
 
-  size = sizeof(UInt32);
-  r = AudioObjectGetPropertyData(input_device_id, &datasource_address_input, 0, NULL, &size, &data);
-  if (r != noErr) {
-    LOG("(%p) Error when getting device !", stm);
-    size = 0;
-    data = 0;
-  }
-
-  (*device)->input_name = new char[size + 1];
-  if (!(*device)->input_name) {
-    return CUBEB_ERROR;
-  }
-
-  // Turn the four chars packed into a uint32 into a string
-  strdata[0] = (char)(data >> 24);
-  strdata[1] = (char)(data >> 16);
-  strdata[2] = (char)(data >> 8);
-  strdata[3] = (char)(data);
-
-  memcpy((*device)->input_name, strdata, size);
-  (*device)->input_name[size] = '\0';
-
   return CUBEB_OK;
 #endif
 }
 
 int audiounit_stream_device_destroy(cubeb_stream * /* stream */,
                                     cubeb_device * device)
 {
   delete [] device->output_name;
@@ -2993,17 +3122,17 @@ int audiounit_stream_device_destroy(cube
 }
 
 int audiounit_stream_register_device_changed_callback(cubeb_stream * stream,
                                                       cubeb_device_changed_callback device_changed_callback)
 {
   auto_lock dev_cb_lock(stream->device_changed_callback_lock);
   /* Note: second register without unregister first causes 'nope' error.
    * Current implementation requires unregister before register a new cb. */
-  assert(!stream->device_changed_callback);
+  assert(!device_changed_callback || !stream->device_changed_callback);
   stream->device_changed_callback = device_changed_callback;
   return CUBEB_OK;
 }
 
 static char *
 audiounit_strref_to_cstr_utf8(CFStringRef strref)
 {
   CFIndex len, size;
@@ -3084,135 +3213,133 @@ audiounit_get_available_samplerate(Audio
   }
 
 }
 
 static UInt32
 audiounit_get_device_presentation_latency(AudioObjectID devid, AudioObjectPropertyScope scope)
 {
   AudioObjectPropertyAddress adr = { 0, scope, kAudioObjectPropertyElementMaster };
-  UInt32 size, dev, stream = 0, offset;
+  UInt32 size, dev, stream = 0;
   AudioStreamID sid[1];
 
   adr.mSelector = kAudioDevicePropertyLatency;
   size = sizeof(UInt32);
   if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &dev) != noErr) {
     dev = 0;
   }
 
   adr.mSelector = kAudioDevicePropertyStreams;
   size = sizeof(sid);
   if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, sid) == noErr) {
     adr.mSelector = kAudioStreamPropertyLatency;
     size = sizeof(UInt32);
     AudioObjectGetPropertyData(sid[0], &adr, 0, NULL, &size, &stream);
   }
 
-  adr.mSelector = kAudioDevicePropertySafetyOffset;
-  size = sizeof(UInt32);
-  if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &offset) != noErr) {
-    offset = 0;
-  }
-
-  return dev + stream + offset;
+  return dev + stream;
 }
 
 static int
-audiounit_create_device_from_hwdev(cubeb_device_info * ret, AudioObjectID devid, cubeb_device_type type)
+audiounit_create_device_from_hwdev(cubeb_device_info * dev_info, AudioObjectID devid, cubeb_device_type type)
 {
   AudioObjectPropertyAddress adr = { 0, 0, kAudioObjectPropertyElementMaster };
-  UInt32 size, ch, latency;
-  CFStringRef str = NULL;
-  AudioValueRange range;
+  UInt32 size;
 
   if (type == CUBEB_DEVICE_TYPE_OUTPUT) {
     adr.mScope = kAudioDevicePropertyScopeOutput;
   } else if (type == CUBEB_DEVICE_TYPE_INPUT) {
     adr.mScope = kAudioDevicePropertyScopeInput;
   } else {
     return CUBEB_ERROR;
   }
 
-  ch = audiounit_get_channel_count(devid, adr.mScope);
+  UInt32 ch = audiounit_get_channel_count(devid, adr.mScope);
   if (ch == 0) {
     return CUBEB_ERROR;
   }
 
-  PodZero(ret, 1);
-
+  PodZero(dev_info, 1);
+
+  CFStringRef device_id_str = nullptr;
   size = sizeof(CFStringRef);
   adr.mSelector = kAudioDevicePropertyDeviceUID;
-  if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &str) == noErr && str != NULL) {
-    ret->device_id = audiounit_strref_to_cstr_utf8(str);
+  OSStatus ret = AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &device_id_str);
+  if ( ret == noErr && device_id_str != NULL) {
+    dev_info->device_id = audiounit_strref_to_cstr_utf8(device_id_str);
     static_assert(sizeof(cubeb_devid) >= sizeof(decltype(devid)), "cubeb_devid can't represent devid");
-    ret->devid = reinterpret_cast<cubeb_devid>(devid);
-    ret->group_id = ret->device_id;
-    CFRelease(str);
+    dev_info->devid = reinterpret_cast<cubeb_devid>(devid);
+    dev_info->group_id = dev_info->device_id;
+    CFRelease(device_id_str);
+  }
+
+  CFStringRef friendly_name_str = nullptr;
+  UInt32 ds;
+  size = sizeof(UInt32);
+  adr.mSelector = kAudioDevicePropertyDataSource;
+  ret = AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &ds);
+  if (ret == noErr) {
+    AudioValueTranslation trl = { &ds, sizeof(ds), &friendly_name_str, sizeof(CFStringRef) };
+    adr.mSelector = kAudioDevicePropertyDataSourceNameForIDCFString;
+    size = sizeof(AudioValueTranslation);
+    AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &trl);
   }
 
-  size = sizeof(CFStringRef);
-  adr.mSelector = kAudioObjectPropertyName;
-  if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &str) == noErr && str != NULL) {
-    UInt32 ds;
-    size = sizeof(UInt32);
-    adr.mSelector = kAudioDevicePropertyDataSource;
-    if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &ds) == noErr) {
-      CFStringRef dsname;
-      AudioValueTranslation trl = { &ds, sizeof(ds), &dsname, sizeof(dsname) };
-      adr.mSelector = kAudioDevicePropertyDataSourceNameForIDCFString;
-      size = sizeof(AudioValueTranslation);
-      // If there is a datasource for this device, use it instead of the device
-      // name.
-      if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &trl) == noErr) {
-        CFRelease(str);
-        str = dsname;
-      }
-    }
-
-    if (str) {
-      ret->friendly_name = audiounit_strref_to_cstr_utf8(str);
-      CFRelease(str);
-    } else {
-      // Couldn't get a friendly_name, nor a datasource name, return a valid
-      // string of length 0.
-      char * fallback_name = new char[1];
-      fallback_name[0] = '\0';
-      ret->friendly_name = fallback_name;
-    }
+  // If there is no datasource for this device, fall back to the
+  // device name.
+  if (!friendly_name_str) {
+    size = sizeof(CFStringRef);
+    adr.mSelector = kAudioObjectPropertyName;
+    AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &friendly_name_str);
   }
 
+  if (friendly_name_str) {
+    dev_info->friendly_name = audiounit_strref_to_cstr_utf8(friendly_name_str);
+    CFRelease(friendly_name_str);
+  } else {
+    // Couldn't get a datasource name nor a device name, return a
+    // valid string of length 0.
+    char * fallback_name = new char[1];
+    fallback_name[0] = '\0';
+    dev_info->friendly_name = fallback_name;
+  }
+
+  CFStringRef vendor_name_str = nullptr;
   size = sizeof(CFStringRef);
   adr.mSelector = kAudioObjectPropertyManufacturer;
-  if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &str) == noErr && str != NULL) {
-    ret->vendor_name = audiounit_strref_to_cstr_utf8(str);
-    CFRelease(str);
+  ret = AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &vendor_name_str);
+  if (ret == noErr && vendor_name_str != NULL) {
+    dev_info->vendor_name = audiounit_strref_to_cstr_utf8(vendor_name_str);
+    CFRelease(vendor_name_str);
   }
 
-  ret->type = type;
-  ret->state = CUBEB_DEVICE_STATE_ENABLED;
-  ret->preferred = (devid == audiounit_get_default_device_id(type)) ?
+  dev_info->type = type;
+  dev_info->state = CUBEB_DEVICE_STATE_ENABLED;
+  dev_info->preferred = (devid == audiounit_get_default_device_id(type)) ?
     CUBEB_DEVICE_PREF_ALL : CUBEB_DEVICE_PREF_NONE;
 
-  ret->max_channels = ch;
-  ret->format = (cubeb_device_fmt)CUBEB_DEVICE_FMT_ALL; /* CoreAudio supports All! */
+  dev_info->max_channels = ch;
+  dev_info->format = (cubeb_device_fmt)CUBEB_DEVICE_FMT_ALL; /* CoreAudio supports All! */
   /* kAudioFormatFlagsAudioUnitCanonical is deprecated, prefer floating point */
-  ret->default_format = CUBEB_DEVICE_FMT_F32NE;
+  dev_info->default_format = CUBEB_DEVICE_FMT_F32NE;
   audiounit_get_available_samplerate(devid, adr.mScope,
-      &ret->min_rate, &ret->max_rate, &ret->default_rate);
-
-  latency = audiounit_get_device_presentation_latency(devid, adr.mScope);
-
+                                     &dev_info->min_rate, &dev_info->max_rate, &dev_info->default_rate);
+
+  UInt32 latency = audiounit_get_device_presentation_latency(devid, adr.mScope);
+
+  AudioValueRange range;
   adr.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
   size = sizeof(AudioValueRange);
-  if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &range) == noErr) {
-    ret->latency_lo = latency + range.mMinimum;
-    ret->latency_hi = latency + range.mMaximum;
+  ret = AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &range);
+  if (ret == noErr) {
+    dev_info->latency_lo = latency + range.mMinimum;
+    dev_info->latency_hi = latency + range.mMaximum;
   } else {
-    ret->latency_lo = 10 * ret->default_rate / 1000;  /* Default to 10ms */
-    ret->latency_hi = 100 * ret->default_rate / 1000; /* Default to 100ms */
+    dev_info->latency_lo = 10 * dev_info->default_rate / 1000;  /* Default to 10ms */
+    dev_info->latency_hi = 100 * dev_info->default_rate / 1000; /* Default to 100ms */
   }
 
   return CUBEB_OK;
 }
 
 bool
 is_aggregate_device(cubeb_device_info * device_info)
 {
@@ -3272,64 +3399,83 @@ audiounit_enumerate_devices(cubeb * /* c
   } else {
     delete [] devices;
     collection->device = NULL;
   }
 
   return CUBEB_OK;
 }
 
+static void
+audiounit_device_destroy(cubeb_device_info * device)
+{
+  delete [] device->device_id;
+  delete [] device->friendly_name;
+  delete [] device->vendor_name;
+}
+
 static int
 audiounit_device_collection_destroy(cubeb * /* context */,
                                     cubeb_device_collection * collection)
 {
   for (size_t i = 0; i < collection->count; i++) {
-    delete [] collection->device[i].device_id;
-    delete [] collection->device[i].friendly_name;
-    delete [] collection->device[i].vendor_name;
+    audiounit_device_destroy(&collection->device[i]);
   }
   delete [] collection->device;
 
   return CUBEB_OK;
 }
 
 static vector<AudioObjectID>
 audiounit_get_devices_of_type(cubeb_device_type devtype)
 {
-  AudioObjectPropertyAddress adr = { kAudioHardwarePropertyDevices,
-                                     kAudioObjectPropertyScopeGlobal,
-                                     kAudioObjectPropertyElementMaster };
   UInt32 size = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &adr, 0, NULL, &size);
+  OSStatus ret = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
+                                                &DEVICES_PROPERTY_ADDRESS, 0,
+                                                NULL, &size);
+  if (ret != noErr) {
+    return vector<AudioObjectID>();
+  }
+  vector<AudioObjectID> devices(size / sizeof(AudioObjectID));
+  ret = AudioObjectGetPropertyData(kAudioObjectSystemObject,
+                                   &DEVICES_PROPERTY_ADDRESS, 0, NULL, &size,
+                                   devices.data());
   if (ret != noErr) {
     return vector<AudioObjectID>();
   }
-  /* Total number of input and output devices. */
-  uint32_t count = (uint32_t)(size / sizeof(AudioObjectID));
-
-  vector<AudioObjectID> devices(count);
-  ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &adr, 0, NULL, &size, devices.data());
-  if (ret != noErr) {
-    return vector<AudioObjectID>();
+
+  // Remove the aggregate device from the list of devices (if any).
+  for (auto it = devices.begin(); it != devices.end();) {
+    CFStringRef name = get_device_name(*it);
+    if (name && CFStringFind(name, CFSTR("CubebAggregateDevice"), 0).location !=
+        kCFNotFound) {
+      it = devices.erase(it);
+    } else {
+      it++;
+    }
+    if (name) {
+      CFRelease(name);
+    }
   }
+
   /* Expected sorted but did not find anything in the docs. */
   sort(devices.begin(), devices.end(), [](AudioObjectID a, AudioObjectID b) {
       return a < b;
     });
 
   if (devtype == (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) {
     return devices;
   }
 
   AudioObjectPropertyScope scope = (devtype == CUBEB_DEVICE_TYPE_INPUT) ?
                                          kAudioDevicePropertyScopeInput :
                                          kAudioDevicePropertyScopeOutput;
 
   vector<AudioObjectID> devices_in_scope;
-  for (uint32_t i = 0; i < count; ++i) {
+  for (uint32_t i = 0; i < devices.