From 15d3341e34f0146fe677b0da5ed86055f3d65c99 Mon Sep 17 00:00:00 2001 From: suetfei <89482184+suetfei@users.noreply.github.com> Date: Fri, 14 Jul 2023 12:50:20 -0700 Subject: [PATCH] Revert "Fast Pair BLE Device Discovery for Windows in Rust" --- .github/workflows/validate.yaml | 14 +- .gitignore | 6 - fastpair/rust/.gitignore | 2 - fastpair/rust/Cargo.toml | 12 - fastpair/rust/rustfmt.toml | 1 - fastpair/rust/src/bluetooth/common.rs | 42 ---- fastpair/rust/src/bluetooth/mod.rs | 35 --- .../rust/src/bluetooth/unsupported/adapter.rs | 49 ---- .../rust/src/bluetooth/unsupported/device.rs | 31 --- .../rust/src/bluetooth/unsupported/mod.rs | 20 -- .../rust/src/bluetooth/windows_ble/adapter.rs | 222 ------------------ .../rust/src/bluetooth/windows_ble/device.rs | 58 ----- .../rust/src/bluetooth/windows_ble/mod.rs | 20 -- fastpair/rust/src/lib.rs | 16 -- fastpair/rust/src/main.rs | 24 +- fastpair/rust/tests/integration_test.rs | 21 -- 16 files changed, 7 insertions(+), 566 deletions(-) delete mode 100644 fastpair/rust/.gitignore delete mode 100644 fastpair/rust/rustfmt.toml delete mode 100644 fastpair/rust/src/bluetooth/common.rs delete mode 100644 fastpair/rust/src/bluetooth/mod.rs delete mode 100644 fastpair/rust/src/bluetooth/unsupported/adapter.rs delete mode 100644 fastpair/rust/src/bluetooth/unsupported/device.rs delete mode 100644 fastpair/rust/src/bluetooth/unsupported/mod.rs delete mode 100644 fastpair/rust/src/bluetooth/windows_ble/adapter.rs delete mode 100644 fastpair/rust/src/bluetooth/windows_ble/device.rs delete mode 100644 fastpair/rust/src/bluetooth/windows_ble/mod.rs delete mode 100644 fastpair/rust/src/lib.rs delete mode 100644 fastpair/rust/tests/integration_test.rs diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index b29d16f9..2583f175 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -47,16 +47,6 @@ jobs: submodules: recursive - name: Build FPP run: cargo build --manifest-path presence/fpp/fpp/Cargo.toml - - name: Build Fast Pair + - name: Build Fairpair run: cargo build --manifest-path fastpair/rust/Cargo.toml - - build-rust-windows: - name: Build Rust on Windows - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Build Fast Pair - run: cargo build --manifest-path fastpair/rust/Cargo.toml - \ No newline at end of file + diff --git a/.gitignore b/.gitignore index b1c8f94a..39b82caf 100644 --- a/.gitignore +++ b/.gitignore @@ -47,9 +47,3 @@ Carthage/Build .UlyssesRoot .Ulysses-Settings.plist .Ulysses-Group.plist - -# IntelliJ -.idea - -# Rust -Cargo.lock \ No newline at end of file diff --git a/fastpair/rust/.gitignore b/fastpair/rust/.gitignore deleted file mode 100644 index c1bf028b..00000000 --- a/fastpair/rust/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Build files -target diff --git a/fastpair/rust/Cargo.toml b/fastpair/rust/Cargo.toml index 20a09107..be7a0a1c 100644 --- a/fastpair/rust/Cargo.toml +++ b/fastpair/rust/Cargo.toml @@ -20,15 +20,3 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0" -futures = { version = "0.3", features = ["executor"] } -tracing = "0.1.37" -cfg-if = "1.0.0" -async-trait = "0.1" - -[target.'cfg(windows)'.dependencies] -windows = { version = "0.48", features = [ - "Devices_Bluetooth", - "Devices_Bluetooth_Advertisement", - "Foundation", -] } diff --git a/fastpair/rust/rustfmt.toml b/fastpair/rust/rustfmt.toml deleted file mode 100644 index 5c8d9318..00000000 --- a/fastpair/rust/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -max_width = 80 \ No newline at end of file diff --git a/fastpair/rust/src/bluetooth/common.rs b/fastpair/rust/src/bluetooth/common.rs deleted file mode 100644 index 33ba2c4c..00000000 --- a/fastpair/rust/src/bluetooth/common.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use async_trait::async_trait; - -/// Concrete types implementing this trait are Bluetooth Central devices. -/// They provide methods for retrieving nearby connections and device info. -#[async_trait] -pub trait Adapter: Sized { - type Device: Device; - - /// Retrieve the system-default Bluetooth adapter. - async fn default() -> Result; - - /// Begin scanning for nearby devices. - fn start_scan_devices(&mut self) -> Result<(), anyhow::Error>; - - /// Stop scanning for nearby devices. - fn stop_scan_devices(&mut self) -> Result<(), anyhow::Error>; - - /// Poll next discovered device. - async fn next_device(&mut self) -> Result; -} - -/// Concrete types implementing this trait represent Bluetooth Peripheral devices. -/// They provide methods for retrieving device info and running device actions, -/// such as pairing. -pub trait Device { - /// Retrieve the name advertised by this device. - fn name(&self) -> Result; -} diff --git a/fastpair/rust/src/bluetooth/mod.rs b/fastpair/rust/src/bluetooth/mod.rs deleted file mode 100644 index 2faa2576..00000000 --- a/fastpair/rust/src/bluetooth/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Split into separate crate once demo is finished, providing custom error types -// instead of using anyhow. -// b/290070686 - -pub mod common; - -pub use common::{Adapter, Device}; - -cfg_if::cfg_if! { - if #[cfg(windows)] { - mod windows_ble; - use windows_ble::BleAdapter; - } else { - mod unsupported; - use unsupported::BleAdapter; - } -} - -pub async fn default_adapter() -> Result { - BleAdapter::default().await -} diff --git a/fastpair/rust/src/bluetooth/unsupported/adapter.rs b/fastpair/rust/src/bluetooth/unsupported/adapter.rs deleted file mode 100644 index f7395ea5..00000000 --- a/fastpair/rust/src/bluetooth/unsupported/adapter.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use async_trait::async_trait; - -use super::BleDevice; -use crate::bluetooth::common::Adapter; - -/// Concrete type implementing `Adapter`, used for unsupported devices. -/// Every method should panic. -pub struct BleAdapter; - -#[async_trait] -impl Adapter for BleAdapter { - type Device = BleDevice; - - async fn default() -> Result { - panic!("Unsupported target platform."); - } - - fn start_scan_devices(&mut self) -> Result<(), anyhow::Error> { - panic!("Unsupported target platform."); - } - - fn stop_scan_devices(&mut self) -> Result<(), anyhow::Error> { - panic!("Unsupported target platform."); - } - - async fn next_device(&mut self) -> Result { - panic!("Unsupported target platform."); - } -} - -mod tests { - use super::*; - - // TODO b/288592509 unit tests -} diff --git a/fastpair/rust/src/bluetooth/unsupported/device.rs b/fastpair/rust/src/bluetooth/unsupported/device.rs deleted file mode 100644 index 6c8bc520..00000000 --- a/fastpair/rust/src/bluetooth/unsupported/device.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::bluetooth::common::Device; - -/// Concrete type implementing `Device`, used for unsupported devices. -/// Every method should panic. -pub struct BleDevice; - -impl Device for BleDevice { - fn name(&self) -> Result { - panic!("Unsupported target platform.") - } -} - -mod tests { - use super::*; - - // TODO b/288592509 unit tests -} diff --git a/fastpair/rust/src/bluetooth/unsupported/mod.rs b/fastpair/rust/src/bluetooth/unsupported/mod.rs deleted file mode 100644 index a1af0e2d..00000000 --- a/fastpair/rust/src/bluetooth/unsupported/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/// Bluetooth LE module for unsupported devices. Every method panics. -mod adapter; -mod device; - -pub use adapter::*; -pub use device::*; diff --git a/fastpair/rust/src/bluetooth/windows_ble/adapter.rs b/fastpair/rust/src/bluetooth/windows_ble/adapter.rs deleted file mode 100644 index 6d7af121..00000000 --- a/fastpair/rust/src/bluetooth/windows_ble/adapter.rs +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::pin::Pin; -use std::sync::Arc; - -use async_trait::async_trait; -use futures::{stream::Stream, StreamExt}; -use tracing::{error, warn}; -use windows::{ - Devices::Bluetooth::{ - Advertisement::{ - // Struct that receives Bluetooth Low Energy (LE) advertisements. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcher?view=winrt-22621 - BluetoothLEAdvertisementReceivedEventArgs, - - // Enum describing the type of advertisement (connectable, directed, etc). - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothaddresstype?view=winrt-22621 - BluetoothLEAdvertisementType, - - // Provides data for a Received event on a `BluetoothLEAdvertisementWatcher`. - // Instance is created when the Received event occurs in the watcher struct. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementreceivedeventargs?view=winrt-22621 - BluetoothLEAdvertisementWatcher, - - // Provides data for a Stopped event on a `BluetoothLEAdvertisementWatcher`. - // Instance is created when the Stopped event occurs on a watcher struct. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcherstoppedeventargs?view=winrt-22621 - BluetoothLEAdvertisementWatcherStoppedEventArgs, - - // Defines constants that specify a Bluetooth LE scanning mode. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothlescanningmode?view=winrt-22621 - BluetoothLEScanningMode, - }, - // Struct for obtaining global constant information about a computer's - // Bluetooth adapter. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothadapter?view=winrt-22621 - BluetoothAdapter, - }, - // Wraps a closure for handling events associated with a struct - // (e.g. Received and Stopped events in BluetoothLEAdvertisementWatcher). - // https://learn.microsoft.com/en-us/uwp/api/windows.foundation.typedeventhandler-2?view=winrt-22621 - Foundation::TypedEventHandler, -}; - -use super::BleDevice; -use crate::bluetooth::common::Adapter; - -/// Concrete type implementing `Adapter`, used for Windows BLE. -pub struct BleAdapter { - inner: BluetoothAdapter, - // NOTE: Using Boxed dyn here is silly because only one concrete type ever - // used. Change this to `impl Stream` once impl trait return types - // stabilized for existential types. - // b/289224233. - device_stream: Option + Send + Sync>>>, -} - -#[async_trait] -impl Adapter for BleAdapter { - type Device = BleDevice; - - async fn default() -> Result { - let inner = BluetoothAdapter::GetDefaultAsync()?.await?; - - if !inner.IsLowEnergySupported()? { - return Err(anyhow::anyhow!( - "This device's Bluetooth Adapter doesn't support Bluetooth LE Transport type." - )); - } - if !inner.IsCentralRoleSupported()? { - return Err(anyhow::anyhow!( - "This device's Bluetooth Adapter doesn't support Bluetooth LE central role." - )); - } - - Ok(BleAdapter { - inner, - device_stream: None, - }) - } - - fn start_scan_devices(&mut self) -> Result<(), anyhow::Error> { - let watcher = BluetoothLEAdvertisementWatcher::new()?; - match watcher.SetScanningMode(BluetoothLEScanningMode::Active) { - Ok(_) => (), - Err(err) => { - warn!("Failed to turn on active scanning. Error: {}", err) - } - }; - - if self.inner.IsExtendedAdvertisingSupported()? { - watcher.SetAllowExtendedAdvertisements(true)?; - } - - // `futures::channel::mpsc` is like `std::sync::mpsc` but `impl Stream`. - let (sender, receiver) = futures::channel::mpsc::channel(16); - let sender = Arc::new(std::sync::Mutex::new(sender)); - - // `received_handler` closure holds non-owning channel reference, to - // ensure `stopped_handler` can close the channel when - // `received_handler` is done. - let weak_sender = Arc::downgrade(&sender); - let received_handler = TypedEventHandler::new( - // Move `weak_sender` into closure. - move |watcher: &Option, - event_args: &Option< - BluetoothLEAdvertisementReceivedEventArgs, - >| { - if watcher.is_some() { - if let Some(event_args) = event_args { - if let Some(sender) = weak_sender.upgrade() { - match sender - .lock() - .unwrap() - .try_send(event_args.clone()) - { - Ok(_) => (), - Err(err) => { - error!("Error while handling Received event: {:?}", err) - } - } - } - } - } - - Ok(()) - }, - ); - - // `stopped_handler` closure owns channel reference, can close channel. - let mut sender = Some(sender); - let stopped_handler = TypedEventHandler::new( - // Move `sender` into closure. - move |_watcher, - _event_args: &Option< - BluetoothLEAdvertisementWatcherStoppedEventArgs, - >| { - // Drop `sender`, closing the channel. - let _sender = sender.take(); - println!("Watcher stopped receiving BLE advertisements."); - Ok(()) - }, - ); - - watcher.Received(&received_handler)?; - watcher.Stopped(&stopped_handler)?; - watcher.Start()?; - - // `receiver` is a `futures::channel::mpsc::Receiver`, which implements - // `futures::stream::Stream`. This is essentially an async Iterator. - // We apply a FilterMap to map from advertisement packet to a future - // returning `BleDevice` and filter out undesired connections. We need a - // pinned box to satisfy trait bounds for `Stream`. - self.device_stream = - Some(Box::pin(receiver.filter_map(move |event_args| { - // Move `watcher` into `FilterMap` closure. This ensures `watcher` - // is only dropped when the stream is closed. - let _watcher = &watcher; - - // Move `event_args` into async block. - async move { - match event_args.AdvertisementType().ok()? { - BluetoothLEAdvertisementType::NonConnectableUndirected => { - None - } - _ => { - let addr = event_args.BluetoothAddress().ok()?; - let kind = event_args.BluetoothAddressType().ok()?; - - match BleDevice::from_addr(addr, kind).await { - Ok(device) => Some(device), - Err(err) => { - warn!("Error creating device: {:?}", err); - None - } - } - } - } - } - }))); - - Ok(()) - } - - fn stop_scan_devices(&mut self) -> Result<(), anyhow::Error> { - if let Some(_) = &self.device_stream { - self.device_stream.take(); - Ok(()) - } else { - Err(anyhow::anyhow!("Device scanning hasn't started.")) - } - } - - async fn next_device(&mut self) -> Result { - if let Some(stream) = &mut self.device_stream { - stream - .next() - .await - .ok_or(anyhow::anyhow!("Device returned from stream is None.")) - } else { - Err(anyhow::anyhow!("Device scanning hasn't started.")) - } - } -} - -mod tests { - use super::*; - - // TODO b/288592509 unit tests -} diff --git a/fastpair/rust/src/bluetooth/windows_ble/device.rs b/fastpair/rust/src/bluetooth/windows_ble/device.rs deleted file mode 100644 index 08c3d123..00000000 --- a/fastpair/rust/src/bluetooth/windows_ble/device.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use async_trait::async_trait; -use windows::Devices::Bluetooth::{ - // Enum describing the type of address (public, random, unspecified). - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothaddresstype?view=winrt-22621 - BluetoothAddressType, - - // Struct for interacting with and pairing to a discovered BLE device. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothledevice?view=winrt-22621 - BluetoothLEDevice, -}; - -use crate::bluetooth::common::Device; - -/// Concrete type implementing `Device`, used for Windows BLE. -pub struct BleDevice { - inner: BluetoothLEDevice, -} - -impl BleDevice { - /// Create a `BleDevice` instance from the raw bluetooth address information. - pub(super) async fn from_addr( - addr: u64, - kind: BluetoothAddressType, - ) -> Result { - let inner = - BluetoothLEDevice::FromBluetoothAddressWithBluetoothAddressTypeAsync(addr, kind)? - .await?; - - Ok(BleDevice { inner }) - } -} - -#[async_trait] -impl Device for BleDevice { - fn name(&self) -> Result { - Ok(self.inner.Name()?.to_string_lossy()) - } -} - -mod tests { - use super::*; - - // TODO b/288592509 unit tests -} diff --git a/fastpair/rust/src/bluetooth/windows_ble/mod.rs b/fastpair/rust/src/bluetooth/windows_ble/mod.rs deleted file mode 100644 index 7d54d4ef..00000000 --- a/fastpair/rust/src/bluetooth/windows_ble/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/// Bluetooth LE module for Windows devices. -mod adapter; -mod device; - -pub use adapter::*; -pub use device::*; diff --git a/fastpair/rust/src/lib.rs b/fastpair/rust/src/lib.rs deleted file mode 100644 index c9a294f5..00000000 --- a/fastpair/rust/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/// Library file, exports modules for use in integration tests and external crates. -pub mod bluetooth; diff --git a/fastpair/rust/src/main.rs b/fastpair/rust/src/main.rs index 5905e135..548089bc 100644 --- a/fastpair/rust/src/main.rs +++ b/fastpair/rust/src/main.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Google LLC +// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,23 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use futures::executor; +mod message_stream; +mod types; -mod bluetooth; - -use bluetooth::{Adapter, Device}; - -fn main() -> Result<(), anyhow::Error> { - let run = async { - let mut adapter = bluetooth::default_adapter().await?; - adapter.start_scan_devices()?; - - while let Ok(device) = adapter.next_device().await { - println!("found {}", device.name()?) - } - - unreachable!("Done scanning"); - }; - - executor::block_on(run) +fn main() { + println!("Fastpair Rust!"); } diff --git a/fastpair/rust/tests/integration_test.rs b/fastpair/rust/tests/integration_test.rs deleted file mode 100644 index 18021531..00000000 --- a/fastpair/rust/tests/integration_test.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use fastpair::*; - -mod tests { - use super::*; - - // TODO b/288592509 write integration tests -}