From 846cc8cf5c2ce05f996fea4ed8f09ff92bc8cb54 Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Thu, 19 Dec 2024 12:42:11 -0800 Subject: [PATCH] Remove fastpair code PiperOrigin-RevId: 707996548 --- README.md | 4 - fastpair/BUILD | 158 --- fastpair/analytics/BUILD | 46 - fastpair/analytics/analytics_recorder.cc | 129 --- fastpair/analytics/analytics_recorder.h | 66 -- fastpair/analytics/analytics_recorder_test.cc | 119 --- fastpair/common/BUILD | 149 --- fastpair/common/account_key.h | 66 -- fastpair/common/account_key_filter.cc | 125 --- fastpair/common/account_key_filter.h | 49 - fastpair/common/account_key_filter_test.cc | 135 --- fastpair/common/battery_notification.cc | 86 -- fastpair/common/battery_notification.h | 66 -- fastpair/common/battery_notification_test.cc | 152 --- fastpair/common/constant.h | 72 -- fastpair/common/device_metadata.h | 54 - fastpair/common/fast_pair_device.cc | 38 - fastpair/common/fast_pair_device.h | 152 --- fastpair/common/fast_pair_device_test.cc | 111 --- fastpair/common/fast_pair_http_result.cc | 147 --- fastpair/common/fast_pair_http_result.h | 65 -- fastpair/common/fast_pair_prefs.cc | 33 - fastpair/common/fast_pair_prefs.h | 34 - fastpair/common/fast_pair_prefs_test.cc | 49 - fastpair/common/fast_pair_switches.cc | 45 - fastpair/common/fast_pair_switches.h | 37 - fastpair/common/fast_pair_switches_test.cc | 51 - fastpair/common/fast_pair_version.h | 29 - .../common/non_discoverable_advertisement.h | 59 -- fastpair/common/pair_failure.cc | 117 --- fastpair/common/pair_failure.h | 89 -- fastpair/common/pair_failure_test.cc | 71 -- fastpair/common/protocol.cc | 39 - fastpair/common/protocol.h | 36 - fastpair/crypto/BUILD | 134 --- fastpair/crypto/decrypted_passkey.h | 45 - fastpair/crypto/decrypted_passkey_test.cc | 45 - fastpair/crypto/decrypted_response.h | 47 - fastpair/crypto/decrypted_response_test.cc | 42 - fastpair/crypto/fast_pair_decryption.cc | 116 --- fastpair/crypto/fast_pair_decryption.h | 44 - fastpair/crypto/fast_pair_decryption_test.cc | 157 --- fastpair/crypto/fast_pair_encryption.cc | 166 --- fastpair/crypto/fast_pair_encryption.h | 46 - fastpair/crypto/fast_pair_encryption_test.cc | 84 -- fastpair/crypto/fast_pair_key_pair.h | 46 - fastpair/crypto/fast_pair_key_pair_test.cc | 53 - fastpair/crypto/fast_pair_message_type.cc | 45 - fastpair/crypto/fast_pair_message_type.h | 43 - .../crypto/fast_pair_message_type_test.cc | 32 - fastpair/dataparser/BUILD | 93 -- fastpair/dataparser/fast_pair_data_parser.cc | 231 ----- fastpair/dataparser/fast_pair_data_parser.h | 84 -- .../dataparser/fast_pair_data_parser_test.cc | 720 -------------- fastpair/dataparser/fast_pair_decoder.cc | 104 -- fastpair/dataparser/fast_pair_decoder.h | 38 - fastpair/dataparser/fast_pair_decoder_test.cc | 143 --- fastpair/fast_pair_controller.cc | 190 ---- fastpair/fast_pair_controller.h | 201 ---- fastpair/fast_pair_controller_test.cc | 83 -- fastpair/fast_pair_events.h | 43 - fastpair/fast_pair_plugin.h | 58 -- fastpair/fast_pair_seeker.h | 102 -- fastpair/fast_pair_service.cc | 210 ---- fastpair/fast_pair_service.h | 117 --- fastpair/fast_pair_service_test.cc | 185 ---- fastpair/handshake/BUILD | 172 ---- .../handshake/fake_fast_pair_data_encryptor.h | 85 -- .../fake_fast_pair_gatt_service_client.h | 80 -- fastpair/handshake/fast_pair_data_encryptor.h | 63 -- .../fast_pair_data_encryptor_impl.cc | 172 ---- .../handshake/fast_pair_data_encryptor_impl.h | 103 -- .../fast_pair_data_encryptor_impl_test.cc | 323 ------ .../handshake/fast_pair_gatt_service_client.h | 76 -- .../fast_pair_gatt_service_client_impl.cc | 401 -------- .../fast_pair_gatt_service_client_impl.h | 164 --- ...fast_pair_gatt_service_client_impl_test.cc | 416 -------- fastpair/handshake/fast_pair_handshake.h | 83 -- .../handshake/fast_pair_handshake_impl.cc | 138 --- fastpair/handshake/fast_pair_handshake_impl.h | 53 - .../fast_pair_handshake_impl_test.cc | 325 ------ .../handshake/fast_pair_handshake_lookup.cc | 104 -- .../handshake/fast_pair_handshake_lookup.h | 94 -- .../fast_pair_handshake_lookup_test.cc | 150 --- fastpair/internal/BUILD | 69 -- fastpair/internal/fast_pair_seeker_impl.cc | 327 ------ fastpair/internal/fast_pair_seeker_impl.h | 148 --- .../internal/fast_pair_seeker_impl_test.cc | 382 ------- fastpair/internal/impl/windows/BUILD | 38 - fastpair/internal/mediums/BUILD | 151 --- fastpair/internal/mediums/ble.cc | 127 --- fastpair/internal/mediums/ble.h | 78 -- fastpair/internal/mediums/ble_test.cc | 80 -- fastpair/internal/mediums/ble_v2.cc | 60 -- fastpair/internal/mediums/ble_v2.h | 60 -- fastpair/internal/mediums/ble_v2_test.cc | 46 - .../internal/mediums/bluetooth_classic.cc | 115 --- fastpair/internal/mediums/bluetooth_classic.h | 71 -- .../mediums/bluetooth_classic_test.cc | 154 --- fastpair/internal/mediums/bluetooth_radio.cc | 87 -- fastpair/internal/mediums/bluetooth_radio.h | 79 -- .../internal/mediums/bluetooth_radio_test.cc | 48 - fastpair/internal/mediums/mediums.h | 60 -- fastpair/internal/mediums/mediums_test.cc | 33 - .../internal/mediums/robust_gatt_client.cc | 425 -------- .../internal/mediums/robust_gatt_client.h | 272 ----- .../mediums/robust_gatt_client_test.cc | 635 ------------ fastpair/internal/test/BUILD | 56 -- .../test/fast_pair_fake_http_client.h | 167 ---- .../test/fast_pair_fake_http_client_test.cc | 148 --- fastpair/message_stream/BUILD | 161 --- fastpair/message_stream/fake_gatt_callbacks.h | 100 -- .../message_stream/fake_medium_observer.h | 90 -- fastpair/message_stream/fake_provider.cc | 390 -------- fastpair/message_stream/fake_provider.h | 246 ----- fastpair/message_stream/medium.cc | 178 ---- fastpair/message_stream/medium.h | 108 -- fastpair/message_stream/medium_test.cc | 249 ----- fastpair/message_stream/message.h | 103 -- fastpair/message_stream/message_stream.cc | 336 ------- fastpair/message_stream/message_stream.h | 123 --- .../message_stream/message_stream_test.cc | 454 --------- fastpair/mock_fast_pair_seeker.h | 51 - fastpair/pairing/BUILD | 72 -- fastpair/pairing/fastpair/BUILD | 74 -- fastpair/pairing/fastpair/fast_pair_pairer.h | 51 - .../pairing/fastpair/fast_pair_pairer_impl.cc | 400 -------- .../pairing/fastpair/fast_pair_pairer_impl.h | 124 --- .../fastpair/fast_pair_pairer_impl_test.cc | 941 ------------------ fastpair/pairing/pairer_broker.h | 55 - fastpair/pairing/pairer_broker_impl.cc | 338 ------- fastpair/pairing/pairer_broker_impl.h | 104 -- fastpair/pairing/pairer_broker_impl_test.cc | 760 -------------- fastpair/plugins/BUILD | 85 -- fastpair/plugins/fake_fast_pair_plugin.cc | 34 - fastpair/plugins/fake_fast_pair_plugin.h | 61 -- fastpair/plugins/fake_initial_pair_plugin.h | 61 -- .../plugins/fake_initial_pair_plugin_test.cc | 51 - fastpair/plugins/windows_admin_plugin.cc | 130 --- fastpair/plugins/windows_admin_plugin.h | 72 -- fastpair/proto/BUILD | 95 -- fastpair/proto/cache.proto | 93 -- fastpair/proto/data.proto | 277 ------ fastpair/proto/enum.proto | 78 -- fastpair/proto/fast_pair_string.proto | 205 ---- fastpair/proto/fastpair_rpcs.proto | 317 ------ fastpair/proto/proto_builder.cc | 133 --- fastpair/proto/proto_builder.h | 35 - fastpair/proto/proto_builder_test.cc | 82 -- fastpair/proto/proto_to_json.cc | 149 --- fastpair/proto/proto_to_json.h | 62 -- fastpair/repository/BUILD | 172 ---- .../repository/fake_fast_pair_repository.cc | 146 --- .../repository/fake_fast_pair_repository.h | 92 -- .../repository/fast_pair_device_repository.cc | 103 -- .../repository/fast_pair_device_repository.h | 79 -- .../fast_pair_device_repository_test.cc | 144 --- fastpair/repository/fast_pair_repository.cc | 67 -- fastpair/repository/fast_pair_repository.h | 98 -- .../repository/fast_pair_repository_impl.cc | 281 ------ .../repository/fast_pair_repository_impl.h | 71 -- .../fast_pair_repository_impl_test.cc | 548 ---------- .../repository/fast_pair_repository_test.cc | 39 - .../repository/mock_fast_pair_repository.h | 36 - fastpair/retroactive/BUILD | 76 -- fastpair/retroactive/retroactive.cc | 221 ---- fastpair/retroactive/retroactive.h | 76 -- .../retroactive_pairing_detector.h | 41 - .../retroactive_pairing_detector_impl.cc | 122 --- .../retroactive_pairing_detector_impl.h | 64 -- fastpair/retroactive/retroactive_test.cc | 163 --- fastpair/rust/.gitignore | 2 - fastpair/rust/bluetooth/Cargo.toml | 40 - .../rust/bluetooth/examples/fastpair_ui.rs | 118 --- fastpair/rust/bluetooth/rustfmt.toml | 1 - fastpair/rust/bluetooth/src/api/adapter.rs | 37 - fastpair/rust/bluetooth/src/api/device.rs | 56 -- fastpair/rust/bluetooth/src/api/mod.rs | 19 - fastpair/rust/bluetooth/src/common/address.rs | 179 ---- .../bluetooth/src/common/advertisement.rs | 172 ---- fastpair/rust/bluetooth/src/common/error.rs | 60 -- fastpair/rust/bluetooth/src/common/mod.rs | 22 - fastpair/rust/bluetooth/src/lib.rs | 53 - fastpair/rust/bluetooth/src/message_stream.rs | 54 - fastpair/rust/bluetooth/src/types.rs | 15 - fastpair/rust/bluetooth/src/types/packets.rs | 89 -- .../rust/bluetooth/src/unsupported/adapter.rs | 50 - .../rust/bluetooth/src/unsupported/device.rs | 68 -- .../rust/bluetooth/src/unsupported/mod.rs | 20 - .../rust/bluetooth/src/windows/adapter.rs | 223 ----- .../rust/bluetooth/src/windows/address.rs | 52 - .../bluetooth/src/windows/advertisement.rs | 115 --- fastpair/rust/bluetooth/src/windows/device.rs | 161 --- fastpair/rust/bluetooth/src/windows/error.rs | 57 -- fastpair/rust/bluetooth/src/windows/mod.rs | 25 - fastpair/rust/demo/.gitignore | 44 - fastpair/rust/demo/.metadata | 45 - fastpair/rust/demo/README.md | 16 - fastpair/rust/demo/analysis_options.yaml | 43 - fastpair/rust/demo/bindgen.script | 4 - .../rust/demo/lib/bridge_definitions.dart | 42 - fastpair/rust/demo/lib/bridge_generated.dart | 305 ------ fastpair/rust/demo/lib/main.dart | 130 --- fastpair/rust/demo/lib/rust.dart | 32 - fastpair/rust/demo/local/525296.json | 40 - fastpair/rust/demo/local/706908.json | 40 - fastpair/rust/demo/pubspec.lock | 652 ------------ fastpair/rust/demo/pubspec.yaml | 110 -- fastpair/rust/demo/rust/Cargo.toml | 19 - fastpair/rust/demo/rust/src/advertisement.rs | 230 ----- fastpair/rust/demo/rust/src/api.rs | 249 ----- .../rust/demo/rust/src/bridge_generated.io.rs | 65 -- .../rust/demo/rust/src/bridge_generated.rs | 119 --- fastpair/rust/demo/rust/src/decoder.rs | 90 -- fastpair/rust/demo/rust/src/error.rs | 43 - fastpair/rust/demo/rust/src/fetcher/common.rs | 63 -- fastpair/rust/demo/rust/src/fetcher/fs.rs | 49 - fastpair/rust/demo/rust/src/fetcher/mock.rs | 38 - fastpair/rust/demo/rust/src/fetcher/mod.rs | 22 - fastpair/rust/demo/rust/src/lib.rs | 20 - fastpair/rust/demo/windows/.gitignore | 17 - fastpair/rust/demo/windows/CMakeLists.txt | 117 --- .../rust/demo/windows/flutter/CMakeLists.txt | 118 --- .../flutter/generated_plugin_registrant.cc | 25 - .../flutter/generated_plugin_registrant.h | 29 - .../windows/flutter/generated_plugins.cmake | 23 - .../rust/demo/windows/runner/CMakeLists.txt | 54 - fastpair/rust/demo/windows/runner/Runner.rc | 121 --- .../demo/windows/runner/flutter_window.cpp | 80 -- .../rust/demo/windows/runner/flutter_window.h | 47 - fastpair/rust/demo/windows/runner/main.cpp | 57 -- fastpair/rust/demo/windows/runner/resource.h | 33 - .../windows/runner/resources/app_icon.ico | Bin 33772 -> 0 bytes .../demo/windows/runner/runner.exe.manifest | 20 - fastpair/rust/demo/windows/runner/utils.cpp | 79 -- fastpair/rust/demo/windows/runner/utils.h | 33 - .../rust/demo/windows/runner/win32_window.cpp | 303 ------ .../rust/demo/windows/runner/win32_window.h | 116 --- fastpair/rust/demo/windows/rust.cmake | 35 - fastpair/scanning/BUILD | 81 -- fastpair/scanning/fastpair/BUILD | 132 --- .../fastpair/fake_fast_pair_scanner.cc | 37 - .../fastpair/fake_fast_pair_scanner.h | 48 - .../fast_pair_discoverable_scanner.cc | 235 ----- .../fastpair/fast_pair_discoverable_scanner.h | 101 -- .../fast_pair_discoverable_scanner_test.cc | 316 ------ .../fast_pair_non_discoverable_scanner.cc | 201 ---- .../fast_pair_non_discoverable_scanner.h | 108 -- ...fast_pair_non_discoverable_scanner_test.cc | 298 ------ .../scanning/fastpair/fast_pair_scanner.h | 56 -- .../fastpair/fast_pair_scanner_impl.cc | 172 ---- .../fastpair/fast_pair_scanner_impl.h | 76 -- .../fastpair/fast_pair_scanner_impl_test.cc | 128 --- fastpair/scanning/mock_scanner_broker.h | 57 -- fastpair/scanning/scanner_broker.h | 58 -- fastpair/scanning/scanner_broker_impl.cc | 110 -- fastpair/scanning/scanner_broker_impl.h | 63 -- fastpair/scanning/scanner_broker_impl_test.cc | 211 ---- fastpair/server_access/BUILD | 113 --- .../server_access/fake_fast_pair_client.h | 123 --- fastpair/server_access/fast_pair_client.h | 51 - .../server_access/fast_pair_client_impl.cc | 347 ------- .../server_access/fast_pair_client_impl.h | 87 -- .../fast_pair_client_impl_test.cc | 677 ------------- .../server_access/fast_pair_http_notifier.cc | 98 -- .../server_access/fast_pair_http_notifier.h | 87 -- .../fast_pair_http_notifier_test.cc | 209 ---- fastpair/testing/BUILD | 31 - .../testing/fast_pair_service_data_creator.cc | 102 -- .../testing/fast_pair_service_data_creator.h | 73 -- fastpair/ui/BUILD | 126 --- fastpair/ui/actions.h | 35 - ...st_pair_notification_controller_observer.h | 78 -- .../ui/fast_pair/fake_fast_pair_presenter.h | 77 -- .../fast_pair_notification_controller.cc | 72 -- .../fast_pair_notification_controller.h | 74 -- .../fast_pair_notification_controller_test.cc | 84 -- fastpair/ui/fast_pair/fast_pair_presenter.h | 42 - .../ui/fast_pair/fast_pair_presenter_impl.cc | 60 -- .../ui/fast_pair/fast_pair_presenter_impl.h | 59 -- .../fast_pair_presenter_impl_test.cc | 113 --- .../mock_fast_pair_notification_controller.h | 45 - fastpair/ui/mock_ui_broker.h | 56 -- fastpair/ui/ui_broker.h | 56 -- fastpair/ui/ui_broker_impl.cc | 87 -- fastpair/ui/ui_broker_impl.h | 55 - fastpair/ui/ui_broker_impl_test.cc | 80 -- internal/analytics/BUILD | 2 +- internal/base/BUILD | 4 +- internal/network/BUILD | 6 +- internal/platform/BUILD | 8 +- internal/platform/flags/BUILD | 2 +- internal/platform/implementation/BUILD | 6 +- internal/platform/implementation/g3/BUILD | 2 +- .../platform/implementation/windows/BUILD | 2 +- .../implementation/windows/generated/BUILD | 2 +- 296 files changed, 17 insertions(+), 34717 deletions(-) delete mode 100644 fastpair/BUILD delete mode 100644 fastpair/analytics/BUILD delete mode 100644 fastpair/analytics/analytics_recorder.cc delete mode 100644 fastpair/analytics/analytics_recorder.h delete mode 100644 fastpair/analytics/analytics_recorder_test.cc delete mode 100644 fastpair/common/BUILD delete mode 100644 fastpair/common/account_key.h delete mode 100644 fastpair/common/account_key_filter.cc delete mode 100644 fastpair/common/account_key_filter.h delete mode 100644 fastpair/common/account_key_filter_test.cc delete mode 100644 fastpair/common/battery_notification.cc delete mode 100644 fastpair/common/battery_notification.h delete mode 100644 fastpair/common/battery_notification_test.cc delete mode 100644 fastpair/common/constant.h delete mode 100644 fastpair/common/device_metadata.h delete mode 100644 fastpair/common/fast_pair_device.cc delete mode 100644 fastpair/common/fast_pair_device.h delete mode 100644 fastpair/common/fast_pair_device_test.cc delete mode 100644 fastpair/common/fast_pair_http_result.cc delete mode 100644 fastpair/common/fast_pair_http_result.h delete mode 100644 fastpair/common/fast_pair_prefs.cc delete mode 100644 fastpair/common/fast_pair_prefs.h delete mode 100644 fastpair/common/fast_pair_prefs_test.cc delete mode 100644 fastpair/common/fast_pair_switches.cc delete mode 100644 fastpair/common/fast_pair_switches.h delete mode 100644 fastpair/common/fast_pair_switches_test.cc delete mode 100644 fastpair/common/fast_pair_version.h delete mode 100644 fastpair/common/non_discoverable_advertisement.h delete mode 100644 fastpair/common/pair_failure.cc delete mode 100644 fastpair/common/pair_failure.h delete mode 100644 fastpair/common/pair_failure_test.cc delete mode 100644 fastpair/common/protocol.cc delete mode 100644 fastpair/common/protocol.h delete mode 100644 fastpair/crypto/BUILD delete mode 100644 fastpair/crypto/decrypted_passkey.h delete mode 100644 fastpair/crypto/decrypted_passkey_test.cc delete mode 100644 fastpair/crypto/decrypted_response.h delete mode 100644 fastpair/crypto/decrypted_response_test.cc delete mode 100644 fastpair/crypto/fast_pair_decryption.cc delete mode 100644 fastpair/crypto/fast_pair_decryption.h delete mode 100644 fastpair/crypto/fast_pair_decryption_test.cc delete mode 100644 fastpair/crypto/fast_pair_encryption.cc delete mode 100644 fastpair/crypto/fast_pair_encryption.h delete mode 100644 fastpair/crypto/fast_pair_encryption_test.cc delete mode 100644 fastpair/crypto/fast_pair_key_pair.h delete mode 100644 fastpair/crypto/fast_pair_key_pair_test.cc delete mode 100644 fastpair/crypto/fast_pair_message_type.cc delete mode 100644 fastpair/crypto/fast_pair_message_type.h delete mode 100644 fastpair/crypto/fast_pair_message_type_test.cc delete mode 100644 fastpair/dataparser/BUILD delete mode 100644 fastpair/dataparser/fast_pair_data_parser.cc delete mode 100644 fastpair/dataparser/fast_pair_data_parser.h delete mode 100644 fastpair/dataparser/fast_pair_data_parser_test.cc delete mode 100644 fastpair/dataparser/fast_pair_decoder.cc delete mode 100644 fastpair/dataparser/fast_pair_decoder.h delete mode 100644 fastpair/dataparser/fast_pair_decoder_test.cc delete mode 100644 fastpair/fast_pair_controller.cc delete mode 100644 fastpair/fast_pair_controller.h delete mode 100644 fastpair/fast_pair_controller_test.cc delete mode 100644 fastpair/fast_pair_events.h delete mode 100644 fastpair/fast_pair_plugin.h delete mode 100644 fastpair/fast_pair_seeker.h delete mode 100644 fastpair/fast_pair_service.cc delete mode 100644 fastpair/fast_pair_service.h delete mode 100644 fastpair/fast_pair_service_test.cc delete mode 100644 fastpair/handshake/BUILD delete mode 100644 fastpair/handshake/fake_fast_pair_data_encryptor.h delete mode 100644 fastpair/handshake/fake_fast_pair_gatt_service_client.h delete mode 100644 fastpair/handshake/fast_pair_data_encryptor.h delete mode 100644 fastpair/handshake/fast_pair_data_encryptor_impl.cc delete mode 100644 fastpair/handshake/fast_pair_data_encryptor_impl.h delete mode 100644 fastpair/handshake/fast_pair_data_encryptor_impl_test.cc delete mode 100644 fastpair/handshake/fast_pair_gatt_service_client.h delete mode 100644 fastpair/handshake/fast_pair_gatt_service_client_impl.cc delete mode 100644 fastpair/handshake/fast_pair_gatt_service_client_impl.h delete mode 100644 fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc delete mode 100644 fastpair/handshake/fast_pair_handshake.h delete mode 100644 fastpair/handshake/fast_pair_handshake_impl.cc delete mode 100644 fastpair/handshake/fast_pair_handshake_impl.h delete mode 100644 fastpair/handshake/fast_pair_handshake_impl_test.cc delete mode 100644 fastpair/handshake/fast_pair_handshake_lookup.cc delete mode 100644 fastpair/handshake/fast_pair_handshake_lookup.h delete mode 100644 fastpair/handshake/fast_pair_handshake_lookup_test.cc delete mode 100644 fastpair/internal/BUILD delete mode 100644 fastpair/internal/fast_pair_seeker_impl.cc delete mode 100644 fastpair/internal/fast_pair_seeker_impl.h delete mode 100644 fastpair/internal/fast_pair_seeker_impl_test.cc delete mode 100644 fastpair/internal/impl/windows/BUILD delete mode 100644 fastpair/internal/mediums/BUILD delete mode 100644 fastpair/internal/mediums/ble.cc delete mode 100644 fastpair/internal/mediums/ble.h delete mode 100644 fastpair/internal/mediums/ble_test.cc delete mode 100644 fastpair/internal/mediums/ble_v2.cc delete mode 100644 fastpair/internal/mediums/ble_v2.h delete mode 100644 fastpair/internal/mediums/ble_v2_test.cc delete mode 100644 fastpair/internal/mediums/bluetooth_classic.cc delete mode 100644 fastpair/internal/mediums/bluetooth_classic.h delete mode 100644 fastpair/internal/mediums/bluetooth_classic_test.cc delete mode 100644 fastpair/internal/mediums/bluetooth_radio.cc delete mode 100644 fastpair/internal/mediums/bluetooth_radio.h delete mode 100644 fastpair/internal/mediums/bluetooth_radio_test.cc delete mode 100644 fastpair/internal/mediums/mediums.h delete mode 100644 fastpair/internal/mediums/mediums_test.cc delete mode 100644 fastpair/internal/mediums/robust_gatt_client.cc delete mode 100644 fastpair/internal/mediums/robust_gatt_client.h delete mode 100644 fastpair/internal/mediums/robust_gatt_client_test.cc delete mode 100644 fastpair/internal/test/BUILD delete mode 100644 fastpair/internal/test/fast_pair_fake_http_client.h delete mode 100644 fastpair/internal/test/fast_pair_fake_http_client_test.cc delete mode 100644 fastpair/message_stream/BUILD delete mode 100644 fastpair/message_stream/fake_gatt_callbacks.h delete mode 100644 fastpair/message_stream/fake_medium_observer.h delete mode 100644 fastpair/message_stream/fake_provider.cc delete mode 100644 fastpair/message_stream/fake_provider.h delete mode 100644 fastpair/message_stream/medium.cc delete mode 100644 fastpair/message_stream/medium.h delete mode 100644 fastpair/message_stream/medium_test.cc delete mode 100644 fastpair/message_stream/message.h delete mode 100644 fastpair/message_stream/message_stream.cc delete mode 100644 fastpair/message_stream/message_stream.h delete mode 100644 fastpair/message_stream/message_stream_test.cc delete mode 100644 fastpair/mock_fast_pair_seeker.h delete mode 100644 fastpair/pairing/BUILD delete mode 100644 fastpair/pairing/fastpair/BUILD delete mode 100644 fastpair/pairing/fastpair/fast_pair_pairer.h delete mode 100644 fastpair/pairing/fastpair/fast_pair_pairer_impl.cc delete mode 100644 fastpair/pairing/fastpair/fast_pair_pairer_impl.h delete mode 100644 fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc delete mode 100644 fastpair/pairing/pairer_broker.h delete mode 100644 fastpair/pairing/pairer_broker_impl.cc delete mode 100644 fastpair/pairing/pairer_broker_impl.h delete mode 100644 fastpair/pairing/pairer_broker_impl_test.cc delete mode 100644 fastpair/plugins/BUILD delete mode 100644 fastpair/plugins/fake_fast_pair_plugin.cc delete mode 100644 fastpair/plugins/fake_fast_pair_plugin.h delete mode 100644 fastpair/plugins/fake_initial_pair_plugin.h delete mode 100644 fastpair/plugins/fake_initial_pair_plugin_test.cc delete mode 100644 fastpair/plugins/windows_admin_plugin.cc delete mode 100644 fastpair/plugins/windows_admin_plugin.h delete mode 100644 fastpair/proto/BUILD delete mode 100644 fastpair/proto/cache.proto delete mode 100644 fastpair/proto/data.proto delete mode 100644 fastpair/proto/enum.proto delete mode 100644 fastpair/proto/fast_pair_string.proto delete mode 100644 fastpair/proto/fastpair_rpcs.proto delete mode 100644 fastpair/proto/proto_builder.cc delete mode 100644 fastpair/proto/proto_builder.h delete mode 100644 fastpair/proto/proto_builder_test.cc delete mode 100644 fastpair/proto/proto_to_json.cc delete mode 100644 fastpair/proto/proto_to_json.h delete mode 100644 fastpair/repository/BUILD delete mode 100644 fastpair/repository/fake_fast_pair_repository.cc delete mode 100644 fastpair/repository/fake_fast_pair_repository.h delete mode 100644 fastpair/repository/fast_pair_device_repository.cc delete mode 100644 fastpair/repository/fast_pair_device_repository.h delete mode 100644 fastpair/repository/fast_pair_device_repository_test.cc delete mode 100644 fastpair/repository/fast_pair_repository.cc delete mode 100644 fastpair/repository/fast_pair_repository.h delete mode 100644 fastpair/repository/fast_pair_repository_impl.cc delete mode 100644 fastpair/repository/fast_pair_repository_impl.h delete mode 100644 fastpair/repository/fast_pair_repository_impl_test.cc delete mode 100644 fastpair/repository/fast_pair_repository_test.cc delete mode 100644 fastpair/repository/mock_fast_pair_repository.h delete mode 100644 fastpair/retroactive/BUILD delete mode 100644 fastpair/retroactive/retroactive.cc delete mode 100644 fastpair/retroactive/retroactive.h delete mode 100644 fastpair/retroactive/retroactive_pairing_detector.h delete mode 100644 fastpair/retroactive/retroactive_pairing_detector_impl.cc delete mode 100644 fastpair/retroactive/retroactive_pairing_detector_impl.h delete mode 100644 fastpair/retroactive/retroactive_test.cc delete mode 100644 fastpair/rust/.gitignore delete mode 100644 fastpair/rust/bluetooth/Cargo.toml delete mode 100644 fastpair/rust/bluetooth/examples/fastpair_ui.rs delete mode 100644 fastpair/rust/bluetooth/rustfmt.toml delete mode 100644 fastpair/rust/bluetooth/src/api/adapter.rs delete mode 100644 fastpair/rust/bluetooth/src/api/device.rs delete mode 100644 fastpair/rust/bluetooth/src/api/mod.rs delete mode 100644 fastpair/rust/bluetooth/src/common/address.rs delete mode 100644 fastpair/rust/bluetooth/src/common/advertisement.rs delete mode 100644 fastpair/rust/bluetooth/src/common/error.rs delete mode 100644 fastpair/rust/bluetooth/src/common/mod.rs delete mode 100644 fastpair/rust/bluetooth/src/lib.rs delete mode 100644 fastpair/rust/bluetooth/src/message_stream.rs delete mode 100644 fastpair/rust/bluetooth/src/types.rs delete mode 100644 fastpair/rust/bluetooth/src/types/packets.rs delete mode 100644 fastpair/rust/bluetooth/src/unsupported/adapter.rs delete mode 100644 fastpair/rust/bluetooth/src/unsupported/device.rs delete mode 100644 fastpair/rust/bluetooth/src/unsupported/mod.rs delete mode 100644 fastpair/rust/bluetooth/src/windows/adapter.rs delete mode 100644 fastpair/rust/bluetooth/src/windows/address.rs delete mode 100644 fastpair/rust/bluetooth/src/windows/advertisement.rs delete mode 100644 fastpair/rust/bluetooth/src/windows/device.rs delete mode 100644 fastpair/rust/bluetooth/src/windows/error.rs delete mode 100644 fastpair/rust/bluetooth/src/windows/mod.rs delete mode 100644 fastpair/rust/demo/.gitignore delete mode 100644 fastpair/rust/demo/.metadata delete mode 100644 fastpair/rust/demo/README.md delete mode 100644 fastpair/rust/demo/analysis_options.yaml delete mode 100644 fastpair/rust/demo/bindgen.script delete mode 100644 fastpair/rust/demo/lib/bridge_definitions.dart delete mode 100644 fastpair/rust/demo/lib/bridge_generated.dart delete mode 100644 fastpair/rust/demo/lib/main.dart delete mode 100644 fastpair/rust/demo/lib/rust.dart delete mode 100644 fastpair/rust/demo/local/525296.json delete mode 100644 fastpair/rust/demo/local/706908.json delete mode 100644 fastpair/rust/demo/pubspec.lock delete mode 100644 fastpair/rust/demo/pubspec.yaml delete mode 100644 fastpair/rust/demo/rust/Cargo.toml delete mode 100644 fastpair/rust/demo/rust/src/advertisement.rs delete mode 100644 fastpair/rust/demo/rust/src/api.rs delete mode 100644 fastpair/rust/demo/rust/src/bridge_generated.io.rs delete mode 100644 fastpair/rust/demo/rust/src/bridge_generated.rs delete mode 100644 fastpair/rust/demo/rust/src/decoder.rs delete mode 100644 fastpair/rust/demo/rust/src/error.rs delete mode 100644 fastpair/rust/demo/rust/src/fetcher/common.rs delete mode 100644 fastpair/rust/demo/rust/src/fetcher/fs.rs delete mode 100644 fastpair/rust/demo/rust/src/fetcher/mock.rs delete mode 100644 fastpair/rust/demo/rust/src/fetcher/mod.rs delete mode 100644 fastpair/rust/demo/rust/src/lib.rs delete mode 100644 fastpair/rust/demo/windows/.gitignore delete mode 100644 fastpair/rust/demo/windows/CMakeLists.txt delete mode 100644 fastpair/rust/demo/windows/flutter/CMakeLists.txt delete mode 100644 fastpair/rust/demo/windows/flutter/generated_plugin_registrant.cc delete mode 100644 fastpair/rust/demo/windows/flutter/generated_plugin_registrant.h delete mode 100644 fastpair/rust/demo/windows/flutter/generated_plugins.cmake delete mode 100644 fastpair/rust/demo/windows/runner/CMakeLists.txt delete mode 100644 fastpair/rust/demo/windows/runner/Runner.rc delete mode 100644 fastpair/rust/demo/windows/runner/flutter_window.cpp delete mode 100644 fastpair/rust/demo/windows/runner/flutter_window.h delete mode 100644 fastpair/rust/demo/windows/runner/main.cpp delete mode 100644 fastpair/rust/demo/windows/runner/resource.h delete mode 100644 fastpair/rust/demo/windows/runner/resources/app_icon.ico delete mode 100644 fastpair/rust/demo/windows/runner/runner.exe.manifest delete mode 100644 fastpair/rust/demo/windows/runner/utils.cpp delete mode 100644 fastpair/rust/demo/windows/runner/utils.h delete mode 100644 fastpair/rust/demo/windows/runner/win32_window.cpp delete mode 100644 fastpair/rust/demo/windows/runner/win32_window.h delete mode 100644 fastpair/rust/demo/windows/rust.cmake delete mode 100644 fastpair/scanning/BUILD delete mode 100644 fastpair/scanning/fastpair/BUILD delete mode 100644 fastpair/scanning/fastpair/fake_fast_pair_scanner.cc delete mode 100644 fastpair/scanning/fastpair/fake_fast_pair_scanner.h delete mode 100644 fastpair/scanning/fastpair/fast_pair_discoverable_scanner.cc delete mode 100644 fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h delete mode 100644 fastpair/scanning/fastpair/fast_pair_discoverable_scanner_test.cc delete mode 100644 fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.cc delete mode 100644 fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.h delete mode 100644 fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner_test.cc delete mode 100644 fastpair/scanning/fastpair/fast_pair_scanner.h delete mode 100644 fastpair/scanning/fastpair/fast_pair_scanner_impl.cc delete mode 100644 fastpair/scanning/fastpair/fast_pair_scanner_impl.h delete mode 100644 fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc delete mode 100644 fastpair/scanning/mock_scanner_broker.h delete mode 100644 fastpair/scanning/scanner_broker.h delete mode 100644 fastpair/scanning/scanner_broker_impl.cc delete mode 100644 fastpair/scanning/scanner_broker_impl.h delete mode 100644 fastpair/scanning/scanner_broker_impl_test.cc delete mode 100644 fastpair/server_access/BUILD delete mode 100644 fastpair/server_access/fake_fast_pair_client.h delete mode 100644 fastpair/server_access/fast_pair_client.h delete mode 100644 fastpair/server_access/fast_pair_client_impl.cc delete mode 100644 fastpair/server_access/fast_pair_client_impl.h delete mode 100644 fastpair/server_access/fast_pair_client_impl_test.cc delete mode 100644 fastpair/server_access/fast_pair_http_notifier.cc delete mode 100644 fastpair/server_access/fast_pair_http_notifier.h delete mode 100644 fastpair/server_access/fast_pair_http_notifier_test.cc delete mode 100644 fastpair/testing/BUILD delete mode 100644 fastpair/testing/fast_pair_service_data_creator.cc delete mode 100644 fastpair/testing/fast_pair_service_data_creator.h delete mode 100644 fastpair/ui/BUILD delete mode 100644 fastpair/ui/actions.h delete mode 100644 fastpair/ui/fast_pair/fake_fast_pair_notification_controller_observer.h delete mode 100644 fastpair/ui/fast_pair/fake_fast_pair_presenter.h delete mode 100644 fastpair/ui/fast_pair/fast_pair_notification_controller.cc delete mode 100644 fastpair/ui/fast_pair/fast_pair_notification_controller.h delete mode 100644 fastpair/ui/fast_pair/fast_pair_notification_controller_test.cc delete mode 100644 fastpair/ui/fast_pair/fast_pair_presenter.h delete mode 100644 fastpair/ui/fast_pair/fast_pair_presenter_impl.cc delete mode 100644 fastpair/ui/fast_pair/fast_pair_presenter_impl.h delete mode 100644 fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc delete mode 100644 fastpair/ui/fast_pair/mock_fast_pair_notification_controller.h delete mode 100644 fastpair/ui/mock_ui_broker.h delete mode 100644 fastpair/ui/ui_broker.h delete mode 100644 fastpair/ui/ui_broker_impl.cc delete mode 100644 fastpair/ui/ui_broker_impl.h delete mode 100644 fastpair/ui/ui_broker_impl_test.cc diff --git a/README.md b/README.md index 4dc13ba11f..859c34838a 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,6 @@ This is not an officially supported Google product. A peer-to-peer networking API that allows apps to easily discover, connect to, and exchange data with nearby devices in real-time, regardless of network connectivity. -### [Fast Pair](fastpair/) - -Utilizes Bluetooth Low Energy (BLE) to discover nearby Bluetooth devices without using significant phone battery, enabling "magical" scenarios based on device proximity. - ### [Nearby Presence](presence/) An extension to Nearby Connections that features an extensible identity model for authentication and restricted visibility, resource management for system health, and proximity detection through sensor fusion. diff --git a/fastpair/BUILD b/fastpair/BUILD deleted file mode 100644 index cc864b84db..0000000000 --- a/fastpair/BUILD +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright 2022 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. -package_group( - name = "nearby_fastpair", - packages = [ - "//fastpair/...", - ], -) - -cc_library( - name = "fast_pair_controller", - srcs = ["fast_pair_controller.cc"], - hdrs = ["fast_pair_controller.h"], - visibility = ["//:__subpackages__"], - deps = [ - "//fastpair/common", - "//fastpair/handshake", - "//fastpair/message_stream", - "//fastpair/repository", - "//internal/base", - "//internal/platform:comm", - "//internal/platform:types", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - ], -) - -cc_test( - name = "fast_pair_controller_test", - size = "small", - srcs = [ - "fast_pair_controller_test.cc", - ], - deps = [ - ":fast_pair_controller", - "//fastpair/message_stream:fake_provider", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) - -cc_library( - name = "fast_pair_seeker", - hdrs = ["fast_pair_seeker.h"], - visibility = ["//:__subpackages__"], - deps = [ - "//fastpair/common", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - ], -) - -cc_library( - name = "fast_pair_plugin", - hdrs = ["fast_pair_plugin.h"], - visibility = ["//:__subpackages__"], - deps = [ - ":fast_pair_events", - ":fast_pair_seeker", - ], -) - -cc_library( - name = "fast_pair_events", - hdrs = ["fast_pair_events.h"], - visibility = ["//:__subpackages__"], - deps = [ - ], -) - -cc_library( - name = "fast_pair_service", - srcs = ["fast_pair_service.cc"], - hdrs = ["fast_pair_service.h"], - visibility = ["//:__subpackages__"], - deps = [ - ":fast_pair_plugin", - ":fast_pair_seeker", - "//fastpair/common", - "//fastpair/internal", - "//fastpair/repository", - "//fastpair/repository:device_repository", - "//fastpair/repository:repository_impl", - "//fastpair/server_access", - "//internal/account", - "//internal/auth:oauth_lib", - "//internal/auth:types", - "//internal/flags:nearby_flags", - "//internal/network:nearby_http_client", - "//internal/network:types", - "//internal/platform:base", - "//internal/platform:types", - "//internal/platform/flags:platform_flags", - "//internal/platform/implementation:account_manager", - "//internal/platform/implementation:types", - "//internal/preferences", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/strings:str_format", - ], -) - -cc_test( - name = "fast_pair_service_test", - size = "small", - srcs = [ - "fast_pair_service_test.cc", - ], - deps = [ - ":fast_pair_events", - ":fast_pair_service", - "//fastpair/internal", - "//fastpair/message_stream:fake_provider", - "//fastpair/plugins:fake_fast_pair_plugin", - "//internal/account", - "//internal/network:types", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test", - "//internal/test/google3_only:test", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_library( - name = "test_support", - testonly = True, - hdrs = [ - "mock_fast_pair_seeker.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":fast_pair_seeker", - "@com_google_absl//absl/status", - "@com_google_googletest//:gtest_for_library_testonly", - ], -) diff --git a/fastpair/analytics/BUILD b/fastpair/analytics/BUILD deleted file mode 100644 index e076f3edff..0000000000 --- a/fastpair/analytics/BUILD +++ /dev/null @@ -1,46 +0,0 @@ -licenses(["notice"]) - -# 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. -cc_library( - name = "analytics", - srcs = [ - "analytics_recorder.cc", - ], - hdrs = [ - "analytics_recorder.h", - ], - copts = [ - "-Ithird_party", - ], - visibility = ["//fastpair:__subpackages__"], - deps = [ - "//internal/analytics:event_logger", - "//internal/proto/analytics:fast_pair_log_cc_proto", - "//proto:fast_pair_enums_cc_proto", - ], -) - -cc_test( - name = "analytics_recorder_test", - srcs = ["analytics_recorder_test.cc"], - deps = [ - ":analytics", - "//internal/analytics:mock_event_logger", - "//internal/proto/analytics:fast_pair_log_cc_proto", - "//proto:fast_pair_enums_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/analytics/analytics_recorder.cc b/fastpair/analytics/analytics_recorder.cc deleted file mode 100644 index c6ac23ef1d..0000000000 --- a/fastpair/analytics/analytics_recorder.cc +++ /dev/null @@ -1,129 +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. - -#include "fastpair/analytics/analytics_recorder.h" - -#include - -#include "internal/analytics/event_logger.h" -#include "internal/proto/analytics/fast_pair_log.proto.h" -#include "proto/fast_pair_enums.proto.h" - -namespace nearby { -namespace fastpair { -namespace analytics { - -using ::nearby::fastpair::analytics::AnalyticsRecorder; -using ::nearby::proto::fastpair::FastPairLog; - -void AnalyticsRecorder::NewGattEvent(int error_from_os) { - auto fast_pair_log = std::make_unique(); - - auto gatt_event = FastPairLog::GattEvent::default_instance().New(); - gatt_event->set_error_from_os(error_from_os); - - fast_pair_log->set_allocated_gatt_event(gatt_event); - LogEvent(*fast_pair_log); -} - -void AnalyticsRecorder::NewBrEdrHandoverEvent( - ::nearby::proto::fastpair::FastPairEvent::BrEdrHandoverErrorCode - error_code) { - auto fast_pair_log = std::make_unique(); - - auto br_edr_event = FastPairLog::BrEdrHandoverEvent::default_instance().New(); - br_edr_event->set_error_code(error_code); - - fast_pair_log->set_allocated_br_edr_handover_event(br_edr_event); - LogEvent(*fast_pair_log); -} - -void AnalyticsRecorder::NewCreateBondEvent( - ::nearby::proto::fastpair::FastPairEvent::CreateBondErrorCode error_code, - int unbond_reason) { - auto fast_pair_log = std::make_unique(); - - auto create_bond_event = - FastPairLog::CreateBondEvent::default_instance().New(); - create_bond_event->set_error_code(error_code); - create_bond_event->set_unbond_reason(unbond_reason); - - fast_pair_log->set_allocated_bond_event(create_bond_event); - LogEvent(*fast_pair_log); -} - -void AnalyticsRecorder::NewConnectEvent( - ::nearby::proto::fastpair::FastPairEvent::ConnectErrorCode error_code, - int profile_uuid) { - auto fast_pair_log = std::make_unique(); - - auto connect_event = FastPairLog::ConnectEvent::default_instance().New(); - connect_event->set_error_code(error_code); - connect_event->set_profile_uuid(profile_uuid); - - fast_pair_log->set_allocated_connect_event(connect_event); - LogEvent(*fast_pair_log); -} - -void AnalyticsRecorder::NewProviderInfo(int number_account_keys_on_provider) { - auto fast_pair_log = std::make_unique(); - - auto provider_info = FastPairLog::ProviderInfo::default_instance().New(); - provider_info->set_number_account_keys_on_provider( - number_account_keys_on_provider); - - fast_pair_log->set_allocated_provider_info(provider_info); - LogEvent(*fast_pair_log); -} - -void AnalyticsRecorder::NewFootprintsInfo(int number_devices_on_footprints) { - auto fast_pair_log = std::make_unique(); - - auto footprints_info = FastPairLog::FootprintsInfo::default_instance().New(); - footprints_info->set_number_devices_on_footprints( - number_devices_on_footprints); - - fast_pair_log->set_allocated_footprints_info(footprints_info); - LogEvent(*fast_pair_log); -} - -void AnalyticsRecorder::NewKeyBasedPairingInfo(int request_flag, - int response_type, - int response_flag, - int response_device_count) { - auto fast_pair_log = std::make_unique(); - - auto key_based_pairing_info = - FastPairLog::KeyBasedPairingInfo::default_instance().New(); - key_based_pairing_info->set_request_flag(request_flag); - key_based_pairing_info->set_response_flag(response_flag); - key_based_pairing_info->set_response_device_count(response_device_count); - key_based_pairing_info->set_response_type(response_type); - - fast_pair_log->set_allocated_key_based_pairing_info(key_based_pairing_info); - LogEvent(*fast_pair_log); -} - -// start private methods - -void AnalyticsRecorder::LogEvent(const FastPairLog& message) { - if (event_logger_ == nullptr) { - return; - } - event_logger_->Log(message); -} - -} // namespace analytics -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/analytics/analytics_recorder.h b/fastpair/analytics/analytics_recorder.h deleted file mode 100644 index 14f6da0026..0000000000 --- a/fastpair/analytics/analytics_recorder.h +++ /dev/null @@ -1,66 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_ANALYTICS_ANALYTICS_RECORDER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_ANALYTICS_ANALYTICS_RECORDER_H_ - -#include - -#include "internal/analytics/event_logger.h" -#include "internal/proto/analytics/fast_pair_log.proto.h" -#include "proto/fast_pair_enums.proto.h" - -namespace nearby { -namespace fastpair { -namespace analytics { - -class AnalyticsRecorder { - public: - explicit AnalyticsRecorder(::nearby::analytics::EventLogger* event_logger) - : event_logger_(event_logger) {} - ~AnalyticsRecorder() = default; - - void NewGattEvent(int error_from_os); - - void NewBrEdrHandoverEvent( - nearby::proto::fastpair::FastPairEvent::BrEdrHandoverErrorCode error_code - - ); - - void NewCreateBondEvent( - ::nearby::proto::fastpair::FastPairEvent::CreateBondErrorCode error_code, - int unbond_reason); - - void NewConnectEvent( - nearby::proto::fastpair::FastPairEvent::ConnectErrorCode error_code, - int profile_uuid); - - void NewProviderInfo(int number_account_keys_on_provider); - - void NewFootprintsInfo(int number_devices_on_footprints); - - void NewKeyBasedPairingInfo(int request_flag, int response_type, - int response_flag, int response_device_count); - - private: - void LogEvent(const nearby::proto::fastpair::FastPairLog& message); - - nearby::analytics::EventLogger* event_logger_ = nullptr; -}; - -} // namespace analytics -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_ANALYTICS_ANALYTICS_RECORDER_H_ diff --git a/fastpair/analytics/analytics_recorder_test.cc b/fastpair/analytics/analytics_recorder_test.cc deleted file mode 100644 index ea0dfcb8ba..0000000000 --- a/fastpair/analytics/analytics_recorder_test.cc +++ /dev/null @@ -1,119 +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. - -#include "fastpair/analytics/analytics_recorder.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/analytics/mock_event_logger.h" -#include "internal/proto/analytics/fast_pair_log.proto.h" -#include "proto/fast_pair_enums.proto.h" - -namespace nearby { -namespace fastpair { -namespace analytics { -namespace { - -using ::nearby::analytics::MockEventLogger; -using ::nearby::proto::fastpair::FastPairEvent; -using ::nearby::proto::fastpair::FastPairLog; -using ::testing::An; - -class AnalyticsRecorderTest : public ::testing::Test { - public: - AnalyticsRecorderTest() = default; - ~AnalyticsRecorderTest() override = default; - - MockEventLogger& event_logger() { return event_logger_; } - - AnalyticsRecorder analytics_recoder() { return analytics_recorder_; } - - private: - MockEventLogger event_logger_; - AnalyticsRecorder analytics_recorder_{&event_logger_}; -}; - -TEST_F(AnalyticsRecorderTest, NewGattEvent) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([=](const FastPairLog& message) { - EXPECT_EQ(message.gatt_event().error_from_os(), 1); - }); - - analytics_recoder().NewGattEvent(1); -} - -TEST_F(AnalyticsRecorderTest, NewBrEdrHandoverEvent) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([=](const FastPairLog& message) { - ASSERT_EQ(message.br_edr_handover_event().error_code(), - FastPairEvent::BLUETOOTH_MAC_INVALID); - }); - analytics_recoder().NewBrEdrHandoverEvent( - FastPairEvent::BLUETOOTH_MAC_INVALID); -} - -TEST_F(AnalyticsRecorderTest, NewCreateBondEvent) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([=](const FastPairLog& message) { - ASSERT_EQ(message.bond_event().error_code(), - FastPairEvent::NO_PERMISSION); - ASSERT_EQ(message.bond_event().unbond_reason(), 12); - }); - analytics_recoder().NewCreateBondEvent(FastPairEvent::NO_PERMISSION, 12); -} - -TEST_F(AnalyticsRecorderTest, NewConnectEvent) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([=](const FastPairLog& message) { - ASSERT_EQ(message.connect_event().error_code(), - FastPairEvent::GET_PROFILE_PROXY_FAILED); - ASSERT_EQ(message.connect_event().profile_uuid(), 13); - }); - analytics_recoder().NewConnectEvent(FastPairEvent::GET_PROFILE_PROXY_FAILED, - 13); -} - -TEST_F(AnalyticsRecorderTest, NewProviderInfo) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([=](const FastPairLog& message) { - ASSERT_EQ(message.provider_info().number_account_keys_on_provider(), - 14); - }); - analytics_recoder().NewProviderInfo(14); -} - -TEST_F(AnalyticsRecorderTest, NewFootprintsInfo) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([=](const FastPairLog& message) { - ASSERT_EQ(message.footprints_info().number_devices_on_footprints(), 15); - }); - analytics_recoder().NewFootprintsInfo(15); -} - -TEST_F(AnalyticsRecorderTest, NewKeyBasedPairingInfo) { - EXPECT_CALL(event_logger(), Log(An())) - .WillOnce([=](const FastPairLog& message) { - ASSERT_EQ(message.key_based_pairing_info().request_flag(), 16); - ASSERT_EQ(message.key_based_pairing_info().response_type(), 17); - ASSERT_EQ(message.key_based_pairing_info().response_flag(), 18); - ASSERT_EQ(message.key_based_pairing_info().response_device_count(), 19); - }); - analytics_recoder().NewKeyBasedPairingInfo(16, 17, 18, 19); -} - -} // namespace -} // namespace analytics -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/BUILD b/fastpair/common/BUILD deleted file mode 100644 index ab62e395fa..0000000000 --- a/fastpair/common/BUILD +++ /dev/null @@ -1,149 +0,0 @@ -# Copyright 2022 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. - -licenses(["notice"]) - -cc_library( - name = "common", - srcs = [ - "account_key_filter.cc", - "battery_notification.cc", - "fast_pair_device.cc", - "fast_pair_http_result.cc", - "fast_pair_prefs.cc", - "fast_pair_switches.cc", - "pair_failure.cc", - "protocol.cc", - ], - hdrs = [ - "account_key.h", - "account_key_filter.h", - "battery_notification.h", - "constant.h", - "device_metadata.h", - "fast_pair_device.h", - "fast_pair_http_result.h", - "fast_pair_prefs.h", - "fast_pair_switches.h", - "fast_pair_version.h", - "non_discoverable_advertisement.h", - "pair_failure.h", - "protocol.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/proto:fastpair_cc_proto", - "//internal/crypto_cros", - "//internal/platform:types", - "//internal/preferences", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - ], -) - -cc_test( - name = "account_key_filter_test", - size = "small", - srcs = [ - "account_key_filter_test.cc", - ], - shard_count = 16, - deps = [ - ":common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_device_test", - size = "small", - srcs = [ - "fast_pair_device_test.cc", - ], - shard_count = 16, - deps = [ - ":common", - "//fastpair/proto:fastpair_cc_proto", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "pair_failure_test", - size = "small", - srcs = [ - "pair_failure_test.cc", - ], - shard_count = 16, - deps = [ - ":common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "battery_notification_test", - size = "small", - srcs = [ - "battery_notification_test.cc", - ], - shard_count = 16, - deps = [ - ":common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_prefs_test", - size = "small", - srcs = [ - "fast_pair_prefs_test.cc", - ], - shard_count = 16, - deps = [ - ":common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_switches_test", - size = "small", - srcs = [ - "fast_pair_switches_test.cc", - ], - shard_count = 16, - deps = [ - ":common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/common/account_key.h b/fastpair/common/account_key.h deleted file mode 100644 index fd07aa7e6a..0000000000 --- a/fastpair/common/account_key.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_ACCOUNT_KEY_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_ACCOUNT_KEY_H_ - -#include -#include -#include - -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/constant.h" -#include "internal/platform/crypto.h" - -namespace nearby { -namespace fastpair { - -class AccountKey { - public: - AccountKey() = default; - explicit AccountKey(absl::string_view bytes) : bytes_(bytes) {} - explicit AccountKey(const std::vector bytes) { - bytes_ = std::string(bytes.begin(), bytes.end()); - } - - static AccountKey CreateRandomKey() { - std::string key(kAccountKeySize, 0); - RandBytes(key.data(), kAccountKeySize); - return AccountKey(key); - } - - absl::string_view GetAsBytes() const { return bytes_; } - - bool Ok() const { return bytes_.size() == kAccountKeySize; } - - explicit operator bool() const { return Ok(); } - - private: - std::string bytes_; -}; - -inline std::ostream& operator<<(std::ostream& stream, const AccountKey& key) { - stream << "AccountKey(" << absl::BytesToHexString(key.GetAsBytes()) << ")"; - return stream; -} - -inline bool operator==(const AccountKey& a, const AccountKey& b) { - return a.GetAsBytes() == b.GetAsBytes(); -} - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_ACCOUNT_KEY_H_ diff --git a/fastpair/common/account_key_filter.cc b/fastpair/common/account_key_filter.cc deleted file mode 100644 index b3a237578c..0000000000 --- a/fastpair/common/account_key_filter.cc +++ /dev/null @@ -1,125 +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. - -#include "fastpair/common/account_key_filter.h" - -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "fastpair/common/battery_notification.h" -#include "fastpair/common/non_discoverable_advertisement.h" -#include "internal/crypto_cros/sha2.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr int kBitsInByte = 8; - -// SASS enabled peripherals create their Bloom filters with the first byte -// equals to either `the account key in use` -// or `the most recently used account key` -// see this spec: -// https://developers.google.com/nearby/fast-pair/early-access/specifications/extensions/sass#SassInUseAccountKey -constexpr uint8_t kRecentlyUsedByte = 0x05; -constexpr uint8_t kInUseByte = 0x06; -constexpr uint8_t kShowUi = 0b00110011; -constexpr uint8_t kHideUi = 0b00110100; - -// Helper to AccountKeyFilter::IsAccountKeyInFilter(). -// Performs the test to see if |data| is in |bit_sets|, a Bloom filter. -bool AccountKeyFilterChecker(const std::vector& data, - const std::vector& bit_sets) { - std::array hashed = crypto::SHA256Hash(data); - - // Iterate over the hashed input in 4 byte increments, combine those 4 - // bytes into an unsigned int and use it as the index into our - // |bit_sets|. - for (size_t i = 0; i < hashed.size(); i += 4) { - uint32_t hash = uint32_t{hashed[i]} << 24 | uint32_t{hashed[i + 1]} << 16 | - uint32_t{hashed[i + 2]} << 8 | hashed[i + 3]; - - size_t num_bits = bit_sets.size() * kBitsInByte; - size_t n = hash % num_bits; - size_t byte_index = floor(n / kBitsInByte); - size_t bit_index = n % kBitsInByte; - bool is_set = (bit_sets[byte_index] >> bit_index) & 0x01; - - if (!is_set) return false; - } - NEARBY_LOGS(INFO) << __func__ << " The accountkey is possibly in set."; - return true; -} - -} // namespace - -AccountKeyFilter::AccountKeyFilter( - const NonDiscoverableAdvertisement& advertisement) - : bit_sets_(advertisement.account_key_filter) { - salt_values_.resize(advertisement.salt.size()); - std::copy(advertisement.salt.begin(), advertisement.salt.end(), - salt_values_.begin()); - - // If the advertisement contains battery information, then that information - // was also appended to the account keys to generate the filter. We need to - // do the same when checking for matches, so save the values in salt_values_ - // for that purpose later. - if (advertisement.battery_notification) { - salt_values_.push_back(advertisement.battery_notification->type == - BatteryNotification::Type::kShowUi - ? kShowUi - : kHideUi); - for (auto battery_info : - advertisement.battery_notification->battery_infos) { - salt_values_.push_back(battery_info.ToByte()); - } - } -} - -AccountKeyFilter::AccountKeyFilter( - const std::vector& account_key_filter_bytes, - const std::vector& salt_values) - : bit_sets_(account_key_filter_bytes), salt_values_(salt_values) {} - -bool AccountKeyFilter::IsPossiblyInSet(const AccountKey& account_key) { - if (!account_key.Ok()) { - NEARBY_LOGS(INFO) << __func__ << " Invalid account key."; - return false; - } - if (bit_sets_.empty()) return false; - // We first need to append the salt value to the input (see - // https://developers.google.com/nearby/fast-pair/spec#AccountKeyFilter). - std::vector data(account_key.GetAsBytes().begin(), - account_key.GetAsBytes().end()); - for (auto& byte : salt_values_) data.push_back(byte); - - // We need to try account keys with different first bytes in case - // the peripheral is SASS per - // https://developers.google.com/nearby/fast-pair/early-access/specifications/extensions/sass#SassAdvertisingPayload - if (AccountKeyFilterChecker(data, bit_sets_)) { - return true; - } - data[0] = kRecentlyUsedByte; - if (AccountKeyFilterChecker(data, bit_sets_)) { - return true; - } - data[0] = kInUseByte; - return AccountKeyFilterChecker(data, bit_sets_); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/account_key_filter.h b/fastpair/common/account_key_filter.h deleted file mode 100644 index 40eaace61b..0000000000 --- a/fastpair/common/account_key_filter.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_ACCOUNT_KEY_FILTER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_ACCOUNT_KEY_FILTER_H_ - -#include -#include - -#include "fastpair/common/account_key.h" -#include "fastpair/common/non_discoverable_advertisement.h" - -namespace nearby { -namespace fastpair { - -// Class which represents a Fast Pair Account Key account_key_filter -// https://developers.google.com/nearby/fast-pair/specifications/service/provider#AccountKeyFilter -class AccountKeyFilter { - public: - explicit AccountKeyFilter(const NonDiscoverableAdvertisement& advertisement); - AccountKeyFilter(const std::vector& account_key_filter_bytes, - const std::vector& salt_values); - ~AccountKeyFilter() = default; - - // Returns true if the `account_key` is possibly in the account key set - // defined by the filter. - // Return false if `account_key` is definitely not in set. - bool IsPossiblyInSet(const AccountKey& account_key); - - private: - std::vector bit_sets_; - std::vector salt_values_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_ACCOUNT_KEY_FILTER_H_ diff --git a/fastpair/common/account_key_filter_test.cc b/fastpair/common/account_key_filter_test.cc deleted file mode 100644 index 31101d0e1c..0000000000 --- a/fastpair/common/account_key_filter_test.cc +++ /dev/null @@ -1,135 +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. - -#include "fastpair/common/account_key_filter.h" - -#include -#include - -#include "gtest/gtest.h" -#include "fastpair/common/battery_notification.h" -#include "fastpair/common/non_discoverable_advertisement.h" - -namespace nearby { -namespace fastpair { -namespace { -// Test data comes from: -// https://developers.google.com/nearby/fast-pair/specifications/appendix/testcases#test_cases - -class AccountKeyFilterTest : public testing::Test { - protected: - const std::vector salt_{0xC7, 0xC8}; - const std::vector account_key_1_{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, - 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, - 0xCC, 0xDD, 0xEE, 0xFF}; - const std::vector account_key_2_{0x11, 0x11, 0x22, 0x22, 0x33, 0x33, - 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, - 0x77, 0x77, 0x88, 0x88}; - - const std::vector filter_1_{0x02, 0x0C, 0x80, 0x2A}; - const std::vector filter_2_{0x84, 0x4A, 0x62, 0x20, 0x8B}; - const std::vector filter_1_and_2_{0x84, 0x4A, 0x62, 0x20, 0x8B}; - - const std::vector battery_data_{0b00110011, 0b01000000, 0b01000000, - 0b01000000}; - - const std::vector filter_1_with_battery_{0x01, 0x01, 0x46, 0x0A}; - const std::vector filter_2_with_battery_{0x46, 0x15, 0x24, 0xD0, - 0x08}; -}; - -TEST_F(AccountKeyFilterTest, ConstrutorWithNonDiscoverableAdvertisement) { - NonDiscoverableAdvertisement non_discoverable_advertisement( - filter_1_, NonDiscoverableAdvertisement::Type::kShowUi, salt_, {}); - EXPECT_TRUE(AccountKeyFilter(non_discoverable_advertisement) - .IsPossiblyInSet(AccountKey(account_key_1_))); - NonDiscoverableAdvertisement non_discoverable_advertisement_with_battery( - filter_1_with_battery_, NonDiscoverableAdvertisement::Type::kShowUi, - salt_, - BatteryNotification::FromBytes({0b01000000, 0b01000000, 0b01000000}, - BatteryNotification::Type::kShowUi)); - EXPECT_TRUE(AccountKeyFilter(non_discoverable_advertisement_with_battery) - .IsPossiblyInSet(AccountKey(account_key_1_))); -} - -TEST_F(AccountKeyFilterTest, EmptyAccountKeyFilter) { - AccountKeyFilter filter({}, {}); - - EXPECT_FALSE(filter.IsPossiblyInSet(AccountKey(account_key_1_))); - EXPECT_FALSE(filter.IsPossiblyInSet(AccountKey(account_key_2_))); -} - -TEST_F(AccountKeyFilterTest, EmptyAccountKey) { - EXPECT_FALSE( - AccountKeyFilter(filter_1_, salt_).IsPossiblyInSet(AccountKey(""))); -} - -TEST_F(AccountKeyFilterTest, SingleAccountKey) { - EXPECT_TRUE(AccountKeyFilter(filter_1_, salt_) - .IsPossiblyInSet(AccountKey(AccountKey(account_key_1_)))); - EXPECT_TRUE(AccountKeyFilter(filter_2_, salt_) - .IsPossiblyInSet(AccountKey(account_key_2_))); -} - -TEST_F(AccountKeyFilterTest, TwoAccountKeys) { - AccountKeyFilter filter(filter_1_and_2_, salt_); - EXPECT_TRUE(filter.IsPossiblyInSet(AccountKey(account_key_1_))); - EXPECT_TRUE(filter.IsPossiblyInSet(AccountKey(account_key_2_))); -} - -TEST_F(AccountKeyFilterTest, MissingAccountKey) { - const std::vector bytes{0x12, 0x22, 0x33, 0x44, 0x55, 0x66, - 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, - 0xCC, 0xDD, 0xEE, 0xFF}; - AccountKey account_key(bytes); - EXPECT_FALSE(AccountKeyFilter(filter_1_, salt_).IsPossiblyInSet(account_key)); - EXPECT_FALSE( - AccountKeyFilter(filter_1_and_2_, salt_).IsPossiblyInSet(account_key)); -} - -TEST_F(AccountKeyFilterTest, AccountKeyWithBatteryData) { - std::vector salt_1 = salt_; - for (auto& byte : battery_data_) salt_1.push_back(byte); - - EXPECT_TRUE(AccountKeyFilter(filter_1_with_battery_, salt_1) - .IsPossiblyInSet(AccountKey(account_key_1_))); - - std::vector salt_2 = salt_; - for (auto& byte : battery_data_) salt_2.push_back(byte); - - EXPECT_TRUE(AccountKeyFilter(filter_2_with_battery_, salt_2) - .IsPossiblyInSet(AccountKey(account_key_2_))); -} - -TEST_F(AccountKeyFilterTest, SassEnabledPeripheral) { - // Value source: b/243855406#comment24 - const std::vector bytes{0x06, 0x3F, 0xC1, 0x8C, 0x63, 0xDC, - 0x75, 0x1A, 0xE8, 0x1A, 0xCF, 0x65, - 0x10, 0x15, 0x1D, 0xB0}; - AccountKey account_key_3(bytes); - const std::vector filter4{0x19, 0x23, 0x50, 0xE8, 0x37, - 0x68, 0xF0, 0x65, 0x22}; - const std::vector salt4{0xD7, 0xDE}; - const std::vector batteryData4{0x33, 0xE4, 0xE4, 0x64}; - std::vector salt_values{}; - salt_values.insert(salt_values.end(), salt4.begin(), salt4.end()); - salt_values.insert(salt_values.end(), batteryData4.begin(), - batteryData4.end()); - EXPECT_TRUE( - AccountKeyFilter(filter4, salt_values).IsPossiblyInSet(account_key_3)); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/battery_notification.cc b/fastpair/common/battery_notification.cc deleted file mode 100644 index d46d6b8620..0000000000 --- a/fastpair/common/battery_notification.cc +++ /dev/null @@ -1,86 +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. - -#include "fastpair/common/battery_notification.h" - -#include -#include -#include - -#include "fastpair/common/constant.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { -BatteryInfo::BatteryInfo(bool is_charging) - : is_charging(is_charging), percentage(std::nullopt) {} - -BatteryInfo::BatteryInfo(bool is_charging, int8_t percentage) - : is_charging(is_charging), percentage(percentage) {} - -// static -BatteryInfo BatteryInfo::FromByte(uint8_t byte) { - // Battery value is in the form 0bSVVVVVVV. - // S = charging (0b1) or not (0b0). - // V = value, Ranges from 0-100, or 0bS1111111 if unknown. - bool is_charging = byte & kBatteryChargingMask; - uint8_t percentage = byte & kBatteryPercentageMask; - int8_t percentage_signed = static_cast(percentage); - if (percentage_signed < 0 || percentage_signed > 100) { - NEARBY_LOGS(INFO) << __func__ << "Invalid battery percentage."; - return BatteryInfo(is_charging); - } - return BatteryInfo(is_charging, percentage_signed); -} - -uint8_t BatteryInfo::ToByte() const { - // Battery value is in the form 0bSVVVVVVV. - // S = charging (0b1) or not (0b0). - // V = value, Ranges from 0-100, or 1111111 if unknown. - if (!percentage) { - return is_charging ? kBatteryIsChargingByte : kBatteryNotChargingByte; - } else { - return percentage.value() | (is_charging ? kBatteryChargingMask : 0); - } -} - -BatteryNotification::BatteryNotification( - Type type, const std::vector& battery_infos) - : type(type), battery_infos(battery_infos) {} - -// static -std::optional BatteryNotification::FromBytes( - const std::vector& bytes, Type type) { - if (bytes.size() == 1) { - // Single component device. - NEARBY_LOGS(INFO) << __func__ << " : Single component device."; - std::vector battery_infos = {BatteryInfo::FromByte(bytes[0])}; - return std::make_optional(type, battery_infos); - } else if (bytes.size() == 3) { - // True wireless headset expecting 3 bytes - Left bud, Right bud and case. - NEARBY_LOGS(INFO) << __func__ << " : True wireless headset."; - std::vector battery_infos = { - /* left bud info */ BatteryInfo::FromByte(bytes[0]), - /* right bud info */ BatteryInfo::FromByte(bytes[1]), - /* case info */ BatteryInfo::FromByte(bytes[2])}; - return std::make_optional(type, battery_infos); - } - NEARBY_LOGS(WARNING) << __func__ - << " : Unexpected battery notification length :" - << bytes.size(); - return std::nullopt; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/battery_notification.h b/fastpair/common/battery_notification.h deleted file mode 100644 index 3c82060f36..0000000000 --- a/fastpair/common/battery_notification.h +++ /dev/null @@ -1,66 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_BATTERY_NOTIFICATION_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_BATTERY_NOTIFICATION_H_ - -#include -#include -#include - -namespace nearby { -namespace fastpair { - -// Fast Pair battery information from notification. See -// https://developers.google.com/nearby/fast-pair/spec#BatteryNotification -struct BatteryInfo { - BatteryInfo() = default; - explicit BatteryInfo(bool is_charging); - BatteryInfo(bool is_charging, int8_t percentage); - ~BatteryInfo() = default; - - static BatteryInfo FromByte(uint8_t byte); - - uint8_t ToByte() const; - - bool is_charging = false; - std::optional percentage; -}; - -// Fast Pair battery notification. See -// https://developers.google.com/nearby/fast-pair/spec#BatteryNotification -struct BatteryNotification { - // Represents if the provider wants to show an indication - // of the battery values - enum class Type { - kNone = 0, - kShowUi = 3, /* Show UI indication: 0b0011 */ - kHideUi = 4, /* Hide UI indication: 0b0100 */ - }; - - BatteryNotification() = default; - BatteryNotification(Type type, const std::vector& battery_infos); - ~BatteryNotification() = default; - - static std::optional FromBytes( - const std::vector& bytes, Type type); - - Type type = Type::kNone; - std::vector battery_infos; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_BATTERY_NOTIFICATION_H_ diff --git a/fastpair/common/battery_notification_test.cc b/fastpair/common/battery_notification_test.cc deleted file mode 100644 index 48c86b6034..0000000000 --- a/fastpair/common/battery_notification_test.cc +++ /dev/null @@ -1,152 +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. - -#include "fastpair/common/battery_notification.h" - -#include -#include - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { -// Test data comes from: -// https://developers.google.com/nearby/fast-pair/specifications/appendix/testcases#test_cases - -TEST(BatteryNotificationTest, TestBatteryInfo) { - // Tests default constructor - BatteryInfo battery_info_1; - EXPECT_FALSE(battery_info_1.is_charging); - - // Tests Constructor with is_charging - BatteryInfo battery_info_2(true); - EXPECT_TRUE(battery_info_2.is_charging); - // Tests ToByte and FromByte - BatteryInfo battery_info_3 = BatteryInfo::FromByte(battery_info_2.ToByte()); - EXPECT_TRUE(battery_info_3.is_charging); - EXPECT_FALSE(battery_info_3.percentage.has_value()); - - // Tests Constructor with is_charging and percentage value - BatteryInfo battery_info_4(true, 80); - EXPECT_TRUE(battery_info_4.is_charging); - EXPECT_EQ(battery_info_4.percentage.value(), 80); - // Tests ToByte and FromByte - BatteryInfo battery_info_5 = BatteryInfo::FromByte(battery_info_4.ToByte()); - EXPECT_TRUE(battery_info_5.is_charging); - EXPECT_EQ(battery_info_5.percentage.value(), 80); - - // Tests Constructor with is_charging and wrong percentage value - BatteryInfo battery_info_6(true, 110); - // Tests ToByte and FromByte - BatteryInfo battery_info_7 = BatteryInfo::FromByte(battery_info_6.ToByte()); - EXPECT_TRUE(battery_info_7.is_charging); - EXPECT_FALSE(battery_info_7.percentage.has_value()); - - // Tests FromByte with battery percentage = 0 - BatteryInfo battery_info_8 = BatteryInfo::FromByte(0); - EXPECT_FALSE(battery_info_8.is_charging); - EXPECT_EQ(battery_info_8.percentage.value(), 0); - - BatteryInfo battery_info_10 = BatteryInfo::FromByte(0x80); - EXPECT_TRUE(battery_info_10.is_charging); - EXPECT_EQ(battery_info_10.percentage.value(), 0); - - // Tests FromByte with battery percentage = 100 - BatteryInfo battery_info_9 = BatteryInfo::FromByte(100); - EXPECT_FALSE(battery_info_9.is_charging); - EXPECT_EQ(battery_info_9.percentage.value(), 100); - - BatteryInfo battery_info_11 = BatteryInfo::FromByte(0x80 | 100); - EXPECT_TRUE(battery_info_11.is_charging); - EXPECT_EQ(battery_info_11.percentage.value(), 100); - - // Test battery with invalid battery percentage - BatteryInfo battery_info_12 = BatteryInfo::FromByte(0x7F); - EXPECT_FALSE(battery_info_12.is_charging); - EXPECT_FALSE(battery_info_12.percentage.has_value()); - - BatteryInfo battery_info_13 = BatteryInfo::FromByte(0xFF); - EXPECT_TRUE(battery_info_13.is_charging); - EXPECT_FALSE(battery_info_13.percentage.has_value()); -} - -TEST(BatteryNotificationTest, TestBatteryNotificationDefaultConstructor) { - // Tests default constructor - BatteryNotification battery_notification; - EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kNone); - EXPECT_EQ(battery_notification.battery_infos.size(), 0); -} - -TEST(BatteryNotificationTest, TestBatteryNotificationForSingleComponentDevice) { - std::vector battery_infos = {BatteryInfo(false, 70)}; - BatteryNotification battery_notification(BatteryNotification::Type::kShowUi, - battery_infos); - EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kShowUi); - EXPECT_FALSE(battery_notification.battery_infos.at(0).is_charging); - EXPECT_EQ(battery_notification.battery_infos.at(0).percentage.value(), 70); -} - -TEST(BatteryNotificationTest, TestBatteryNotificationForTrueWirelessHeadset) { - std::vector battery_infos = { - BatteryInfo(false, 70), BatteryInfo(false, 80), BatteryInfo(true, 90)}; - BatteryNotification battery_notification(BatteryNotification::Type::kShowUi, - battery_infos); - EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kShowUi); - // Left bud - EXPECT_FALSE(battery_notification.battery_infos.at(0).is_charging); - EXPECT_EQ(battery_notification.battery_infos.at(0).percentage.value(), 70); - // Right bud - EXPECT_FALSE(battery_notification.battery_infos.at(1).is_charging); - EXPECT_EQ(battery_notification.battery_infos.at(1).percentage.value(), 80); - // Case - EXPECT_TRUE(battery_notification.battery_infos.at(2).is_charging); - EXPECT_EQ(battery_notification.battery_infos.at(2).percentage.value(), 90); -} - -TEST(BatteryNotificationTest, - TestBatteryNotificationFromBytesForSingleComponentDevice) { - const std::vector batteryData{0b01000000}; - BatteryNotification battery_notification = - BatteryNotification::FromBytes(batteryData, - BatteryNotification::Type::kShowUi) - .value(); - EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kShowUi); - EXPECT_EQ(battery_notification.battery_infos.at(0).percentage.value(), 64); -} - -TEST(BatteryNotificationTest, - TestBatteryNotificationFromBytesForTrueWirelessHeadset) { - const std::vector batteryData{0b01000000, 0b01000000, 0b01000000}; - BatteryNotification battery_notification = - BatteryNotification::FromBytes(batteryData, - BatteryNotification::Type::kShowUi) - .value(); - EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kShowUi); - EXPECT_EQ(battery_notification.battery_infos.at(0).percentage.value(), 64); - EXPECT_EQ(battery_notification.battery_infos.at(1).percentage.value(), 64); - EXPECT_EQ(battery_notification.battery_infos.at(2).percentage.value(), 64); -} - -TEST(BatteryNotificationTest, TestBatteryNotificationFromWrongBytes) { - const std::vector batteryDataWithWrongLenth{0b01000000, 0b01000000}; - EXPECT_FALSE( - BatteryNotification::FromBytes(batteryDataWithWrongLenth, - BatteryNotification::Type::kShowUi) - .has_value()); -} -} // namespace - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/constant.h b/fastpair/common/constant.h deleted file mode 100644 index 200eb0ac45..0000000000 --- a/fastpair/common/constant.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_CONSTANT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_CONSTANT_H_ - -#include - -namespace nearby { -namespace fastpair { - -// Bluetooth Uuid -constexpr char kServiceId[] = "Fast Pair"; - -constexpr char kRfcommUuid[] = "df21fe2c-2515-4fdb-8886-f12c4d67927c"; -constexpr int kAccountKeySize = 16; - -// Key pair -constexpr int kSharedSecretKeyByteSize = 16; -constexpr int kPublicKeyByteSize = 64; - -// Encryption -constexpr int kAesBlockByteSize = 16; -constexpr int kEncryptedDataByteSize = 16; -// Decryption -constexpr int kDecryptedResponseAddressByteSize = 6; -constexpr int kDecryptedResponseSaltByteSize = 9; -constexpr int kDecryptedPasskeySaltByteSize = 12; - -// Handshake response index -constexpr int kMessageTypeIndex = 0; -constexpr int kResponseAddressStartIndex = 1; -constexpr int kResponseSaltStartIndex = 7; -constexpr int kPasskeySaltStartIndex = 4; - -// Handshake response message type -constexpr uint8_t kKeybasedPairingResponseType = 0x01; -constexpr uint8_t kSeekerPasskeyType = 0x02; -constexpr uint8_t kProviderPasskeyType = 0x03; - -// Handshake request inex -constexpr uint8_t kProviderAddressStartIndex = 2; -constexpr uint8_t kSeekerAddressStartIndex = 8; -constexpr uint8_t kSeekerPasskey = 0x02; -constexpr uint8_t kAccountKeyStartByte = 0x04; - -// Handshake request message type -constexpr uint8_t kKeyBasedPairingType = 0x00; -constexpr uint8_t kInitialOrSubsequentFlags = 0x00; -constexpr uint8_t kRetroactiveFlags = 0x10; - -// Battery Info -constexpr int kBatteryChargingMask = 0b10000000; -constexpr int kBatteryPercentageMask = 0b01111111; -constexpr int kBatteryIsChargingByte = 0b11111111; -constexpr int kBatteryNotChargingByte = 0b01111111; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_CONSTANT_H_ diff --git a/fastpair/common/device_metadata.h b/fastpair/common/device_metadata.h deleted file mode 100644 index b33ddc5160..0000000000 --- a/fastpair/common/device_metadata.h +++ /dev/null @@ -1,54 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_DEVICE_METADATA_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_DEVICE_METADATA_H_ - -#include - -#include "fastpair/common/fast_pair_version.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" - -namespace nearby { -namespace fastpair { -class DeviceMetadata { - public: - explicit DeviceMetadata(const proto::GetObservedDeviceResponse response) - : response_(std::move(response)) {} - DeviceMetadata(DeviceMetadata &&) = default; - DeviceMetadata(const DeviceMetadata &) = default; - DeviceMetadata &operator=(const DeviceMetadata &) = default; - DeviceMetadata &operator=(DeviceMetadata &&) = default; - ~DeviceMetadata() = default; - const proto::Device &GetDetails() const { return response_.device(); } - const proto::GetObservedDeviceResponse &GetResponse() const { - return response_; - } - - DeviceFastPairVersion GetFastPairVersion() const { - // Anti-spoofing keys were introduced in Fast Pair v2, so if this isn't - // available then the device is v1. - if (GetDetails().anti_spoofing_key_pair().public_key().empty()) { - return DeviceFastPairVersion::kV1; - } - return DeviceFastPairVersion::kHigherThanV1; - } - - private: - proto::GetObservedDeviceResponse response_; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_DEVICE_METADATA_H_ diff --git a/fastpair/common/fast_pair_device.cc b/fastpair/common/fast_pair_device.cc deleted file mode 100644 index b3f9368095..0000000000 --- a/fastpair/common/fast_pair_device.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/common/fast_pair_device.h" - -#include -#include -#include - -#include "fastpair/common/protocol.h" - -namespace nearby { -namespace fastpair { - -std::ostream& operator<<(std::ostream& stream, const FastPairDevice& device) { - stream << "[Device: model_id = " << device.GetModelId() - << ", ble_address = " << device.GetBleAddress() - << ", public_address = " << device.GetPublicAddress().value_or("null") - << ", display_name = " << device.GetDisplayName().value_or("null") - << ", " << device.GetAccountKey() - << ", protocol = " << device.GetProtocol() << "]"; - - return stream; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/fast_pair_device.h b/fastpair/common/fast_pair_device.h deleted file mode 100644 index cf2553121a..0000000000 --- a/fastpair/common/fast_pair_device.h +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_DEVICE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_DEVICE_H_ - -#include -#include -#include -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_version.h" -#include "fastpair/common/protocol.h" - -namespace nearby { -namespace fastpair { - -// Thin class which is used by the higher level components of the Fast Pair -// system to represent a device. -class FastPairDevice { - public: - explicit FastPairDevice(Protocol protocol) : protocol_(protocol) {} - FastPairDevice(absl::string_view model_id, absl::string_view ble_address, - Protocol protocol) - : model_id_(model_id), ble_address_(ble_address), protocol_(protocol) {} - - FastPairDevice(const FastPairDevice&) = delete; - FastPairDevice(FastPairDevice&&) = default; - FastPairDevice& operator=(const FastPairDevice&) = delete; - FastPairDevice& operator=(FastPairDevice&&) = default; - ~FastPairDevice() = default; - - std::optional GetPublicAddress() const { - return public_address_; - } - - void SetPublicAddress(absl::string_view address) { - public_address_ = std::string(address); - } - - std::optional GetDisplayName() const { return display_name_; } - - void SetDisplayName(absl::string_view display_name) { - display_name_ = std::string(display_name); - } - - std::optional GetVersion() const { - if (metadata_) { - return metadata_->GetFastPairVersion(); - } - return std::nullopt; - } - - const AccountKey& GetAccountKey() const { return account_key_; } - - void SetAccountKey(AccountKey account_key) { account_key_ = account_key; } - - void SetModelId(absl::string_view model_id) { - model_id_ = std::string(model_id); - } - - absl::string_view GetModelId() const { return model_id_; } - - void SetBleAddress(absl::string_view address) { - ble_address_ = std::string(address); - } - - absl::string_view GetBleAddress() const { return ble_address_; } - - Protocol GetProtocol() const { return protocol_; } - - void SetMetadata(const DeviceMetadata& metadata) { metadata_ = metadata; } - - const std::optional& GetMetadata() const { return metadata_; } - - const std::string& GetUniqueId() const { - if (public_address_.has_value()) { - return *public_address_; - } - return ble_address_; - } - - void SetShowUiNotification(bool should_show_ui_notification) { - should_show_ui_notification_ = should_show_ui_notification; - } - - std::optional ShouldShowUiNotification() const { - return should_show_ui_notification_; - } - - void StartedPairing(bool started_pairing) { - has_started_pairing_ = started_pairing; - } - - bool HasStartedPairing() const { return has_started_pairing_; } - - private: - std::string model_id_; - - // Bluetooth LE address of the device. - std::string ble_address_; - - // The Quick Pair protocol implementation that this device belongs to. - Protocol protocol_; - - // Bluetooth public classic address of the device. - std::optional public_address_; - - // Display name for the device - // Similar to Bluetooth classic address field, this will be null when a - // device is found from a discoverable advertisement due to the fact that - // initial pair notifications show the OEM default name from the device - // metadata instead of the display name. - std::optional display_name_; - - // Fast Pair version number, possible versions numbers are defined at the top - // of this file. - std::optional version_; - - // Account key which will be saved to the user's account during Fast Pairing - // for eligible devices (V2 or higher) and used for detecting subsequent - // pairing scenarios. - AccountKey account_key_; - - std::optional metadata_; - std::optional should_show_ui_notification_; - bool has_started_pairing_ = false; -}; - -std::ostream& operator<<(std::ostream& stream, const FastPairDevice& device); - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_DEVICE_H_ diff --git a/fastpair/common/fast_pair_device_test.cc b/fastpair/common/fast_pair_device_test.cc deleted file mode 100644 index 36010f75d1..0000000000 --- a/fastpair/common/fast_pair_device_test.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/common/fast_pair_device.h" - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/protocol.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(FastPairDevice, GetAndSetAccountKey) { - FastPairDevice device("model_id", "ble_address", - Protocol::kFastPairInitialPairing); - AccountKey firstKey = AccountKey::CreateRandomKey(); - device.SetAccountKey(firstKey); - EXPECT_EQ(device.GetAccountKey(), firstKey); - - // Test that overriding works. - AccountKey secondKey = AccountKey::CreateRandomKey(); - device.SetAccountKey(secondKey); - EXPECT_EQ(device.GetAccountKey(), secondKey); -} - -TEST(FastPairDevice, GetAndSetName) { - FastPairDevice device("model_id", "ble_address", - Protocol::kFastPairInitialPairing); - // Test that name returns null before any sets. - EXPECT_FALSE(device.GetDisplayName().has_value()); - - // Test that name returns the set value. - std::string test_name = "test_name"; - device.SetDisplayName(test_name); - EXPECT_EQ(device.GetDisplayName().value(), test_name); - - // Test that overriding works. - std::string new_test_name = "new_test_name"; - device.SetDisplayName(new_test_name); - EXPECT_EQ(device.GetDisplayName().value(), new_test_name); -} - -TEST(FastPairDevice, GetAndPublicAddress) { - FastPairDevice device("model_id", "ble_address", - Protocol::kFastPairInitialPairing); - // Test that public address returns null before any sets. - EXPECT_FALSE(device.GetPublicAddress().has_value()); - - // Test that name returns the set value. - std::string test_GetPublicAddress = "test_GetPublicAddress "; - device.SetPublicAddress(test_GetPublicAddress); - EXPECT_EQ(device.GetPublicAddress().value(), test_GetPublicAddress); - - // Test that overriding works. - std::string new_test_GetPublicAddress = "new_test_GetPublicAddress "; - device.SetPublicAddress(new_test_GetPublicAddress); - EXPECT_EQ(device.GetPublicAddress().value(), new_test_GetPublicAddress); -} - -TEST(FastPairDevice, GetVersionUnset) { - FastPairDevice device("model_id", "ble_address", - Protocol::kFastPairInitialPairing); - - EXPECT_FALSE(device.GetVersion()); -} - -TEST(FastPairDevice, GetVersionV1) { - FastPairDevice device("model_id", "ble_address", - Protocol::kFastPairInitialPairing); - proto::GetObservedDeviceResponse response; - device.SetMetadata(DeviceMetadata(response)); - - EXPECT_EQ(device.GetVersion(), DeviceFastPairVersion::kV1); -} - -TEST(FastPairDevice, GetVersionHigherThanV1) { - FastPairDevice device("model_id", "ble_address", - Protocol::kFastPairInitialPairing); - proto::GetObservedDeviceResponse response; - std::string anti_spoofing_key(kPublicKeyByteSize, 0); - response.mutable_device()->mutable_anti_spoofing_key_pair()->set_public_key( - anti_spoofing_key); - device.SetMetadata(DeviceMetadata(response)); - - EXPECT_EQ(device.GetVersion(), DeviceFastPairVersion::kHigherThanV1); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/fast_pair_http_result.cc b/fastpair/common/fast_pair_http_result.cc deleted file mode 100644 index d66038a67c..0000000000 --- a/fastpair/common/fast_pair_http_result.cc +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/common/fast_pair_http_result.h" - -#include -#include - -#include "absl/status/status.h" - -namespace nearby { -namespace fastpair { - -FastPairHttpError FastPairHttpErrorForHttpResponseCode(absl::Status status) { - switch (status.code()) { - case absl::StatusCode::kOk: - return FastPairHttpError::kSuccess; - case absl::StatusCode::kInvalidArgument: - return FastPairHttpError::kHttpErrorInvalidArgument; - case absl::StatusCode::kUnauthenticated: - return FastPairHttpError::kHttpErrorUnauthenticated; - case absl::StatusCode::kPermissionDenied: - return FastPairHttpError::kHttpErrorPermissionDenied; - case absl::StatusCode::kDeadlineExceeded: - return FastPairHttpError::kHttpErrorDeadlineExceeded; - case absl::StatusCode::kUnavailable: - return FastPairHttpError::kHttpErrorUnavailable; - case absl::StatusCode::kUnknown: - return FastPairHttpError::kHttpErrorUnknown; - case absl::StatusCode::kInternal: - return FastPairHttpError::kHttpErrorInternal; - case absl::StatusCode::kCancelled: - case absl::StatusCode::kUnimplemented: - case absl::StatusCode::kOutOfRange: - case absl::StatusCode::kAborted: - case absl::StatusCode::kNotFound: - return FastPairHttpError::kHttpErrorOtherFailure; - default: - break; - } - return FastPairHttpError::kHttpErrorUnknown; -} - -FastPairHttpStatus::FastPairHttpStatus(const absl::Status& absl_status) - : absl_status_(absl_status) { - if (absl_status_.ok()) { - status_ = Status::kSuccess; - } else { - if (absl_status_.code() == absl::StatusCode::kFailedPrecondition) { - status_ = Status::kNetworkFailure; - } else { - status_ = Status::kHttpFailure; - } - } -} - -FastPairHttpStatus::FastPairHttpStatus(const FastPairHttpStatus& status) = - default; - -FastPairHttpStatus::~FastPairHttpStatus() = default; - -bool FastPairHttpStatus::IsSuccess() const { - return status_ == Status::kSuccess; -} - -std::string FastPairHttpStatus::ToString() const { - std::string status; - switch (status_) { - case Status::kSuccess: - status = "kSuccess"; - break; - case Status::kNetworkFailure: - status = "kNetworkFailure"; - break; - case Status::kHttpFailure: - status = "kHttpFailure"; - break; - } - - return "status=" + status; -} - -std::ostream& operator<<(std::ostream& stream, const FastPairHttpError& error) { - switch (error) { - case FastPairHttpError::kSuccess: - stream << "[Success]"; - break; - case FastPairHttpError::kTimeout: - stream << "[Timeout]"; - break; - case FastPairHttpError::kUnknown: - stream << "[Unknown]"; - break; - case FastPairHttpError::kAuthenticationError: - stream << "[Authentication]"; - break; - case FastPairHttpError::kHttpErrorUnknown: - stream << "[HTTP Error: Unknown]"; - break; - case FastPairHttpError::kHttpErrorDeadlineExceeded: - stream << "[HTTP Error: Deadline exceeded]"; - break; - case FastPairHttpError::kHttpErrorPermissionDenied: - stream << "[HTTP Error: Permission denied]"; - break; - case FastPairHttpError::kHttpErrorUnavailable: - stream << "[HTTP Error: Unavailable]"; - break; - case FastPairHttpError::kHttpErrorUnauthenticated: - stream << "[HTTP Error: Unauthenticated]"; - break; - case FastPairHttpError::kHttpErrorInvalidArgument: - stream << "[HTTP Error: Invalid argument]"; - break; - case FastPairHttpError::kHttpErrorOffline: - stream << "[HTTP Error: offline]"; - break; - case FastPairHttpError::kHttpErrorInternal: - stream << "[HTTP Error: Internal server error]"; - break; - case FastPairHttpError::kHttpErrorOtherFailure: - stream << "[HTTP Error: Other failure]"; - break; - } - - return stream; -} - -std::ostream& operator<<(std::ostream& stream, - const FastPairHttpStatus& status) { - stream << status.ToString(); - return stream; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/fast_pair_http_result.h b/fastpair/common/fast_pair_http_result.h deleted file mode 100644 index c69b8ed875..0000000000 --- a/fastpair/common/fast_pair_http_result.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_HTTP_RESULT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_HTTP_RESULT_H_ - -#include -#include - -#include "absl/status/status.h" - -namespace nearby { -namespace fastpair { - -enum class FastPairHttpError { - kSuccess, - kTimeout, - kUnknown, - kAuthenticationError, - kHttpErrorUnknown, - kHttpErrorDeadlineExceeded, - kHttpErrorPermissionDenied, - kHttpErrorUnavailable, - kHttpErrorUnauthenticated, - kHttpErrorInvalidArgument, - kHttpErrorOffline, - kHttpErrorInternal, - kHttpErrorOtherFailure -}; - -class FastPairHttpStatus { - public: - explicit FastPairHttpStatus(const absl::Status& absl_status); - FastPairHttpStatus(const FastPairHttpStatus& status); - ~FastPairHttpStatus(); - - bool IsSuccess() const; - std::string ToString() const; - - private: - enum class Status { kSuccess, kNetworkFailure, kHttpFailure } status_; - absl::Status absl_status_; -}; - -FastPairHttpError FastPairHttpErrorForHttpResponseCode(absl::Status status); - -std::ostream& operator<<(std::ostream& stream, const FastPairHttpError& error); -std::ostream& operator<<(std::ostream& stream, - const FastPairHttpStatus& status); - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_HTTP_RESULT_H_ diff --git a/fastpair/common/fast_pair_prefs.cc b/fastpair/common/fast_pair_prefs.cc deleted file mode 100644 index 7278822a22..0000000000 --- a/fastpair/common/fast_pair_prefs.cc +++ /dev/null @@ -1,33 +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. - -#include "fastpair/common/fast_pair_prefs.h" - -namespace nearby { -namespace fastpair { -namespace prefs { -namespace { -using json = ::nlohmann::json; -} - -const char kNearbyFastPairUsersName[] = "nearby_fastpair.users"; - -void RegisterNearbyFastPairPrefs( - preferences::PreferencesManager* preferences_manager) { - preferences_manager->Set(kNearbyFastPairUsersName, json::object()); -} - -} // namespace prefs -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/fast_pair_prefs.h b/fastpair/common/fast_pair_prefs.h deleted file mode 100644 index a689b760a6..0000000000 --- a/fastpair/common/fast_pair_prefs.h +++ /dev/null @@ -1,34 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FASTPAIR_PREFS_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FASTPAIR_PREFS_H_ - -#include "absl/base/attributes.h" -#include "internal/preferences/preferences_manager.h" - -namespace nearby { -namespace fastpair { -namespace prefs { - -ABSL_CONST_INIT extern const char kNearbyFastPairUsersName[]; - -void RegisterNearbyFastPairPrefs( - preferences::PreferencesManager* preferences_manager); - -} // namespace prefs -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FASTPAIR_PREFS_H_ diff --git a/fastpair/common/fast_pair_prefs_test.cc b/fastpair/common/fast_pair_prefs_test.cc deleted file mode 100644 index 03f54a98ca..0000000000 --- a/fastpair/common/fast_pair_prefs_test.cc +++ /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. - -#include "fastpair/common/fast_pair_prefs.h" - -#include -#include - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace prefs { -namespace { - -using json = ::nlohmann::json; - -constexpr char kPreferencesFilePath[] = "Google/Nearby/Preferences"; - -TEST(FastPairPreference, RegisterNearbyFastPairPrefs) { - auto preferences_manager = - std::make_unique(kPreferencesFilePath); - RegisterNearbyFastPairPrefs(preferences_manager.get()); - EXPECT_TRUE( - preferences_manager->Get(kNearbyFastPairUsersName, json()).empty()); - - json value = {{"current_user", "abc@gmail.com"}}; - preferences_manager->Set(kNearbyFastPairUsersName, value); - auto result = preferences_manager->Get(kNearbyFastPairUsersName, json()); - ASSERT_FALSE(result.empty()); - auto val = result["current_user"]; - EXPECT_EQ(val.get(), "abc@gmail.com"); -} - -} // namespace -} // namespace prefs -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/fast_pair_switches.cc b/fastpair/common/fast_pair_switches.cc deleted file mode 100644 index 5391958c12..0000000000 --- a/fastpair/common/fast_pair_switches.cc +++ /dev/null @@ -1,45 +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. - -#include "fastpair/common/fast_pair_switches.h" - -#include - -namespace nearby { -namespace fastpair { -namespace switches { - -namespace { - -// Switch value for nearby fast pair global host. -int global_host_size = 0; -char global_host[256]; - -} // namespace - -void SetNearbyFastPairHttpHost(const std::string& host) { - if (host.size() > 256) { - return; - } - global_host_size = host.size(); - memcpy(global_host, host.c_str(), global_host_size); -} - -std::string GetNearbyFastPairHttpHost() { - return std::string(global_host, global_host_size); -} - -} // namespace switches -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/fast_pair_switches.h b/fastpair/common/fast_pair_switches.h deleted file mode 100644 index 1b3a51ca58..0000000000 --- a/fastpair/common/fast_pair_switches.h +++ /dev/null @@ -1,37 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FASTPAIR_SWITCHES_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FASTPAIR_SWITCHES_H_ - -#include - -#include "fastpair/common/fast_pair_switches.h" - -namespace nearby { -namespace fastpair { -namespace switches { - -// All switches in alphabetical order. The switches should be documented -// alongside the definition of their values in the .cc file. - -// Setter and Getter for Nearby Fast Pair http host. -void SetNearbyFastPairHttpHost(const std::string& host); -std::string GetNearbyFastPairHttpHost(); - -} // namespace switches -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FASTPAIR_SWITCHES_H_ diff --git a/fastpair/common/fast_pair_switches_test.cc b/fastpair/common/fast_pair_switches_test.cc deleted file mode 100644 index b085cb2bba..0000000000 --- a/fastpair/common/fast_pair_switches_test.cc +++ /dev/null @@ -1,51 +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. - -#include "fastpair/common/fast_pair_switches.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace switches { -namespace { - -TEST(FastPairSwitches, DefautEmptyHttpHost) { - EXPECT_THAT(GetNearbyFastPairHttpHost(), testing::IsEmpty()); -} - -TEST(FastPairSwitches, SetLongSizedHttpHostSkipped) { - std::string s(5000, '*'); - SetNearbyFastPairHttpHost(s); - EXPECT_THAT(GetNearbyFastPairHttpHost(), testing::IsEmpty()); -} - -TEST(FastPairSwitches, SetNonEmptyHttpHost) { - SetNearbyFastPairHttpHost("fakehost.com"); - EXPECT_THAT(GetNearbyFastPairHttpHost(), "fakehost.com"); -} - -TEST(FastPairSwitches, SetEmptyHttpHost) { - SetNearbyFastPairHttpHost(""); - EXPECT_THAT(GetNearbyFastPairHttpHost(), testing::IsEmpty()); -} - -} // namespace -} // namespace switches -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/fast_pair_version.h b/fastpair/common/fast_pair_version.h deleted file mode 100644 index 3bb65aa475..0000000000 --- a/fastpair/common/fast_pair_version.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_VERSION_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_VERSION_H_ - -namespace nearby { -namespace fastpair { - -enum class DeviceFastPairVersion { - kV1, - kHigherThanV1, -}; - -} -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_FAST_PAIR_VERSION_H_ diff --git a/fastpair/common/non_discoverable_advertisement.h b/fastpair/common/non_discoverable_advertisement.h deleted file mode 100644 index a03fc4215c..0000000000 --- a/fastpair/common/non_discoverable_advertisement.h +++ /dev/null @@ -1,59 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_NON_DISCOVERABLE_ADVERTISEMENT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_NON_DISCOVERABLE_ADVERTISEMENT_H_ - -#include -#include -#include -#include - -#include "fastpair/common/battery_notification.h" - -namespace nearby { -namespace fastpair { - -// Fast Pair 'Not Discoverable' advertisement. See -// https://developers.google.com/nearby/fast-pair/specifications/service/provider#AdvertisingWhenNotDiscoverable -struct NonDiscoverableAdvertisement { - // Represents showing UI indication - enum class Type { - kShowUi = 0, /* Show UI indication: 0b0000*/ - kNone = 1, - kHideUi = 2, /* Hide UI indication: 0b0010*/ - }; - - NonDiscoverableAdvertisement() = default; - NonDiscoverableAdvertisement( - std::vector account_key_filter, Type type, - std::vector salt, - std::optional battery_notification) - : account_key_filter(std::move(account_key_filter)), - type(type), - salt(std::move(salt)), - battery_notification(std::move(battery_notification)) {} - - ~NonDiscoverableAdvertisement() = default; - - std::vector account_key_filter; - Type type = Type::kNone; - std::vector salt; - std::optional battery_notification; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_NON_DISCOVERABLE_ADVERTISEMENT_H_ diff --git a/fastpair/common/pair_failure.cc b/fastpair/common/pair_failure.cc deleted file mode 100644 index eade856321..0000000000 --- a/fastpair/common/pair_failure.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/common/pair_failure.h" - -#include - -namespace nearby { -namespace fastpair { - -std::ostream& operator<<(std::ostream& stream, PairFailure failure) { - switch (failure) { - case PairFailure::kUnknown: - stream << "[Failed with unknown reason]"; - break; - case PairFailure::kCreateGattConnection: - stream << "[Failed to create a GATT connection to the device]"; - break; - case PairFailure::kGattServiceDiscovery: - stream << "[Failed to find the expected GATT service]"; - break; - case PairFailure::kGattServiceDiscoveryTimeout: - stream << "[Timed out while starting discovery of GATT service]"; - break; - case PairFailure::kDataEncryptorRetrieval: - stream << "[Failed to retrieve the data encryptor]"; - break; - case PairFailure::kKeyBasedPairingCharacteristicDiscovery: - stream << "[Failed to find the Key-based pairing GATT characteristic]"; - break; - case PairFailure::kPasskeyCharacteristicDiscovery: - stream << "[Failed to find the Passkey GATT characteristic]"; - break; - case PairFailure::kAccountKeyCharacteristicDiscovery: - stream << "[Failed to find the Account Key GATT characteristic]"; - break; - case PairFailure::kKeyBasedPairingCharacteristicSubscription: - stream << "[Failed to start a subscription on the Key-based pairing " - "GATT characteristic]"; - break; - case PairFailure::kPasskeyCharacteristicSubscription: - stream << "[Failed to start a subscription on the Passkey GATT " - "characteristic]"; - break; - case PairFailure::kKeyBasedPairingCharacteristicSubscriptionTimeout: - stream << "[Timed out while starting a subscription on the Key-based " - "pairing GATT characteristic]"; - break; - case PairFailure::kPasskeyCharacteristicSubscriptionTimeout: - stream << "[Timed out while starting a subscription on the Passkey " - "GATT characteristic]"; - break; - case PairFailure::kKeyBasedPairingCharacteristicWrite: - stream - << "[Failed to write to the Key-based pairing GATT characteristic]"; - break; - case PairFailure::kPasskeyPairingCharacteristicWrite: - stream << "[Failed to write to the Passkey GATT characteristic]"; - break; - case PairFailure::kAccountKeyCharacteristicWrite: - stream << "[Failed to write to the Account Key GATT characteristic]"; - break; - case PairFailure::kKeyBasedPairingResponseTimeout: - stream << "[Timed out while waiting for the Key-based Pairing response]"; - break; - case PairFailure::kPasskeyResponseTimeout: - stream << "[Timed out while waiting for the Passkey response]"; - break; - case PairFailure::kKeybasedPairingResponseDecryptFailure: - stream << "[Failed to decrypt Key-based Pairing response]"; - break; - case PairFailure::kIncorrectKeyBasedPairingResponseType: - stream << "[Incorrect Key-based response message type]"; - break; - case PairFailure::kPasskeyDecryptFailure: - stream << "[Failed to decrypt Passkey response]"; - break; - case PairFailure::kIncorrectPasskeyResponseType: - stream << "[Incorrect Passkey response message type]"; - break; - case PairFailure::kPasskeyMismatch: - stream << "[Passkeys did not match]"; - break; - case PairFailure::kPairingDeviceLostBetweenGattConnectionAttempts: - stream - << "[Potential pairing device lost between GATT connection attempts]"; - break; - case PairFailure::kDeviceLostMidPairing: - stream << "[Potential pairing device lost during pairing.]"; - break; - case PairFailure::kPairingAndConnect: - stream << "[Failed to pair with discovered device.]"; - break; - case PairFailure::kPairingTimeout: - stream << "[Potential pairing failed with timeout.]"; - break; - case PairFailure::kWriteAccountKeyToFootprints: - stream << "[Failed to write Account Key to Footprints.]"; - break; - } - - return stream; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/pair_failure.h b/fastpair/common/pair_failure.h deleted file mode 100644 index c4d7100921..0000000000 --- a/fastpair/common/pair_failure.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_PAIR_FAILURE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_PAIR_FAILURE_H_ - -#include - -namespace nearby { -namespace fastpair { - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class PairFailure { - kUnknown = 0, - // Failed to create a GATT connection to the device. - kCreateGattConnection = 1, - // Failed to find the expected GATT service. - kGattServiceDiscovery = 2, - // Timed out while starting discovery of GATT service. - kGattServiceDiscoveryTimeout = 3, - // Failed to retrieve the data encryptor. - kDataEncryptorRetrieval = 4, - // Failed to find the Key-based pairing GATT characteristic. - kKeyBasedPairingCharacteristicDiscovery = 5, - // Failed to find the Passkey GATT characteristic. - kPasskeyCharacteristicDiscovery = 6, - // Failed to find the Account Key GATT characteristic. - kAccountKeyCharacteristicDiscovery = 7, - // Failed to subscribe the notification on the Key-based pairing GATT - // characteristic. - kKeyBasedPairingCharacteristicSubscription = 8, - // Failed to start a notify session on the Passkey GATT characteristic. - kPasskeyCharacteristicSubscription = 9, - // Timed out while waiting to start a notify session on the Key-based pairing - // GATT characteristic. - kKeyBasedPairingCharacteristicSubscriptionTimeout = 10, - // / Timed out while waiting to start a notify session on the Passkey GATT - // characteristic. - kPasskeyCharacteristicSubscriptionTimeout = 11, - // Failed to write to the Key-based pairing GATT characteristic. - kKeyBasedPairingCharacteristicWrite = 12, - // Failed to write to the Passkey GATT characteristic. - kPasskeyPairingCharacteristicWrite = 13, - // Failed to write to the AccountKey GATT characteristic. - kAccountKeyCharacteristicWrite = 14, - // Timed out while waiting for the Key-based Pairing response. - kKeyBasedPairingResponseTimeout = 15, - // Timed out while waiting for the Passkey response. - kPasskeyResponseTimeout = 16, - // Failed to decrypt Key-based response message. - kKeybasedPairingResponseDecryptFailure = 17, - // Incorrect Key-based response message type. - kIncorrectKeyBasedPairingResponseType = 18, - // Failed to decrypt Passkey response message. - kPasskeyDecryptFailure = 19, - // Incorrect Passkey response message type. - kIncorrectPasskeyResponseType = 20, - // Passkeys did not match. - kPasskeyMismatch = 21, - // Potential pairing device lost between GATT connection attempts. - kPairingDeviceLostBetweenGattConnectionAttempts = 22, - // Potential pairing device lost during pairing. - kDeviceLostMidPairing = 23, - // Failed to pair and connect with discovered device. - kPairingAndConnect = 24, - // Potential pairing timeout. - kPairingTimeout = 25, - kWriteAccountKeyToFootprints = 26, - kMaxValue = kWriteAccountKeyToFootprints, -}; - -std::ostream& operator<<(std::ostream& stream, PairFailure failure); - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_PAIR_FAILURE_H_ diff --git a/fastpair/common/pair_failure_test.cc b/fastpair/common/pair_failure_test.cc deleted file mode 100644 index 01cc6ff933..0000000000 --- a/fastpair/common/pair_failure_test.cc +++ /dev/null @@ -1,71 +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. - -#include "fastpair/common/pair_failure.h" - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(PairFailureTest, PairFailureValue) { - EXPECT_EQ(static_cast(PairFailure::kUnknown), 0); - EXPECT_EQ(static_cast(PairFailure::kCreateGattConnection), 1); - EXPECT_EQ(static_cast(PairFailure::kGattServiceDiscovery), 2); - EXPECT_EQ(static_cast(PairFailure::kGattServiceDiscoveryTimeout), 3); - EXPECT_EQ(static_cast(PairFailure::kDataEncryptorRetrieval), 4); - EXPECT_EQ( - static_cast(PairFailure::kKeyBasedPairingCharacteristicDiscovery), - 5); - EXPECT_EQ(static_cast(PairFailure::kPasskeyCharacteristicDiscovery), 6); - EXPECT_EQ(static_cast(PairFailure::kAccountKeyCharacteristicDiscovery), - 7); - EXPECT_EQ( - static_cast(PairFailure::kKeyBasedPairingCharacteristicSubscription), - 8); - EXPECT_EQ(static_cast(PairFailure::kPasskeyCharacteristicSubscription), - 9); - EXPECT_EQ(static_cast( - PairFailure::kKeyBasedPairingCharacteristicSubscriptionTimeout), - 10); - EXPECT_EQ( - static_cast(PairFailure::kPasskeyCharacteristicSubscriptionTimeout), - 11); - EXPECT_EQ(static_cast(PairFailure::kKeyBasedPairingCharacteristicWrite), - 12); - EXPECT_EQ(static_cast(PairFailure::kPasskeyPairingCharacteristicWrite), - 13); - EXPECT_EQ(static_cast(PairFailure::kAccountKeyCharacteristicWrite), 14); - EXPECT_EQ(static_cast(PairFailure::kKeyBasedPairingResponseTimeout), 15); - EXPECT_EQ(static_cast(PairFailure::kPasskeyResponseTimeout), 16); - EXPECT_EQ( - static_cast(PairFailure::kKeybasedPairingResponseDecryptFailure), - 17); - EXPECT_EQ( - static_cast(PairFailure::kIncorrectKeyBasedPairingResponseType), 18); - EXPECT_EQ(static_cast(PairFailure::kPasskeyDecryptFailure), 19); - EXPECT_EQ(static_cast(PairFailure::kIncorrectPasskeyResponseType), 20); - EXPECT_EQ(static_cast(PairFailure::kPasskeyMismatch), 21); - EXPECT_EQ(static_cast( - PairFailure::kPairingDeviceLostBetweenGattConnectionAttempts), - 22); - EXPECT_EQ(static_cast(PairFailure::kDeviceLostMidPairing), 23); - EXPECT_EQ(static_cast(PairFailure::kPairingAndConnect), 24); - EXPECT_EQ(static_cast(PairFailure::kPairingTimeout), 25); - EXPECT_EQ(static_cast(PairFailure::kWriteAccountKeyToFootprints), 26); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/protocol.cc b/fastpair/common/protocol.cc deleted file mode 100644 index 90a165aa7a..0000000000 --- a/fastpair/common/protocol.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/common/protocol.h" - -#include - -namespace nearby { -namespace fastpair { - -std::ostream& operator<<(std::ostream& stream, Protocol protocol) { - switch (protocol) { - case Protocol::kFastPairInitialPairing: - stream << "[Fast Pair Initial Pairing]"; - break; - case Protocol::kFastPairRetroactivePairing: - stream << "[Fast Pair Retroactive Pairing]"; - break; - case Protocol::kFastPairSubsequentPairing: - stream << "[Fast Pair Subsequent Pairing]"; - break; - } - - return stream; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/common/protocol.h b/fastpair/common/protocol.h deleted file mode 100644 index ae0724e6db..0000000000 --- a/fastpair/common/protocol.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_PROTOCOL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_PROTOCOL_H_ - -#include - -namespace nearby { -namespace fastpair { - -// Pairing scenarios -enum class Protocol { - // Google Fast Pair - kFastPairInitialPairing = 0, - kFastPairRetroactivePairing = 1, - kFastPairSubsequentPairing = 2, -}; - -std::ostream& operator<<(std::ostream& stream, Protocol protocol); - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_PROTOCOL_H_ diff --git a/fastpair/crypto/BUILD b/fastpair/crypto/BUILD deleted file mode 100644 index ffa91bf518..0000000000 --- a/fastpair/crypto/BUILD +++ /dev/null @@ -1,134 +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. - -cc_library( - name = "crypto", - srcs = [ - "fast_pair_decryption.cc", - "fast_pair_encryption.cc", - "fast_pair_message_type.cc", - ], - hdrs = [ - "decrypted_passkey.h", - "decrypted_response.h", - "fast_pair_decryption.h", - "fast_pair_encryption.h", - "fast_pair_key_pair.h", - "fast_pair_message_type.h", - ], - visibility = [ - "//:__subpackages__", - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//internal/base:bluetooth_address", - "//internal/platform:base", - "//internal/platform:types", - "@boringssl//:crypto", - "@com_google_absl//absl/log:check", - ], -) - -cc_test( - name = "decrypted_passkey_test", - size = "small", - srcs = [ - "decrypted_passkey_test.cc", - ], - shard_count = 1, - deps = [ - ":crypto", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "decrypted_response_test", - size = "small", - srcs = [ - "decrypted_response_test.cc", - ], - shard_count = 1, - deps = [ - ":crypto", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_key_pair_test", - size = "small", - srcs = [ - "fast_pair_key_pair_test.cc", - ], - shard_count = 1, - deps = [ - ":crypto", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_encryption_test", - size = "small", - srcs = [ - "fast_pair_encryption_test.cc", - ], - shard_count = 1, - deps = [ - ":crypto", - "//fastpair/common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_decryption_test", - size = "small", - srcs = [ - "fast_pair_decryption_test.cc", - ], - shard_count = 1, - deps = [ - ":crypto", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_message_type_test", - size = "small", - srcs = [ - "fast_pair_message_type_test.cc", - ], - shard_count = 1, - deps = [ - ":crypto", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/crypto/decrypted_passkey.h b/fastpair/crypto/decrypted_passkey.h deleted file mode 100644 index 166270bc8a..0000000000 --- a/fastpair/crypto/decrypted_passkey.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_DECRYPTED_PASSKEY_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_DECRYPTED_PASSKEY_H_ - -#include -#include - -#include - -#include "fastpair/common/constant.h" -#include "fastpair/crypto/fast_pair_message_type.h" - -namespace nearby { -namespace fastpair { - -// Thin structure which is used by the higher level components of the Fast Pair -// system to represent a decrypted account passkey. -struct DecryptedPasskey { - DecryptedPasskey( - FastPairMessageType message_type, uint32_t passkey, - const std::array& salt) - : message_type(message_type), passkey(passkey), salt(salt) {} - - FastPairMessageType message_type; - uint32_t passkey; - std::array salt; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_DECRYPTED_PASSKEY_H_ diff --git a/fastpair/crypto/decrypted_passkey_test.cc b/fastpair/crypto/decrypted_passkey_test.cc deleted file mode 100644 index df6c98db9d..0000000000 --- a/fastpair/crypto/decrypted_passkey_test.cc +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/crypto/decrypted_passkey.h" - -#include - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(DecryptedPasskeyTest, CreateDecryptedPasskey) { - // Message type - FastPairMessageType messgaeType = FastPairMessageType::kSeekersPasskey; - // Passkey bytes. - std::array passkey_bytes = {0x02, 0x03, 0x04}; - uint32_t passkey = passkey_bytes[2]; - passkey += passkey_bytes[1] << 8; - passkey += passkey_bytes[0] << 16; - - // Random salt - std::array salt = {0x08, 0x09, 0x0A, 0x08, 0x09, 0x0E, - 0x0A, 0x0C, 0x0D, 0x0E, 0x05, 0x02}; - - DecryptedPasskey decryptedPasskey(messgaeType, passkey, salt); - EXPECT_EQ(decryptedPasskey.message_type, messgaeType); - EXPECT_EQ(decryptedPasskey.passkey, passkey); - EXPECT_EQ(decryptedPasskey.salt, salt); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/crypto/decrypted_response.h b/fastpair/crypto/decrypted_response.h deleted file mode 100644 index eef4bacca4..0000000000 --- a/fastpair/crypto/decrypted_response.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_DECRYPTED_RESPONSE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_DECRYPTED_RESPONSE_H_ - -#include -#include - -#include - -#include "fastpair/common/constant.h" -#include "fastpair/crypto/fast_pair_message_type.h" - -namespace nearby { -namespace fastpair { - -// Thin structure which is used by the higher level components of the Fast Pair -// system to represent a decrypted response. -struct DecryptedResponse { - DecryptedResponse( - FastPairMessageType message_type, - const std::array& - address_bytes, - const std::array& salt) - : message_type(message_type), address_bytes(address_bytes), salt(salt) {} - - FastPairMessageType message_type; - std::array address_bytes; - std::array salt; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_DECRYPTED_RESPONSE_H_ diff --git a/fastpair/crypto/decrypted_response_test.cc b/fastpair/crypto/decrypted_response_test.cc deleted file mode 100644 index d0a9f66167..0000000000 --- a/fastpair/crypto/decrypted_response_test.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/crypto/decrypted_response.h" - -#include - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(DecryptedResponseTest, CreateDecryptedResponse) { - constexpr std::array address_bytes = {0x02, 0x03, 0x04, - 0x05, 0x06, 0x07}; - - constexpr std::array salt = {0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x00}; - - DecryptedResponse decryptedResponse( - FastPairMessageType::kKeyBasedPairingResponse, address_bytes, salt); - EXPECT_EQ(decryptedResponse.message_type, - FastPairMessageType::kKeyBasedPairingResponse); - EXPECT_EQ(decryptedResponse.address_bytes, address_bytes); - EXPECT_EQ(decryptedResponse.salt, salt); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/crypto/fast_pair_decryption.cc b/fastpair/crypto/fast_pair_decryption.cc deleted file mode 100644 index f16a3df95d..0000000000 --- a/fastpair/crypto/fast_pair_decryption.cc +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/crypto/fast_pair_decryption.h" - -#include -#include -#include - -#ifdef NEARBY_CHROMIUM -#include "base/check.h" -#elif defined(NEARBY_SWIFTPM) -#include "internal/platform/logging.h" -#else -#include "absl/log/check.h" // nogncheck -#endif - -#include "fastpair/common/constant.h" -#include "fastpair/crypto/decrypted_passkey.h" -#include "fastpair/crypto/decrypted_response.h" -#include - -namespace nearby { -namespace fastpair { -namespace { -std::array DecryptBytes( - const std::array& aes_key_bytes, - const std::array& encrypted_bytes) { - AES_KEY aes_key; - int aes_key_was_set = AES_set_decrypt_key(aes_key_bytes.data(), - aes_key_bytes.size() * 8, &aes_key); - CHECK(aes_key_was_set == 0) << "Invalid AES key size."; - std::array decrypted_bytes; - // Encrypted_bytes is less than 16 bytes and can be guaranteed to be a - // single block, so we encrypt/decrypt it using AES ECB mode (Approved by: - // b/73360609) - AES_decrypt(encrypted_bytes.data(), decrypted_bytes.data(), &aes_key); - return decrypted_bytes; -} -} // namespace - -// Decrypts the encrypted response -// (https://developers.google.com/nearby/fast-pair/specifications/characteristics#table1.4) -// and returns the parsed decrypted response -// (https://developers.google.com/nearby/fast-pair/specifications/characteristics#table1.3) -std::optional FastPairDecryption::ParseDecryptResponse( - const std::array& aes_key_bytes, - const std::array& encrypted_response_bytes) { - std::array decrypted_response_bytes = - DecryptBytes(aes_key_bytes, encrypted_response_bytes); - - uint8_t message_type = decrypted_response_bytes[kMessageTypeIndex]; - - // If the message type index is not the expected fast pair message type, then - // this is not a valid fast pair response. - if (message_type != kKeybasedPairingResponseType) { - return std::nullopt; - } - - std::array address_bytes; - std::copy(decrypted_response_bytes.begin() + kResponseAddressStartIndex, - decrypted_response_bytes.begin() + kResponseSaltStartIndex, - address_bytes.begin()); - - std::array salt; - std::copy(decrypted_response_bytes.begin() + kResponseSaltStartIndex, - decrypted_response_bytes.end(), salt.begin()); - return DecryptedResponse(FastPairMessageType::kKeyBasedPairingResponse, - address_bytes, salt); -} - -// Decrypts the encrypted passkey -// (https://developers.google.com/nearby/fast-pair/specifications/characteristics#table2.1) -// and returns the parsed decrypted passkey -// (https://developers.google.com/nearby/fast-pair/specifications/characteristics#table2.2) -// TODO(b/263400788) Add unit test to cover this function and fix all Mutants -// warning -std::optional FastPairDecryption::ParseDecryptPasskey( - const std::array& aes_key_bytes, - const std::array& encrypted_passkey_bytes) { - std::array decrypted_passkey_bytes = - DecryptBytes(aes_key_bytes, encrypted_passkey_bytes); - - FastPairMessageType message_type; - if (decrypted_passkey_bytes[kMessageTypeIndex] == kSeekerPasskeyType) { - message_type = FastPairMessageType::kSeekersPasskey; - } else if (decrypted_passkey_bytes[kMessageTypeIndex] == - kProviderPasskeyType) { - message_type = FastPairMessageType::kProvidersPasskey; - } else { - return std::nullopt; - } - - uint32_t passkey = decrypted_passkey_bytes[3]; - passkey += decrypted_passkey_bytes[2] << 8; - passkey += decrypted_passkey_bytes[1] << 16; - - std::array salt; - std::copy(decrypted_passkey_bytes.begin() + kPasskeySaltStartIndex, - decrypted_passkey_bytes.end(), salt.begin()); - return DecryptedPasskey(message_type, passkey, salt); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/crypto/fast_pair_decryption.h b/fastpair/crypto/fast_pair_decryption.h deleted file mode 100644 index b6cabe4be9..0000000000 --- a/fastpair/crypto/fast_pair_decryption.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_DECRYPTION_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_DECRYPTION_H_ - -#include -#include -#include - -#include "fastpair/crypto/decrypted_passkey.h" -#include "fastpair/crypto/decrypted_response.h" - -namespace nearby { -namespace fastpair { -/** Utilities used for encrypting and decrypting Fast Pair packets. */ -class FastPairDecryption { - public: - static constexpr int kAesBlockByteSize = 16; - - static std::optional ParseDecryptResponse( - const std::array& aes_key_bytes, - const std::array& encrypted_response_bytes); - - static std::optional ParseDecryptPasskey( - const std::array& aes_key_bytes, - const std::array& encrypted_passkey_bytes); -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_DECRYPTION_H_ diff --git a/fastpair/crypto/fast_pair_decryption_test.cc b/fastpair/crypto/fast_pair_decryption_test.cc deleted file mode 100644 index 234c6d262f..0000000000 --- a/fastpair/crypto/fast_pair_decryption_test.cc +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/crypto/fast_pair_decryption.h" - -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "fastpair/crypto/fast_pair_encryption.h" - -namespace nearby { -namespace fastpair { -namespace { - -// All test data comes from -// https://developers.google.com/nearby/fast-pair/specifications/appendix/testcases#test_cases - -constexpr std::array aes_key_bytes = { - 0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, 0xF7, 0xB6, - 0xCF, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D}; - -TEST(FastPairDecryptionTest, ParseDecryptResponseSuccess) { - std::vector response_bytes; - - // Message type. - response_bytes.push_back(0x01); - - // Address bytes. - std::array address_bytes = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; - std::copy(address_bytes.begin(), address_bytes.end(), - std::back_inserter(response_bytes)); - - // Random salt - std::array salt = {0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x00}; - std::copy(salt.begin(), salt.end(), std::back_inserter(response_bytes)); - - std::array response_bytes_array; - std::copy_n(response_bytes.begin(), kAesBlockByteSize, - response_bytes_array.begin()); - - auto encrypted_bytes = - FastPairEncryption::EncryptBytes(aes_key_bytes, response_bytes_array); - auto response = - FastPairDecryption::ParseDecryptResponse(aes_key_bytes, encrypted_bytes); - - EXPECT_TRUE(response.has_value()); - EXPECT_EQ(response->message_type, - FastPairMessageType::kKeyBasedPairingResponse); - EXPECT_EQ(response->address_bytes, address_bytes); - EXPECT_EQ(response->salt, salt); -} - -TEST(FastPairDecryptionTest, ParseDecryptResponseFailure) { - constexpr std::array response_bytes = { - /*message_type=*/0x02, - /*address_bytes=*/0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - /*salt=*/0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F, - 0x00}; - - auto encrypted_bytes = - FastPairEncryption::EncryptBytes(aes_key_bytes, response_bytes); - auto response = - FastPairDecryption::ParseDecryptResponse(aes_key_bytes, encrypted_bytes); - - EXPECT_FALSE(response.has_value()); -} - -TEST(FastPairDecryptionTest, ParseDecryptPasskeySuccess) { - std::vector passkey_bytes; - - // Message type. - passkey_bytes.push_back(0x02); - - // Passkey bytes. - uint32_t passkey = 5; - passkey_bytes.push_back(passkey >> 16); - passkey_bytes.push_back(passkey >> 8); - passkey_bytes.push_back(passkey); - - // Random salt - std::array salt = {0x08, 0x09, 0x0A, 0x08, 0x09, 0x0E, - 0x0A, 0x0C, 0x0D, 0x0E, 0x05, 0x02}; - std::copy(salt.begin(), salt.end(), std::back_inserter(passkey_bytes)); - - std::array passkey_bytes_array; - std::copy_n(passkey_bytes.begin(), kAesBlockByteSize, - passkey_bytes_array.begin()); - - auto encrypted_bytes = - FastPairEncryption::EncryptBytes(aes_key_bytes, passkey_bytes_array); - auto decrypted_passkey = - FastPairDecryption::ParseDecryptPasskey(aes_key_bytes, encrypted_bytes); - - EXPECT_TRUE(decrypted_passkey.has_value()); - EXPECT_EQ(decrypted_passkey->message_type, - FastPairMessageType::kSeekersPasskey); - EXPECT_EQ(decrypted_passkey->passkey, passkey); - EXPECT_EQ(decrypted_passkey->salt, salt); -} - -TEST(FastPairDecryptionTest, ParseDecryptPasskeyFailure) { - constexpr std::array passkey_bytes = { - /*message_type=*/0x04, - /*passkey=*/0x02, - 0x03, - 0x04, - /*salt=*/0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F, - 0x0E}; - - auto encrypted_bytes = - FastPairEncryption::EncryptBytes(aes_key_bytes, passkey_bytes); - auto passkey = - FastPairDecryption::ParseDecryptPasskey(aes_key_bytes, encrypted_bytes); - - EXPECT_FALSE(passkey.has_value()); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/crypto/fast_pair_encryption.cc b/fastpair/crypto/fast_pair_encryption.cc deleted file mode 100644 index dd781f7236..0000000000 --- a/fastpair/crypto/fast_pair_encryption.cc +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/crypto/fast_pair_encryption.h" - -#include -#include -#include -#include -#include -#include - -#ifdef NEARBY_CHROMIUM -#include "base/check.h" -#elif defined(NEARBY_SWIFTPM) -#include "internal/platform/logging.h" -#else -#include "absl/log/check.h" // nogncheck -#endif - -#include "fastpair/common/constant.h" -#include "fastpair/crypto/fast_pair_key_pair.h" -#include "fastpair/crypto/fast_pair_message_type.h" -#include "internal/platform/logging.h" -#include -#include -#include -#include -#include -#include -#include - -namespace nearby { -namespace fastpair { - -namespace { - -// Converts the public anti-spoofing key into an EC_Point. -bssl::UniquePtr GetEcPointFromPublicAntiSpoofingKey( - const bssl::UniquePtr& ec_group, - std::string_view decoded_public_anti_spoofing) { - std::array buffer; - buffer[0] = POINT_CONVERSION_UNCOMPRESSED; - std::copy(decoded_public_anti_spoofing.begin(), - decoded_public_anti_spoofing.end(), buffer.begin() + 1); - - bssl::UniquePtr new_ec_point(EC_POINT_new(ec_group.get())); - - if (!EC_POINT_oct2point(ec_group.get(), new_ec_point.get(), buffer.data(), - buffer.size(), nullptr)) { - return nullptr; - } - - return new_ec_point; -} - -// Key derivation function to be used in hashing the generated secret key. -void* KDF(const void* in, size_t inlen, void* out, size_t* outlen) { - // Set this to 16 since that's the amount of bytes we want to use - // for the key, even though more will be written by SHA256 below. - *outlen = kSharedSecretKeyByteSize; - return SHA256(static_cast(in), inlen, - static_cast(out)); -} -} // namespace - -// TODO(b/263400788) Add unit test to cover this function and fix all Mutants -// warning -std::optional FastPairEncryption::GenerateKeysWithEcdhKeyAgreement( - std::string_view decoded_public_anti_spoofing) { - if (decoded_public_anti_spoofing.size() != kPublicKeyByteSize) { - NEARBY_LOGS(INFO) << "Expected " << kPublicKeyByteSize - << " byte value for anti-spoofing key. Got:" - << decoded_public_anti_spoofing.size(); - return std::nullopt; - } - - // Generate the secp256r1 key-pair. - bssl::UniquePtr ec_group( - EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); - bssl::UniquePtr ec_key( - EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); - - if (!EC_KEY_generate_key(ec_key.get())) { - NEARBY_LOGS(INFO) << __func__ << ": Failed to generate ec key"; - return std::nullopt; - } - - // The ultimate goal here is to get a 64-byte public key. We accomplish this - // by converting the generated public key into the uncompressed X9.62 format, - // which is 0x04 followed by padded x and y coordinates. - std::array uncompressed_private_key; - int point_bytes_written = EC_POINT_point2oct( - ec_group.get(), EC_KEY_get0_public_key(ec_key.get()), - POINT_CONVERSION_UNCOMPRESSED, uncompressed_private_key.data(), - uncompressed_private_key.size(), nullptr); - - if (point_bytes_written != uncompressed_private_key.size()) { - NEARBY_LOGS(INFO) << __func__ - << ": EC_POINT_point2oct failed to convert public key " - "to uncompressed x9.62 format."; - return std::nullopt; - } - - bssl::UniquePtr public_anti_spoofing_point = - GetEcPointFromPublicAntiSpoofingKey(ec_group, - decoded_public_anti_spoofing); - - if (!public_anti_spoofing_point) { - NEARBY_LOGS(INFO) - << __func__ - << ": Failed to convert Public Anti-Spoofing key to EC_POINT"; - return std::nullopt; - } - - uint8_t secret[SHA256_DIGEST_LENGTH]; - int computed_key_size = - ECDH_compute_key(secret, SHA256_DIGEST_LENGTH, - public_anti_spoofing_point.get(), ec_key.get(), &KDF); - - if (computed_key_size != kSharedSecretKeyByteSize) { - NEARBY_LOGS(INFO) << __func__ << ": ECDH_compute_key failed."; - return std::nullopt; - } - - // Take first 16 bytes from secret as the shared secret key. - std::array shared_secret_key; - std::copy(secret, secret + kSharedSecretKeyByteSize, - std::begin(shared_secret_key)); - - // Ignore the first byte since it is 0x04, from the above uncompressed X9 .62 - // format. - std::array public_key; - std::copy(uncompressed_private_key.begin() + 1, - uncompressed_private_key.end(), public_key.begin()); - - return KeyPair(shared_secret_key, public_key); -} - -std::array FastPairEncryption::EncryptBytes( - const std::array& aes_key_bytes, - const std::array& bytes_to_encrypt) { - AES_KEY aes_key; - int aes_key_was_set = AES_set_encrypt_key(aes_key_bytes.data(), - aes_key_bytes.size() * 8, &aes_key); - DCHECK(aes_key_was_set == 0) << "Invalid AES key size."; - std::array encrypted_bytes; - // Bytes_to_encrypt is less than 16 bytes and can be guaranteed to be a - // single block, so we encrypt it using AES ECB mode (Approved by: b/73360609) - AES_encrypt(bytes_to_encrypt.data(), encrypted_bytes.data(), &aes_key); - return encrypted_bytes; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/crypto/fast_pair_encryption.h b/fastpair/crypto/fast_pair_encryption.h deleted file mode 100644 index 8961284a7e..0000000000 --- a/fastpair/crypto/fast_pair_encryption.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_ENCRYPTION_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_ENCRYPTION_H_ - -#include - -#include -#include -#include -#include - -#include "fastpair/common/constant.h" -#include "fastpair/crypto/fast_pair_key_pair.h" - -namespace nearby { -namespace fastpair { - -/** Utilities used for generating Ecdh key agreement and - * encrypting Fast Pair packets. */ -class FastPairEncryption { - public: - static std::optional GenerateKeysWithEcdhKeyAgreement( - std::string_view decoded_public_anti_spoofing); - - static std::array EncryptBytes( - const std::array& aes_key_bytes, - const std::array& bytes_to_encrypt); -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_ENCRYPTION_H_ diff --git a/fastpair/crypto/fast_pair_encryption_test.cc b/fastpair/crypto/fast_pair_encryption_test.cc deleted file mode 100644 index 57222b9b1b..0000000000 --- a/fastpair/crypto/fast_pair_encryption_test.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/crypto/fast_pair_encryption.h" - -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" - -namespace nearby { -namespace fastpair { -namespace { - -// All test data comes from -// https://developers.google.com/nearby/fast-pair/specifications/appendix/testcases#test_cases - -constexpr std::array aes_key_bytes = { - 0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, 0xF7, 0xB6, - 0xCF, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D}; - -std::string DecodeKey(const std::string& encoded_key) { - std::string key; - absl::Base64Unescape(encoded_key, &key); - return key; -} - -class FastPairEncryptionTest : public testing::Test {}; - -TEST(FastPairEncryptionTest, EncryptBytes_Success) { - constexpr std::array input = { - 0xF3, 0x0F, 0x4E, 0x78, 0x6C, 0x59, 0xA7, 0xBB, - 0xF3, 0x87, 0x3B, 0x5A, 0x49, 0xBA, 0x97, 0xEA}; - - constexpr std::array expected = { - 0xAC, 0x9A, 0x16, 0xF0, 0x95, 0x3A, 0x3F, 0x22, - 0x3D, 0xD1, 0x0C, 0xF5, 0x36, 0xE0, 0x9E, 0x9C}; - - EXPECT_EQ(FastPairEncryption::EncryptBytes(aes_key_bytes, input), expected); -} - -TEST(FastPairEncryptionTest, GenerateKeysWithEcdhKeyAgreement_EmptyKey) { - EXPECT_FALSE( - FastPairEncryption::GenerateKeysWithEcdhKeyAgreement("").has_value()); -} - -TEST(FastPairEncryptionTest, GenerateKeysWithEcdhKeyAgreement_ShortKey) { - EXPECT_FALSE(FastPairEncryption::GenerateKeysWithEcdhKeyAgreement("too_short") - .has_value()); -} - -TEST(FastPairEncryptionTest, GenerateKeysWithEcdhKeyAgreement_InvalidKey) { - EXPECT_FALSE( - FastPairEncryption::GenerateKeysWithEcdhKeyAgreement( - DecodeKey("U2PWc3FHTxah/o0YT9n1VRvtm57SNIRSXOEBXm4fdtMo+06tNoFlt8D0/" - "2BsN8auolz5ikwLRvQh+MiQ6oYveg==")) - .has_value()); -} - -TEST(FastPairEncryptionTest, GenerateKeysWithEcdhKeyAgreement_ValidKey) { - EXPECT_TRUE( - FastPairEncryption::GenerateKeysWithEcdhKeyAgreement( - DecodeKey("U2PWc3FHTxah/o0YU9n1VRvtm57SNIRSXOEBXm4fdtMo+06tNoFlt8D0/" - "2BsN8auolz5ikwLRvQh+MiQ6oYveg==")) - .has_value()); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/crypto/fast_pair_key_pair.h b/fastpair/crypto/fast_pair_key_pair.h deleted file mode 100644 index 0ea026fe6d..0000000000 --- a/fastpair/crypto/fast_pair_key_pair.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_KEY_PAIR_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_KEY_PAIR_H_ - -#include -#include - -#include -#include -#include - -#include "fastpair/common/constant.h" - -namespace nearby { -namespace fastpair { - -// Key pair structure to represent public and private keys used for encryption/ -// decryption. -struct KeyPair { - KeyPair( - const std::array& shared_secret_key, - const std::array& public_key) - : shared_secret_key(std::move(shared_secret_key)), - public_key(std::move(public_key)) {} - - const std::array shared_secret_key; - const std::array public_key; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_KEY_PAIR_H_ diff --git a/fastpair/crypto/fast_pair_key_pair_test.cc b/fastpair/crypto/fast_pair_key_pair_test.cc deleted file mode 100644 index 7e76b21076..0000000000 --- a/fastpair/crypto/fast_pair_key_pair_test.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/crypto/fast_pair_key_pair.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { - -// Test data comes from -// https://developers.google.com/nearby/fast-pair/specifications/appendix/testcases#test_cases -TEST(KeyPairTest, CreateKeyPair) { - // Shared secret key bytes. - constexpr std::array - shared_secret_key_bytes = {0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, - 0xF7, 0xB6, 0xCF, 0x5E, 0x3F, 0x45, - 0x61, 0xC3, 0x32, 0x1D}; - - // Public key bytes. - constexpr std::array public_key_bytes = { - 0x04, 0xb9, 0xda, 0x0d, 0x71, 0x60, 0xb3, 0x63, 0x28, 0x22, 0x67, - 0xe7, 0xe0, 0xa3, 0xf8, 0x00, 0x8e, 0x4c, 0x89, 0xed, 0x31, 0x34, - 0xf6, 0xdb, 0xc4, 0xfe, 0x0b, 0x5d, 0xe1, 0x11, 0x39, 0x49, 0xa6, - 0x50, 0xa8, 0xe3, 0x4a, 0xc0, 0x40, 0x88, 0xb8, 0x38, 0x3f, 0x56, - 0xfb, 0x33, 0x8d, 0xd4, 0x64, 0x91, 0xd6, 0x15, 0x77, 0x42, 0x27, - 0xc5, 0xaa, 0x44, 0xff, 0xab, 0x4d, 0xb5, 0x7e, 0x25}; - - KeyPair keyPair(shared_secret_key_bytes, public_key_bytes); - - EXPECT_EQ(keyPair.shared_secret_key, shared_secret_key_bytes); - EXPECT_EQ(keyPair.public_key, public_key_bytes); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/crypto/fast_pair_message_type.cc b/fastpair/crypto/fast_pair_message_type.cc deleted file mode 100644 index 8fd6b932b7..0000000000 --- a/fastpair/crypto/fast_pair_message_type.cc +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/crypto/fast_pair_message_type.h" - -#include - -namespace nearby { -namespace fastpair { - -std::ostream& operator<<(std::ostream& stream, - FastPairMessageType message_type) { - switch (message_type) { - case FastPairMessageType::kKeyBasedPairingRequest: - stream << "[Key-Based Pairing Request]"; - break; - case FastPairMessageType::kKeyBasedPairingResponse: - stream << "[Key-Based Pairing Response]"; - break; - case FastPairMessageType::kSeekersPasskey: - stream << "[Seeker's Passkey]"; - break; - case FastPairMessageType::kProvidersPasskey: - stream << "[Providers' Passkey]"; - break; - default: - stream << "[Unknown]"; - } - - return stream; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/crypto/fast_pair_message_type.h b/fastpair/crypto/fast_pair_message_type.h deleted file mode 100644 index fc0491ef44..0000000000 --- a/fastpair/crypto/fast_pair_message_type.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_MESSAGE_TYPE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_MESSAGE_TYPE_H_ - -#include - -namespace nearby { -namespace fastpair { - -// Type values for Fast Pair messages. -enum class FastPairMessageType { - // Unknown message type. - kUnknown = 0, - // Key-based Pairing Request. - kKeyBasedPairingRequest = 1, - // Key-based Pairing Response. - kKeyBasedPairingResponse = 2, - // Seeker's passkey. - kSeekersPasskey = 3, - // Provider's passkey. - kProvidersPasskey = 4, -}; - -std::ostream& operator<<(std::ostream& stream, - FastPairMessageType message_type); - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_CRYPTO_FAST_PAIR_MESSAGE_TYPE_H_ diff --git a/fastpair/crypto/fast_pair_message_type_test.cc b/fastpair/crypto/fast_pair_message_type_test.cc deleted file mode 100644 index ce99b8ad6b..0000000000 --- a/fastpair/crypto/fast_pair_message_type_test.cc +++ /dev/null @@ -1,32 +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. - -#include "fastpair/crypto/fast_pair_message_type.h" - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(FastPairMessageTypeTest, FastPairMessageTypeValue) { - EXPECT_EQ(static_cast(FastPairMessageType::kUnknown), 0); - EXPECT_EQ(static_cast(FastPairMessageType::kKeyBasedPairingRequest), 1); - EXPECT_EQ(static_cast(FastPairMessageType::kKeyBasedPairingResponse), 2); - EXPECT_EQ(static_cast(FastPairMessageType::kSeekersPasskey), 3); - EXPECT_EQ(static_cast(FastPairMessageType::kProvidersPasskey), 4); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/dataparser/BUILD b/fastpair/dataparser/BUILD deleted file mode 100644 index dea9c0bec3..0000000000 --- a/fastpair/dataparser/BUILD +++ /dev/null @@ -1,93 +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. - -licenses(["notice"]) - -cc_library( - name = "dataparser", - srcs = [ - "fast_pair_data_parser.cc", - ], - hdrs = [ - "fast_pair_data_parser.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":decoder", - "//fastpair/common", - "//fastpair/crypto", - "//internal/base:bluetooth_address", - "//internal/platform:base", - "//internal/platform:types", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - ], -) - -cc_library( - name = "decoder", - srcs = [ - "fast_pair_decoder.cc", - ], - hdrs = [ - "fast_pair_decoder.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "@com_google_absl//absl/strings", - ], -) - -cc_test( - name = "fast_pair_data_parser_test", - size = "small", - srcs = [ - "fast_pair_data_parser_test.cc", - ], - shard_count = 16, - deps = [ - ":dataparser", - "//fastpair/common", - "//fastpair/crypto", - "//fastpair/testing", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@boringssl//:crypto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_decoder_test", - size = "small", - srcs = [ - "fast_pair_decoder_test.cc", - ], - shard_count = 16, - deps = [ - ":decoder", - "//fastpair/testing", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/dataparser/fast_pair_data_parser.cc b/fastpair/dataparser/fast_pair_data_parser.cc deleted file mode 100644 index b6e2c4f2db..0000000000 --- a/fastpair/dataparser/fast_pair_data_parser.cc +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/dataparser/fast_pair_data_parser.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "third_party/nearby//fastpair/crypto/fast_pair_decryption.h" -#include "fastpair/common/battery_notification.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/non_discoverable_advertisement.h" -#include "fastpair/dataparser/fast_pair_decoder.h" -#include "internal/base/bluetooth_address.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr int kHeaderIndex = 0; -constexpr int kFieldTypeBitmask = 0b00001111; -constexpr int kFieldLengthBitmask = 0b11110000; -constexpr int kHeaderLength = 1; -constexpr int kFieldLengthOffset = 4; -constexpr int kFieldTypeAccountKeyFilter = 0; -constexpr int kFieldTypeAccountKeyFilterSalt = 1; -constexpr int kFieldTypeAccountKeyFilterNoNotification = 2; -constexpr int kFieldTypeBattery = 3; -constexpr int kFieldTypeBatteryNoNotification = 4; -constexpr int kAddressByteSize = 6; -constexpr int kMaxLengthOfSaltBytes = 2; - -bool ValidateInputSizes(const std::vector& aes_key_bytes, - const std::vector& encrypted_bytes) { - if (aes_key_bytes.size() != kAesBlockByteSize) { - NEARBY_LOGS(WARNING) << __func__ - << ": AES key should have size = " << kAesBlockByteSize - << ", actual = " << aes_key_bytes.size(); - return false; - } - - if (encrypted_bytes.size() != kEncryptedDataByteSize) { - NEARBY_LOGS(WARNING) << __func__ << ": Encrypted bytes should have size = " - << kEncryptedDataByteSize - << ", actual = " << encrypted_bytes.size(); - return false; - } - - return true; -} - -void ConvertVectorsToArrays( - const std::vector& aes_key_bytes, - const std::vector& encrypted_bytes, - std::array& out_aes_key_bytes, - std::array& out_encrypted_bytes) { - std::copy(aes_key_bytes.begin(), aes_key_bytes.end(), - out_aes_key_bytes.begin()); - std::copy(encrypted_bytes.begin(), encrypted_bytes.end(), - out_encrypted_bytes.begin()); -} - -std::vector CopyFieldBytesToVector( - const std::vector& service_data, - const absl::flat_hash_map>& field_indices, - size_t key) { - std::vector out; - DCHECK(field_indices.contains(key)); - - auto indices = field_indices.find(key)->second; - for (size_t i = indices.first; i < indices.second; i++) { - out.push_back(service_data[i]); - } - return out; -} -} // namespace - -void FastPairDataParser::GetHexModelIdFromServiceData( - const std::vector& service_data, - GetHexModelIdFromServiceDataCallback callback) { - callback(FastPairDecoder::HasModelId(&service_data) - ? FastPairDecoder::GetHexModelIdFromServiceData(&service_data) - : std::nullopt); -} - -void FastPairDataParser::ParseDecryptedResponse( - const std::vector& aes_key_bytes, - const std::vector& encrypted_response_bytes, - ParseDecryptResponseCallback callback) { - if (!ValidateInputSizes(aes_key_bytes, encrypted_response_bytes)) { - callback(std::nullopt); - return; - } - - std::array key; - std::array bytes; - ConvertVectorsToArrays(aes_key_bytes, encrypted_response_bytes, key, bytes); - callback(FastPairDecryption::ParseDecryptResponse(key, bytes)); -} - -void FastPairDataParser::ParseDecryptedPasskey( - const std::vector& aes_key_bytes, - const std::vector& encrypted_passkey_bytes, - ParseDecryptPasskeyCallback callback) { - if (!ValidateInputSizes(aes_key_bytes, encrypted_passkey_bytes)) { - callback(std::nullopt); - return; - } - - std::array key; - std::array bytes; - ConvertVectorsToArrays(aes_key_bytes, encrypted_passkey_bytes, key, bytes); - - callback(FastPairDecryption::ParseDecryptPasskey(key, bytes)); -} - -void FastPairDataParser::ParseNotDiscoverableAdvertisement( - absl::string_view fast_pair_service_data, absl::string_view address, - ParseNotDiscoverableAdvertisementCallback callback) { - std::vector service_data; - std::move(std::begin(fast_pair_service_data), - std::end(fast_pair_service_data), std::back_inserter(service_data)); - if (service_data.empty() || FastPairDecoder::GetVersion(&service_data) != 0) { - NEARBY_LOGS(WARNING) << " Invalid service data."; - callback(std::nullopt); - return; - } - - absl::flat_hash_map> field_indices; - size_t headerIndex = kHeaderIndex + kHeaderLength + - FastPairDecoder::GetIdLength(&service_data); - - while (headerIndex < service_data.size()) { - size_t type = service_data[headerIndex] & kFieldTypeBitmask; - size_t length = - (service_data[headerIndex] & kFieldLengthBitmask) >> kFieldLengthOffset; - size_t index = headerIndex + kHeaderLength; - size_t end = index + length; - - if (end <= service_data.size()) { - field_indices[type] = std::make_pair(index, end); - } - - headerIndex = end; - } - - // Account key filter bytes - std::vector account_key_filter_bytes; - NonDiscoverableAdvertisement::Type show_ui = - NonDiscoverableAdvertisement::Type::kNone; - if (field_indices.contains(kFieldTypeAccountKeyFilter)) { - account_key_filter_bytes = CopyFieldBytesToVector( - service_data, field_indices, kFieldTypeAccountKeyFilter); - show_ui = NonDiscoverableAdvertisement::Type::kShowUi; - } else if (field_indices.contains(kFieldTypeAccountKeyFilterNoNotification)) { - account_key_filter_bytes = CopyFieldBytesToVector( - service_data, field_indices, kFieldTypeAccountKeyFilterNoNotification); - show_ui = NonDiscoverableAdvertisement::Type::kHideUi; - } - - if (account_key_filter_bytes.empty()) { - NEARBY_LOGS(WARNING) << " Service data doesn't contain account key filter."; - callback(std::nullopt); - return; - } - - // Salt bytes - std::vector salt_bytes; - if (field_indices.contains(kFieldTypeAccountKeyFilterSalt)) { - salt_bytes = CopyFieldBytesToVector(service_data, field_indices, - kFieldTypeAccountKeyFilterSalt); - } - - // https://developers.devsite.corp.google.com/nearby/fast-pair/specifications/service/provider#AccountKeyFilter - if (salt_bytes.size() > kMaxLengthOfSaltBytes) { - NEARBY_LOGS(WARNING) << " Parsed a salt field larger than two bytes: " - << salt_bytes.size(); - callback(std::nullopt); - return; - } - - if (salt_bytes.empty()) { - NEARBY_LOGS(INFO) - << __func__ - << ": missing salt field from device. Using device address instead."; - std::array address_bytes; - device::ParseBluetoothAddress( - address, absl::MakeSpan(address_bytes.data(), kAddressByteSize)); - salt_bytes = - std::vector(address_bytes.begin(), address_bytes.end()); - } - - // Battery info bytes - std::vector battery_bytes; - BatteryNotification::Type show_ui_for_battery = - BatteryNotification::Type::kNone; - if (field_indices.contains(kFieldTypeBattery)) { - battery_bytes = - CopyFieldBytesToVector(service_data, field_indices, kFieldTypeBattery); - show_ui_for_battery = BatteryNotification::Type::kShowUi; - } else if (field_indices.contains(kFieldTypeBatteryNoNotification)) { - battery_bytes = CopyFieldBytesToVector(service_data, field_indices, - kFieldTypeBatteryNoNotification); - show_ui_for_battery = BatteryNotification::Type::kHideUi; - } - - callback(NonDiscoverableAdvertisement( - std::move(account_key_filter_bytes), show_ui, std::move(salt_bytes), - BatteryNotification::FromBytes(battery_bytes, show_ui_for_battery))); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/dataparser/fast_pair_data_parser.h b/fastpair/dataparser/fast_pair_data_parser.h deleted file mode 100644 index 95662e9e44..0000000000 --- a/fastpair/dataparser/fast_pair_data_parser.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_DATAPARSER_FAST_PAIR_DATA_PARSER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_DATAPARSER_FAST_PAIR_DATA_PARSER_H_ - -#include -#include - -#include -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/non_discoverable_advertisement.h" -#include "fastpair/crypto/decrypted_passkey.h" -#include "fastpair/crypto/decrypted_response.h" - -namespace nearby { -namespace fastpair { - - - -// This class is responsible for parsing the untrusted bytes for Fast Pair. -class FastPairDataParser { - using GetHexModelIdFromServiceDataCallback = - absl::AnyInvocable)>; - - using ParseDecryptResponseCallback = - absl::AnyInvocable)>; - - using ParseDecryptPasskeyCallback = - absl::AnyInvocable)>; - - using ParseNotDiscoverableAdvertisementCallback = - absl::AnyInvocable)>; - - public: - // Gets the hex string representation of the device's model ID from the - // service data. - static void GetHexModelIdFromServiceData( - const std::vector& fast_pair_service_data, - GetHexModelIdFromServiceDataCallback callback); - - // Decrypts |encrypted_response_bytes| using |aes_key| and returns a parsed - // DecryptedResponse instance if possible. - static void ParseDecryptedResponse( - const std::vector& aes_key_bytes, - const std::vector& encrypted_response_bytes, - ParseDecryptResponseCallback callback); - - // Decrypts |encrypted_passkey_bytes| using |aes_key| and returns a parsed - // DecryptedPasskey instance if possible. - static void ParseDecryptedPasskey( - const std::vector& aes_key_bytes, - const std::vector& encrypted_passkey_bytes, - ParseDecryptPasskeyCallback callback); - - // Parses a 'Non Discoverable' advertisement from |service_data|. - // If the advertisement does not contain information about salt, use the - // |address| as salt instead. - static void ParseNotDiscoverableAdvertisement( - absl::string_view fast_pair_service_data, absl::string_view address, - ParseNotDiscoverableAdvertisementCallback callback); -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_DATAPARSER_FAST_PAIR_DATA_PARSER_H_ diff --git a/fastpair/dataparser/fast_pair_data_parser_test.cc b/fastpair/dataparser/fast_pair_data_parser_test.cc deleted file mode 100644 index 9ebbd34c17..0000000000 --- a/fastpair/dataparser/fast_pair_data_parser_test.cc +++ /dev/null @@ -1,720 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/dataparser/fast_pair_data_parser.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/non_discoverable_advertisement.h" -#include "fastpair/crypto/fast_pair_encryption.h" -#include "fastpair/testing/fast_pair_service_data_creator.h" -#include "internal/platform/count_down_latch.h" - -namespace nearby { -namespace fastpair { -namespace { -// Test data comes from: -// https://developers.google.com/nearby/fast-pair/specifications/appendix/testcases#test_cases - -constexpr absl::string_view kModelId("aabbcc"); -constexpr absl::string_view kInvalidModelId("aabb"); -constexpr absl::string_view kDeviceAddress("11:12:13:14:15:16"); -constexpr absl::string_view kAccountKeyFilter("112233445566"); -constexpr absl::string_view kSalt("01"); -constexpr absl::string_view kBattery("01048F"); -constexpr int kBatteryHeader = 0b00110011; -constexpr std::array kAeskeyarray = { - 0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, 0xF7, 0xB6, - 0xCF, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D}; -constexpr int kNotDiscoverableAdvHeader = 0b00000110; -constexpr int kAccountKeyFilterHeader = 0b01100000; -constexpr int kSaltHeader = 0b00010001; - -TEST(FastPairDataParserTest, GetHexModelIdFromServiceDataUnsucessfully) { - const std::vector service_data = - FastPairServiceDataCreator::Builder() - .SetModelId(kInvalidModelId) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - FastPairDataParser::GetHexModelIdFromServiceData( - service_data, [&](std::optional model_id) { - EXPECT_EQ(model_id, std::nullopt); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, GetHexModelIdFromServiceDataSuccessfully) { - const std::vector service_data = - FastPairServiceDataCreator::Builder() - .SetModelId(kModelId) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - FastPairDataParser::GetHexModelIdFromServiceData( - service_data, [&](std::optional model_id) { - EXPECT_EQ(model_id, kModelId); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, DecryptResponseUnsuccessfullyWithInvalidAesKey) { - const std::vector kAesKeyBytes = {0xA0, 0xBA, 0xF0, 0xBB, 0x95, - 0x1F, 0xF7, 0xB6, 0xCF, 0x5E, - 0x3F, 0x45, 0x61, 0xC3, 0x32}; - - const std::vector kResponseBytes = {/*message_type=*/0x02, - /*address_bytes=*/0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - /*salt=*/0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F, - 0x00}; - - std::array response_bytes_array; - std::copy(kResponseBytes.begin(), kResponseBytes.end(), - response_bytes_array.begin()); - auto encrypted_bytes_array = - FastPairEncryption::EncryptBytes(kAeskeyarray, response_bytes_array); - std::vector encrypted_bytes(encrypted_bytes_array.begin(), - encrypted_bytes_array.end()); - - CountDownLatch latch(1); - FastPairDataParser::ParseDecryptedResponse( - kAesKeyBytes, encrypted_bytes, - [&](std::optional response) { - EXPECT_FALSE(response.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, DecryptResponseUnsuccessfullyWithInvalidResponse) { - const std::vector kAesKeyBytes = {0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, - 0xF7, 0xB6, 0xCF, 0x5E, 0x3F, 0x45, - 0x61, 0xC3, 0x32, 0x1D}; - - const std::vector kResponseBytes = {/*message_type=*/0x02, - /*address_bytes=*/0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - /*salt=*/0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F, - 0x00}; - - std::array response_bytes_array; - std::copy(kResponseBytes.begin(), kResponseBytes.end(), - response_bytes_array.begin()); - auto encrypted_bytes_array = - FastPairEncryption::EncryptBytes(kAeskeyarray, response_bytes_array); - std::vector encrypted_bytes(encrypted_bytes_array.begin(), - encrypted_bytes_array.end() - 1); - - CountDownLatch latch(1); - FastPairDataParser::ParseDecryptedResponse( - kAesKeyBytes, encrypted_bytes, - [&](std::optional response) { - EXPECT_FALSE(response.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, DecryptResponseSuccessfully) { - const std::vector kAesKeyBytes = {0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, - 0xF7, 0xB6, 0xCF, 0x5E, 0x3F, 0x45, - 0x61, 0xC3, 0x32, 0x1D}; - std::vector response_bytes; - - // Message type. - constexpr uint8_t kMessageType = 0x01; - response_bytes.push_back(kMessageType); - - // Address bytes. - constexpr std::array kAddressBytes = {0x02, 0x03, 0x04, - 0x05, 0x06, 0x07}; - std::copy(kAddressBytes.begin(), kAddressBytes.end(), - std::back_inserter(response_bytes)); - - // Random salt - constexpr std::array kSalt = {0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x00}; - std::copy(kSalt.begin(), kSalt.end(), std::back_inserter(response_bytes)); - - std::array response_bytes_array; - std::copy(response_bytes.begin(), response_bytes.end(), - response_bytes_array.begin()); - auto encrypted_bytes_array = - FastPairEncryption::EncryptBytes(kAeskeyarray, response_bytes_array); - std::vector encrypted_bytes(encrypted_bytes_array.begin(), - encrypted_bytes_array.end()); - - CountDownLatch latch(1); - FastPairDataParser::ParseDecryptedResponse( - kAesKeyBytes, encrypted_bytes, - [&](std::optional response) { - ASSERT_TRUE(response.has_value()); - EXPECT_EQ(response.value().message_type, - FastPairMessageType::kKeyBasedPairingResponse); - EXPECT_EQ(response.value().address_bytes, kAddressBytes); - EXPECT_EQ(response.value().salt, kSalt); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, DecryptPasskeyUnsuccessfullyWithInvalidAesKey) { - const std::vector kAesKeyBytes = {0xA0, 0xBA, 0xF0, 0xBB, 0x95, - 0x1F, 0xF7, 0xB6, 0xCF, 0x5E, - 0x3F, 0x45, 0x61, 0xC3, 0x32}; - - const std::vector kPasskeyBytes = {/*message_type=*/0x02, - /*address_bytes=*/0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - /*salt=*/0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F, - 0x00}; - - std::array passkey_bytes_array; - std::copy(kPasskeyBytes.begin(), kPasskeyBytes.end(), - passkey_bytes_array.begin()); - auto encrypted_bytes_array = - FastPairEncryption::EncryptBytes(kAeskeyarray, passkey_bytes_array); - std::vector encrypted_bytes(encrypted_bytes_array.begin(), - encrypted_bytes_array.end()); - - CountDownLatch latch(1); - FastPairDataParser::ParseDecryptedPasskey( - kAesKeyBytes, encrypted_bytes, - [&](std::optional decrypted_passkey) { - EXPECT_FALSE(decrypted_passkey.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, DecryptPasskeyUnsuccessfullyWithInvalidPasskey) { - const std::vector kAesKeyBytes = {0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, - 0xF7, 0xB6, 0xCF, 0x5E, 0x3F, 0x45, - 0x61, 0xC3, 0x32, 0x1D}; - - const std::vector kPasskeyBytes = {/*message_type=*/0x04, - /*passkey=*/0x02, - 0x03, - 0x04, - /*salt=*/0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F}; - - std::array passkey_bytes_array; - std::copy(kPasskeyBytes.begin(), kPasskeyBytes.end(), - passkey_bytes_array.begin()); - auto encrypted_bytes_array = - FastPairEncryption::EncryptBytes(kAeskeyarray, passkey_bytes_array); - std::vector encrypted_bytes(encrypted_bytes_array.begin(), - encrypted_bytes_array.end() - 1); - - CountDownLatch latch(1); - FastPairDataParser::ParseDecryptedPasskey( - kAesKeyBytes, encrypted_bytes, - [&](std::optional decrypted_passkey) { - EXPECT_FALSE(decrypted_passkey.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, DecryptSeekerPasskeySuccessfully) { - const std::vector kAesKeyBytes = {0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, - 0xF7, 0xB6, 0xCF, 0x5E, 0x3F, 0x45, - 0x61, 0xC3, 0x32, 0x1D}; - - std::vector passkey_bytes; - // Message type. - constexpr uint8_t kMessageType = 0x02; - passkey_bytes.push_back(kMessageType); - - // Passkey bytes. - constexpr uint32_t kPasskey = 5; - passkey_bytes.push_back(kPasskey >> 16); - passkey_bytes.push_back(kPasskey >> 8); - passkey_bytes.push_back(kPasskey); - - // Random salt - constexpr std::array kSalt = { - 0x08, 0x09, 0x0A, 0x08, 0x09, 0x0E, 0x0A, 0x0C, 0x0D, 0x0E, 0x05, 0x02}; - std::copy(kSalt.begin(), kSalt.end(), std::back_inserter(passkey_bytes)); - std::array passkey_bytes_array; - std::copy(passkey_bytes.begin(), passkey_bytes.end(), - passkey_bytes_array.begin()); - auto encrypted_bytes_array = - FastPairEncryption::EncryptBytes(kAeskeyarray, passkey_bytes_array); - std::vector encrypted_bytes(encrypted_bytes_array.begin(), - encrypted_bytes_array.end()); - - CountDownLatch latch(1); - FastPairDataParser::ParseDecryptedPasskey( - kAesKeyBytes, encrypted_bytes, - [&](std::optional decrypted_passkey) { - ASSERT_TRUE(decrypted_passkey.has_value()); - EXPECT_EQ(decrypted_passkey.value().message_type, - FastPairMessageType::kSeekersPasskey); - EXPECT_EQ(decrypted_passkey.value().passkey, kPasskey); - EXPECT_EQ(decrypted_passkey.value().salt, kSalt); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, DecryptProviderPasskeySuccessfully) { - const std::vector kAesKeyBytes = {0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, - 0xF7, 0xB6, 0xCF, 0x5E, 0x3F, 0x45, - 0x61, 0xC3, 0x32, 0x1D}; - std::vector passkey_bytes; - // Message type. - constexpr uint8_t kMessageType = 0x03; - passkey_bytes.push_back(kMessageType); - - // Passkey bytes. - constexpr uint32_t kPasskey = 5; - passkey_bytes.push_back(kPasskey >> 16); - passkey_bytes.push_back(kPasskey >> 8); - passkey_bytes.push_back(kPasskey); - - // Random salt - constexpr std::array kSalt = { - 0x08, 0x09, 0x0A, 0x08, 0x09, 0x0E, 0x0A, 0x0C, 0x0D, 0x0E, 0x05, 0x02}; - std::copy(kSalt.begin(), kSalt.end(), std::back_inserter(passkey_bytes)); - - std::array passkey_bytes_array; - std::copy(passkey_bytes.begin(), passkey_bytes.end(), - passkey_bytes_array.begin()); - auto encrypted_bytes_array = - FastPairEncryption::EncryptBytes(kAeskeyarray, passkey_bytes_array); - std::vector encrypted_bytes(encrypted_bytes_array.begin(), - encrypted_bytes_array.end()); - - CountDownLatch latch(1); - FastPairDataParser::ParseDecryptedPasskey( - kAesKeyBytes, encrypted_bytes, - [&](std::optional decrypted_passkey) { - ASSERT_TRUE(decrypted_passkey.has_value()); - EXPECT_EQ(decrypted_passkey.value().message_type, - FastPairMessageType::kProvidersPasskey); - EXPECT_EQ(decrypted_passkey.value().passkey, kPasskey); - EXPECT_EQ(decrypted_passkey.value().salt, kSalt); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, ParseNotDiscoverableAdvertisementEmpty) { - CountDownLatch latch(1); - FastPairDataParser::ParseNotDiscoverableAdvertisement( - "", kDeviceAddress, - [&](const std::optional advertisement) { - EXPECT_FALSE(advertisement.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, - ParseNotDiscoverableAdvertisementNoApplicibleData) { - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - EXPECT_FALSE(advertisement.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, - ParseNotDiscoverableAdvertisementAccountKeyFilter) { - const std::vector kSaltBytes = {0x01}; - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - ASSERT_TRUE(advertisement.has_value()); - EXPECT_EQ(absl::BytesToHexString( - std::string(advertisement->account_key_filter.begin(), - advertisement->account_key_filter.end())), - kAccountKeyFilter); - EXPECT_EQ(advertisement->salt, kSaltBytes); - EXPECT_EQ(advertisement->type, - NonDiscoverableAdvertisement::Type::kShowUi); - EXPECT_FALSE(advertisement->battery_notification.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, - ParseNotDiscoverableAdvertisementAccountKeyFilterNoNotification) { - const std::vector kSaltBytes = {0x01}; - std::vector bytes = - FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader( - /*accountKeyFilterNoNotificationHeader*/ 0b01100010) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - ASSERT_TRUE(advertisement.has_value()); - EXPECT_EQ(absl::BytesToHexString( - std::string(advertisement->account_key_filter.begin(), - advertisement->account_key_filter.end())), - kAccountKeyFilter); - EXPECT_EQ(advertisement->salt, kSaltBytes); - EXPECT_EQ(advertisement->type, - NonDiscoverableAdvertisement::Type::kHideUi); - EXPECT_FALSE(advertisement->battery_notification.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, ParseNotDiscoverableAdvertisementWrongVersion) { - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(/*InvalidHeader*/ 0b00100000) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - EXPECT_FALSE(advertisement.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, - ParseNotDiscoverableAdvertisementZeroLengthExtraField) { - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField("") - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - EXPECT_FALSE(advertisement.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, ParseNotDiscoverableAdvertisementWrongType) { - std::vector bytes = - FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader /*InvalidType*/ (0b01100001) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - EXPECT_FALSE(advertisement.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, ParseNotDiscoverableAdvertisementSaltTwoBytes) { - const std::vector kLargeSaltBytes = {0xC7, 0xC8}; - std::vector bytes = - FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(/*SaltTwoBytes*/ 0b00100001) - .AddExtraField(/*LargeSalt*/ "C7C8") - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - ASSERT_TRUE(advertisement.has_value()); - EXPECT_EQ(absl::BytesToHexString( - std::string(advertisement->account_key_filter.begin(), - advertisement->account_key_filter.end())), - kAccountKeyFilter); - EXPECT_EQ(advertisement->salt, kLargeSaltBytes); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, ParseNotDiscoverableAdvertisementSaltTooLarge) { - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(0b00110001) - .AddExtraField(/*invalidSalt*/ "C7C8C9") - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - EXPECT_FALSE(advertisement.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, ParseNotDiscoverableAdvertisementWithBattery) { - const std::vector kSaltBytes = {0x01}; - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .AddExtraFieldHeader(kBatteryHeader) - .AddExtraField(kBattery) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - ASSERT_TRUE(advertisement.has_value()); - EXPECT_EQ(absl::BytesToHexString( - std::string(advertisement->account_key_filter.begin(), - advertisement->account_key_filter.end())), - kAccountKeyFilter); - EXPECT_EQ(advertisement->salt, kSaltBytes); - EXPECT_EQ(advertisement->type, - NonDiscoverableAdvertisement::Type::kShowUi); - ASSERT_TRUE(advertisement->battery_notification.has_value()); - EXPECT_EQ(advertisement->battery_notification->type, - BatteryNotification::Type::kShowUi); - EXPECT_FALSE(advertisement->battery_notification->battery_infos.at(0) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(0).percentage, - 1); - EXPECT_FALSE(advertisement->battery_notification->battery_infos.at(1) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(1).percentage, - 4); - ASSERT_TRUE(advertisement->battery_notification->battery_infos.at(2) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(2).percentage, - 15); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, ParseNotDiscoverableAdvertisementMissingSalt) { - const std::vector kDeviceAddressBytes = {17, 18, 19, 20, 21, 22}; - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kBatteryHeader) - .AddExtraField(kBattery) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - ASSERT_TRUE(advertisement.has_value()); - EXPECT_EQ(absl::BytesToHexString( - std::string(advertisement->account_key_filter.begin(), - advertisement->account_key_filter.end())), - kAccountKeyFilter); - EXPECT_EQ(advertisement->salt, kDeviceAddressBytes); - EXPECT_EQ(advertisement->type, - NonDiscoverableAdvertisement::Type::kShowUi); - ASSERT_TRUE(advertisement->battery_notification.has_value()); - EXPECT_EQ(advertisement->battery_notification->type, - BatteryNotification::Type::kShowUi); - EXPECT_FALSE(advertisement->battery_notification->battery_infos.at(0) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(0).percentage, - 1); - EXPECT_FALSE(advertisement->battery_notification->battery_infos.at(1) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(1).percentage, - 4); - ASSERT_TRUE(advertisement->battery_notification->battery_infos.at(2) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(2).percentage, - 15); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairDataParserTest, ParseNotDiscoverableAdvertisementWithBatteryNoUi) { - const std::vector kSaltBytes = {0x01}; - std::vector bytes = - FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .AddExtraFieldHeader(/*batterHeaderNoNotification*/ 0b00110100) - .AddExtraField(kBattery) - .Build() - ->CreateServiceData(); - CountDownLatch latch(1); - - FastPairDataParser::ParseNotDiscoverableAdvertisement( - std::string(bytes.begin(), bytes.end()), kDeviceAddress, - [&](const std::optional advertisement) { - ASSERT_TRUE(advertisement.has_value()); - EXPECT_EQ(absl::BytesToHexString( - std::string(advertisement->account_key_filter.begin(), - advertisement->account_key_filter.end())), - kAccountKeyFilter); - EXPECT_EQ(advertisement->salt, kSaltBytes); - EXPECT_EQ(advertisement->type, - NonDiscoverableAdvertisement::Type::kShowUi); - ASSERT_TRUE(advertisement->battery_notification.has_value()); - EXPECT_EQ(advertisement->battery_notification->type, - BatteryNotification::Type::kHideUi); - EXPECT_FALSE(advertisement->battery_notification->battery_infos.at(0) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(0).percentage, - 1); - EXPECT_FALSE(advertisement->battery_notification->battery_infos.at(1) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(1).percentage, - 4); - ASSERT_TRUE(advertisement->battery_notification->battery_infos.at(2) - .is_charging); - EXPECT_EQ( - advertisement->battery_notification->battery_infos.at(2).percentage, - 15); - latch.CountDown(); - }); - latch.Await(); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/dataparser/fast_pair_decoder.cc b/fastpair/dataparser/fast_pair_decoder.cc deleted file mode 100644 index 1b12e64ec9..0000000000 --- a/fastpair/dataparser/fast_pair_decoder.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/dataparser/fast_pair_decoder.h" - -#include -#include -#include -#include -#include -#include - -#include "absl/strings/escaping.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr int kHeaderIndex = 0; -constexpr int kHeaderLength = 1; -constexpr int kHeaderLengthBitmask = 0b00011110; -constexpr int kHeaderLengthOffset = 1; -constexpr int kHeaderVersionBitmask = 0b11100000; -constexpr int kHeaderVersionOffset = 5; -constexpr int kMinModelIdLength = 3; -constexpr int kMaxModelIdLength = 14; -} // namespace - -int FastPairDecoder::GetIdLength(const std::vector* service_data) { - return service_data->size() == kMinModelIdLength - ? kMinModelIdLength - : ((*service_data)[kHeaderIndex] & kHeaderLengthBitmask) >> - kHeaderLengthOffset; -} - -int FastPairDecoder::GetVersion(const std::vector* service_data) { - return service_data->size() == kMinModelIdLength - ? 0 - : ((*service_data)[kHeaderIndex] & kHeaderVersionBitmask) >> - kHeaderVersionOffset; -} - -bool IsIdLengthValid(const std::vector* service_data) { - int id_length = FastPairDecoder::GetIdLength(service_data); - return kMinModelIdLength <= id_length && id_length <= kMaxModelIdLength && - id_length + kHeaderLength <= static_cast(service_data->size()); -} - -bool FastPairDecoder::HasModelId(const std::vector* service_data) { - return service_data != nullptr && - (service_data->size() == kMinModelIdLength || - // Header byte exists. We support only format version 0. (A different - // version indicates a breaking change in the format.) - (service_data->size() > kMinModelIdLength && - GetVersion(service_data) == 0 && IsIdLengthValid(service_data))); -} - -std::optional FastPairDecoder::GetHexModelIdFromServiceData( - const std::vector* service_data) { - if (service_data == nullptr || service_data->size() < kMinModelIdLength) { - return std::nullopt; - } - - if (service_data->size() == kMinModelIdLength) { - // If the size is 3, all the bytes are the ID, - std::vector bytes = *service_data; - std::string model_id(bytes.begin(), bytes.end()); - return absl::BytesToHexString(model_id); - } - // Otherwise, the first byte is a header which contains the length of the - // big-endian model ID that follows. The model ID will be trimmed if it - // contains leading zeros. - int id_index = 1; - int end = id_index + GetIdLength(service_data); - - // Ignore leading zeros. - while ((*service_data)[id_index] == 0 && end - id_index > kMinModelIdLength) { - id_index++; - } - - // Copy appropriate bytes to new array. - int bytes_size = end - id_index; - std::vector bytes; - bytes.reserve(bytes_size); - for (int i = 0; i < bytes_size; i++) { - bytes.push_back((*service_data)[i + id_index]); - } - std::string model_id(bytes.begin(), bytes.end()); - return absl::BytesToHexString(model_id); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/dataparser/fast_pair_decoder.h b/fastpair/dataparser/fast_pair_decoder.h deleted file mode 100644 index bbf983280f..0000000000 --- a/fastpair/dataparser/fast_pair_decoder.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_DATAPARSER_FAST_PAIR_DECODER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_DATAPARSER_FAST_PAIR_DECODER_H_ - -#include -#include -#include -#include - -namespace nearby { -namespace fastpair { - -class FastPairDecoder { - public: - static int GetVersion(const std::vector* service_data); - static int GetIdLength(const std::vector* service_data); - static bool HasModelId(const std::vector* service_data); - - static std::optional GetHexModelIdFromServiceData( - const std::vector* service_data); -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_DATAPARSER_FAST_PAIR_DECODER_H_ diff --git a/fastpair/dataparser/fast_pair_decoder_test.cc b/fastpair/dataparser/fast_pair_decoder_test.cc deleted file mode 100644 index 2c48a1c61e..0000000000 --- a/fastpair/dataparser/fast_pair_decoder_test.cc +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/dataparser/fast_pair_decoder.h" - -#include -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "fastpair/testing/fast_pair_service_data_creator.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr char kModelId[7] = "aabbcc"; -constexpr char kLongModelId[17] = "1122334455667788"; -constexpr char kPaddedModelId[9] = "00001111"; -constexpr char kTrimmedModelId[7] = "001111"; -constexpr uint8_t kLongModelIdHeader = 0b00010000; -constexpr uint8_t kPaddedLongModelIdHeader = 0b00001000; - -bool HasModelIdString(std::string model_id) { - std::string bytes_str = absl::HexStringToBytes(model_id); - std::vector model_id_bytes; - std::move(std::begin(bytes_str), std::end(bytes_str), - std::back_inserter(model_id_bytes)); - return FastPairDecoder::HasModelId(&model_id_bytes); -} - -TEST(FastPairDecoderTest, HasModelIdThreeByteFormat) { - EXPECT_TRUE(HasModelIdString(kModelId)); -} - -TEST(FastPairDecoderTest, HasModelIdTooShort) { - EXPECT_FALSE(HasModelIdString("11")); -} - -TEST(FastPairDecoderTest, HasModelIdLongFormat) { - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(0b00001000) - .SetModelId("11223344") - .Build() - ->CreateServiceData(); - EXPECT_TRUE(FastPairDecoder::HasModelId(&bytes)); - - bytes = FastPairServiceDataCreator::Builder() - .SetHeader(0b00001010) - .SetModelId("1122334455") - .Build() - ->CreateServiceData(); - - EXPECT_TRUE(FastPairDecoder::HasModelId(&bytes)); -} - -TEST(FastPairDecoderTest, HasModelIdLongInvalidVersion) { - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(0b00101000) - .SetModelId("11223344") - .Build() - ->CreateServiceData(); - EXPECT_FALSE(FastPairDecoder::HasModelId(&bytes)); -} - -TEST(FastPairDecoderTest, HasModelIdLongInvalidLength) { - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(0b00001010) - .SetModelId("11223344") - .Build() - ->CreateServiceData(); - EXPECT_FALSE(FastPairDecoder::HasModelId(&bytes)); - - bytes = FastPairServiceDataCreator::Builder() - .SetHeader(0b00000010) - .SetModelId("11223344") - .Build() - ->CreateServiceData(); - - EXPECT_FALSE(FastPairDecoder::HasModelId(&bytes)); -} - -TEST(FastPairDecoderTest, GetHexModelIdFromServiceDataNoResultForNullData) { - EXPECT_EQ(FastPairDecoder::GetHexModelIdFromServiceData(nullptr), - absl::nullopt); -} - -TEST(FastPairDecoderTest, GetHexModelIdFromServiceDataNoResultForEmptyData) { - std::vector empty; - EXPECT_EQ(FastPairDecoder::GetHexModelIdFromServiceData(&empty), - absl::nullopt); -} - -TEST(FastPairDecoderTest, GetHexModelIdFromServiceDataThreeByteData) { - std::vector service_data = FastPairServiceDataCreator::Builder() - .SetModelId(kModelId) - .Build() - ->CreateServiceData(); - EXPECT_EQ(FastPairDecoder::GetHexModelIdFromServiceData(&service_data), - kModelId); -} - -TEST(FastPairDecoderTest, GetHexModelIdFromServiceDataLongModelId) { - std::vector service_data = FastPairServiceDataCreator::Builder() - .SetHeader(kLongModelIdHeader) - .SetModelId(kLongModelId) - .Build() - ->CreateServiceData(); - - EXPECT_EQ(FastPairDecoder::GetHexModelIdFromServiceData(&service_data), - kLongModelId); -} - -TEST(FastPairDecoderTest, GetHexModelIdFromServiceDataLongModelIdTrimmed) { - std::vector service_data = FastPairServiceDataCreator::Builder() - .SetHeader(kPaddedLongModelIdHeader) - .SetModelId(kPaddedModelId) - .Build() - ->CreateServiceData(); - - EXPECT_EQ(FastPairDecoder::GetHexModelIdFromServiceData(&service_data), - kTrimmedModelId); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/fast_pair_controller.cc b/fastpair/fast_pair_controller.cc deleted file mode 100644 index 9d1ad89f83..0000000000 --- a/fastpair/fast_pair_controller.cc +++ /dev/null @@ -1,190 +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. - -#include "fastpair/fast_pair_controller.h" - -#include -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "fastpair/common/protocol.h" -#include "fastpair/handshake/fast_pair_data_encryptor_impl.h" -#include "fastpair/message_stream/message_stream.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -FastPairController::FastPairController(Mediums* mediums, FastPairDevice* device, - SingleThreadExecutor* executor) - : mediums_(mediums), device_(device), executor_(executor) {} - -absl::Status FastPairController::OpenMessageStream() { - message_stream_ = std::make_unique( - *device_, &mediums_->GetBluetoothClassic().GetMedium(), *this); - return message_stream_->OpenRfcomm(); -} - -void FastPairController::AddMessageStreamConnectionObserver( - MessageStreamConnectionObserver* observer) { - connection_observers_.AddObserver(observer); - if (message_stream_status_.ok() && observer->on_connected != nullptr) { - observer->on_connected(*device_); - } else if (!message_stream_status_.ok() && - observer->on_disconnected != nullptr) { - observer->on_disconnected(*device_, message_stream_status_); - } -} - -void FastPairController::RemoveMessageStreamConnectionObserver( - MessageStreamConnectionObserver* observer) { - connection_observers_.RemoveObserver(observer); -} - -void FastPairController::AddAddressRotationObserver( - BleAddressRotationObserver* observer) { - address_rotation_observers_.AddObserver(observer); - if (!device_->GetBleAddress().empty()) { - observer->on_ble_address_rotated(*device_, device_->GetBleAddress()); - } -} - -void FastPairController::RemoveAddressRotationObserver( - BleAddressRotationObserver* observer) { - address_rotation_observers_.RemoveObserver(observer); -} - -void FastPairController::AddModelIdObserver(ModelIdObserver* observer) { - model_id_observers_.AddObserver(observer); - if (!device_->GetModelId().empty()) { - observer->on_model_id(*device_); - } -} - -void FastPairController::RemoveModelIdObserver(ModelIdObserver* observer) { - model_id_observers_.RemoveObserver(observer); -} - -Future> -FastPairController::GetDataEncryptor() { - if (!encryptor_) { - encryptor_ = - std::make_unique>>(); - if (device_->GetMetadata()) { - CreateDataEncryptor(); - } else { - FastPairRepository::Get()->GetDeviceMetadata( - device_->GetModelId(), - [this](std::optional metadata) { - if (!metadata.has_value()) { - NEARBY_LOGS(WARNING) - << __func__ << ": Failed to get device metadata"; - return; - } - device_->SetMetadata(metadata.value()); - CreateDataEncryptor(); - }); - } - } - return *encryptor_; -} - -void FastPairController::CreateDataEncryptor() { - FastPairDataEncryptorImpl::Factory::CreateAsync( - *device_, [borrowable = lender_.GetBorrowable()]( - std::unique_ptr encryptor) mutable { - auto borrowed = borrowable.Borrow(); - if (borrowed) { - (*borrowed)->SetDataEncryptor(std::move(encryptor)); - } - }); -} - -Future -FastPairController::GetGattClientRef() { - Future result; - if (gatt_client_ == nullptr) { - gatt_client_ref_count_ = 0; - gatt_client_ = FastPairGattServiceClientImpl::Factory::Create( - *device_, *mediums_, executor_); - gatt_client_->InitializeGattConnection( - [](std::optional result) { - if (result.has_value()) { - NEARBY_LOGS(INFO) << "InitializeGattConnection: " << result.value(); - } else { - NEARBY_LOGS(INFO) << "InitializeGattConnection: OK"; - } - }); - } - result.Set(GattClientRef(this)); - return result; -} - -// MessageStream::Observer callbacks -void FastPairController::OnConnectionResult(absl::Status result) { - NEARBY_LOGS(INFO) << "OnConnectionResult " << result; - message_stream_status_ = result; - if (!result.ok()) { - NEARBY_LOGS(INFO) << "Connection attempt failed with " << result; - return; - } - for (auto* observer : connection_observers_.GetObservers()) { - if (observer->on_connected != nullptr) { - observer->on_connected(*device_); - } - } -} -void FastPairController::OnDisconnected(absl::Status status) { - NEARBY_LOGS(INFO) << "OnDisconnected " << status; - message_stream_status_ = status; - for (auto* observer : connection_observers_.GetObservers()) { - if (observer->on_disconnected != nullptr) { - observer->on_disconnected(*device_, status); - } - } -} -void FastPairController::OnEnableSilenceMode(bool enable) {} -void FastPairController::OnLogBufferFull() {} -void FastPairController::OnModelId(absl::string_view model_id) { - device_->SetModelId(absl::BytesToHexString(model_id)); - NEARBY_LOGS(INFO) << "Setting model id: " << device_->GetModelId(); - for (auto* observer : model_id_observers_.GetObservers()) { - observer->on_model_id(*device_); - } -} - -void FastPairController::OnBleAddressUpdated(absl::string_view address) { - std::string old_address = std::string(device_->GetBleAddress()); - device_->SetBleAddress(address); - for (auto* observer : address_rotation_observers_.GetObservers()) { - observer->on_ble_address_rotated(*device_, old_address); - } -} - -void FastPairController::OnBatteryUpdated( - std::vector battery_levels) {} -void FastPairController::OnRemainingBatteryTime(absl::Duration duration) {} -bool FastPairController::OnRing(uint8_t components, absl::Duration duration) { - return false; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/fast_pair_controller.h b/fastpair/fast_pair_controller.h deleted file mode 100644 index bcf69bd661..0000000000 --- a/fastpair/fast_pair_controller.h +++ /dev/null @@ -1,201 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_CONTROLLER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_CONTROLLER_H_ - -#include -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_gatt_service_client_impl.h" -#include "fastpair/message_stream/message_stream.h" -#include "internal/base/observer_list.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/borrowable.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -class FastPairController : public MessageStream::Observer { - public: - struct MessageStreamConnectionObserver { - // Callback triggered when a Message Stream connection is opened. - absl::AnyInvocable on_connected; - - // Callback triggered when a Message Stream connection is terminated. - absl::AnyInvocable - on_disconnected; - }; - struct BleAddressRotationObserver { - absl::AnyInvocable - on_ble_address_rotated; - }; - struct ModelIdObserver { - absl::AnyInvocable on_model_id; - }; - // RAII accessor to GattClient - class GattClientRef { - public: - GattClientRef() = default; - explicit GattClientRef(FastPairController* controller) - : controller_(controller) { - CHECK(controller_ != nullptr); - controller_->AcquireGattClient(); - } - GattClientRef(const GattClientRef& other) { - controller_ = other.controller_; - if (controller_ != nullptr) { - controller_->AcquireGattClient(); - } - } - GattClientRef(GattClientRef&& other) { - controller_ = other.controller_; - other.controller_ = nullptr; - } - GattClientRef& operator=(const GattClientRef& other) { - if (controller_ != nullptr) { - controller_->ReleaseGattClient(); - } - controller_ = other.controller_; - if (controller_ != nullptr) { - controller_->AcquireGattClient(); - } - return *this; - } - GattClientRef& operator=(GattClientRef&& other) { - if (controller_ != nullptr) { - controller_->ReleaseGattClient(); - } - controller_ = other.controller_; - other.controller_ = nullptr; - return *this; - } - - ~GattClientRef() { - if (controller_ != nullptr) { - controller_->ReleaseGattClient(); - } - } - - FastPairGattServiceClient* operator->() { - CHECK(controller_ != nullptr); - return controller_->GetGattClient(); - } - - private: - FastPairController* controller_ = nullptr; - }; - // Creates a device controller in retroactive pairing path. - FastPairController(Mediums* mediums, FastPairDevice* device, - SingleThreadExecutor* executor); - - ~FastPairController() override { - NEARBY_LOGS(INFO) << "Destroy FastPairController"; - lender_.Release(); - connection_observers_.Clear(); - address_rotation_observers_.Clear(); - model_id_observers_.Clear(); - message_stream_.reset(); - NEARBY_LOGS(INFO) << "Destroyed FastPairController"; - } - - absl::Status OpenMessageStream(); - - // Registers an observer for connection events. The observer must stay alive - // until it is removed. - // The callback is also called during registration with the current state - // of the connection. - void AddMessageStreamConnectionObserver( - MessageStreamConnectionObserver* observer); - void RemoveMessageStreamConnectionObserver( - MessageStreamConnectionObserver* observer); - - // Registers an observer for BLE address rotation. - // The callback is also called during registration with the current BLE - // address unless FP does not know the device's address. - void AddAddressRotationObserver(BleAddressRotationObserver* observer); - void RemoveAddressRotationObserver(BleAddressRotationObserver* observer); - - void AddModelIdObserver(ModelIdObserver* observer); - void RemoveModelIdObserver(ModelIdObserver* observer); - - Future> GetDataEncryptor(); - Future GetGattClientRef(); - - // MessageStream::Observer callbacks - void OnConnectionResult(absl::Status result) override; - void OnDisconnected(absl::Status status) override; - void OnEnableSilenceMode(bool enable) override; - void OnLogBufferFull() override; - void OnModelId(absl::string_view model_id) override; - void OnBleAddressUpdated(absl::string_view address) override; - void OnBatteryUpdated( - std::vector battery_levels) override; - void OnRemainingBatteryTime(absl::Duration duration) override; - bool OnRing(uint8_t components, absl::Duration duration) override; - - FastPairDevice& GetDevice() { return *device_; } - std::string GetSeekerMacAddress() const { - return mediums_->GetBluetoothClassic().GetMedium().GetMacAddress(); - } - - private: - void SetDataEncryptor(std::unique_ptr encryptor) { - if (encryptor != nullptr) { - encryptor_->Set(std::move(encryptor)); - } else { - encryptor_->SetException({Exception::kFailed}); - } - } - void AcquireGattClient() { ++gatt_client_ref_count_; } - void ReleaseGattClient() { - if (--gatt_client_ref_count_ == 0) { - gatt_client_.reset(); - } - } - FastPairGattServiceClient* GetGattClient() { - CHECK(gatt_client_ != nullptr); - return gatt_client_.get(); - } - void CreateDataEncryptor(); - Mediums* mediums_; - FastPairDevice* device_; - SingleThreadExecutor* executor_; - std::unique_ptr>> encryptor_; - std::unique_ptr message_stream_; - absl::Status message_stream_status_ = - absl::FailedPreconditionError("not connected"); - ObserverList connection_observers_; - ObserverList address_rotation_observers_; - ObserverList model_id_observers_; - // TODO(jsobczak): Improve locking around gatt_client_ - std::unique_ptr gatt_client_; - std::atomic_int gatt_client_ref_count_; - Lender lender_{this}; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_CONTROLLER_H_ diff --git a/fastpair/fast_pair_controller_test.cc b/fastpair/fast_pair_controller_test.cc deleted file mode 100644 index 53d9642d7b..0000000000 --- a/fastpair/fast_pair_controller_test.cc +++ /dev/null @@ -1,83 +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. - -#include "fastpair/fast_pair_controller.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "fastpair/message_stream/fake_provider.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -namespace { - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class FastPairControllerTest : public testing::Test { - protected: - void SetUp() override { - BluetoothClassicMedium& seeker_medium = - mediums_.GetBluetoothClassic().GetMedium(); - provider_.DiscoverProvider(seeker_medium); - std::string address = provider_.GetMacAddress(); - NEARBY_LOGS(INFO) << "Provider address: " << address; - remote_device_ = seeker_medium.GetRemoteDevice(provider_.GetMacAddress()); - ASSERT_TRUE(remote_device_.IsValid()); - fast_pair_device_ = - std::make_unique(Protocol::kFastPairRetroactivePairing); - fast_pair_device_->SetPublicAddress(remote_device_.GetMacAddress()); - } - - void TearDown() override { - executor_.Shutdown(); - provider_.Shutdown(); - MediumEnvironment::Instance().Stop(); - } - - // The medium environment must be initialized (started) before adding - // adapters. - MediumEnvironmentStarter env_; - SingleThreadExecutor executor_; - Mediums mediums_; - FakeProvider provider_; - BluetoothDevice remote_device_; - std::unique_ptr fast_pair_device_; -}; - -TEST_F(FastPairControllerTest, Constructor) { - FastPairController controller(&mediums_, &*fast_pair_device_, &executor_); -} - -TEST_F(FastPairControllerTest, OpenMessageStream) { - FastPairController controller(&mediums_, &*fast_pair_device_, &executor_); - - EXPECT_OK(controller.OpenMessageStream()); -} - -} // namespace - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/fast_pair_events.h b/fastpair/fast_pair_events.h deleted file mode 100644 index 93cd727c6a..0000000000 --- a/fastpair/fast_pair_events.h +++ /dev/null @@ -1,43 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_EVENTS_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_EVENTS_H_ - -#include -namespace nearby { -namespace fastpair { - -// Fast Pair plugins receive notifications from the FP service about various -// system events. The structures below provide details about the events. - -struct InitialDiscoveryEvent {}; - -struct SubsequentDiscoveryEvent {}; - -struct PairEvent { - bool is_paired; -}; - -struct ScreenEvent { - std::optional is_locked; -}; - -struct BatteryEvent {}; - -struct RingEvent {}; - -} // namespace fastpair -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_EVENTS_H_ diff --git a/fastpair/fast_pair_plugin.h b/fastpair/fast_pair_plugin.h deleted file mode 100644 index 0d6628c179..0000000000 --- a/fastpair/fast_pair_plugin.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_PLUGIN_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_PLUGIN_H_ - -#include - -#include "fastpair/fast_pair_events.h" -#include "fastpair/fast_pair_seeker.h" - -namespace nearby { -namespace fastpair { - -class FastPairPlugin { - public: - virtual ~FastPairPlugin() = default; - - // All functions below are synchronous. - virtual void OnInitialDiscoveryEvent(const InitialDiscoveryEvent& event) {} - virtual void OnSubsequentDiscoveryEvent( - const SubsequentDiscoveryEvent& event) {} - // Handles pair, unpair events. - virtual void OnPairEvent(const PairEvent& event) {} - virtual void OnScreenEvent(const ScreenEvent& event) {} - virtual void OnBatteryEvent(const BatteryEvent& event) {} - virtual void OnRingEvent(const RingEvent& event) {} -}; - -class FastPairPluginProvider { - public: - virtual ~FastPairPluginProvider() = default; - - // Returns an instance of `FastPairPlugin`. - // - // The plugin can use the `seeker` to communicate with the Fast Pair Seeker - // Service. `seeker` is always non-null and has a lifetime at least as long as - // the plugin returned by this call. - // `device` is a non-null. - virtual std::unique_ptr GetPlugin( - FastPairSeeker* seeker, const FastPairDevice* device) = 0; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_PLUGIN_H_ diff --git a/fastpair/fast_pair_seeker.h b/fastpair/fast_pair_seeker.h deleted file mode 100644 index 38458750e1..0000000000 --- a/fastpair/fast_pair_seeker.h +++ /dev/null @@ -1,102 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_SEEKER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_SEEKER_H_ - -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "fastpair/common/fast_pair_device.h" - -namespace nearby { -namespace fastpair { - -// Pairing result callback. -struct PairingCallback { - absl::AnyInvocable - on_pairing_result = - [](const FastPairDevice& device, absl::Status status) {}; -}; - -// Initial Pairing parameters. -struct InitialPairingParam {}; - -// Subsequent Pairing parameters. -struct SubsequentPairingParam {}; - -// Retroactive Pairing parameters. -struct RetroactivePairingParam {}; - -// Finish Retroactive Pairing parameters. -struct FinishRetroactivePairingParam { - // Save the negotiated Account Key or abandon it and forget the Fast Pair - // Device. - bool save_account_key = false; -}; - -// Fast Pair Seeker API available to plugins. -class FastPairSeeker { - public: - virtual ~FastPairSeeker() = default; - - // Starts asynchronous initial pairing flow. This pairing flow is used with - // devices that we see for the first time. - // - // Returns an error if pairing flow could not be started. Otherwise, the - // pairing result will be returned via the `callback`. - virtual absl::Status StartInitialPairing(const FastPairDevice& device, - const InitialPairingParam& params, - PairingCallback callback) = 0; - - // Starts asynchronous subsequent pairing flow. This pairing flow is used when - // device is an already known peripheral. The user paired with that device in - // the past, perhaps using a different seeker and `device` already has an - // Account Key. - // - // Returns an error if pairing flow could not be started. Otherwise, the - // pairing result will be returned via the `callback`. - virtual absl::Status StartSubsequentPairing( - const FastPairDevice& device, const SubsequentPairingParam& params, - PairingCallback callback) = 0; - - // Starts asynchronous retroactive pairing flow. This pairing flow is used - // when the user has paired manually with a new device and we want to - // retroactively exchange an Account Key. See: - // https://developers.google.com/nearby/fast-pair/specifications/extensions/retroactiveacctkey - // The retroactive pairing flow should be started immediately after the - // pairing event, before we had a chance to ask for the user for permission. - // Therefore, the retroactive is split into two stages. The client should call - // `StartRetroactivePairing()` first. When the pairing result returned via - // `callback` is successful, the client should ask the user for permission to - // save the account key. Finally, the client should call - // `FinishRetroactivePairing()` with the user's decision to complete the - // retroactive pairing flow. - // - // Returns an error if pairing flow could not be started. Otherwise, the - // pairing result will be returned via the `callback`. - virtual absl::Status StartRetroactivePairing( - const FastPairDevice& device, const RetroactivePairingParam& param, - PairingCallback callback) = 0; - - // Finishes the retroactive pairing flow. - // - // Returns an error if the flow could not be started. Otherwise, the - // result will be returned via the `callback`. - virtual absl::Status FinishRetroactivePairing( - const FastPairDevice& device, const FinishRetroactivePairingParam& param, - PairingCallback callback) = 0; -}; -} // namespace fastpair -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_SEEKER_H_ diff --git a/fastpair/fast_pair_service.cc b/fastpair/fast_pair_service.cc deleted file mode 100644 index 87eb2dde85..0000000000 --- a/fastpair/fast_pair_service.cc +++ /dev/null @@ -1,210 +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. - -#include "fastpair/fast_pair_service.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/str_format.h" -#include "fastpair/common/fast_pair_prefs.h" -#include "fastpair/fast_pair_plugin.h" -#include "fastpair/internal/fast_pair_seeker_impl.h" -#include "fastpair/repository/fast_pair_repository_impl.h" -#include "fastpair/server_access/fast_pair_client_impl.h" -#include "fastpair/server_access/fast_pair_http_notifier.h" -#include "internal/account/account_manager_impl.h" -#include "internal/auth/authentication_manager_impl.h" -#include "internal/flags/nearby_flags.h" -#include "internal/network/http_client_impl.h" -#include "internal/platform/device_info_impl.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/flags/nearby_platform_feature_flags.h" -#include "internal/platform/logging.h" -#include "internal/platform/task_runner_impl.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr char kFastPairPreferencesFilePath[] = "Google/Nearby/FastPair"; -constexpr FeatureFlags::Flags fast_pair_feature_flags = FeatureFlags::Flags{ - .enable_scan_for_fast_pair_advertisement = true, - .skip_service_discovery_before_connecting_to_rfcomm = true, -}; -constexpr absl::Duration kTimeout = absl::Seconds(3); -} // namespace - -FastPairService::FastPairService() - : FastPairService(std::make_unique(), - std::make_unique(), - std::make_unique()) {} - -FastPairService::FastPairService( - std::unique_ptr authentication_manager, - std::unique_ptr http_client, - std::unique_ptr device_info) - : authentication_manager_(std::move(authentication_manager)), - http_client_(std::move(http_client)), - device_info_(std::move(device_info)), - task_runner_(std::make_unique(1)), - preferences_manager_(std::make_unique( - kFastPairPreferencesFilePath)), - account_manager_(AccountManagerImpl::Factory::Create( - preferences_manager_.get(), prefs::kNearbyFastPairUsersName, - authentication_manager_.get(), task_runner_.get())), - fast_pair_client_(std::make_unique( - authentication_manager_.get(), account_manager_.get(), - http_client_.get(), &fast_pair_http_notifier_, device_info_.get())), - fast_pair_repository_( - std::make_unique(fast_pair_client_.get())), - on_device_destroyed_callback_( - [this](const FastPairDevice& device) { OnDeviceDestroyed(device); }) { - NearbyFlags::GetInstance().OverrideBoolFlagValue( - platform::config_package_nearby::nearby_platform_feature:: - kEnableBleV2Gatt, - true); - const_cast(FeatureFlags::GetInstance()) - .SetFlags(fast_pair_feature_flags); - - devices_.AddObserver(&on_device_destroyed_callback_); - seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{ - .on_initial_discovery = - [this](const FastPairDevice& device, - InitialDiscoveryEvent event) { - OnInitialDiscoveryEvent(device, std::move(event)); - }, - .on_subsequent_discovery = - [this](const FastPairDevice& device, - SubsequentDiscoveryEvent event) { - OnSubsequentDiscoveryEvent(device, std::move(event)); - }, - .on_pair_event = - [this](const FastPairDevice& device, PairEvent event) { - OnPairEvent(device, std::move(event)); - }, - .on_screen_event = - [this](ScreenEvent event) { OnScreenEvent(std::move(event)); }, - .on_battery_event = - [this](const FastPairDevice& device, BatteryEvent event) { - OnBatteryEvent(device, std::move(event)); - }, - .on_ring_event = - [this](const FastPairDevice& device, RingEvent event) { - OnRingEvent(device, std::move(event)); - }}, - &executor_, account_manager_.get(), &devices_, - fast_pair_repository_.get()); -} - -FastPairService::~FastPairService() { executor_.Shutdown(); } - -absl::Status FastPairService::RegisterPluginProvider( - absl::string_view name, std::unique_ptr provider) { - Future result; - executor_.Execute("register-plugin", [&]() { - bool success = plugin_states_ - .insert({std::string(name), - PluginState{.provider = std::move(provider)}}) - .second; - absl::Status status = success - ? absl::OkStatus() - : absl::AlreadyExistsError(absl::StrFormat( - "Plugin '%s' already registered", name)); - result.Set(status); - }); - ExceptionOr status = result.Get(kTimeout); - return status.ok() ? status.GetResult() - : absl::DeadlineExceededError("Register plugin timeout"); -} - -absl::Status FastPairService::UnregisterPluginProvider(absl::string_view name) { - Future result; - executor_.Execute("unregister-plugin", [&]() { - bool success = success = plugin_states_.erase(name); - absl::Status status = success - ? absl::OkStatus() - : absl::NotFoundError(absl::StrFormat( - "Plugin '%s' already registered", name)); - result.Set(status); - }); - ExceptionOr status = result.Get(kTimeout); - return status.ok() ? status.GetResult() - : absl::DeadlineExceededError("Unregister plugin timeout"); -} - -void FastPairService::OnInitialDiscoveryEvent(const FastPairDevice& device, - InitialDiscoveryEvent event) { - executor_.Execute("on-initial-discovery", [this, device = &device, - event = std::move(event)]() { - NEARBY_LOGS(INFO) << "OnInitialDiscoveryEvent " << *device; - for (auto& entry : plugin_states_) { - auto plugin = entry.second.GetPlugin(seeker_.get(), device); - plugin->OnInitialDiscoveryEvent(event); - } - }); -} - -void FastPairService::OnSubsequentDiscoveryEvent( - const FastPairDevice& device, SubsequentDiscoveryEvent event) {} - -void FastPairService::OnPairEvent(const FastPairDevice& device, - PairEvent event) { - executor_.Execute( - "on-pair-event", [this, device = &device, event = std::move(event)]() { - NEARBY_LOGS(INFO) << "OnPairEvent " << *device; - for (auto& entry : plugin_states_) { - auto plugin = entry.second.GetPlugin(seeker_.get(), device); - plugin->OnPairEvent(event); - } - }); -} - -void FastPairService::OnScreenEvent(ScreenEvent event) { - executor_.Execute("on-screen-event", [this, event = std::move(event)]() { - NEARBY_LOGS(INFO) << "OnScreenEvent "; - for (auto& entry : plugin_states_) { - for (auto& plugin : entry.second.plugins) { - plugin.second->OnScreenEvent(event); - } - } - }); -} -void FastPairService::OnBatteryEvent(const FastPairDevice& device, - BatteryEvent event) {} -void FastPairService::OnRingEvent(const FastPairDevice& device, - RingEvent event) {} - -void FastPairService::OnDeviceDestroyed(const FastPairDevice& device) { - NEARBY_LOGS(INFO) << "OnDeviceDestroyed " << device; - for (auto& entry : plugin_states_) { - entry.second.plugins.erase(&device); - } -} - -FastPairPlugin* FastPairService::PluginState::GetPlugin( - FastPairSeeker* seeker, const FastPairDevice* device) { - auto it = plugins.find(device); - if (it != plugins.end()) { - return it->second.get(); - } - auto result = plugins.insert({device, provider->GetPlugin(seeker, device)}); - DCHECK(result.second); - return result.first->second.get(); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/fast_pair_service.h b/fastpair/fast_pair_service.h deleted file mode 100644 index 10c95cf07b..0000000000 --- a/fastpair/fast_pair_service.h +++ /dev/null @@ -1,117 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_SERVICE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_SERVICE_H_ - -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "fastpair/fast_pair_plugin.h" -#include "fastpair/fast_pair_seeker.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/server_access/fast_pair_client.h" -#include "fastpair/server_access/fast_pair_http_notifier.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/auth/authentication_manager.h" -#include "internal/network/http_client.h" -#include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/platform/task_runner.h" -#include "internal/preferences/preferences_manager.h" - -namespace nearby { -namespace fastpair { - -// Fast Pair Seeker Service. There should be only one instance of the service -// running on the system. -class FastPairService { - public: - FastPairService(); - // Constructor for tests. Allows us to inject a serverless metadata - // repository. - FastPairService( - std::unique_ptr authentication_manager, - std::unique_ptr http_client, - std::unique_ptr device_info); - ~FastPairService(); - - // Registers a plugin provider. `name` must be a unique. - // Returns an error if a provider with the same `name` is already registered. - absl::Status RegisterPluginProvider( - absl::string_view name, std::unique_ptr provider); - - // Unregisters a plugin provider and removes all plugins created by that - // provider. Returns an error if there is no plugin provider registered with - // `name`. - absl::Status UnregisterPluginProvider(absl::string_view name); - - // Returns a `FastPairSeeker` implementation. The returned object has the - // same lifetime as this `FastPairService` instance. - FastPairSeeker* GetSeeker() const { return seeker_.get(); } - - // Returns a `AccountManager` implementation. The returned object has the - // same lifetime as this `FastPairService` instance. - AccountManager* GetAccountManager() { return account_manager_.get(); } - - // Returns a `FastPairRepository` implementation. The returned object has the - // same lifetime as this `FastPairService` instance. - FastPairRepository* GetFastPairRepository() { - return fast_pair_repository_.get(); - } - - private: - struct PluginState { - // Gets the plugin for `device`. Creates the plugin if it does not exist. - FastPairPlugin* GetPlugin(FastPairSeeker* seeker, - const FastPairDevice* device); - std::unique_ptr provider; - absl::flat_hash_map> - plugins; - }; - void OnInitialDiscoveryEvent(const FastPairDevice& device, - InitialDiscoveryEvent event); - void OnSubsequentDiscoveryEvent(const FastPairDevice& device, - SubsequentDiscoveryEvent event); - void OnPairEvent(const FastPairDevice& device, PairEvent event); - void OnScreenEvent(ScreenEvent event); - void OnBatteryEvent(const FastPairDevice& device, BatteryEvent event); - void OnRingEvent(const FastPairDevice& device, RingEvent event); - void OnDeviceDestroyed(const FastPairDevice& device); - - SingleThreadExecutor executor_; - FastPairHttpNotifier fast_pair_http_notifier_; - std::unique_ptr seeker_; - // Plugin name is the key. - absl::flat_hash_map plugin_states_; - FastPairDeviceRepository devices_{&executor_}; - std::unique_ptr authentication_manager_; - std::unique_ptr http_client_; - std::unique_ptr device_info_; - std::unique_ptr task_runner_; - std::unique_ptr preferences_manager_; - std::unique_ptr account_manager_; - std::unique_ptr fast_pair_client_; - std::unique_ptr fast_pair_repository_; - FastPairDeviceRepository::RemoveDeviceCallback on_device_destroyed_callback_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_FAST_PAIR_SERVICE_H_ diff --git a/fastpair/fast_pair_service_test.cc b/fastpair/fast_pair_service_test.cc deleted file mode 100644 index 7ab94f97fa..0000000000 --- a/fastpair/fast_pair_service_test.cc +++ /dev/null @@ -1,185 +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. - -#include "fastpair/fast_pair_service.h" - -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "fastpair/fast_pair_events.h" -#include "fastpair/internal/fast_pair_seeker_impl.h" -#include "fastpair/message_stream/fake_provider.h" -#include "fastpair/plugins/fake_fast_pair_plugin.h" -#include "internal/account/account_manager_impl.h" -#include "internal/network/http_client.h" -#include "internal/platform/device_info.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/test/fake_account_manager.h" -#include "internal/test/fake_device_info.h" -#include "internal/test/fake_http_client.h" -#include "internal/test/google3_only/fake_authentication_manager.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr absl::string_view kPluginName = "my plugin"; -constexpr absl::string_view kModelId{"718c17"}; -constexpr absl::string_view kPublicAntiSpoof = - "Wuyr48lD3txnUhGiMF1IfzlTwRxxe+wMB1HLzP+" - "0wVcljfT3XPoiy1fntlneziyLD5knDVAJSE+RM/zlPRP/Jg=="; -using ::testing::status::StatusIs; - -class FastPairServiceTest : public ::testing::Test { - protected: - FastPairServiceTest() { - AccountManagerImpl::Factory::SetFactoryForTesting([]() { - return std::make_unique(); - }); - http_client_ = std::make_unique(); - device_info_ = std::make_unique(); - authentication_manager_ = - std::make_unique(); - } - - void SetUp() override { - MediumEnvironment::Instance().Start(); - GetAuthManager()->EnableSyncMode(); - } - - void TearDown() override { - AccountManagerImpl::Factory::SetFactoryForTesting(nullptr); - MediumEnvironment::Instance().Stop(); - } - - nearby::FakeAuthenticationManager* GetAuthManager() { - return reinterpret_cast( - authentication_manager_.get()); - } - - network::FakeHttpClient* GetHttpClient() { - return reinterpret_cast(http_client_.get()); - } - - void SetUpDeviceMetadata() { - proto::GetObservedDeviceResponse response_proto; - auto* device = response_proto.mutable_device(); - int64_t device_id; - CHECK(absl::SimpleHexAtoi(kModelId, &device_id)); - device->set_id(device_id); - network::HttpResponse response; - response.SetStatusCode(network::HttpStatusCode::kHttpOk); - response.SetBody(response_proto.SerializeAsString()); - GetHttpClient()->SetResponseForSyncRequest(response); - } - - std::unique_ptr authentication_manager_; - std::unique_ptr http_client_; - std::unique_ptr device_info_; -}; - -TEST(FastPairService, RegisterUnregister) { - FastPairService service; - - EXPECT_OK(service.RegisterPluginProvider( - kPluginName, std::make_unique())); - EXPECT_OK(service.UnregisterPluginProvider(kPluginName)); -} - -TEST(FastPairService, RegisterTwiceFails) { - FastPairService service; - EXPECT_OK(service.RegisterPluginProvider( - kPluginName, std::make_unique())); - - EXPECT_THAT(service.RegisterPluginProvider( - kPluginName, std::make_unique()), - StatusIs(absl::StatusCode::kAlreadyExists)); -} - -TEST(FastPairService, UnregisterTwiceFails) { - FastPairService service; - EXPECT_OK(service.RegisterPluginProvider( - kPluginName, std::make_unique())); - EXPECT_OK(service.UnregisterPluginProvider(kPluginName)); - - EXPECT_THAT(service.UnregisterPluginProvider(kPluginName), - StatusIs(absl::StatusCode::kNotFound)); -} - -TEST_F(FastPairServiceTest, InitialDiscoveryEvent) { - FakeProvider provider; - SetUpDeviceMetadata(); - FastPairService service(std::move(authentication_manager_), - std::move(http_client_), std::move(device_info_)); - - CountDownLatch latch(1); - auto plugin_provider = std::make_unique(); - plugin_provider->on_initial_discovery_event_ = - [&](const FastPairDevice* device, const InitialDiscoveryEvent& event) { - NEARBY_LOGS(INFO) << "Initial discovery: " << device; - EXPECT_EQ(device->GetModelId(), kModelId); - latch.CountDown(); - }; - EXPECT_OK( - service.RegisterPluginProvider(kPluginName, std::move(plugin_provider))); - FastPairSeekerExt* seeker = - static_cast(service.GetSeeker()); - - EXPECT_OK(seeker->StartFastPairScan()); - provider.StartDiscoverableAdvertisement(kModelId); - latch.Await(); - - EXPECT_OK(seeker->StopFastPairScan()); - EXPECT_OK(service.UnregisterPluginProvider(kPluginName)); -} - -TEST_F(FastPairServiceTest, ScreenEvent) { - FakeProvider provider; - SetUpDeviceMetadata(); - FastPairService service(std::move(authentication_manager_), - std::move(http_client_), std::move(device_info_)); - - CountDownLatch latch(1); - auto plugin_provider = std::make_unique(); - plugin_provider->on_initial_discovery_event_ = - [&](const FastPairDevice* device, const InitialDiscoveryEvent& event) { - NEARBY_LOGS(INFO) << "Initial discovery: " << device; - EXPECT_EQ(device->GetModelId(), kModelId); - latch.CountDown(); - }; - plugin_provider->on_screen_event_ = [&](ScreenEvent event) { - EXPECT_TRUE(event.is_locked); - latch.CountDown(); - }; - EXPECT_OK( - service.RegisterPluginProvider(kPluginName, std::move(plugin_provider))); - FastPairSeekerExt* seeker = - static_cast(service.GetSeeker()); - EXPECT_OK(seeker->StartFastPairScan()); - provider.StartDiscoverableAdvertisement(kModelId); - seeker->SetIsScreenLocked(true); - latch.Await(); - - EXPECT_OK(seeker->StopFastPairScan()); - EXPECT_OK(service.UnregisterPluginProvider(kPluginName)); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/handshake/BUILD b/fastpair/handshake/BUILD deleted file mode 100644 index c845dac1c7..0000000000 --- a/fastpair/handshake/BUILD +++ /dev/null @@ -1,172 +0,0 @@ -# Copyright 2022 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. - -licenses(["notice"]) - -cc_library( - name = "handshake", - srcs = [ - "fast_pair_data_encryptor_impl.cc", - "fast_pair_gatt_service_client_impl.cc", - "fast_pair_handshake_impl.cc", - "fast_pair_handshake_lookup.cc", - ], - hdrs = [ - "fast_pair_data_encryptor.h", - "fast_pair_data_encryptor_impl.h", - "fast_pair_gatt_service_client.h", - "fast_pair_gatt_service_client_impl.h", - "fast_pair_handshake.h", - "fast_pair_handshake_impl.h", - "fast_pair_handshake_lookup.h", - ], - visibility = [ - "//:__subpackages__", - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//fastpair/crypto", - "//fastpair/dataparser", - "//fastpair/internal/mediums", - "//fastpair/repository", - "//internal/base:bluetooth_address", - "//internal/platform:comm", - "//internal/platform:types", - "//internal/platform:uuid", - "@boringssl//:crypto", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/functional:bind_front", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/synchronization", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:span", - ], -) - -cc_library( - name = "test_support", - hdrs = [ - "fake_fast_pair_data_encryptor.h", - "fake_fast_pair_gatt_service_client.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":handshake", - "//fastpair/common", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - ], -) - -cc_test( - name = "fast_pair_data_encryptor_impl_test", - size = "small", - srcs = [ - "fast_pair_data_encryptor_impl_test.cc", - ], - shard_count = 16, - deps = [ - ":handshake", - "//fastpair/common", - "//fastpair/crypto", - "//fastpair/dataparser", - "//fastpair/internal/mediums", - "//fastpair/repository:test_support", - "//fastpair/testing", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/functional:bind_front", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_gatt_service_client_impl_test", - size = "small", - srcs = [ - "fast_pair_gatt_service_client_impl_test.cc", - ], - shard_count = 16, - deps = [ - ":handshake", - ":test_support", - "//fastpair/common", - "//fastpair/internal/mediums", - "//fastpair/testing", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_handshake_impl_test", - size = "small", - srcs = [ - "fast_pair_handshake_impl_test.cc", - ], - shard_count = 16, - deps = [ - ":handshake", - ":test_support", - "//fastpair/common", - "//fastpair/crypto", - "//fastpair/proto:fastpair_cc_proto", - "//internal/platform:base", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_handshake_lookup_test", - size = "small", - srcs = [ - "fast_pair_handshake_lookup_test.cc", - ], - shard_count = 16, - deps = [ - ":handshake", - "//fastpair/common", - "//fastpair/internal/mediums", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/handshake/fake_fast_pair_data_encryptor.h b/fastpair/handshake/fake_fast_pair_data_encryptor.h deleted file mode 100644 index bdedc954ce..0000000000 --- a/fastpair/handshake/fake_fast_pair_data_encryptor.h +++ /dev/null @@ -1,85 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAKE_FAST_PAIR_DATA_ENCRYPTOR_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAKE_FAST_PAIR_DATA_ENCRYPTOR_H_ - -#include -#include -#include -#include - -#include "fastpair/common/constant.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" - -namespace nearby { -namespace fastpair { - -class FakeFastPairDataEncryptor : public FastPairDataEncryptor { - public: - FakeFastPairDataEncryptor() = default; - - void SetPublickey(std::optional> public_key) { - public_key_ = std::move(public_key); - } - - void SetEncryptedBytes( - std::array encrypted_bytes) { - encrypted_bytes_ = std::move(encrypted_bytes); - } - - void SetResponse(std::optional response) { - response_ = std::move(response); - } - - void SetPasskey(std::optional passkey) { - passkey_ = std::move(passkey); - } - - // FastPairDataEncryptor: - std::array EncryptBytes( - const std::array& bytes_to_encrypt) - const override { - return encrypted_bytes_; - } - - std::optional> GetPublicKey() const override { - return public_key_; - } - - void ParseDecryptResponse( - const std::vector& encrypted_response_bytes, - absl::AnyInvocable)> callback) - override { - callback(response_); - } - - void ParseDecryptPasskey( - const std::vector& encrypted_passkey_bytes, - absl::AnyInvocable)> callback) - override { - callback(passkey_); - } - - private: - std::optional> public_key_; - std::array encrypted_bytes_; - std::optional response_; - std::optional passkey_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAKE_FAST_PAIR_DATA_ENCRYPTOR_H_ diff --git a/fastpair/handshake/fake_fast_pair_gatt_service_client.h b/fastpair/handshake/fake_fast_pair_gatt_service_client.h deleted file mode 100644 index 019e2e0dae..0000000000 --- a/fastpair/handshake/fake_fast_pair_gatt_service_client.h +++ /dev/null @@ -1,80 +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. -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAKE_FAST_PAIR_GATT_SERVICE_CLIENT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAKE_FAST_PAIR_GATT_SERVICE_CLIENT_H_ - -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/handshake/fast_pair_gatt_service_client.h" - -namespace nearby { -namespace fastpair { - -// This class fakes FastPairGattServiceClient and permits setting which -// PairFailure, if any, is run with the callback. -class FakeFastPairGattServiceClient : public FastPairGattServiceClient { - public: - void InitializeGattConnection( - absl::AnyInvocable)> - on_gatt_initialized_callback) override { - on_initialized_callback_ = std::move(on_gatt_initialized_callback); - } - - void WriteRequestAsync( - uint8_t message_type, uint8_t flags, absl::string_view provider_address, - absl::string_view seekers_address, - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteResponseCallback write_response_callback) override { - key_based_write_response_callback_ = std::move(write_response_callback); - } - - void WritePasskeyAsync( - uint8_t message_type, uint32_t passkey, - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteResponseCallback write_response_callback) override { - passkey_write_response_callback_ = std::move(write_response_callback); - } - - void RunOnGattClientInitializedCallback( - std::optional failure = std::nullopt) { - std::move(on_initialized_callback_)(failure); - } - - void RunWriteResponseCallback( - absl::string_view value, - std::optional failure = std::nullopt) { - std::move(key_based_write_response_callback_)(value, failure); - } - - void RunWritePasskeyCallback( - absl::string_view value, - std::optional failure = std::nullopt) { - std::move(passkey_write_response_callback_)(value, failure); - } - - private: - absl::AnyInvocable)> on_initialized_callback_; - WriteResponseCallback key_based_write_response_callback_; - WriteResponseCallback passkey_write_response_callback_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAKE_FAST_PAIR_GATT_SERVICE_CLIENT_H_ diff --git a/fastpair/handshake/fast_pair_data_encryptor.h b/fastpair/handshake/fast_pair_data_encryptor.h deleted file mode 100644 index 4287066c81..0000000000 --- a/fastpair/handshake/fast_pair_data_encryptor.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_DATA_ENCRYPTOR_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_DATA_ENCRYPTOR_H_ - -#include -#include - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/constant.h" -#include "fastpair/crypto/decrypted_passkey.h" -#include "fastpair/crypto/decrypted_response.h" - -namespace nearby { -namespace fastpair { - -// Holds a secret key for a device and has methods to encrypt bytes, decrypt -// response and decrypt passkey. -class FastPairDataEncryptor { - public: - virtual ~FastPairDataEncryptor() = default; - - // Encrypts bytes with the stored secret key. - virtual std::array EncryptBytes( - const std::array& bytes_to_encrypt) const = 0; - - // Return stored PublicKey - virtual std::optional> GetPublicKey() const = 0; - - // Decrypt and parse decrypted response bytes with the stored secret key. - virtual void ParseDecryptResponse( - const std::vector& encrypted_response_bytes, - absl::AnyInvocable)> - callback) = 0; - - // Decrypt and parse decrypted passkey bytes with the stored secret key. - virtual void ParseDecryptPasskey( - const std::vector& encrypted_passkey_bytes, - absl::AnyInvocable)> - callback) = 0; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_DATA_ENCRYPTOR_H_ diff --git a/fastpair/handshake/fast_pair_data_encryptor_impl.cc b/fastpair/handshake/fast_pair_data_encryptor_impl.cc deleted file mode 100644 index 1d20a59366..0000000000 --- a/fastpair/handshake/fast_pair_data_encryptor_impl.cc +++ /dev/null @@ -1,172 +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. - -#include "fastpair/handshake/fast_pair_data_encryptor_impl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/protocol.h" -#include "fastpair/crypto/decrypted_passkey.h" -#include "fastpair/crypto/decrypted_response.h" -#include "fastpair/crypto/fast_pair_encryption.h" -#include "fastpair/crypto/fast_pair_key_pair.h" -#include "fastpair/dataparser/fast_pair_data_parser.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -namespace { -FastPairDataEncryptorImpl::Factory* g_test_factory_ = nullptr; - -bool ValidateInputSize(const std::vector& encrypted_bytes) { - if (encrypted_bytes.size() != kAesBlockByteSize) { - NEARBY_LOGS(VERBOSE) << __func__ << ": Encrypted bytes should have size = " - << kAesBlockByteSize - << ", actual = " << encrypted_bytes.size(); - return false; - } - return true; -} - -} // namespace - -// FastPairDataEncryptorImpl::Factory -void FastPairDataEncryptorImpl::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -FastPairDataEncryptorImpl::Factory::~Factory() = default; - -void FastPairDataEncryptorImpl::Factory::CreateAsync( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback) { - if (g_test_factory_) { - g_test_factory_->CreateInstance(device, - std::move(on_get_instance_callback)); - return; - } - - if (device.GetProtocol() == Protocol::kFastPairInitialPairing || - device.GetProtocol() == Protocol::kFastPairRetroactivePairing) { - CreateAsyncWithKeyExchange(device, std::move(on_get_instance_callback)); - } else { - CreateAsyncWithAccountKey(device, std::move(on_get_instance_callback)); - } -} - -void FastPairDataEncryptorImpl::Factory::CreateAsyncWithKeyExchange( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback) { - NEARBY_LOGS(VERBOSE) << __func__; - auto& metadata = device.GetMetadata(); - DCHECK(metadata); - std::optional key_pair = - FastPairEncryption::GenerateKeysWithEcdhKeyAgreement( - metadata->GetDetails().anti_spoofing_key_pair().public_key()); - if (!key_pair.has_value()) { - NEARBY_LOGS(INFO) << "Fail to generate key pair"; - std::move(on_get_instance_callback)(nullptr); - return; - } - - auto data_encryptor = - std::make_unique(key_pair.value()); - std::move(on_get_instance_callback)(std::move(data_encryptor)); -} - -void FastPairDataEncryptorImpl::Factory::CreateAsyncWithAccountKey( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback) { - NEARBY_LOGS(INFO) << __func__; - absl::string_view account_key = device.GetAccountKey().GetAsBytes(); - CHECK_EQ(account_key.size(), static_cast(kSharedSecretKeyByteSize)); - std::array shared_secret_key; - std::copy_n(account_key.begin(), kSharedSecretKeyByteSize, - shared_secret_key.begin()); - - std::move(on_get_instance_callback)( - std::make_unique( - std::move(shared_secret_key))); -} - -// FastPairDataEncryptorImpl -FastPairDataEncryptorImpl::FastPairDataEncryptorImpl(const KeyPair& key_pair) - : shared_secret_key_(key_pair.shared_secret_key), - public_key_(key_pair.public_key) {} - -FastPairDataEncryptorImpl::FastPairDataEncryptorImpl( - const std::array& shared_secret_key) - : shared_secret_key_(shared_secret_key) {} - -FastPairDataEncryptorImpl::~FastPairDataEncryptorImpl() = default; - -std::array FastPairDataEncryptorImpl::EncryptBytes( - const std::array& bytes_to_encrypt) const { - return FastPairEncryption::EncryptBytes(shared_secret_key_, bytes_to_encrypt); -} - -std::optional> -FastPairDataEncryptorImpl::GetPublicKey() const { - return public_key_; -} - -void FastPairDataEncryptorImpl::ParseDecryptResponse( - const std::vector& encrypted_response_bytes, - absl::AnyInvocable)> callback) { - if (!ValidateInputSize(encrypted_response_bytes)) { - callback(std::nullopt); - return; - } - - FastPairDataParser::ParseDecryptedResponse( - std::vector(shared_secret_key_.begin(), - shared_secret_key_.end()), - encrypted_response_bytes, std::move(callback)); -} - -void FastPairDataEncryptorImpl::ParseDecryptPasskey( - const std::vector& encrypted_passkey_bytes, - absl::AnyInvocable)> callback) { - if (!ValidateInputSize(encrypted_passkey_bytes)) { - callback(std::nullopt); - return; - } - FastPairDataParser::ParseDecryptedPasskey( - std::vector(shared_secret_key_.begin(), - shared_secret_key_.end()), - encrypted_passkey_bytes, std::move(callback)); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/handshake/fast_pair_data_encryptor_impl.h b/fastpair/handshake/fast_pair_data_encryptor_impl.h deleted file mode 100644 index 3c6c319af6..0000000000 --- a/fastpair/handshake/fast_pair_data_encryptor_impl.h +++ /dev/null @@ -1,103 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_DATA_ENCRYPTOR_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_DATA_ENCRYPTOR_IMPL_H_ - -#include - -#include -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/crypto/fast_pair_key_pair.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" - -namespace nearby { -namespace fastpair { - -// Holds a secret key for a device and has methods to encrypt bytes, decrypt -// response and decrypt passkey. -class FastPairDataEncryptorImpl : public FastPairDataEncryptor { - public: - class Factory { - public: - static void CreateAsync( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback); - - static void SetFactoryForTesting(Factory* test_factory); - - protected: - virtual ~Factory(); - - virtual void CreateInstance( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback) = 0; - - private: - static void CreateAsyncWithKeyExchange( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback); - - static void CreateAsyncWithAccountKey( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback); - }; - - std::array EncryptBytes( - const std::array& bytes_to_encrypt) - const override; - - std::optional> GetPublicKey() - const override; - - void ParseDecryptResponse( - const std::vector& encrypted_response_bytes, - absl::AnyInvocable)> callback) - override; - - void ParseDecryptPasskey( - const std::vector& encrypted_passkey_bytes, - absl::AnyInvocable)> callback) - override; - - explicit FastPairDataEncryptorImpl(const KeyPair& key_pair); - explicit FastPairDataEncryptorImpl( - const std::array& secret_key); - ~FastPairDataEncryptorImpl() override; - - private: - const std::array shared_secret_key_; - - // The public key is only required during initial pairing and optional during - // communication with paired devices. - const std::optional> public_key_ = - std::nullopt; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_DATA_ENCRYPTOR_IMPL_H_ diff --git a/fastpair/handshake/fast_pair_data_encryptor_impl_test.cc b/fastpair/handshake/fast_pair_data_encryptor_impl_test.cc deleted file mode 100644 index 80124ad43e..0000000000 --- a/fastpair/handshake/fast_pair_data_encryptor_impl_test.cc +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/handshake/fast_pair_data_encryptor_impl.h" - -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/functional/bind_front.h" -#include "absl/strings/escaping.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/protocol.h" -#include "fastpair/crypto/fast_pair_encryption.h" -#include "fastpair/dataparser/fast_pair_data_parser.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "internal/platform/count_down_latch.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr std::array kResponseBytes = { - 0x01, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D, - 0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, 0xF7, 0xB6}; - -constexpr std::array kPasskeyBytes = { - 0x02, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D, - 0xA0, 0xBA, 0xF0, 0xBB, 0x95, 0x1F, 0xF7, 0xB6}; - -constexpr char kPublicAntiSpoof[] = - "Wuyr48lD3txnUhGiMF1IfzlTwRxxe+wMB1HLzP+" - "0wVcljfT3XPoiy1fntlneziyLD5knDVAJSE+RM/zlPRP/Jg=="; -constexpr char kInvalidPublicAntiSpoof[] = "InvalidPublicAntiSpoof"; - -constexpr char kValidModelId[] = "718c17"; -constexpr char kTestAddress[] = "test_address"; -constexpr absl::Duration kWaitTimeout = absl::Milliseconds(200); - -class FastPairDataEncryptorImplTest : public testing::Test { - public: - void TearDown() override { data_encryptor_.reset(); } - - void FailedSetUpDeviceWithNoPublicKey() { - proto::GetObservedDeviceResponse response; - std::string decoded_key; - absl::Base64Unescape(kInvalidPublicAntiSpoof, &decoded_key); - response.mutable_device()->mutable_anti_spoofing_key_pair()->set_public_key( - decoded_key); - FastPairDevice device(kValidModelId, kTestAddress, - Protocol::kFastPairInitialPairing); - device.SetMetadata(DeviceMetadata(response)); - CountDownLatch latch(1); - FastPairDataEncryptorImpl::Factory::CreateAsync( - device, absl::bind_front( - &FastPairDataEncryptorImplTest::OnDataEncryptorCreateAsync, - this, latch)); - latch.Await(); - } - - void SuccessCreateFastPairDataEncryptorWithKeyExchange() { - proto::GetObservedDeviceResponse response; - std::string decoded_key; - absl::Base64Unescape(kPublicAntiSpoof, &decoded_key); - response.mutable_device()->mutable_anti_spoofing_key_pair()->set_public_key( - decoded_key); - FastPairDevice device(kValidModelId, kTestAddress, - Protocol::kFastPairInitialPairing); - device.SetMetadata(DeviceMetadata(response)); - CountDownLatch latch(1); - FastPairDataEncryptorImpl::Factory::CreateAsync( - device, absl::bind_front( - &FastPairDataEncryptorImplTest::OnDataEncryptorCreateAsync, - this, latch)); - latch.Await(); - } - - void SuccessCreateFastPairDataEncryptorWithAccountKey() { - FastPairDevice device(kValidModelId, kTestAddress, - Protocol::kFastPairSubsequentPairing); - const std::vector kAccountKey{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, - 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, - 0xCC, 0xDD, 0xEE, 0xFF}; - device.SetAccountKey( - AccountKey(std::string(kAccountKey.begin(), kAccountKey.end()))); - CountDownLatch latch(1); - FastPairDataEncryptorImpl::Factory::CreateAsync( - device, absl::bind_front( - &FastPairDataEncryptorImplTest::OnDataEncryptorCreateAsync, - this, latch)); - latch.Await(); - } - - void OnDataEncryptorCreateAsync( - CountDownLatch latch, - std::unique_ptr fast_pair_data_encryptor) { - data_encryptor_ = std::move(fast_pair_data_encryptor); - latch.CountDown(); - } - - std::array EncryptBytes() { - return data_encryptor_->EncryptBytes(kResponseBytes); - } - - void ParseDecryptedResponse() { - const std::array bytes = - data_encryptor_->EncryptBytes(kResponseBytes); - CountDownLatch latch(1); - data_encryptor_->ParseDecryptResponse( - std::vector(bytes.begin(), bytes.end()), - absl::bind_front( - &FastPairDataEncryptorImplTest::ParseDecryptedResponseCallback, - this, latch)); - latch.Await(); - } - - void ParseDecryptedResponseInvalidBytes() { - const std::array bytes = - data_encryptor_->EncryptBytes(kResponseBytes); - CountDownLatch latch(1); - data_encryptor_->ParseDecryptResponse( - std::vector(bytes.begin() + 3, bytes.end()), - absl::bind_front( - &FastPairDataEncryptorImplTest::ParseDecryptedResponseCallback, - this, latch)); - latch.Await(); - } - - void ParseDecryptedResponseCallback( - CountDownLatch latch, const std::optional& response) { - response_ = response; - latch.CountDown(); - } - - void ParseDecryptedPasskey() { - const std::array bytes = - data_encryptor_->EncryptBytes(kPasskeyBytes); - CountDownLatch latch(1); - data_encryptor_->ParseDecryptPasskey( - std::vector(bytes.begin(), bytes.end()), - absl::bind_front( - &FastPairDataEncryptorImplTest::ParseDecryptPasskeyCallback, this, - latch)); - latch.Await(); - } - - void ParseDecryptedPasskeyWithAccountKey() { - const std::array kAccountKey{ - 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, - 0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; - - auto bytes = FastPairEncryption::EncryptBytes(kAccountKey, kPasskeyBytes); - CountDownLatch latch(1); - data_encryptor_->ParseDecryptPasskey( - std::vector(bytes.begin(), bytes.end()), - absl::bind_front( - &FastPairDataEncryptorImplTest::ParseDecryptPasskeyCallback, this, - latch)); - latch.Await(); - } - - void ParseDecryptedPasskeyInvalidBytes() { - const std::array bytes = - data_encryptor_->EncryptBytes(kPasskeyBytes); - CountDownLatch latch(1); - data_encryptor_->ParseDecryptPasskey( - std::vector(bytes.begin() + 3, bytes.end()), - absl::bind_front( - &FastPairDataEncryptorImplTest::ParseDecryptPasskeyCallback, this, - latch)); - latch.Await(); - } - - void ParseDecryptResponseCallback( - CountDownLatch latch, const std::optional& response) { - response_ = response; - } - - void ParseDecryptPasskeyCallback( - CountDownLatch latch, const std::optional& passkey) { - passkey_ = passkey; - latch.CountDown(); - } - - protected: - std::unique_ptr data_encryptor_; - std::optional response_ = std::nullopt; - std::optional passkey_ = std::nullopt; - std::unique_ptr data_parser_; - - private: - std::unique_ptr device_; -}; - -TEST_F(FastPairDataEncryptorImplTest, NoKeyPair) { - FailedSetUpDeviceWithNoPublicKey(); - EXPECT_FALSE(data_encryptor_); -} - -TEST_F(FastPairDataEncryptorImplTest, - SuccessCreateFastPairDataEncryptorWithKeyExchange) { - EXPECT_FALSE(data_encryptor_); - SuccessCreateFastPairDataEncryptorWithKeyExchange(); - EXPECT_TRUE(data_encryptor_); -} - -TEST_F(FastPairDataEncryptorImplTest, - SuccessCreateFastPairDataEncryptorWithAccountKey) { - EXPECT_FALSE(data_encryptor_); - SuccessCreateFastPairDataEncryptorWithAccountKey(); - EXPECT_TRUE(data_encryptor_); -} - -TEST_F(FastPairDataEncryptorImplTest, GetPublicKey) { - SuccessCreateFastPairDataEncryptorWithKeyExchange(); - EXPECT_TRUE(data_encryptor_); - EXPECT_NE(data_encryptor_->GetPublicKey(), std::nullopt); -} - -TEST_F(FastPairDataEncryptorImplTest, GetNoPublicKey) { - SuccessCreateFastPairDataEncryptorWithAccountKey(); - EXPECT_TRUE(data_encryptor_); - EXPECT_EQ(data_encryptor_->GetPublicKey(), std::nullopt); -} - -TEST_F(FastPairDataEncryptorImplTest, EncryptBytesWithKeyExchange) { - SuccessCreateFastPairDataEncryptorWithKeyExchange(); - EXPECT_TRUE(data_encryptor_); - EXPECT_FALSE(EncryptBytes().empty()); -} - -TEST_F(FastPairDataEncryptorImplTest, EncryptBytesWithAccountKey) { - SuccessCreateFastPairDataEncryptorWithAccountKey(); - EXPECT_TRUE(data_encryptor_); - EXPECT_FALSE(EncryptBytes().empty()); -} - -TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseWithKeyExchange) { - SuccessCreateFastPairDataEncryptorWithKeyExchange(); - EXPECT_TRUE(data_encryptor_); - ParseDecryptedResponse(); - EXPECT_TRUE(response_); - const std::array kAddressBytes = { - 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32}; - EXPECT_EQ(response_->address_bytes, kAddressBytes); - EXPECT_EQ(response_->message_type, - FastPairMessageType::kKeyBasedPairingResponse); -} - -TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseWithAccountKey) { - SuccessCreateFastPairDataEncryptorWithAccountKey(); - EXPECT_TRUE(data_encryptor_); - ParseDecryptedResponse(); - EXPECT_TRUE(response_); - const std::array kAddressBytes = { - 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32}; - EXPECT_EQ(response_->address_bytes, kAddressBytes); - EXPECT_EQ(response_->message_type, - FastPairMessageType::kKeyBasedPairingResponse); -} - -TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseInvalidInputSize) { - SuccessCreateFastPairDataEncryptorWithKeyExchange(); - EXPECT_TRUE(data_encryptor_); - ParseDecryptedResponseInvalidBytes(); - EXPECT_FALSE(response_); -} - -TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyWithKeyExchange) { - SuccessCreateFastPairDataEncryptorWithKeyExchange(); - EXPECT_TRUE(data_encryptor_); - ParseDecryptedPasskey(); - EXPECT_TRUE(passkey_); - // Passkey bytes. - std::array passkey_bytes = {0x5E, 0x3F, 0x45}; - uint32_t passkey = passkey_bytes[2]; - passkey += passkey_bytes[1] << 8; - passkey += passkey_bytes[0] << 16; - - EXPECT_EQ(passkey_->passkey, passkey); - EXPECT_EQ(passkey_->message_type, FastPairMessageType::kSeekersPasskey); -} - -TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyWithAccountKey) { - SuccessCreateFastPairDataEncryptorWithAccountKey(); - EXPECT_TRUE(data_encryptor_); - ParseDecryptedPasskeyWithAccountKey(); - EXPECT_TRUE(passkey_); - // Passkey bytes. - std::array passkey_bytes = {0x5E, 0x3F, 0x45}; - uint32_t passkey = passkey_bytes[2]; - passkey += passkey_bytes[1] << 8; - passkey += passkey_bytes[0] << 16; - - EXPECT_EQ(passkey_->passkey, passkey); - EXPECT_EQ(passkey_->message_type, FastPairMessageType::kSeekersPasskey); -} - -TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyInvalidInputSize) { - SuccessCreateFastPairDataEncryptorWithKeyExchange(); - EXPECT_TRUE(data_encryptor_); - ParseDecryptedPasskeyInvalidBytes(); - EXPECT_FALSE(passkey_); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/handshake/fast_pair_gatt_service_client.h b/fastpair/handshake/fast_pair_gatt_service_client.h deleted file mode 100644 index 5a2351f8b9..0000000000 --- a/fastpair/handshake/fast_pair_gatt_service_client.h +++ /dev/null @@ -1,76 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_GATT_SERVICE_CLIENT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_GATT_SERVICE_CLIENT_H_ - -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "internal/platform/ble_v2.h" - -namespace nearby { -namespace fastpair { -using WriteResponseCallback = absl::AnyInvocable failure)>; -using WriteAccountkeyCallback = absl::AnyInvocable account_key, std::optional failure)>; - -// This class is responsible for connecting to the Fast Pair GATT service for a -// device and invoking a callback when ready, or when an error is discovered -// during initialization. -class FastPairGattServiceClient { - public: - virtual ~FastPairGattServiceClient() = default; - - virtual void InitializeGattConnection( - absl::AnyInvocable)> - on_gatt_initialized_callback) = 0; - - // Constructs a data vector based on the message type, flags, provider - // address, and seekers address. - // Subscribe a notification for key based Pairing. - // Once the notification subscribed successfully, the message data will be - // written to the key based characteristic. - virtual void WriteRequestAsync( - uint8_t message_type, uint8_t flags, absl::string_view provider_address, - absl::string_view seekers_address, - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteResponseCallback write_response_callback) = 0; - - // Constructs a data vector based on the message type and passkey. - // Subscribe a notification for the passkey. - // Once the notification subscribed successfully, the passkey data will be - // written to the passkey characteristic. - virtual void WritePasskeyAsync( - uint8_t message_type, uint32_t passkey, - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteResponseCallback write_response_callback) = 0; - - // Writes the account key to the account key characteristic. - virtual void WriteAccountKey( - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteAccountkeyCallback write_accountkey_callback) = 0; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_GATT_SERVICE_CLIENT_H_ diff --git a/fastpair/handshake/fast_pair_gatt_service_client_impl.cc b/fastpair/handshake/fast_pair_gatt_service_client_impl.cc deleted file mode 100644 index 9ca2c66aaa..0000000000 --- a/fastpair/handshake/fast_pair_gatt_service_client_impl.cc +++ /dev/null @@ -1,401 +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. - -#include "fastpair/handshake/fast_pair_gatt_service_client_impl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/functional/bind_front.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "absl/types/span.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_gatt_service_client.h" -#include "fastpair/internal/mediums/mediums.h" -#include "internal/base/bluetooth_address.h" -#include "internal/platform/logging.h" -#include "internal/platform/uuid.h" -#include - -namespace nearby { -namespace fastpair { - -namespace { -// We have two UUID possibilities for each characteristic because they changed -// across different Fast Pair versions. -constexpr Uuid kFastPairServiceUuid(0x0000FE2C00001000, 0x800000805F9B34FB); -constexpr Uuid kKeyBasedCharacteristicUuidV1(0x0000123400001000, - 0x800000805F9B34FB); -constexpr Uuid kKeyBasedCharacteristicUuidV2(0xFE2C123483664814, - 0x8EB001DE32100BEA); -constexpr Uuid kPasskeyCharacteristicUuidV1(0x0000123500001000, - 0x800000805F9B34FB); -constexpr Uuid kPasskeyCharacteristicUuidV2(0xFE2C123583664814, - 0x8EB001DE32100BEA); -constexpr Uuid kAccountKeyCharacteristicUuidV1(0x0000123600001000, - 0x800000805F9B34FB); -constexpr Uuid kAccountKeyCharacteristicUuidV2(0xFE2C123683664814, - 0x8EB001DE32100BEA); - -constexpr int kKeyBasedCharacteristicIndex = 0; -constexpr int kPasskeyCharacteristicIndex = 1; -constexpr int kAccountKeyCharacteristicIndex = 2; -constexpr int kNumCharacteristics = 3; - -constexpr absl::Duration kGattOperationTimeout = absl::Seconds(15); -constexpr int kMaxNumGattConnectionAttempts = 3; -} // namespace - -// FastPairGattServiceClientImpl::Factory -// static -FastPairGattServiceClientImpl::Factory* - FastPairGattServiceClientImpl::Factory::g_test_factory_ = nullptr; - -// static -std::unique_ptr -FastPairGattServiceClientImpl::Factory::Create(const FastPairDevice& device, - Mediums& mediums, - SingleThreadExecutor* executor) { - if (g_test_factory_) { - return g_test_factory_->CreateInstance(); - } - - return std::make_unique(device, mediums, - executor); -} - -// static -void FastPairGattServiceClientImpl::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -FastPairGattServiceClientImpl::Factory::~Factory() = default; - -FastPairGattServiceClientImpl::FastPairGattServiceClientImpl( - const FastPairDevice& device, Mediums& mediums, - SingleThreadExecutor* executor) - : device_address_(device.GetBleAddress()), - mediums_(mediums), - executor_(executor) { - gatt_connection_params_.service_uuid = kFastPairServiceUuid; - gatt_connection_params_.characteristic_uuids.resize(kNumCharacteristics); - gatt_connection_params_.characteristic_uuids[kKeyBasedCharacteristicIndex] = { - kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}; - gatt_connection_params_.characteristic_uuids[kPasskeyCharacteristicIndex] = { - kPasskeyCharacteristicUuidV2, kPasskeyCharacteristicUuidV1}; - gatt_connection_params_.characteristic_uuids[kAccountKeyCharacteristicIndex] = - {kAccountKeyCharacteristicUuidV2, kAccountKeyCharacteristicUuidV1}; -} - -void FastPairGattServiceClientImpl::InitializeGattConnection( - absl::AnyInvocable)> - on_gatt_initialized_callback) { - NEARBY_LOGS(INFO) << __func__ - << ": Starting the GATT connection to the device."; - on_gatt_initialized_callback_ = std::move(on_gatt_initialized_callback); - AttemptGattConnection(); -} - -void FastPairGattServiceClientImpl::AttemptGattConnection() { - NEARBY_LOGS(INFO) << __func__ << ": Attempt to connect to the device."; - ClearCurrentState(); - CreateGattConnection(); -} - -void FastPairGattServiceClientImpl::CreateGattConnection() { - NEARBY_LOGS(INFO) << __func__ << " : Create Gatt Connection to the device."; - MutexLock lock(&mutex_); - if (mediums_.GetBluetoothRadio().Enable() && - mediums_.GetBleV2().IsAvailable()) { - gatt_client_ = mediums_.GetBleV2().ConnectToGattServer( - device_address_, gatt_connection_params_, [this](absl::Status status) { - NEARBY_LOGS(INFO) << "Gatt connection status: " << status; - if (status.ok()) { - executor_->Execute("init-success", [this]() { - if (on_gatt_initialized_callback_) { - std::move(on_gatt_initialized_callback_)(std::nullopt); - } - }); - } else { - NotifyInitializedError(PairFailure::kCreateGattConnection); - } - }); - } - if (gatt_client_) { - is_initialized_ = true; - } else { - // The device must have been lost between connection attempts. - NotifyInitializedError( - PairFailure::kPairingDeviceLostBetweenGattConnectionAttempts); - return; - } -} - -std::array -FastPairGattServiceClientImpl::CreateRequest( - uint8_t message_type, uint8_t flags, absl::string_view provider_address, - absl::string_view seekers_address) { - std::array data_to_write; - RAND_bytes(data_to_write.data(), kAesBlockByteSize); - - data_to_write[0] = message_type; - data_to_write[1] = flags; - - std::array provider_address_bytes; - - device::ParseBluetoothAddress(provider_address, - absl::MakeSpan(provider_address_bytes.data(), - provider_address_bytes.size())); - std::copy(provider_address_bytes.begin(), provider_address_bytes.end(), - std::begin(data_to_write) + kProviderAddressStartIndex); - - // Seekers address can be empty, in which we would just have the bytes be - // the salt. - if (!seekers_address.empty()) { - std::array seeker_address_bytes; - device::ParseBluetoothAddress(seekers_address, - absl::MakeSpan(seeker_address_bytes.data(), - seeker_address_bytes.size())); - std::copy(seeker_address_bytes.begin(), seeker_address_bytes.end(), - std::begin(data_to_write) + kSeekerAddressStartIndex); - } - return data_to_write; -} - -std::array -FastPairGattServiceClientImpl::CreatePasskeyBlock(uint8_t message_type, - uint32_t passkey) { - std::array data_to_write; - RAND_bytes(data_to_write.data(), kAesBlockByteSize); - - data_to_write[0] = message_type; - - // Need to convert the uint_32 to uint_8 to use in our data vector. - data_to_write[1] = (passkey & 0x00ff0000) >> 16; - data_to_write[2] = (passkey & 0x0000ff00) >> 8; - data_to_write[3] = passkey & 0x000000ff; - return data_to_write; -} - -std::array -FastPairGattServiceClientImpl::CreateAccountKeyBlock() { - std::array account_key; - RAND_bytes(account_key.data(), account_key.size()); - account_key[0] = 0x04; - return account_key; -} - -void FastPairGattServiceClientImpl::WriteRequestAsync( - uint8_t message_type, uint8_t flags, absl::string_view provider_address, - absl::string_view seekers_address, - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteResponseCallback callback) { - CHECK(!key_based_write_response_callback_); - - key_based_write_response_callback_ = std::move(callback); - - const std::array data_to_write = - fast_pair_data_encryptor.EncryptBytes(CreateRequest( - message_type, flags, provider_address, seekers_address)); - std::vector data_to_write_vec(data_to_write.begin(), - data_to_write.end()); - - // Append the public version of the private key to the message so the device - // can generate the shared secret to decrypt the message. - const std::optional> public_key = - fast_pair_data_encryptor.GetPublicKey(); - - if (public_key) { - const std::vector public_key_vec = std::vector( - public_key.value().begin(), public_key.value().end()); - data_to_write_vec.insert(data_to_write_vec.end(), public_key_vec.begin(), - public_key_vec.end()); - } - - // Write public address request to the keybased characteristic and get - // response. - WriteKeyBasedCharacteristic( - std::string(data_to_write_vec.begin(), data_to_write_vec.end())); - } - -void FastPairGattServiceClientImpl::WriteKeyBasedCharacteristic( - absl::string_view request) { - NEARBY_LOGS(INFO) << __func__ << " :Start to write keybased characteristic."; - MutexLock lock(&mutex_); - gatt_client_->CallRemoteFunction( - kKeyBasedCharacteristicIndex, request, - [this](absl::StatusOr response) { - if (response.ok()) { - NEARBY_LOGS(INFO) - << __func__ << ": key based characteristic value changed."; - NotifyWriteRequestResult(*response); - } else { - NEARBY_LOGS(INFO) - << __func__ << ": Failed to write the key based characteristic: " - << response.status(); - PairFailure failure = - absl::IsDeadlineExceeded(response.status()) - ? PairFailure::kKeyBasedPairingResponseTimeout - : PairFailure::kKeyBasedPairingCharacteristicWrite; - NotifyWriteRequestError(failure); - } - }); -} - -void FastPairGattServiceClientImpl::WritePasskeyAsync( - uint8_t message_type, uint32_t passkey, - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteResponseCallback callback) { - CHECK(is_initialized_); - CHECK(message_type == kSeekerPasskey); - - passkey_write_response_callback_ = std::move(callback); - const std::array data_to_write = - fast_pair_data_encryptor.EncryptBytes( - CreatePasskeyBlock(message_type, passkey)); - std::vector data_to_write_vec(data_to_write.begin(), - data_to_write.end()); - - // Write passkey confirmation request to the passkey characteristic - WritePasskeyCharacteristic( - std::string(data_to_write_vec.begin(), data_to_write_vec.end())); - } - -void FastPairGattServiceClientImpl::WritePasskeyCharacteristic( - absl::string_view request) { - MutexLock lock(&mutex_); - gatt_client_->CallRemoteFunction( - kPasskeyCharacteristicIndex, request, - [this](absl::StatusOr response) { - if (response.ok()) { - NEARBY_LOGS(INFO) - << __func__ << ": Passkey characteristic value changed."; - NotifyWritePasskeyResult(*response); - } else { - NEARBY_LOGS(INFO) - << __func__ << ": Failed to write the passkey characteristic " - << response.status(); - PairFailure failure = - absl::IsDeadlineExceeded(response.status()) - ? PairFailure::kPasskeyResponseTimeout - : PairFailure::kPasskeyPairingCharacteristicWrite; - NotifyWritePasskeyError(failure); - } - }); -} - -void FastPairGattServiceClientImpl::WriteAccountKey( - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteAccountkeyCallback write_accountkey_callback) { - MutexLock lock(&mutex_); - CHECK(is_initialized_); - account_key_write_callback_ = std::move(write_accountkey_callback); - std::array raw_account_key = - CreateAccountKeyBlock(); - const std::array data_to_write = - fast_pair_data_encryptor.EncryptBytes(raw_account_key); - gatt_client_->WriteCharacteristic( - kAccountKeyCharacteristicIndex, - std::string(data_to_write.begin(), data_to_write.end()), - api::ble_v2::GattClient::WriteType::kWithResponse, - [this, account_key = - std::string(raw_account_key.begin(), raw_account_key.end())]( - absl::Status status) { - if (status.ok()) { - NEARBY_LOGS(INFO) - << __func__ - << ": Successfully write the accoutkey characteristic."; - NotifyWriteAccountKeyResult(AccountKey(account_key)); - } else { - NEARBY_LOGS(INFO) - << __func__ << ": Failed to write the passkey characteristic "; - NotifyWriteAccountKeyError( - PairFailure::kAccountKeyCharacteristicWrite); - } - }); -} - -void FastPairGattServiceClientImpl::NotifyInitializedError( - PairFailure failure) { - NEARBY_LOGS(VERBOSE) << __func__ << failure; - ClearCurrentState(); - - executor_->Execute("init-error", [this, failure]() { - if (on_gatt_initialized_callback_) { - NEARBY_LOGS(VERBOSE) << __func__ << "Executing initialized callback"; - std::move(on_gatt_initialized_callback_)(failure); - } - }); -} - -void FastPairGattServiceClientImpl::NotifyWriteRequestResult( - absl::string_view value, std::optional failure) { - NEARBY_LOGS(VERBOSE) << __func__; - executor_->Execute( - "key-based-response", [this, value = std::string(value), failure]() { - if (key_based_write_response_callback_) { - std::move(key_based_write_response_callback_)(value, failure); - } - }); -} - -void FastPairGattServiceClientImpl::NotifyWritePasskeyResult( - absl::string_view value, std::optional failure) { - NEARBY_LOGS(VERBOSE) << __func__; - executor_->Execute( - "passkey-response", [this, value = std::string(value), failure]() { - if (passkey_write_response_callback_) { - std::move(passkey_write_response_callback_)(value, failure); - } - }); -} - -void FastPairGattServiceClientImpl::NotifyWriteAccountKeyResult( - std::optional account_key, std::optional failure) { - NEARBY_LOGS(VERBOSE) << __func__; - executor_->Execute("passkey-response", [this, account_key, failure]() { - if (account_key_write_callback_) { - std::move(account_key_write_callback_)(account_key, failure); - } - }); -} - -void FastPairGattServiceClientImpl::ClearCurrentState() { - MutexLock lock(&mutex_); - executor_->Execute("clear-current-state", - [this, gatt_client = std::move(gatt_client_)]() mutable { - if (gatt_client != nullptr) { - gatt_client->Stop(); - defunct_gatt_client_ = std::move(gatt_client); - } - }); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/handshake/fast_pair_gatt_service_client_impl.h b/fastpair/handshake/fast_pair_gatt_service_client_impl.h deleted file mode 100644 index cad75110b0..0000000000 --- a/fastpair/handshake/fast_pair_gatt_service_client_impl.h +++ /dev/null @@ -1,164 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_GATT_SERVICE_CLIENT_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_GATT_SERVICE_CLIENT_IMPL_H_ - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/handshake/fast_pair_gatt_service_client.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/internal/mediums/robust_gatt_client.h" -#include "internal/platform/mutex.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -// This class is responsible for connecting to the Fast Pair GATT service for a -// device and invoking a callback when ready, or when an error is discovered -// during initialization. -class FastPairGattServiceClientImpl : public FastPairGattServiceClient { - public: - class Factory { - public: - static std::unique_ptr Create( - const FastPairDevice& device, Mediums& mediums, - SingleThreadExecutor* executor); - static void SetFactoryForTesting(Factory* test_factory); - - protected: - virtual ~Factory(); - virtual std::unique_ptr CreateInstance() = 0; - - private: - static Factory* g_test_factory_; - }; - - explicit FastPairGattServiceClientImpl(const FastPairDevice& device, - Mediums& mediums, - SingleThreadExecutor* executor); - FastPairGattServiceClientImpl(const FastPairGattServiceClientImpl&) = delete; - FastPairGattServiceClientImpl& operator=( - const FastPairGattServiceClientImpl&) = delete; - ~FastPairGattServiceClientImpl() override = default; - - void InitializeGattConnection( - absl::AnyInvocable)> - on_gatt_initialized_callback) override; - - void WriteRequestAsync( - uint8_t message_type, uint8_t flags, absl::string_view provider_address, - absl::string_view seekers_address, - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteResponseCallback write_response_callback) override; - - void WritePasskeyAsync( - uint8_t message_type, uint32_t passkey, - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteResponseCallback write_response_callback) override; - - void WriteAccountKey( - const FastPairDataEncryptor& fast_pair_data_encryptor, - WriteAccountkeyCallback write_accountkey_callback) override; - - // Allows tests to modify GATT operation timeouts. - RobustGattClient::ConnectionParams& GetConnectionParams() { - return gatt_connection_params_; - } - - private: - // Attempt to create a GATT connection with the device. This method may be - // called multiple times. - void AttemptGattConnection(); - void CreateGattConnection(); - - // Operations on KeyBased Characteristic - // Creates a data vector based on parameter information. - std::array CreateRequest( - uint8_t message_type, uint8_t flags, absl::string_view provider_address, - absl::string_view seekers_address); - // Write request to KeyBased Characteristic - void WriteKeyBasedCharacteristic(absl::string_view request); - - // Operations on Passkey Characteristic - // Creates a data vector based on parameter information. - std::array CreatePasskeyBlock( - uint8_t message_type, uint32_t passkey); - // Write request to Passkey Characteristic - void WritePasskeyCharacteristic(absl::string_view request); - - // Operations on Account Key Characteristic - // Creates an Account key. - std::array CreateAccountKeyBlock(); - - // Invokes the initialized callback with the proper PairFailure and clears - // local state. - void NotifyInitializedError(PairFailure failure); - // Invokes the write response callback with the proper PairFailure on a - // write error. - void NotifyWriteRequestError(PairFailure failure) { - NotifyWriteRequestResult("", failure); - } - void NotifyWriteRequestResult(absl::string_view value, - std::optional = std::nullopt); - void NotifyWritePasskeyError(PairFailure failure) { - NotifyWritePasskeyResult("", failure); - } - void NotifyWritePasskeyResult(absl::string_view value, - std::optional = std::nullopt); - void NotifyWriteAccountKeyError(PairFailure failure) { - NotifyWriteAccountKeyResult(std::nullopt, failure); - } - void NotifyWriteAccountKeyResult( - std::optional account_key, - std::optional failure = std::nullopt); - - void ClearCurrentState(); - - // Timers - TimerImpl passkey_subscription_timer_; - TimerImpl key_based_write_request_timer_; - TimerImpl passkey_write_request_timer_; - TimerImpl account_key_write_request_timer_; - - void OnGattServiceDiscoveryTimeout(); - - // Callback - absl::AnyInvocable)> - on_gatt_initialized_callback_; - WriteResponseCallback key_based_write_response_callback_; - WriteResponseCallback passkey_write_response_callback_; - WriteAccountkeyCallback account_key_write_callback_; - - Mutex mutex_; - bool is_initialized_ = false; - std::string device_address_; - std::unique_ptr gatt_client_ ABSL_GUARDED_BY(mutex_); - std::unique_ptr defunct_gatt_client_; - RobustGattClient::ConnectionParams gatt_connection_params_; - Mediums& mediums_; - SingleThreadExecutor* executor_; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_GATT_SERVICE_CLIENT_IMPL_H_ diff --git a/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc b/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc deleted file mode 100644 index 3d5b30948c..0000000000 --- a/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc +++ /dev/null @@ -1,416 +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. - -#include "fastpair/handshake/fast_pair_gatt_service_client_impl.h" - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/common/protocol.h" -#include "fastpair/handshake/fake_fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_gatt_service_client.h" -#include "fastpair/internal/mediums/mediums.h" -#include "internal/platform/ble_v2.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -namespace { -using Property = nearby::api::ble_v2::GattCharacteristic::Property; -using Permission = nearby::api::ble_v2::GattCharacteristic::Permission; -using GattCharacteristic = nearby::api::ble_v2::GattCharacteristic; -using WriteType = nearby::api::ble_v2::GattClient::WriteType; - -constexpr absl::Duration kGattOperationTimeout = absl::Seconds(15); -constexpr absl::string_view kMetadataId("test_id"); -constexpr absl::string_view kSeekerAddress("AA:BB:CC:DD:EE:00"); -constexpr Uuid kFastPairServiceUuid(0x0000FE2C00001000, 0x800000805F9B34FB); -constexpr Uuid kKeyBasedCharacteristicUuidV2(0xFE2C123483664814, - 0x8EB001DE32100BEA); -constexpr Uuid kPasskeyCharacteristicUuidV2(0xFE2C123583664814, - 0x8EB001DE32100BEA); -constexpr Uuid kAccountKeyCharacteristicUuidV2(0xFE2C123683664814, - 0x8EB001DE32100BEA); -// Length of advertisement byte should be 16 -constexpr absl::string_view kKeyBasedCharacteristicAdvertisementByte = - "keyBasedCharacte"; -constexpr absl::string_view kPasskeyharacteristicAdvertisementByte = - "passkeyCharacter"; -constexpr Uuid kWrongServiceId(0x0000FE2B00001000, 0x800000805F9B34FB); -constexpr uint8_t kMessageType = 0x00; -constexpr uint8_t kFlags = 0x00; - -constexpr uint32_t kPasskey = 123456; - -constexpr std::array kPublicKey = { - 0x01, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D, 0x01, 0x5E, 0x3F, - 0x45, 0x61, 0xC3, 0x32, 0x1D, 0x01, 0x5E, 0x3F, 0x45, 0x61, 0xC3, - 0x32, 0x1D, 0x01, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D, 0x01, - 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D, 0x01, 0x5E, 0x3F, 0x45, - 0x61, 0xC3, 0x32, 0x1D, 0x01, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, - 0x1D, 0x01, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D}; -} // namespace - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -struct CharacteristicData { - // Write result returned to the gatt client. - absl::Status write_result; - std::optional notify_response; -}; - -class FastPairGattServiceClientTest : public testing::Test { - public: - FastPairGattServiceClientTest() { - fast_pair_data_encryptor_ = std::make_unique(); - fast_pair_data_encryptor_->SetPublickey(kPublicKey); - } - - void SetUp() override { - gatt_server_ = - provider_ble_.StartGattServer(/*ServerGattConnectionCallback=*/{ - .on_characteristic_write_cb = - [&](const api::ble_v2::BlePeripheral& remote_device, - const api::ble_v2::GattCharacteristic& characteristic, - int offset, absl::string_view data, - BleV2Medium::ServerGattConnectionCallback:: - WriteValueCallback callback) { - auto it = characteristics_.find(characteristic); - if (it == characteristics_.end()) { - callback(absl::NotFoundError("characteristic not found")); - return; - } - callback(it->second.write_result); - if (it->second.notify_response.has_value()) { - NEARBY_LOGS(INFO) << "Notify seeker"; - auto ignored = gatt_server_->NotifyCharacteristicChanged( - characteristic, false, - ByteArray(*it->second.notify_response)); - } - }}); - provider_address_ = *gatt_server_->GetBlePeripheral().GetAddress(); - device_ = std::make_unique( - kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); - } - - void TearDown() override { - executor_.Shutdown(); - key_based_characteristic_ = std::nullopt; - passkey_characteristic_ = std::nullopt; - accountkey_characteristic_ = std::nullopt; - characteristics_.clear(); - initalized_failure_ = std::nullopt; - write_failure_ = std::nullopt; - gatt_client_.reset(); - gatt_server_->Stop(); - gatt_server_.reset(); - } - - void InsertCorrectGattCharacteristics() { - key_based_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kKeyBasedCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*key_based_characteristic_].write_result = - absl::OkStatus(); - - passkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kPasskeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*passkey_characteristic_].write_result = absl::OkStatus(); - - accountkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kAccountKeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*accountkey_characteristic_].write_result = - absl::OkStatus(); - } - - void InsertCharacteristicsWithWrongServiceId() { - key_based_characteristic_ = gatt_server_->CreateCharacteristic( - kWrongServiceId, kKeyBasedCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*key_based_characteristic_].write_result = - absl::OkStatus(); - - passkey_characteristic_ = gatt_server_->CreateCharacteristic( - kWrongServiceId, kPasskeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*passkey_characteristic_].write_result = absl::OkStatus(); - - accountkey_characteristic_ = gatt_server_->CreateCharacteristic( - kWrongServiceId, kAccountKeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*accountkey_characteristic_].write_result = - absl::OkStatus(); - } - - void InitializeFastPairGattServiceClient(bool short_timeouts = false) { - CountDownLatch latch(1); - gatt_client_ = FastPairGattServiceClientImpl::Factory::Create( - *device_, mediums_, &executor_); - if (short_timeouts) { - FastPairGattServiceClientImpl* impl = - dynamic_cast(gatt_client_.get()); - auto& params = impl->GetConnectionParams(); - params.gatt_operation_timeout = absl::Seconds(1); - params.gatt_operation_timeout = absl::Seconds(1); - params.max_back_off = absl::Milliseconds(500); - } - gatt_client_->InitializeGattConnection( - [&](std::optional failure) { - initalized_failure_ = failure; - latch.CountDown(); - }); - latch.Await(); - } - - std::optional GetInitializedCallbackResult() { - return initalized_failure_; - } - - void WriteTestCallback(std::optional failure) { - write_failure_ = failure; - } - - std::optional GetWriteCallbackResult() { return write_failure_; } - - void WriteRequestToKeyBased() { - CountDownLatch latch(1); - gatt_client_->WriteRequestAsync( - kMessageType, kFlags, provider_address_, /* Seeker Address*/ "", - *fast_pair_data_encryptor_, - [&](absl::string_view response, std::optional failure) { - EXPECT_FALSE(response.empty()); - WriteTestCallback(failure); - latch.CountDown(); - }); - latch.Await(); - } - - void WriteRequestToPasskey() { - CountDownLatch latch(1); - gatt_client_->WritePasskeyAsync( - kSeekerPasskey, kPasskey, *fast_pair_data_encryptor_, - [&](absl::string_view response, std::optional failure) { - EXPECT_FALSE(response.empty()); - WriteTestCallback(failure); - latch.CountDown(); - }); - latch.Await(); - } - - void WriteRequestToAccountkey() { - CountDownLatch latch(1); - gatt_client_->WriteAccountKey(*fast_pair_data_encryptor_, - [&](std::optional account_key, - std::optional failure) { - EXPECT_TRUE(account_key.has_value()); - WriteTestCallback(failure); - latch.CountDown(); - }); - latch.Await(); - } - - void SetKeyBaseCharacteristicsWriteResultToFailure() { - auto it = characteristics_.find(*key_based_characteristic_); - it->second.write_result = absl::UnknownError("Failed to write account key"); - } - - void SetPasskeyCharacteristicsWriteResultToFailure() { - auto it = characteristics_.find(*passkey_characteristic_); - it->second.write_result = absl::UnknownError("Failed to write account key"); - } - - void SetAccountkeyCharacteristicsWriteResultToFailure() { - auto it = characteristics_.find(*accountkey_characteristic_); - it->second.write_result = absl::UnknownError("Failed to write account key"); - } - - protected: - MediumEnvironmentStarter env_; - SingleThreadExecutor executor_; - BluetoothAdapter provider_adapter_; - BleV2Medium provider_ble_{provider_adapter_}; - std::unique_ptr internal_gatt_client_; - std::unique_ptr gatt_client_; - std::unique_ptr gatt_server_; - std::string provider_address_; - std::unique_ptr fast_pair_data_encryptor_; - std::unique_ptr device_; - Mediums mediums_; - std::optional initalized_failure_ = PairFailure::kUnknown; - std::optional write_failure_ = PairFailure::kUnknown; - Property properties_ = Property::kWrite | Property::kNotify; - Permission permissions_ = Permission::kWrite; - std::optional key_based_characteristic_; - std::optional passkey_characteristic_; - std::optional accountkey_characteristic_; - absl::flat_hash_map characteristics_; -}; - -TEST_F(FastPairGattServiceClientTest, SuccessInitializeGattConnection) { - EXPECT_EQ(GetInitializedCallbackResult(), PairFailure::kUnknown); - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(); - EXPECT_EQ(GetInitializedCallbackResult(), std::nullopt); -} - -TEST_F(FastPairGattServiceClientTest, FailedDiscoverServiceAndCharacteristics) { - EXPECT_EQ(GetInitializedCallbackResult(), PairFailure::kUnknown); - InsertCharacteristicsWithWrongServiceId(); - InitializeFastPairGattServiceClient(); - EXPECT_EQ(GetInitializedCallbackResult(), PairFailure::kCreateGattConnection); -} - -TEST_F(FastPairGattServiceClientTest, SuccessfulWriteKeyBaseCharacteristics) { - EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kUnknown); - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(); - characteristics_[*key_based_characteristic_].notify_response = - std::string(kKeyBasedCharacteristicAdvertisementByte); - WriteRequestToKeyBased(); - EXPECT_EQ(GetWriteCallbackResult(), std::nullopt); -} - -TEST_F(FastPairGattServiceClientTest, SuccessfulWritePasskeyCharacteristics) { - EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kUnknown); - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(); - - characteristics_[*passkey_characteristic_].notify_response = - std::string(kPasskeyharacteristicAdvertisementByte); - WriteRequestToPasskey(); - - EXPECT_EQ(GetWriteCallbackResult(), std::nullopt); -} - -TEST_F(FastPairGattServiceClientTest, - SuccessfulWriteAccountKeyCharacteristics) { - EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kUnknown); - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(); - WriteRequestToAccountkey(); - EXPECT_EQ(GetWriteCallbackResult(), std::nullopt); -} - -TEST_F(FastPairGattServiceClientTest, FailedToWriteKeyBaseCharacteristics) { - EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kUnknown); - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(); - SetKeyBaseCharacteristicsWriteResultToFailure(); - CountDownLatch latch(1); - gatt_client_->WriteRequestAsync( - kMessageType, kFlags, provider_address_, kSeekerAddress, - *fast_pair_data_encryptor_, - [&](absl::string_view response, std::optional failure) { - WriteTestCallback(failure); - latch.CountDown(); - }); - latch.Await(); - EXPECT_EQ(GetWriteCallbackResult(), - PairFailure::kKeyBasedPairingCharacteristicWrite); -} - -TEST_F(FastPairGattServiceClientTest, FailedToWritePasskeyCharacteristics) { - EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kUnknown); - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(); - SetPasskeyCharacteristicsWriteResultToFailure(); - CountDownLatch latch(1); - gatt_client_->WritePasskeyAsync( - kSeekerPasskey, kPasskey, *fast_pair_data_encryptor_, - [&](absl::string_view response, std::optional failure) { - WriteTestCallback(failure); - latch.CountDown(); - }); - latch.Await(); - EXPECT_EQ(GetWriteCallbackResult(), - PairFailure::kPasskeyPairingCharacteristicWrite); -} - -TEST_F(FastPairGattServiceClientTest, FailedToWriteAccountKey) { - EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kUnknown); - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(); - SetAccountkeyCharacteristicsWriteResultToFailure(); - CountDownLatch latch(1); - gatt_client_->WriteAccountKey(*fast_pair_data_encryptor_, - [&](std::optional account_key, - std::optional failure) { - EXPECT_FALSE(account_key.has_value()); - WriteTestCallback(failure); - latch.CountDown(); - }); - latch.Await(); - EXPECT_EQ(GetWriteCallbackResult(), - PairFailure::kAccountKeyCharacteristicWrite); -} - -TEST_F(FastPairGattServiceClientTest, KeyBasedPairingResponseTimeout) { - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(/*short_timeouts=*/true); - CountDownLatch latch(1); - - // Seeker writes to Key based pairing characteristic but the provider does not - // respond. - gatt_client_->WriteRequestAsync( - kMessageType, kFlags, provider_address_, kSeekerAddress, - *fast_pair_data_encryptor_, - [&](absl::string_view response, std::optional failure) { - EXPECT_EQ(failure, PairFailure::kKeyBasedPairingResponseTimeout); - latch.CountDown(); - }); - latch.Await(); -} - -TEST_F(FastPairGattServiceClientTest, PasskeyResponseTimeout) { - EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kUnknown); - InsertCorrectGattCharacteristics(); - InitializeFastPairGattServiceClient(); - CountDownLatch latch(1); - gatt_client_->WritePasskeyAsync( - kSeekerPasskey, kPasskey, *fast_pair_data_encryptor_, - [&](absl::string_view response, std::optional failure) { - WriteTestCallback(failure); - latch.CountDown(); - }); - SystemClock::Sleep(kGattOperationTimeout); - latch.Await(); - EXPECT_EQ(GetWriteCallbackResult(), PairFailure::kPasskeyResponseTimeout); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/handshake/fast_pair_handshake.h b/fastpair/handshake/fast_pair_handshake.h deleted file mode 100644 index 73b1e730cf..0000000000 --- a/fastpair/handshake/fast_pair_handshake.h +++ /dev/null @@ -1,83 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_H_ - -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_gatt_service_client.h" - -namespace nearby { -namespace fastpair { - -// This class performs the Fast Pair handshake procedure upon creation and -// calls |on_complete| once finished. It also exposes the -// |FastPairDataEncryptor| and |FastPairGattServiceClient| instances that were -// used during the handshake. -// -// The procedure steps are as follows: -// 1. Create a GATT connection to the device. -// 2. Create a data encryptor instance with the generated keys. -// 3. Write the Key-Based Pairing Request to the characteristic -// (https://developers.google.com/nearby/fast-pair/spec#table1.1) -// 4. Decrypt the response. -// 5. Validate response. -// 6. Set classic address field on |FastPairDevice| instance. -// 7. Complete. - -class FastPairHandshake { - public: - using OnCompleteCallback = absl::AnyInvocable failure)>; - - FastPairHandshake( - OnCompleteCallback on_complete_cb, - std::unique_ptr data_encryptor, - std::unique_ptr gatt_service_client) - : on_complete_callback_(std::move(on_complete_cb)), - fast_pair_data_encryptor_(std::move(data_encryptor)), - fast_pair_gatt_service_client_(std::move(gatt_service_client)) {} - - FastPairHandshake(const FastPairHandshake&) = delete; - FastPairHandshake& operator=(const FastPairHandshake&) = delete; - virtual ~FastPairHandshake() = default; - - bool completed_successfully() { return completed_successfully_; } - - FastPairDataEncryptor* fast_pair_data_encryptor() { - return fast_pair_data_encryptor_.get(); - } - - FastPairGattServiceClient* fast_pair_gatt_service_client() { - return fast_pair_gatt_service_client_.get(); - } - - protected: - bool completed_successfully_ = false; - OnCompleteCallback on_complete_callback_; - std::unique_ptr fast_pair_data_encryptor_; - std::unique_ptr fast_pair_gatt_service_client_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_H_ diff --git a/fastpair/handshake/fast_pair_handshake_impl.cc b/fastpair/handshake/fast_pair_handshake_impl.cc deleted file mode 100644 index 1ecddff016..0000000000 --- a/fastpair/handshake/fast_pair_handshake_impl.cc +++ /dev/null @@ -1,138 +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. - -#include "fastpair/handshake/fast_pair_handshake_impl.h" - -#include -#include -#include -#include - -#include "absl/functional/bind_front.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/handshake/fast_pair_data_encryptor_impl.h" -#include "fastpair/handshake/fast_pair_gatt_service_client_impl.h" -#include "internal/base/bluetooth_address.h" -#include "internal/platform/logging.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -FastPairHandshakeImpl::FastPairHandshakeImpl(FastPairDevice& device, - Mediums& mediums, - OnCompleteCallback on_complete, - SingleThreadExecutor* executor) - : FastPairHandshake(std::move(on_complete), nullptr, nullptr) { - fast_pair_gatt_service_client_ = - FastPairGattServiceClientImpl::Factory::Create(device, mediums, executor); - fast_pair_gatt_service_client_->InitializeGattConnection( - [&](std::optional failure) { - OnGattClientInitializedCallback(device, failure); - }); -} - -void FastPairHandshakeImpl::OnGattClientInitializedCallback( - FastPairDevice& device, std::optional failure) { - if (failure.has_value()) { - NEARBY_LOGS(WARNING) << __func__ - << ": Failed to init gatt client with failure = " - << failure.value(); - std::move(on_complete_callback_)(device, failure.value()); - return; - } - - NEARBY_LOGS(INFO) - << __func__ - << ": Fast Pair GATT service client initialization successful."; - FastPairDataEncryptorImpl::Factory::CreateAsync( - device, - [&](std::unique_ptr fast_pair_data_encryptor) { - OnDataEncryptorCreateAsync(device, std::move(fast_pair_data_encryptor)); - }); -} - -void FastPairHandshakeImpl::OnDataEncryptorCreateAsync( - FastPairDevice& device, - std::unique_ptr fast_pair_data_encryptor) { - if (!fast_pair_data_encryptor) { - NEARBY_LOGS(WARNING) << __func__ - << ": Failed to create Fast Pair Data Encryptor."; - std::move(on_complete_callback_)(device, - PairFailure::kDataEncryptorRetrieval); - return; - } - - fast_pair_data_encryptor_ = std::move(fast_pair_data_encryptor); - NEARBY_LOGS(INFO) << __func__ << ": Beginning key-based pairing protocol"; - fast_pair_gatt_service_client_->WriteRequestAsync( - /*message_type=*/kKeyBasedPairingType, - /*flags=*/kInitialOrSubsequentFlags, - /*provider_address=*/device.GetBleAddress(), - /*seekers_address=*/"", *fast_pair_data_encryptor_, - [&](absl::string_view response, std::optional failure) { - OnWriteResponse(device, response, failure); - }); -} - -void FastPairHandshakeImpl::OnWriteResponse( - FastPairDevice& device, absl::string_view response, - std::optional failure) { - if (failure.has_value()) { - NEARBY_LOGS(WARNING) - << __func__ - << ": Failed during key-based pairing protocol with failure = " - << failure.value(); - std::move(on_complete_callback_)(device, failure.value()); - return; - } - - NEARBY_LOGS(INFO) << __func__ << ": Successfully wrote response."; - - if (response.size() != kAesBlockByteSize) { - NEARBY_LOGS(WARNING) - << __func__ << ": Handshake failed because of incorrect response size."; - std::move(on_complete_callback_)( - device, PairFailure::kKeybasedPairingResponseDecryptFailure); - return; - } - - std::vector response_bytes(response.begin(), response.end()); - fast_pair_data_encryptor_->ParseDecryptResponse( - response_bytes, [&](std::optional response) { - OnParseDecryptedResponse(device, response); - }); -} - -void FastPairHandshakeImpl::OnParseDecryptedResponse( - FastPairDevice& device, std::optional& response) { - if (!response.has_value()) { - NEARBY_LOGS(WARNING) << __func__ - << ": Missing decrypted response from parse."; - std::move(on_complete_callback_)( - device, PairFailure::kKeybasedPairingResponseDecryptFailure); - return; - } - NEARBY_LOGS(INFO) << __func__ - << ": Successfully decrypted and parsed response."; - - device.SetPublicAddress( - device::CanonicalizeBluetoothAddress(response->address_bytes)); - completed_successfully_ = true; - std::move(on_complete_callback_)(device, std::nullopt); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/handshake/fast_pair_handshake_impl.h b/fastpair/handshake/fast_pair_handshake_impl.h deleted file mode 100644 index f98e7fda69..0000000000 --- a/fastpair/handshake/fast_pair_handshake_impl.h +++ /dev/null @@ -1,53 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_IMPL_H_ - -#include -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/crypto/decrypted_response.h" -#include "fastpair/handshake/fast_pair_handshake.h" -#include "fastpair/internal/mediums/mediums.h" - -namespace nearby { -namespace fastpair { - -class FastPairHandshakeImpl : public FastPairHandshake { - public: - explicit FastPairHandshakeImpl(FastPairDevice& device, Mediums& mediums, - OnCompleteCallback on_complete, - SingleThreadExecutor* executor); - FastPairHandshakeImpl(const FastPairHandshakeImpl&) = delete; - FastPairHandshakeImpl& operator=(const FastPairHandshakeImpl&) = delete; - - private: - void OnGattClientInitializedCallback(FastPairDevice& device, - std::optional failure); - void OnDataEncryptorCreateAsync( - FastPairDevice& device, - std::unique_ptr fast_pair_data_encryptor); - void OnWriteResponse(FastPairDevice& device, absl::string_view response, - std::optional failure); - void OnParseDecryptedResponse(FastPairDevice& device, - std::optional& response); -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_IMPL_H_ diff --git a/fastpair/handshake/fast_pair_handshake_impl_test.cc b/fastpair/handshake/fast_pair_handshake_impl_test.cc deleted file mode 100644 index 467bfcb3ac..0000000000 --- a/fastpair/handshake/fast_pair_handshake_impl_test.cc +++ /dev/null @@ -1,325 +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. - -#include "fastpair/handshake/fast_pair_handshake_impl.h" - -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/common/protocol.h" -#include "fastpair/crypto/decrypted_response.h" -#include "fastpair/handshake/fake_fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_data_encryptor_impl.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -namespace { -using Property = nearby::api::ble_v2::GattCharacteristic::Property; -using Permission = nearby::api::ble_v2::GattCharacteristic::Permission; -using ::nearby::api::ble_v2::GattCharacteristic; - -constexpr absl::string_view kMetadataId("718c17"); -constexpr absl::string_view kPublicAddress("5E:3F:45:61:C3:32"); -constexpr absl::string_view kKeyBasedResponse("keybasedresponse"); -constexpr absl::string_view kWrongResponse("wrongresponse"); -constexpr Uuid kFastPairServiceUuid(0x0000FE2C00001000, 0x800000805F9B34FB); -constexpr Uuid kKeyBasedCharacteristicUuidV2(0xFE2C123483664814, - 0x8EB001DE32100BEA); -constexpr Uuid kPasskeyCharacteristicUuidV2(0xFE2C123583664814, - 0x8EB001DE32100BEA); -constexpr Uuid kAccountKeyCharacteristicUuidV2(0xFE2C123683664814, - 0x8EB001DE32100BEA); -constexpr std::array address_bytes = {0x5E, 0x3F, 0x45, - 0x61, 0xC3, 0x32}; - -constexpr std::array salt = {0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x00}; -} // namespace - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class FastPairFakeDataEncryptorImplFactory - : public FastPairDataEncryptorImpl::Factory { - public: - void CreateInstance( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback) override { - if (!successful_retrieval_) { - std::move(on_get_instance_callback)(nullptr); - return; - } - - auto data_encryptor = std::make_unique(); - data_encryptor_ = data_encryptor.get(); - data_encryptor->SetResponse(response_); - std::move(on_get_instance_callback)(std::move(data_encryptor)); - } - - FakeFastPairDataEncryptor* data_encryptor() { return data_encryptor_; } - - void SetFailedRetrieval() { successful_retrieval_ = false; } - - void SetResponse(std::optional response) { - response_ = std::move(response); - } - - private: - FakeFastPairDataEncryptor* data_encryptor_ = nullptr; - bool successful_retrieval_ = true; - std::optional response_; -}; - -struct CharacteristicData { - // Write result returned to the gatt client. - absl::Status write_result; - std::optional notify_response; -}; - -class FastPairHandshakeImplTest : public testing::Test { - public: - FastPairHandshakeImplTest() { - FastPairDataEncryptorImpl::Factory::SetFactoryForTesting( - &fake_data_encryptor_factory_); - } - - void TearDown() override { - executor_.Shutdown(); - key_based_characteristic_ = std::nullopt; - passkey_characteristic_ = std::nullopt; - handshake_.reset(); - gatt_server_->Stop(); - gatt_server_.reset(); - } - - void StartGattServer() { - gatt_server_ = - provider_ble_.StartGattServer(/*ServerGattConnectionCallback=*/{ - .on_characteristic_write_cb = - [&](const api::ble_v2::BlePeripheral& remote_device, - const api::ble_v2::GattCharacteristic& characteristic, - int offset, absl::string_view data, - BleV2Medium::ServerGattConnectionCallback:: - WriteValueCallback callback) mutable { - MutexLock lock(&mutex_); - auto it = characteristics_.find(characteristic); - if (it == characteristics_.end()) { - callback(absl::NotFoundError("characteristic not found")); - return; - } - callback(it->second.write_result); - if (it->second.notify_response.has_value()) { - auto ignored = gatt_server_->NotifyCharacteristicChanged( - characteristic, false, - ByteArray(*it->second.notify_response)); - } - }}); - provider_address_ = *gatt_server_->GetBlePeripheral().GetAddress(); - } - - void InsertCorrectGattCharacteristics() { - MutexLock lock(&mutex_); - key_based_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kKeyBasedCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*key_based_characteristic_].write_result = - absl::OkStatus(); - - passkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kPasskeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*passkey_characteristic_].write_result = absl::OkStatus(); - - accountkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kAccountKeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*accountkey_characteristic_].write_result = - absl::OkStatus(); - } - - void SetNotifyResponse(GattCharacteristic characteristic, - absl::string_view response) { - MutexLock lock(&mutex_); - CHECK(characteristics_.find(characteristic) != characteristics_.end()); - characteristics_[characteristic].notify_response = response; - } - - void SetDecryptedResponse() { - DecryptedResponse decrypted_response( - FastPairMessageType::kKeyBasedPairingResponse, address_bytes, salt); - fake_data_encryptor_factory_.SetResponse(std::move(decrypted_response)); - } - - protected: - MediumEnvironmentStarter env_; - Mutex mutex_; - SingleThreadExecutor executor_; - std::unique_ptr handshake_; - BluetoothAdapter provider_adapter_; - BleV2Medium provider_ble_{provider_adapter_}; - std::string provider_address_; - Mediums mediums_; - std::unique_ptr fast_pair_device_; - absl::flat_hash_map characteristics_ - ABSL_GUARDED_BY(mutex_); - std::optional key_based_characteristic_; - std::optional passkey_characteristic_; - std::optional accountkey_characteristic_; - FastPairFakeDataEncryptorImplFactory fake_data_encryptor_factory_; - - private: - std::unique_ptr gatt_server_; - Property properties_ = Property::kWrite | Property::kNotify; - Permission permissions_ = Permission::kWrite; -}; - -TEST_F(FastPairHandshakeImplTest, Success) { - StartGattServer(); - InsertCorrectGattCharacteristics(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - fast_pair_device_ = std::make_unique( - kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); - SetDecryptedResponse(); - CountDownLatch latch(1); - handshake_ = std::make_unique( - *fast_pair_device_, mediums_, - [&](FastPairDevice& callback_device, std::optional failure) { - EXPECT_EQ(fast_pair_device_.get(), &callback_device); - EXPECT_EQ(fast_pair_device_->GetPublicAddress(), kPublicAddress); - EXPECT_FALSE(failure.has_value()); - latch.CountDown(); - }, - &executor_); - latch.Await(); - EXPECT_TRUE(handshake_->completed_successfully()); -} - -TEST_F(FastPairHandshakeImplTest, GattError) { - StartGattServer(); - fast_pair_device_ = std::make_unique( - kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); - SetDecryptedResponse(); - CountDownLatch latch(1); - handshake_ = std::make_unique( - *fast_pair_device_, mediums_, - [&](FastPairDevice& callback_device, std::optional failure) { - EXPECT_EQ(fast_pair_device_.get(), &callback_device); - EXPECT_EQ(failure.value(), PairFailure::kCreateGattConnection); - latch.CountDown(); - }, - &executor_); - latch.Await(); - EXPECT_FALSE(handshake_->completed_successfully()); -} - -TEST_F(FastPairHandshakeImplTest, DataEncryptorCreateError) { - StartGattServer(); - InsertCorrectGattCharacteristics(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - fast_pair_device_ = std::make_unique( - kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); - fake_data_encryptor_factory_.SetFailedRetrieval(); - CountDownLatch latch(1); - handshake_ = std::make_unique( - *fast_pair_device_, mediums_, - [&](FastPairDevice& callback_device, std::optional failure) { - EXPECT_EQ(fast_pair_device_.get(), &callback_device); - EXPECT_EQ(failure.value(), PairFailure::kDataEncryptorRetrieval); - latch.CountDown(); - }, - &executor_); - latch.Await(); - EXPECT_FALSE(handshake_->completed_successfully()); -} - -TEST_F(FastPairHandshakeImplTest, WriteResponseError) { - StartGattServer(); - InsertCorrectGattCharacteristics(); - fast_pair_device_ = std::make_unique( - kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); - SetDecryptedResponse(); - CountDownLatch latch(1); - handshake_ = std::make_unique( - *fast_pair_device_, mediums_, - [&](FastPairDevice& callback_device, std::optional failure) { - EXPECT_EQ(fast_pair_device_.get(), &callback_device); - EXPECT_EQ(failure.value(), - PairFailure::kKeyBasedPairingResponseTimeout); - latch.CountDown(); - }, - &executor_); - latch.Await(); - EXPECT_FALSE(handshake_->completed_successfully()); -} - -TEST_F(FastPairHandshakeImplTest, WriteResponseWrongSize) { - StartGattServer(); - InsertCorrectGattCharacteristics(); - SetNotifyResponse(*key_based_characteristic_, kWrongResponse); - fast_pair_device_ = std::make_unique( - kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); - SetDecryptedResponse(); - CountDownLatch latch(1); - handshake_ = std::make_unique( - *fast_pair_device_, mediums_, - [&](FastPairDevice& callback_device, std::optional failure) { - EXPECT_EQ(fast_pair_device_.get(), &callback_device); - EXPECT_EQ(failure.value(), - PairFailure::kKeybasedPairingResponseDecryptFailure); - latch.CountDown(); - }, - &executor_); - latch.Await(); - EXPECT_FALSE(handshake_->completed_successfully()); -} - -TEST_F(FastPairHandshakeImplTest, ParseResponseError) { - StartGattServer(); - InsertCorrectGattCharacteristics(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - fast_pair_device_ = std::make_unique( - kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); - CountDownLatch latch(1); - handshake_ = std::make_unique( - *fast_pair_device_, mediums_, - [&](FastPairDevice& callback_device, std::optional failure) { - EXPECT_EQ(fast_pair_device_.get(), &callback_device); - EXPECT_EQ(failure.value(), - PairFailure::kKeybasedPairingResponseDecryptFailure); - latch.CountDown(); - }, - &executor_); - latch.Await(); - EXPECT_FALSE(handshake_->completed_successfully()); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/handshake/fast_pair_handshake_lookup.cc b/fastpair/handshake/fast_pair_handshake_lookup.cc deleted file mode 100644 index 589992213a..0000000000 --- a/fastpair/handshake/fast_pair_handshake_lookup.cc +++ /dev/null @@ -1,104 +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. - -#include "fastpair/handshake/fast_pair_handshake_lookup.h" - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" -#include "fastpair/handshake/fast_pair_handshake_impl.h" - -namespace nearby { -namespace fastpair { - -FastPairHandshakeLookup* FastPairHandshakeLookup::instance_ = nullptr; -absl::Mutex FastPairHandshakeLookup::mutex_(absl::kConstInit); -namespace { -absl::optional g_test_create_function = - std::nullopt; -} - -// static -FastPairHandshakeLookup* FastPairHandshakeLookup::GetInstance() { - absl::MutexLock lock(&mutex_); - if (!instance_) { - instance_ = new FastPairHandshakeLookup(); - } - return instance_; -} - -// static Create function override which can be set by tests. -void FastPairHandshakeLookup::SetCreateFunctionForTesting( - CreateFunction create_function) { - g_test_create_function = std::move(create_function); -} - -FastPairHandshake* FastPairHandshakeLookup::Get(FastPairDevice* device) { - absl::MutexLock lock(&mutex_); - auto it = fast_pair_handshakes_.find(device); - return it != fast_pair_handshakes_.end() ? it->second.get() : nullptr; -} - -FastPairHandshake* FastPairHandshakeLookup::Get(absl::string_view address) { - absl::MutexLock lock(&mutex_); - for (const auto& pair : fast_pair_handshakes_) { - if (pair.first->GetPublicAddress() == address || - pair.first->GetBleAddress() == address) { - return pair.second.get(); - } - } - return nullptr; -} - -bool FastPairHandshakeLookup::Erase(FastPairDevice* device) { - absl::MutexLock lock(&mutex_); - return fast_pair_handshakes_.erase(device) == 1; -} - -bool FastPairHandshakeLookup::Erase(absl::string_view address) { - absl::MutexLock lock(&mutex_); - for (const auto& pair : fast_pair_handshakes_) { - if (pair.first->GetPublicAddress() == address || - pair.first->GetBleAddress() == address) { - fast_pair_handshakes_.erase(pair.first); - return true; - } - } - return false; -} - -void FastPairHandshakeLookup::Clear() { - absl::MutexLock lock(&mutex_); - fast_pair_handshakes_.clear(); -} - -FastPairHandshake* FastPairHandshakeLookup::Create( - FastPairDevice& device, Mediums& mediums, OnCompleteCallback on_complete, - SingleThreadExecutor* executor) { - absl::MutexLock lock(&mutex_); - auto it = fast_pair_handshakes_.emplace( - &device, g_test_create_function.has_value() - ? g_test_create_function.value()(device, mediums, - std::move(on_complete)) - : std::make_unique( - device, mediums, std::move(on_complete), executor)); - DCHECK(it.second); - return it.first->second.get(); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/handshake/fast_pair_handshake_lookup.h b/fastpair/handshake/fast_pair_handshake_lookup.h deleted file mode 100644 index 2593d0069b..0000000000 --- a/fastpair/handshake/fast_pair_handshake_lookup.h +++ /dev/null @@ -1,94 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_LOOKUP_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_LOOKUP_H_ - -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/functional/any_invocable.h" -#include "absl/synchronization/mutex.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/handshake/fast_pair_handshake.h" -#include "fastpair/internal/mediums/mediums.h" - -namespace nearby { -namespace fastpair { - -// This Singletonclass creates, deletes and exposes FastPairHandshake instances. -class FastPairHandshakeLookup { - public: - using OnCompleteCallback = absl::AnyInvocable failure)>; - - using CreateFunction = absl::AnyInvocable( - FastPairDevice& device, Mediums& mediums, OnCompleteCallback callback)>; - - // This is the static method that controls the access to the singleton - // instance. On the first run, it creates a singleton object and places it - // into the static field. On subsequent runs, it returns the existing object - // stored in the static field. - static FastPairHandshakeLookup* GetInstance(); - - static void SetCreateFunctionForTesting(CreateFunction create_function); - - // Singletons should not be cloneable. - FastPairHandshakeLookup(const FastPairHandshakeLookup&) = delete; - // Singletons should not be assignable. - FastPairHandshakeLookup& operator=(const FastPairHandshakeLookup&) = delete; - - // Get an existing instance for |FastPairdevice|. - FastPairHandshake* Get(FastPairDevice* device); - - // Get an existing instance for |address|. - FastPairHandshake* Get(absl::string_view address); - - // Erases the FastPairHandshake instance for |FastPairdevice| if it exists. - bool Erase(FastPairDevice* device); - - // Erases the FastPairHandshake instance for |FastPairdevice| if it exists. - bool Erase(absl::string_view address); - - // Deletes all existing FastPairHandshake instances. - void Clear(); - - // Creates and returns a new instance for |FastPairdevice| if no instance - // already exists. - // Returns the existing instance if there is one. - FastPairHandshake* Create(FastPairDevice& device, Mediums& mediums, - OnCompleteCallback on_complete, - SingleThreadExecutor* executor); - - protected: - // Constructor/destructor of singleton object should not be public - // for which the destructor will never be called. - // and constructor will be invoked once from GetInstance() static method. - FastPairHandshakeLookup() = default; - ~FastPairHandshakeLookup() = default; - - private: - static absl::Mutex mutex_; - static FastPairHandshakeLookup* instance_ ABSL_GUARDED_BY(mutex_); - - absl::flat_hash_map> - fast_pair_handshakes_ ABSL_GUARDED_BY(mutex_); -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_HANDSHAKE_FAST_PAIR_HANDSHAKE_LOOKUP_H_ diff --git a/fastpair/handshake/fast_pair_handshake_lookup_test.cc b/fastpair/handshake/fast_pair_handshake_lookup_test.cc deleted file mode 100644 index cedc3390ed..0000000000 --- a/fastpair/handshake/fast_pair_handshake_lookup_test.cc +++ /dev/null @@ -1,150 +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. - -#include "fastpair/handshake/fast_pair_handshake_lookup.h" - -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/common/protocol.h" -#include "fastpair/internal/mediums/mediums.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr absl::string_view kValidModelId("718c17"); -constexpr absl::string_view kPubliceAddress("public_address"); - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class FastPairHandshakeLookupTest : public ::testing::Test { - public: - FastPairHandshakeLookupTest() { - provider_address_ = adapter_.GetMacAddress(); - device_ = new FastPairDevice(kValidModelId, provider_address_, - Protocol::kFastPairInitialPairing); - device_->SetPublicAddress(kPubliceAddress); - } - - ~FastPairHandshakeLookupTest() override { delete device_; } - - void TearDown() override { executor_.Shutdown(); } - - void CreateFastPairHandshkeInstanceForDevice(FastPairDevice& device) { - CountDownLatch latch(1); - Mediums mediums; - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Create( - device, mediums, - [&](FastPairDevice& cb_device, std::optional failure) { - EXPECT_EQ(&device, &cb_device); - EXPECT_TRUE(failure.has_value()); - latch.CountDown(); - }, - &executor_)); - latch.Await(); - } - - protected: - MediumEnvironmentStarter env_; - SingleThreadExecutor executor_; - BluetoothAdapter adapter_; - BleV2Medium ble_{adapter_}; - std::string provider_address_; - - FastPairDevice* device_ = nullptr; -}; - -TEST_F(FastPairHandshakeLookupTest, CreateFastPairHandshkeInstanceForDevice) { - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(provider_address_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(kPubliceAddress)); - - CreateFastPairHandshkeInstanceForDevice(*device_); - - // GetFastPairHandshakeWithDevicePtr - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - // GetFastPairHandshakeWithBLEAddress - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(provider_address_)); - // GetFastPairHandshakeWithPublicAddress - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(kPubliceAddress)); - // GetFastPairHandshakeWithDevicePtr - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - // GetFastPairHandshakeWithWrongAddress - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get("")); -} - -TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithDevicePtr) { - CreateFastPairHandshkeInstanceForDevice(*device_); - - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(device_)); - // Already Erased - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - EXPECT_FALSE( - FastPairHandshakeLookup::GetInstance()->Erase(provider_address_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(kPubliceAddress)); -} - -TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithBLEAddress) { - CreateFastPairHandshkeInstanceForDevice(*device_); - - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - // Erase Wrong Address - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase("")); - - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(provider_address_)); - // Already Erased - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(device_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(kPubliceAddress)); -} - -TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithPublicAddress) { - CreateFastPairHandshkeInstanceForDevice(*device_); - - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(kPubliceAddress)); - // Already Erased - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(device_)); - EXPECT_FALSE( - FastPairHandshakeLookup::GetInstance()->Erase(provider_address_)); -} - -TEST_F(FastPairHandshakeLookupTest, ClearAllFastPairHandshakeInstances) { - CreateFastPairHandshkeInstanceForDevice(*device_); - - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - - FastPairHandshakeLookup::GetInstance()->Clear(); - - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/BUILD b/fastpair/internal/BUILD deleted file mode 100644 index ac7411c859..0000000000 --- a/fastpair/internal/BUILD +++ /dev/null @@ -1,69 +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. - -licenses(["notice"]) - -cc_library( - name = "internal", - srcs = ["fast_pair_seeker_impl.cc"], - hdrs = [ - "fast_pair_seeker_impl.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair:fast_pair_controller", - "//fastpair:fast_pair_events", - "//fastpair:fast_pair_seeker", - "//fastpair/common", - "//fastpair/internal/mediums", - "//fastpair/pairing", - "//fastpair/repository", - "//fastpair/repository:device_repository", - "//fastpair/retroactive", - "//fastpair/scanning:scanner", - "//internal/platform:types", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings:str_format", - ], -) - -cc_test( - name = "fast_pair_seeker_impl_test", - size = "small", - srcs = [ - "fast_pair_seeker_impl_test.cc", - ], - deps = [ - ":internal", - "//fastpair:fast_pair_events", - "//fastpair:fast_pair_seeker", - "//fastpair/common", - "//fastpair/message_stream:fake_gatt_callbacks", - "//fastpair/message_stream:fake_provider", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/repository", - "//fastpair/repository:device_repository", - "//fastpair/repository:test_support", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/internal/fast_pair_seeker_impl.cc b/fastpair/internal/fast_pair_seeker_impl.cc deleted file mode 100644 index 30b27f9526..0000000000 --- a/fastpair/internal/fast_pair_seeker_impl.cc +++ /dev/null @@ -1,327 +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. - -#include "fastpair/internal/fast_pair_seeker_impl.h" - -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/str_format.h" -#include "fastpair/common/account_key.h" -#include "fastpair/fast_pair_controller.h" -#include "fastpair/fast_pair_events.h" -#include "fastpair/pairing/pairer_broker_impl.h" -#include "fastpair/scanning/scanner_broker_impl.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/logging.h" -#include "internal/platform/pending_job_registry.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr absl::Duration kCleanupTimeout = absl::Seconds(3); -} // namespace - -FastPairSeekerImpl::FastPairSeekerImpl(ServiceCallbacks callbacks, - SingleThreadExecutor* executor, - AccountManager* account_manager, - FastPairDeviceRepository* devices, - FastPairRepository* repository) - : callbacks_(std::move(callbacks)), - executor_(executor), - account_manager_(account_manager), - devices_(devices), - repository_(repository) { - pairer_broker_ = - std::make_unique(mediums_, executor_, account_manager_); - pairer_broker_->AddObserver(this); - mediums_.GetBluetoothClassic().AddObserver(this); - retro_detector_ = std::make_unique( - mediums_, devices, account_manager_, executor); - retro_detector_->AddObserver(this); -} - -FastPairSeekerImpl::~FastPairSeekerImpl() { - NEARBY_LOGS(INFO) << "~FastPairSeekerImpl start"; - pairer_broker_->RemoveObserver(this); - mediums_.GetBluetoothClassic().RemoveObserver(this); - auto unused = StopFastPairScan(); - CountDownLatch latch(1); - executor_->Execute("~FastPairSeekerImpl", [this, latch]() mutable { - FinishPairing(absl::AbortedError("Pairing terminated")); - pairer_broker_.reset(); - executor_->Execute("sync", [latch]() mutable { latch.CountDown(); }); - }); - if (!latch.Await(kCleanupTimeout)) { - NEARBY_LOGS(WARNING) << "Cleanup didn't finish in " << kCleanupTimeout; - } - PendingJobRegistry::GetInstance().ListAllJobs(); - NEARBY_LOGS(INFO) << "~FastPairSeekerImpl done"; -} - -absl::Status FastPairSeekerImpl::StartInitialPairing( - const FastPairDevice& device, const InitialPairingParam& params, - PairingCallback callback) { - if (pairer_broker_->IsPairing()) { - return absl::AlreadyExistsError("Already pairing"); - } - - pairing_callback_ = std::make_unique(std::move(callback)); - device_under_pairing_ = &const_cast(device); - device_under_pairing_->StartedPairing(true); - pairer_broker_->PairDevice(*device_under_pairing_); - return absl::OkStatus(); -} - -absl::Status FastPairSeekerImpl::StartSubsequentPairing( - const FastPairDevice& device, const SubsequentPairingParam& params, - PairingCallback callback) { - return absl::UnimplementedError("StartSubsequentPairing"); -} - -absl::Status FastPairSeekerImpl::StartRetroactivePairing( - const FastPairDevice& device, const RetroactivePairingParam& param, - PairingCallback callback) { - if (pairer_broker_->IsPairing()) { - return absl::AlreadyExistsError("Already pairing"); - } - - device_under_pairing_ = &const_cast(device); - device_under_pairing_->StartedPairing(true); - controller_ = std::make_unique( - &mediums_, device_under_pairing_, executor_); - retroactive_pair_ = std::make_unique(controller_.get()); - pairing_callback_ = std::make_unique(std::move(callback)); - retroactive_pair_->Pair().AddListener( - [this](ExceptionOr result) { - // TODO(jsobczak): We could/should keep controller_ alive until the - // client calls FinishRetroactivePairing(), verify that they called - // Finish for the correct device, and if the user has given consent, we - // should keep the MessageStream connection open. - retroactive_pair_.reset(); - controller_.reset(); - FinishPairing(result.result()); - }, - executor_); - return absl::OkStatus(); -} - -absl::Status FastPairSeekerImpl::FinishRetroactivePairing( - const FastPairDevice& device, const FinishRetroactivePairingParam& param, - PairingCallback callback) { - if (device.GetProtocol() != Protocol::kFastPairRetroactivePairing) { - return absl::InvalidArgumentError( - "Fast Pair Device is not a retroactive pairing device"); - } - if (!device.GetAccountKey()) { - return absl::InvalidArgumentError( - "Fast Pair Device does not have an account key"); - } - if (!param.save_account_key) { - executor_->Execute( - "abandon retro device", - [this, &device, callback = std::move(callback)]() mutable { - NEARBY_LOGS(INFO) << "Abandon device on retroactive pairing path"; - callback.on_pairing_result(device, absl::OkStatus()); - devices_->RemoveDevice(&device); - }); - } else { - executor_->Execute( - "save account key", - [this, &device, callback = std::move(callback)]() mutable { - NEARBY_LOGS(INFO) << "Save account key for " << device; - repository_->WriteAccountAssociationToFootprints( - const_cast(device), - [&device, - callback = std::move(callback)](absl::Status status) mutable { - callback.on_pairing_result(device, status); - }); - }); - } - return absl::OkStatus(); -} - -absl::Status FastPairSeekerImpl::StartFastPairScan() { - if (scanning_session_ != nullptr) { - return absl::AlreadyExistsError("already scanning"); - } - scanner_ = std::make_unique(mediums_, executor_, devices_); - scanner_->AddObserver(this); - scanning_session_ = - scanner_->StartScanning(Protocol::kFastPairInitialPairing); - return absl::OkStatus(); -} - -absl::Status FastPairSeekerImpl::StopFastPairScan() { - if (scanning_session_ == nullptr) { - return absl::NotFoundError("scanner is not running"); - } - scanning_session_.reset(); - scanner_->RemoveObserver(this); - DestroyOnExecutor(std::move(scanner_), executor_); - return absl::OkStatus(); -} - -// ScannerBroker::Observer::OnDeviceFound -void FastPairSeekerImpl::OnDeviceFound(FastPairDevice& device) { - NEARBY_LOGS(INFO) << "Device found: " << device; - callbacks_.on_initial_discovery(device, InitialDiscoveryEvent{}); -} - -// ScannerBroker::Observer::OnDeviceLost -void FastPairSeekerImpl::OnDeviceLost(FastPairDevice& device) { - NEARBY_LOGS(INFO) << "Device lost: " << device; - if (IsDeviceUnderPairing(device)) { - FinishPairing(absl::UnavailableError("Device lost during pairing")); - } -} - -// PairerBroker:Observer::OnDevicePaired -void FastPairSeekerImpl::OnDevicePaired(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": " << device; -} - -// PairerBroker:Observer::OnAccountKeyWrite -void FastPairSeekerImpl::OnAccountKeyWrite(FastPairDevice& device, - std::optional error) { - if (error.has_value()) { - NEARBY_LOGS(INFO) << __func__ << ": Device=" << device - << ",Error=" << error.value(); - return; - } - - NEARBY_LOGS(INFO) << __func__ << ": Device=" << device; - if (device.GetProtocol() == Protocol::kFastPairRetroactivePairing) { - // TODO: UI ShowAssociateAccount - } -} - -// PairerBroker:Observer::OnPairingComplete -void FastPairSeekerImpl::OnPairingComplete(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": " << device; - if (!IsDeviceUnderPairing(device)) { - NEARBY_LOGS(WARNING) << "unexpected on pair complete callback"; - return; - } - FinishPairing(absl::OkStatus()); -} - -// PairerBroker:Observer::OnPairFailure -void FastPairSeekerImpl::OnPairFailure(FastPairDevice& device, - PairFailure failure) { - NEARBY_LOGS(INFO) << __func__ << ": " << device - << " with PairFailure: " << failure; - if (!IsDeviceUnderPairing(device)) { - NEARBY_LOGS(WARNING) << "unexpected on pair failure callback"; - return; - } - FinishPairing( - absl::InternalError(absl::StrFormat("Pairing failed with %v", failure))); -} - -bool FastPairSeekerImpl::IsDeviceUnderPairing(const FastPairDevice& device) { - return device_under_pairing_ == &device; -} - -void FastPairSeekerImpl::FinishPairing(absl::Status result) { - if (pairing_callback_ && device_under_pairing_ != nullptr) { - pairing_callback_->on_pairing_result(*device_under_pairing_, result); - } - pairing_callback_.reset(); - device_under_pairing_ = nullptr; -} - -void FastPairSeekerImpl::SetIsScreenLocked(bool locked) { - NEARBY_LOGS(INFO) << __func__ << ": Screen lock state changed. ( " - << std::boolalpha << locked << ")"; - is_screen_locked_ = locked; - callbacks_.on_screen_event(ScreenEvent{.is_locked = locked}); -} - -void FastPairSeekerImpl::InvalidateScanningState() { - // Stop scanning when screen is off. - if (is_screen_locked_) { - absl::Status status = StopFastPairScan(); - NEARBY_LOGS(VERBOSE) << __func__ - << ": Stopping scanning because the screen is locked."; - return; - } - - // TODO(b/275452353): Check if bluetooth and fast pair is enabled - - // Screen is on, Bluetooth is enabled, and Fast Pair is enabled, start - // scanning. - absl::Status status = StartFastPairScan(); -} - -void FastPairSeekerImpl::DeviceAdded(BluetoothDevice& device) { - NEARBY_LOGS(VERBOSE) << __func__ << "(" << device.GetMacAddress() << ")"; -} - -void FastPairSeekerImpl::DeviceRemoved(BluetoothDevice& device) { - NEARBY_LOGS(VERBOSE) << __func__ << "(" << device.GetMacAddress() << ")"; -} - -void FastPairSeekerImpl::DeviceAddressChanged(BluetoothDevice& device, - absl::string_view old_address) { - NEARBY_LOGS(VERBOSE) << __func__ << "(" << device.GetMacAddress() << ", " - << old_address << ")"; -} - -void FastPairSeekerImpl::DevicePairedChanged(BluetoothDevice& device, - bool new_paired_status) { - NEARBY_LOGS(VERBOSE) << __func__ << "(" << device.GetMacAddress() << ", " - << new_paired_status << ")"; - // Note, the FP service will be notified about paired events from the - // retroactive pairing path if `device` is an FP device. - // TODO(jsobczak): Notify service about unpair events if `device` is a known - // FP device. -} - -void FastPairSeekerImpl::DeviceConnectedStateChanged(BluetoothDevice& device, - bool connected) { - NEARBY_LOGS(VERBOSE) << __func__ << "(" << device.GetMacAddress() << ", " - << connected << ")"; -} - -void FastPairSeekerImpl::OnRetroactivePairFound(FastPairDevice& device) { - NEARBY_LOGS(VERBOSE) << __func__ << ": " << device; - callbacks_.on_pair_event(device, PairEvent{.is_paired = true}); -} - -void FastPairSeekerImpl::ForgetDeviceByAccountKey( - const AccountKey& account_key) { - NEARBY_LOGS(VERBOSE) << __func__; - auto opt_device = devices_->FindDevice(account_key); - if (!opt_device.has_value()) { - NEARBY_LOGS(INFO) << __func__ << "No FP device matching the account key."; - } else { - devices_->RemoveDevice(opt_device.value()); - } - - repository_->DeleteAssociatedDeviceByAccountKey( - account_key, [&](absl::Status success) { - if (!success.ok()) return; - NEARBY_LOGS(VERBOSE) << "Deleted associated devcie by account key"; - // Temporary solution to refresh the saved_devices_sheet. - repository_->GetUserSavedDevices(); - }); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/fast_pair_seeker_impl.h b/fastpair/internal/fast_pair_seeker_impl.h deleted file mode 100644 index bf096f2b6e..0000000000 --- a/fastpair/internal/fast_pair_seeker_impl.h +++ /dev/null @@ -1,148 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_DEFAULT_FAST_PAIR_SEEKER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_DEFAULT_FAST_PAIR_SEEKER_H_ - -#include -#include -#include - -#include "fastpair/fast_pair_controller.h" -#include "fastpair/fast_pair_events.h" -#include "fastpair/fast_pair_seeker.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/pairing/pairer_broker_impl.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "fastpair/retroactive/retroactive.h" -#include "fastpair/retroactive/retroactive_pairing_detector_impl.h" -#include "fastpair/scanning/scanner_broker_impl.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -// Fast Pair Seeker Extended interface. -// The methods in this interface are available only to FP internal plugins. -class FastPairSeekerExt : public FastPairSeeker { - public: - virtual absl::Status StartFastPairScan() = 0; - virtual absl::Status StopFastPairScan() = 0; - - // Handle the state changes of screen lock. - virtual void SetIsScreenLocked(bool is_locked) = 0; - virtual void ForgetDeviceByAccountKey(const AccountKey& account_key) = 0; -}; - -class FastPairSeekerImpl : public FastPairSeekerExt, - ScannerBrokerImpl::Observer, - PairerBroker::Observer, - BluetoothClassicMedium::Observer, - RetroactivePairingDetector::Observer { - public: - struct ServiceCallbacks { - absl::AnyInvocable - on_initial_discovery; - absl::AnyInvocable - on_subsequent_discovery; - absl::AnyInvocable on_pair_event; - absl::AnyInvocable on_screen_event; - absl::AnyInvocable - on_battery_event; - absl::AnyInvocable on_ring_event; - }; - - FastPairSeekerImpl(ServiceCallbacks callbacks, SingleThreadExecutor* executor, - AccountManager* account_manager, - FastPairDeviceRepository* devices, - FastPairRepository* repository); - - ~FastPairSeekerImpl() override; - - // From FastPairSeeker. - absl::Status StartInitialPairing(const FastPairDevice& device, - const InitialPairingParam& params, - PairingCallback callback) override; - - absl::Status StartSubsequentPairing(const FastPairDevice& device, - const SubsequentPairingParam& params, - PairingCallback callback) override; - - absl::Status StartRetroactivePairing(const FastPairDevice& device, - const RetroactivePairingParam& param, - PairingCallback callback) override; - - absl::Status FinishRetroactivePairing( - const FastPairDevice& device, const FinishRetroactivePairingParam& param, - PairingCallback callback) override; - - // From FastPairSeekerExt. - absl::Status StartFastPairScan() override; - absl::Status StopFastPairScan() override; - void SetIsScreenLocked(bool is_locked) override; - void ForgetDeviceByAccountKey(const AccountKey& account_key) override; - - // From BluetoothClassicMedium::Observer. - void DeviceAdded(BluetoothDevice& device) override; - void DeviceRemoved(BluetoothDevice& device) override; - void DeviceAddressChanged(BluetoothDevice& device, - absl::string_view old_address) override; - void DevicePairedChanged(BluetoothDevice& device, - bool new_paired_status) override; - void DeviceConnectedStateChanged(BluetoothDevice& device, - bool connected) override; - - // From RetroactivePairingDetector::Observer. - void OnRetroactivePairFound(FastPairDevice& device) override; - - // Internal methods, not exported to plugins. - private: - // From ScannerBrokerImpl::Observer. - void OnDeviceFound(FastPairDevice& device) override; - void OnDeviceLost(FastPairDevice& device) override; - - // From PairerBroker:Observer - void OnDevicePaired(FastPairDevice& device) override; - void OnAccountKeyWrite(FastPairDevice& device, - std::optional error) override; - void OnPairingComplete(FastPairDevice& device) override; - void OnPairFailure(FastPairDevice& device, PairFailure failure) override; - - void InvalidateScanningState() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - bool IsDeviceUnderPairing(const FastPairDevice& device); - void FinishPairing(absl::Status result); - - ServiceCallbacks callbacks_; - SingleThreadExecutor* executor_; - AccountManager* account_manager_; - FastPairDeviceRepository* devices_; - FastPairRepository* repository_; - Mediums mediums_; - std::unique_ptr scanner_; - std::unique_ptr scanning_session_; - std::unique_ptr pairer_broker_; - std::unique_ptr pairing_callback_; - std::unique_ptr retro_detector_; - std::unique_ptr controller_; - std::unique_ptr retroactive_pair_; - FastPairDevice* device_under_pairing_ = nullptr; - FastPairDevice* test_device_ = nullptr; - bool is_screen_locked_ = false; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_DEFAULT_FAST_PAIR_SEEKER_H_ diff --git a/fastpair/internal/fast_pair_seeker_impl_test.cc b/fastpair/internal/fast_pair_seeker_impl_test.cc deleted file mode 100644 index f49f262b1a..0000000000 --- a/fastpair/internal/fast_pair_seeker_impl_test.cc +++ /dev/null @@ -1,382 +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. - -#include "fastpair/internal/fast_pair_seeker_impl.h" - -#include - -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/fast_pair_events.h" -#include "fastpair/fast_pair_seeker.h" -#include "fastpair/message_stream/fake_gatt_callbacks.h" -#include "fastpair/message_stream/fake_provider.h" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/enum.proto.h" -#include "fastpair/repository/fake_fast_pair_repository.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/test/fake_account_manager.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr absl::string_view kServiceID{"Fast Pair"}; -constexpr absl::string_view kFastPairServiceUuid{ - "0000FE2C-0000-1000-8000-00805F9B34FB"}; -constexpr absl::string_view kModelId{"718c17"}; -constexpr absl::string_view kBobPrivateKey = - "02B437B0EDD6BBD429064A4E529FCBF1C48D0D624924D592274B7ED81193D763"; -constexpr absl::string_view kBobPublicKey = - "F7D496A62ECA416351540AA343BC690A6109F551500666B83B1251FB84FA2860795EBD63D3" - "B8836F44A9A3E28BB34017E015F5979305D849FDF8DE10123B61D2"; -constexpr absl::string_view kPasskey = "123456"; -constexpr absl::string_view kTestAccountId = "test_account_id"; - -using ::testing::status::StatusIs; - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class FastPairRepositoryObserver : public FastPairRepository::Observer { - public: - explicit FastPairRepositoryObserver(CountDownLatch* latch) { latch_ = latch; } - - void OnGetUserSavedDevices( - const proto::OptInStatus& opt_in_status, - const std::vector& devices) override { - latch_->CountDown(); - } - - CountDownLatch* latch_ = nullptr; -}; - -class FastPairSeekerImplTest : public testing::Test { - protected: - FastPairSeekerImplTest() = default; - - void SetUp() override { - NEARBY_LOG_SET_SEVERITY(VERBOSE); - repository_ = FakeFastPairRepository::Create( - kModelId, absl::HexStringToBytes(kBobPublicKey)); - repository_->SetResultOfIsDeviceSavedToAccount( - absl::NotFoundError("not found")); - account_manager_ = std::make_unique(); - AccountManager::Account account; - account.id = kTestAccountId; - account_manager_->SetAccount(account); - } - - void TearDown() override { executor_.Shutdown(); } - - void WaitForBackgroundTasks() { - CountDownLatch latch(1); - executor_.Execute([&]() { latch.CountDown(); }); - latch.Await(); - } - - MediumEnvironmentStarter env_; - SingleThreadExecutor executor_; - std::unique_ptr account_manager_; - FastPairDeviceRepository devices_{&executor_}; - std::unique_ptr repository_; - std::unique_ptr fast_pair_seeker_; - FakeGattCallbacks fake_gatt_callbacks_; -}; - -TEST_F(FastPairSeekerImplTest, StartAndStopFastPairScan) { - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{}, &executor_, - account_manager_.get(), &devices_, repository_.get()); - - EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); - EXPECT_OK(fast_pair_seeker_->StopFastPairScan()); -} - -TEST_F(FastPairSeekerImplTest, DISABLED_DiscoverDevice) { - FakeProvider provider; - CountDownLatch latch(1); - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{ - .on_initial_discovery = - [&](const FastPairDevice& device, InitialDiscoveryEvent event) { - EXPECT_EQ(device.GetModelId(), kModelId); - latch.CountDown(); - }}, - &executor_, account_manager_.get(), &devices_, repository_.get()); - - EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); - provider.StartDiscoverableAdvertisement(kModelId); - - // Waits for the device to be discovered - latch.Await(); -} - -TEST_F(FastPairSeekerImplTest, StartFastPairScanTwiceFails) { - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{}, &executor_, - account_manager_.get(), &devices_, repository_.get()); - EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); - - EXPECT_THAT(fast_pair_seeker_->StartFastPairScan(), - StatusIs(absl::StatusCode::kAlreadyExists)); -} - -TEST_F(FastPairSeekerImplTest, StopFastPairScanTwiceFails) { - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{}, &executor_, - account_manager_.get(), &devices_, repository_.get()); - EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); - - EXPECT_OK(fast_pair_seeker_->StopFastPairScan()); - EXPECT_THAT(fast_pair_seeker_->StopFastPairScan(), - StatusIs(absl::StatusCode::kNotFound)); -} - -TEST_F(FastPairSeekerImplTest, ScreenLocksDuringAdvertising) { - CountDownLatch latch(2); - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{ - .on_initial_discovery = - [&](const FastPairDevice& device, InitialDiscoveryEvent event) { - latch.CountDown(); - }, - .on_screen_event = - [&](ScreenEvent event) { - EXPECT_TRUE(event.is_locked); - latch.CountDown(); - }}, - &executor_, account_manager_.get(), &devices_, repository_.get()); - // Create Advertiser and startAdvertising - Mediums mediums_2; - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_2.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); - - fast_pair_seeker_->SetIsScreenLocked(true); - - EXPECT_TRUE(latch.Await().Ok()); -} - -TEST_F(FastPairSeekerImplTest, InitialPairing) { - NEARBY_LOG_SET_SEVERITY(VERBOSE); - FakeProvider provider; - CountDownLatch discover_latch(1); - CountDownLatch pair_latch(1); - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{ - .on_initial_discovery = - [&](const FastPairDevice& device, InitialDiscoveryEvent event) { - EXPECT_EQ(device.GetModelId(), kModelId); - EXPECT_OK(fast_pair_seeker_->StartInitialPairing( - device, {}, - {.on_pairing_result = [&](const FastPairDevice& device, - absl::Status status) { - EXPECT_EQ(device.GetBleAddress(), - provider.GetMacAddress()); - EXPECT_OK(status); - pair_latch.CountDown(); - }})); - discover_latch.CountDown(); - }}, - &executor_, account_manager_.get(), &devices_, repository_.get()); - - EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); - provider.PrepareForInitialPairing( - { - .private_key = absl::HexStringToBytes(kBobPrivateKey), - .public_key = absl::HexStringToBytes(kBobPublicKey), - .model_id = std::string(kModelId), - .pass_key = std::string(kPasskey), - }, - &fake_gatt_callbacks_); - - discover_latch.Await(); - pair_latch.Await(); - auto fp_device = devices_.FindDevice(provider.GetMacAddress()); - ASSERT_TRUE(fp_device.has_value()); - EXPECT_EQ(provider.GetAccountKey(), fp_device.value()->GetAccountKey()); - fast_pair_seeker_.reset(); -} - -TEST_F(FastPairSeekerImplTest, ForgetDeviceByAccountKey) { - NEARBY_LOG_SET_SEVERITY(VERBOSE); - FakeProvider provider; - CountDownLatch discover_latch(1); - CountDownLatch pair_latch(1); - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{ - .on_initial_discovery = - [&](const FastPairDevice& device, InitialDiscoveryEvent event) { - EXPECT_EQ(device.GetModelId(), kModelId); - EXPECT_OK(fast_pair_seeker_->StartInitialPairing( - device, {}, - {.on_pairing_result = [&](const FastPairDevice& device, - absl::Status status) { - EXPECT_EQ(device.GetBleAddress(), - provider.GetMacAddress()); - EXPECT_OK(status); - pair_latch.CountDown(); - }})); - discover_latch.CountDown(); - }}, - &executor_, account_manager_.get(), &devices_, repository_.get()); - - EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); - provider.PrepareForInitialPairing( - { - .private_key = absl::HexStringToBytes(kBobPrivateKey), - .public_key = absl::HexStringToBytes(kBobPublicKey), - .model_id = std::string(kModelId), - .pass_key = std::string(kPasskey), - }, - &fake_gatt_callbacks_); - - discover_latch.Await(); - pair_latch.Await(); - auto fp_device = devices_.FindDevice(provider.GetMacAddress()); - ASSERT_TRUE(fp_device.has_value()); - EXPECT_EQ(provider.GetAccountKey(), fp_device.value()->GetAccountKey()); - - // Adds FastPairRepository observer. - CountDownLatch repository_latch(1); - FastPairRepositoryObserver observer(&repository_latch); - repository_->AddObserver(&observer); - // Adds FastPairDeviceRepository observer. - CountDownLatch devices_latch(1); - FastPairDeviceRepository::RemoveDeviceCallback callback = - [&](const FastPairDevice& device) { devices_latch.CountDown(); }; - devices_.AddObserver(&callback); - - fast_pair_seeker_->ForgetDeviceByAccountKey( - fp_device.value()->GetAccountKey()); - repository_latch.Await(); - devices_latch.Await(); - EXPECT_FALSE(devices_.FindDevice(provider.GetMacAddress()).has_value()); - fast_pair_seeker_.reset(); -} - -TEST_F(FastPairSeekerImplTest, RetroactivePairingWithUserConsent) { - NEARBY_LOG_SET_SEVERITY(VERBOSE); - FakeProvider provider; - CountDownLatch pair_latch(1); - CountDownLatch retro_latch(1); - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{ - .on_pair_event = - [&](const FastPairDevice& device, PairEvent event) { - NEARBY_LOGS(INFO) << "Pair callback"; - pair_latch.CountDown(); - EXPECT_OK(fast_pair_seeker_->StartRetroactivePairing( - device, RetroactivePairingParam{}, - {.on_pairing_result = [&](const FastPairDevice&, - absl::Status status) { - EXPECT_OK(status); - retro_latch.CountDown(); - }})); - }}, - &executor_, account_manager_.get(), &devices_, repository_.get()); - - provider.PrepareForRetroactivePairing( - {.private_key = absl::HexStringToBytes(kBobPrivateKey), - .public_key = absl::HexStringToBytes(kBobPublicKey), - .model_id = std::string(kModelId)}, - &fake_gatt_callbacks_); - - EXPECT_TRUE(pair_latch.Await().Ok()); - EXPECT_TRUE(retro_latch.Await().Ok()); - auto fp_device = devices_.FindDevice(provider.GetMacAddress()); - ASSERT_TRUE(fp_device.has_value()); - EXPECT_EQ(provider.GetAccountKey(), fp_device.value()->GetAccountKey()); - - // The client asks the user for consent, the user grants it. - CountDownLatch finish_latch(1); - EXPECT_OK(fast_pair_seeker_->FinishRetroactivePairing( - **fp_device, FinishRetroactivePairingParam{.save_account_key = true}, - {.on_pairing_result = [&](const FastPairDevice&, absl::Status status) { - EXPECT_OK(status); - finish_latch.CountDown(); - }})); - EXPECT_TRUE(finish_latch.Await()); -} - -TEST_F(FastPairSeekerImplTest, RetroactivePairingNoUserConsent) { - NEARBY_LOG_SET_SEVERITY(VERBOSE); - FakeProvider provider; - CountDownLatch pair_latch(1); - CountDownLatch retro_latch(1); - fast_pair_seeker_ = std::make_unique( - FastPairSeekerImpl::ServiceCallbacks{ - .on_pair_event = - [&](const FastPairDevice& device, PairEvent event) { - NEARBY_LOGS(INFO) << "Pair callback"; - pair_latch.CountDown(); - EXPECT_OK(fast_pair_seeker_->StartRetroactivePairing( - device, RetroactivePairingParam{}, - {.on_pairing_result = [&](const FastPairDevice&, - absl::Status status) { - EXPECT_OK(status); - retro_latch.CountDown(); - }})); - }}, - &executor_, account_manager_.get(), &devices_, repository_.get()); - - provider.PrepareForRetroactivePairing( - {.private_key = absl::HexStringToBytes(kBobPrivateKey), - .public_key = absl::HexStringToBytes(kBobPublicKey), - .model_id = std::string(kModelId)}, - &fake_gatt_callbacks_); - - EXPECT_TRUE(pair_latch.Await().Ok()); - EXPECT_TRUE(retro_latch.Await().Ok()); - auto fp_device = devices_.FindDevice(provider.GetMacAddress()); - ASSERT_TRUE(fp_device.has_value()); - EXPECT_EQ(provider.GetAccountKey(), fp_device.value()->GetAccountKey()); - - // The client asks the user for consent, the user rejects it. - CountDownLatch finish_latch(1); - EXPECT_OK(fast_pair_seeker_->FinishRetroactivePairing( - **fp_device, FinishRetroactivePairingParam{.save_account_key = false}, - {.on_pairing_result = [&](const FastPairDevice&, absl::Status status) { - EXPECT_OK(status); - finish_latch.CountDown(); - }})); - EXPECT_TRUE(finish_latch.Await()); - // The device should be deleted. - WaitForBackgroundTasks(); - EXPECT_FALSE(devices_.FindDevice(provider.GetMacAddress()).has_value()); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/impl/windows/BUILD b/fastpair/internal/impl/windows/BUILD deleted file mode 100644 index 06ba234bd7..0000000000 --- a/fastpair/internal/impl/windows/BUILD +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2022 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. - -licenses(["notice"]) - -cc_library( - name = "platform_windows_libs", - linkopts = [ - "wininet.lib", - "kernel32.lib", - "user32.lib", - "gdi32.lib", - "winspool.lib", - "comdlg32.lib", - "advapi32.lib", - "shell32.lib", - "ole32.lib", - "oleaut32.lib", - "uuid.lib", - "odbc32.lib", - "odbccp32.lib", - "wbemuuid.lib", - "wtsapi32.lib", - "version.lib", - ], - visibility = ["//visibility:private"], -) diff --git a/fastpair/internal/mediums/BUILD b/fastpair/internal/mediums/BUILD deleted file mode 100644 index 589e600408..0000000000 --- a/fastpair/internal/mediums/BUILD +++ /dev/null @@ -1,151 +0,0 @@ -# Copyright 2022 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. - -licenses(["notice"]) - -cc_library( - name = "mediums", - srcs = [ - "ble.cc", - "ble_v2.cc", - "bluetooth_classic.cc", - "bluetooth_radio.cc", - "robust_gatt_client.cc", - ], - hdrs = [ - "ble.h", - "ble_v2.h", - "bluetooth_classic.h", - "bluetooth_radio.h", - "mediums.h", - "robust_gatt_client.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//internal/platform:comm", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - ], -) - -cc_test( - name = "bluetooth_radio_test", - size = "small", - srcs = [ - "bluetooth_radio_test.cc", - ], - shard_count = 16, - deps = [ - ":mediums", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "mediums_test", - size = "small", - srcs = [ - "mediums_test.cc", - ], - shard_count = 16, - deps = [ - ":mediums", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "ble_test", - size = "small", - srcs = [ - "ble_test.cc", - ], - shard_count = 16, - deps = [ - ":mediums", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "ble_v2_test", - size = "small", - srcs = [ - "ble_v2_test.cc", - ], - shard_count = 16, - deps = [ - ":mediums", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "bluetooth_classic_test", - size = "small", - srcs = [ - "bluetooth_classic_test.cc", - ], - shard_count = 16, - deps = [ - ":mediums", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "robust_gatt_client_test", - size = "small", - srcs = [ - "robust_gatt_client_test.cc", - ], - deps = [ - ":mediums", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/internal/mediums/ble.cc b/fastpair/internal/mediums/ble.cc deleted file mode 100644 index 764af9692d..0000000000 --- a/fastpair/internal/mediums/ble.cc +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/internal/mediums/ble.h" - -#include -#include - -#include "fastpair/internal/mediums/bluetooth_radio.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" - -namespace nearby { -namespace fastpair { -Ble::Ble(BluetoothRadio& radio) : radio_(radio) {} - -bool Ble::IsAvailable() const { - MutexLock lock(&mutex_); - return IsAvailableLocked(); -} - -bool Ble::IsAvailableLocked() const { - return medium_.IsValid() && adapter_.IsValid() && adapter_.IsEnabled(); -} - -bool Ble::StartScanning(const std::string& service_id, - const std::string& fast_pair_service_uuid, - DiscoveredPeripheralCallback callback) { - MutexLock lock(&mutex_); - - discovered_peripheral_callback_ = std::move(callback); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) - << "Refusing to start BLE scanning with empty service id."; - return false; - } - - if (IsScanningLocked()) { - NEARBY_LOGS(INFO) << "Refusing to start BLE scanning because " - "another scanning is already in-progress."; - return false; - } - - if (!radio_.IsEnabled()) { - NEARBY_LOGS(INFO) - << "Can't start BLE scanning because Bluetooth was NOT enabled"; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) << "Can't scan BLE scanning because BLE isn't available."; - return false; - } - - if (!medium_.StartScanning( - service_id, fast_pair_service_uuid, - { - .peripheral_discovered_cb = - [this](BlePeripheral& peripheral, - const std::string& service_id, - const ByteArray& medium_advertisement_bytes, - bool fast_advertisement) { - // Don't bother trying to parse zero byte advertisements. - if (medium_advertisement_bytes.size() == 0) { - NEARBY_LOGS(INFO) << "Skipping zero byte advertisement " - << "with service_id: " << service_id; - return; - } - discovered_peripheral_callback_.peripheral_discovered_cb( - peripheral, service_id, medium_advertisement_bytes, - fast_advertisement); - }, - .peripheral_lost_cb = - [this](BlePeripheral& peripheral, - const std::string& service_id) { - discovered_peripheral_callback_.peripheral_lost_cb( - peripheral, service_id); - }, - })) { - NEARBY_LOGS(INFO) << "Failed to start BLE scanning"; - return false; - } - - NEARBY_LOGS(INFO) << "Start BLE scanning with service id=" << service_id; - // Mark the fact that we're currently performing a BLE scanning. - is_scanning_ = true; - return true; -} - -bool Ble::StopScanning(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (!IsScanningLocked()) { - NEARBY_LOGS(INFO) << "Can't stop BLE scanning because we never " - "started scanning."; - return false; - } - - NEARBY_LOGS(INFO) << "Stop BLE scanning with service id=" << service_id; - bool ret = medium_.StopScanning(service_id); - is_scanning_ = false; - return ret; -} - -bool Ble::IsScanning() { - NEARBY_LOGS(INFO) << __func__; - MutexLock lock(&mutex_); - return IsScanningLocked(); -} - -bool Ble::IsScanningLocked() { return is_scanning_; } - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/ble.h b/fastpair/internal/mediums/ble.h deleted file mode 100644 index dd40e56f45..0000000000 --- a/fastpair/internal/mediums/ble.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BLE_BLE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BLE_BLE_H_ - -#include - -#include "fastpair/internal/mediums/bluetooth_radio.h" -#include "internal/platform/ble.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/mutex.h" - -namespace nearby { -namespace fastpair { - -// Provides the operations that can be performed on the Bluetooth Low Energy -// (BLE) medium. -class Ble { - public: - using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback; - - explicit Ble(BluetoothRadio& bluetooth_radio); - Ble(Ble&&) = delete; - Ble& operator=(Ble&&) = delete; - ~Ble() = default; - - // Returns true, if Ble communications are supported by a platform. - bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Enables Ble scanning mode. Will report any discoverable peripherals in - // range through a callback. Returns true, if scanning mode was enabled, - // false otherwise. - bool StartScanning(const std::string& service_id, - const std::string& fast_pair_service_uuid, - DiscoveredPeripheralCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables Ble discovery mode. - bool StopScanning(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - // Return true if Ble is currenlty scanning. - bool IsScanning() ABSL_LOCKS_EXCLUDED(mutex_); - - // Return BleMedium - BleMedium& GetMedium() { return medium_; } - - private: - // Same as IsAvailable(), but must be called with mutex_ held. - bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsDiscovering(), but must be called with mutex_ held. - bool IsScanningLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - mutable Mutex mutex_; - DiscoveredPeripheralCallback discovered_peripheral_callback_; - BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_); - BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){ - radio_.GetBluetoothAdapter()}; - BleMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; - bool is_scanning_ = false; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BLE_BLE_H_ diff --git a/fastpair/internal/mediums/ble_test.cc b/fastpair/internal/mediums/ble_test.cc deleted file mode 100644 index 0c2b773851..0000000000 --- a/fastpair/internal/mediums/ble_test.cc +++ /dev/null @@ -1,80 +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. - -#include "fastpair/internal/mediums/ble.h" - -#include - -#include "gtest/gtest.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" - -namespace nearby { -namespace fastpair { -namespace { - -using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback; -constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); -constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; -constexpr absl::string_view kAdvertisementString{"96C12E"}; -constexpr absl::string_view kFastPairServiceUuid{"\x2c\xfe"}; - -TEST(BleTest, ConstructorDestructorWorks) { - BluetoothRadio radio; - Ble ble(radio); - EXPECT_TRUE(ble.IsAvailable()); - EXPECT_FALSE(ble.IsScanning()); -} - -TEST(BleTest, CanStartDiscovery) { - MediumEnvironment::Instance().Start(); - BluetoothRadio radio_a; - BluetoothRadio radio_b; - Ble ble_a{radio_a}; - Ble ble_b{radio_b}; - radio_a.Enable(); - radio_b.Enable(); - std::string service_id(kServiceID); - ByteArray advertisement_bytes{std::string(kAdvertisementString)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - CountDownLatch accept_latch(1); - CountDownLatch lost_latch(1); - ble_b.GetMedium().StartAdvertising(service_id, advertisement_bytes, - fast_pair_service_uuid); - - EXPECT_TRUE(ble_a.StartScanning( - service_id, fast_pair_service_uuid, - DiscoveredPeripheralCallback{ - .peripheral_discovered_cb = - [&accept_latch]( - BlePeripheral& peripheral, const std::string& service_id, - const ByteArray& advertisement_bytes, - bool fast_advertisement) { accept_latch.CountDown(); }, - .peripheral_lost_cb = - [&lost_latch](BlePeripheral& peripheral, - const std::string& service_id) { - lost_latch.CountDown(); - }, - })); - EXPECT_TRUE(ble_a.IsScanning()); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - ble_b.GetMedium().StopAdvertising(service_id); - EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(ble_a.StopScanning(service_id)); - EXPECT_FALSE(ble_a.IsScanning()); - MediumEnvironment::Instance().Stop(); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/ble_v2.cc b/fastpair/internal/mediums/ble_v2.cc deleted file mode 100644 index 2147d6d161..0000000000 --- a/fastpair/internal/mediums/ble_v2.cc +++ /dev/null @@ -1,60 +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. - -#include "fastpair/internal/mediums/ble_v2.h" - -#include -#include -#include - -#include "internal/platform/mutex_lock.h" - -namespace nearby { -namespace fastpair { - -BleV2::BleV2(BluetoothRadio& radio) : radio_(radio) {} - -bool BleV2::IsAvailable() const { - MutexLock lock(&mutex_); - return IsAvailableLocked(); -} - -bool BleV2::IsAvailableLocked() const { - return medium_.IsValid() && adapter_.IsValid() && adapter_.IsEnabled(); -} - -std::unique_ptr BleV2::ConnectToGattServer( - absl::string_view ble_address, RobustGattClient::ConnectionParams params, - RobustGattClient::ConnectionStatusCallback connection_status_callback) { - MutexLock lock(&mutex_); - if (!radio_.IsEnabled()) { - NEARBY_LOGS(INFO) - << "Can't connect to GattServer because Bluetooth was NOT enabled"; - return nullptr; - } - if (!IsAvailableLocked()) { - NEARBY_LOGS(VERBOSE) - << __func__ - << "Can't connect to GattServer because BleV2 isn't available."; - return nullptr; - } - - BleV2Peripheral v2_peripheral = - medium_.GetRemotePeripheral(std::string(ble_address)); - return std::make_unique( - medium_, v2_peripheral, std::move(params), - std::move(connection_status_callback)); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/ble_v2.h b/fastpair/internal/mediums/ble_v2.h deleted file mode 100644 index 81adf30ae2..0000000000 --- a/fastpair/internal/mediums/ble_v2.h +++ /dev/null @@ -1,60 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLE_V2_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLE_V2_H_ - -#include -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/internal/mediums/bluetooth_radio.h" -#include "fastpair/internal/mediums/robust_gatt_client.h" -#include "internal/platform/ble_v2.h" -#include "internal/platform/mutex.h" -#include "internal/platform/mutex_lock.h" - -namespace nearby { -namespace fastpair { - -// Provides the operations that can be performed on the Bluetooth Low Energy -// (BLE_V2) medium. -class BleV2 { - public: - explicit BleV2(BluetoothRadio& bluetooth_radio); - ~BleV2() = default; - - // Returns true, if BleV2 communications are supported by a platform. - bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns a new GattClient connection to a gatt server. - std::unique_ptr ConnectToGattServer( - absl::string_view ble_address, RobustGattClient::ConnectionParams params, - RobustGattClient::ConnectionStatusCallback connection_status_callback); - - private: - // Same as IsAvailable(), but must be called with mutex_ held. - bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - mutable Mutex mutex_; - BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_); - BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){ - radio_.GetBluetoothAdapter()}; - BleV2Medium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLE_V2_H_ diff --git a/fastpair/internal/mediums/ble_v2_test.cc b/fastpair/internal/mediums/ble_v2_test.cc deleted file mode 100644 index 642c288b62..0000000000 --- a/fastpair/internal/mediums/ble_v2_test.cc +++ /dev/null @@ -1,46 +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. - -#include "fastpair/internal/mediums/ble_v2.h" - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(BleV2Test, IsAvailable) { - BluetoothRadio radio; - BleV2 bleV2(radio); - EXPECT_TRUE(bleV2.IsAvailable()); - EXPECT_TRUE(radio.Disable()); - EXPECT_FALSE(bleV2.IsAvailable()); -} - -TEST(BleV2Test, CanConnectToGattServer) { - BluetoothRadio radio; - BleV2 bleV2(radio); - EXPECT_TRUE(bleV2.ConnectToGattServer("bleaddress", {}, nullptr)); -} - -TEST(BleV2Test, CannotConnectToGattServer) { - BluetoothRadio radio; - BleV2 bleV2(radio); - EXPECT_TRUE(radio.Disable()); - EXPECT_FALSE(bleV2.ConnectToGattServer("bleaddress", {}, nullptr)); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/bluetooth_classic.cc b/fastpair/internal/mediums/bluetooth_classic.cc deleted file mode 100644 index a80e10be8f..0000000000 --- a/fastpair/internal/mediums/bluetooth_classic.cc +++ /dev/null @@ -1,115 +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. - -#include "fastpair/internal/mediums/bluetooth_classic.h" - -#include -#include - -#include "absl/strings/escaping.h" -#include "internal/platform/bluetooth_adapter.h" - -namespace nearby { -namespace fastpair { - -BluetoothClassic::BluetoothClassic(BluetoothRadio& radio) : radio_(radio) {} - -bool BluetoothClassic::IsAvailable() const { - MutexLock lock(&mutex_); - return IsAvailableLocked(); -} - -bool BluetoothClassic::IsAvailableLocked() const { - return medium_.IsValid() && adapter_.IsValid() && adapter_.IsEnabled(); -} - -void BluetoothClassic::AddObserver(BluetoothClassicMedium::Observer* observer) { - MutexLock lock(&mutex_); - medium_.AddObserver(observer); -} - -void BluetoothClassic::RemoveObserver( - BluetoothClassicMedium::Observer* observer) { - MutexLock lock(&mutex_); - medium_.RemoveObserver(observer); -} - -bool BluetoothClassic::StartDiscovery() { - MutexLock lock(&mutex_); - if (!radio_.IsEnabled()) { - NEARBY_LOGS(INFO) << "Can't discover BT devices because BT isn't enabled."; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) - << "Can't discover BT devices because BT isn't available."; - return false; - } - - if (!medium_.StartDiscovery({})) { - NEARBY_LOGS(INFO) << "Failed to start discovery of BT devices."; - return false; - } - // Mark the fact that we're currently performing a Bluetooth scan. - is_scanning = true; - return true; -} - -bool BluetoothClassic::StopDiscovery() { - MutexLock lock(&mutex_); - if (!IsDiscovering()) { - NEARBY_LOGS(INFO) - << "Can't stop discovery of BT devices because it never started."; - return false; - } - - if (!medium_.StopDiscovery()) { - NEARBY_LOGS(INFO) << "Failed to stop discovery of Bluetooth devices."; - return false; - } - is_scanning = false; - return true; -} - -bool BluetoothClassic::IsDiscovering() const { return is_scanning; } - -std::unique_ptr BluetoothClassic::CreatePairing( - absl::string_view public_address) { - MutexLock lock(&mutex_); - if (!radio_.IsEnabled()) { - NEARBY_LOGS(INFO) - << __func__ - << "Can't create bluetooth pairing because Bluetooth was NOT enabled"; - return nullptr; - } - if (!IsAvailableLocked()) { - NEARBY_LOGS(VERBOSE) << __func__ - << "Can't create bluetooth pairing because " - "BluetoothClassic isn't available."; - return nullptr; - } - BluetoothDevice device = medium_.GetRemoteDevice(std::string(public_address)); - if (!device.IsValid()) { - NEARBY_LOGS(INFO) << __func__ - << "Can't create bluetooth pairing because Bluetooth " - "device was NOT found"; - return nullptr; - } - return medium_.CreatePairing(device); -} - -BluetoothClassicMedium& BluetoothClassic::GetMedium() { return medium_; } -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/bluetooth_classic.h b/fastpair/internal/mediums/bluetooth_classic.h deleted file mode 100644 index 1256354c7f..0000000000 --- a/fastpair/internal/mediums/bluetooth_classic.h +++ /dev/null @@ -1,71 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_CLASSIC_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_CLASSIC_H_ - -#include - -#include "absl/strings/string_view.h" -#include "fastpair/internal/mediums/bluetooth_radio.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/mutex.h" -namespace nearby { -namespace fastpair { - -class BluetoothClassic { - public: - explicit BluetoothClassic(BluetoothRadio& bluetooth_radio); - ~BluetoothClassic() = default; - - // Returns true, if BT communications are supported by a platform. - bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); - - void AddObserver(BluetoothClassicMedium::Observer* observer); - void RemoveObserver(BluetoothClassicMedium::Observer* observer); - - // Enables BT discovery mode to observer any discoverable device in range. - // Returns true, if discovery mode was enabled, false otherwise. - bool StartDiscovery() ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables BT discovery mode. - // Returns true, if discovery mode was previously enabled, false otherwise. - bool StopDiscovery() ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns a new BluetoothPairing instance to handle the pairing process - // with the remote device. - std::unique_ptr CreatePairing( - absl::string_view public_address); - - BluetoothClassicMedium& GetMedium() ABSL_LOCKS_EXCLUDED(mutex_); - - private: - // Same as IsAvailable(), but must be called with mutex_ held. - bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Returns true if device is currently in discovery mode. - bool IsDiscovering() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - mutable Mutex mutex_; - BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_); - BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){ - radio_.GetBluetoothAdapter()}; - BluetoothClassicMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; - bool is_scanning ABSL_GUARDED_BY(mutex_) = false; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_CLASSIC_H_ diff --git a/fastpair/internal/mediums/bluetooth_classic_test.cc b/fastpair/internal/mediums/bluetooth_classic_test.cc deleted file mode 100644 index 307ed47070..0000000000 --- a/fastpair/internal/mediums/bluetooth_classic_test.cc +++ /dev/null @@ -1,154 +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. - -#include "fastpair/internal/mediums/bluetooth_classic.h" - -#include "gtest/gtest.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" - -namespace nearby { -namespace fastpair { -namespace { -class BluetoothClassicMediumObserver - : public BluetoothClassicMedium ::Observer { - public: - explicit BluetoothClassicMediumObserver( - BluetoothClassic* bluetooth_classic, CountDownLatch* device_added_latch, - CountDownLatch* device_removed_latch, - CountDownLatch* device_paired_changed_latch) - : bluetooth_classic_(bluetooth_classic), - device_added_latch_(device_added_latch), - device_removed_latch_(device_removed_latch), - device_paired_changed_latch_(device_paired_changed_latch) { - bluetooth_classic_->AddObserver(this); - } - - ~BluetoothClassicMediumObserver() override { - bluetooth_classic_->RemoveObserver(this); - } - - void DeviceAdded(BluetoothDevice& device) override { - if (!device_added_latch_) return; - device_added_latch_->CountDown(); - } - - void DeviceRemoved(BluetoothDevice& device) override { - if (!device_removed_latch_) return; - device_removed_latch_->CountDown(); - } - - void DevicePairedChanged(BluetoothDevice& device, - bool new_paired_status) override { - if (!device_paired_changed_latch_) return; - device_paired_changed_latch_->CountDown(); - } - - BluetoothClassic* bluetooth_classic_; - CountDownLatch* device_added_latch_; - CountDownLatch* device_removed_latch_; - CountDownLatch* device_paired_changed_latch_; -}; - -TEST(BluetoothClassicTest, CanStartAndStopDiscovery) { - MediumEnvironment::Instance().Start(); - BluetoothRadio radio; - BluetoothClassic bluetooth_classic(radio); - BluetoothAdapter provider_adapter; - provider_adapter.SetStatus(BluetoothAdapter::Status::kEnabled); - provider_adapter.SetScanMode( - BluetoothAdapter::ScanMode::kConnectableDiscoverable); - BluetoothClassicMedium bt_provider(provider_adapter); - CountDownLatch device_added_latch(1); - CountDownLatch device_removed_latch(1); - BluetoothClassicMediumObserver observer( - &bluetooth_classic, &device_added_latch, &device_removed_latch, nullptr); - - EXPECT_TRUE(bluetooth_classic.StartDiscovery()); - device_added_latch.Await(); - provider_adapter.SetStatus(BluetoothAdapter::Status::kDisabled); - device_removed_latch.Await(); - - EXPECT_TRUE(bluetooth_classic.StopDiscovery()); - MediumEnvironment::Instance().Stop(); -} - -TEST(BluetoothClassicTest, CanCreatePairing) { - MediumEnvironment::Instance().Start(); - BluetoothRadio radio; - BluetoothClassic bluetooth_classic(radio); - BluetoothAdapter provider_adapter; - provider_adapter.SetStatus(BluetoothAdapter::Status::kEnabled); - BluetoothClassicMedium bt_provider(provider_adapter); - - EXPECT_TRUE(bluetooth_classic.IsAvailable()); - EXPECT_TRUE( - bluetooth_classic.CreatePairing(provider_adapter.GetMacAddress())); - MediumEnvironment::Instance().Stop(); -} - -TEST(BluetoothClassicTest, FailedToCreatePairingDueToRemoteDeviceNotFound) { - MediumEnvironment::Instance().Start(); - BluetoothRadio radio; - BluetoothClassic bluetooth_classic(radio); - BluetoothAdapter provider_adapter; - provider_adapter.SetStatus(BluetoothAdapter::Status::kEnabled); - BluetoothClassicMedium bt_provider(provider_adapter); - - EXPECT_TRUE(bluetooth_classic.IsAvailable()); - EXPECT_FALSE(bluetooth_classic.CreatePairing("bleaddress")); - MediumEnvironment::Instance().Stop(); -} - -TEST(BluetoothClassicTest, RadioDisable) { - BluetoothRadio radio; - BluetoothClassic bluetooth_classic(radio); - BluetoothAdapter provider_adapter; - provider_adapter.SetStatus(BluetoothAdapter::Status::kEnabled); - BluetoothClassicMedium bt_provider(provider_adapter); - radio.Disable(); - - EXPECT_FALSE(bluetooth_classic.IsAvailable()); - EXPECT_FALSE( - bluetooth_classic.CreatePairing(provider_adapter.GetMacAddress())); - EXPECT_FALSE(bluetooth_classic.StartDiscovery()); - EXPECT_FALSE(bluetooth_classic.StopDiscovery()); -} - -TEST(BluetoothClassicTest, BluetoothAdapterDisable) { - BluetoothRadio radio; - radio.GetBluetoothAdapter().SetStatus(BluetoothAdapter::Status::kDisabled); - BluetoothClassic bluetooth_classic(radio); - BluetoothAdapter adapter_provider; - adapter_provider.SetStatus(BluetoothAdapter::Status::kEnabled); - BluetoothClassicMedium bt_provider(adapter_provider); - - EXPECT_FALSE(bluetooth_classic.IsAvailable()); - EXPECT_FALSE( - bluetooth_classic.CreatePairing(adapter_provider.GetMacAddress())); - EXPECT_FALSE(bluetooth_classic.StartDiscovery()); - EXPECT_FALSE(bluetooth_classic.StopDiscovery()); -} - -TEST(BluetoothClassicTest, GetMedium) { - BluetoothRadio radio; - BluetoothClassic bluetooth_classic(radio); - - EXPECT_TRUE(bluetooth_classic.GetMedium().IsValid()); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/bluetooth_radio.cc b/fastpair/internal/mediums/bluetooth_radio.cc deleted file mode 100644 index 2d85fbcb52..0000000000 --- a/fastpair/internal/mediums/bluetooth_radio.cc +++ /dev/null @@ -1,87 +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. - -#include "fastpair/internal/mediums/bluetooth_radio.h" - -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -BluetoothRadio::BluetoothRadio() { - if (!IsAdapterValid()) { - NEARBY_LOGS(ERROR) << "Bluetooth adapter is not valid: BT is not supported"; - } -} - -BluetoothRadio::~BluetoothRadio() { - NEARBY_LOGS(VERBOSE) << "~BluetoothRadio start"; - // We never enabled Bluetooth, nothing to do. - if (!ever_saved_state_.Get()) { - NEARBY_LOGS(INFO) << "BT adapter was not used. Not touching HW."; - return; - } - NEARBY_LOGS(INFO) << "Bring BT adapter to original state"; - if (!SetBluetoothState(originally_enabled_.Get())) { - NEARBY_LOGS(INFO) << "Failed to restore BT adapter original state."; - } - NEARBY_LOGS(VERBOSE) << "~BluetoothRadio done"; -} - -bool BluetoothRadio::Enable() { - NEARBY_LOGS(INFO) << __func__; - if (!SaveOriginalState()) { - return false; - } - - return SetBluetoothState(true); -} - -bool BluetoothRadio::Disable() { - if (!SaveOriginalState()) { - return false; - } - - return SetBluetoothState(false); -} - -bool BluetoothRadio::IsEnabled() const { - return IsAdapterValid() && IsInDesiredState(true); -} - -bool BluetoothRadio::SetBluetoothState(bool enable) { - return bluetooth_adapter_.SetStatus( - enable ? BluetoothAdapter::Status::kEnabled - : BluetoothAdapter::Status::kDisabled); -} - -bool BluetoothRadio::IsInDesiredState(bool should_be_enabled) const { - return bluetooth_adapter_.IsEnabled() == should_be_enabled; -} - -bool BluetoothRadio::SaveOriginalState() { - if (!IsAdapterValid()) { - return false; - } - - // If we haven't saved the original state of the radio, save it. - if (!ever_saved_state_.Set(true)) { - originally_enabled_.Set(bluetooth_adapter_.IsEnabled()); - } - - return true; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/bluetooth_radio.h b/fastpair/internal/mediums/bluetooth_radio.h deleted file mode 100644 index 135d373104..0000000000 --- a/fastpair/internal/mediums/bluetooth_radio.h +++ /dev/null @@ -1,79 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_RADIO_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_RADIO_H_ - -#include "internal/platform/atomic_boolean.h" -#include "internal/platform/bluetooth_adapter.h" - -namespace nearby { -namespace fastpair { - -// Provides the operations that can be performed on the Bluetooth radio. -class BluetoothRadio { - public: - BluetoothRadio(); - BluetoothRadio(BluetoothRadio&&) = default; - BluetoothRadio& operator=(BluetoothRadio&&) = default; - - // Reverts the Bluetooth radio to its original state. - ~BluetoothRadio(); - - // Enables Bluetooth. - // - // This must be called before attempting to invoke any other methods of - // this class. - // - // Returns true if enabled successfully. - bool Enable(); - - // Disables Bluetooth. - // - // Returns true if disabled successfully. - bool Disable(); - - // Returns true if the Bluetooth radio is currently enabled. - bool IsEnabled() const; - - // Returns result of BluetoothAdapter::IsValid() for private adapter instance. - bool IsAdapterValid() const { return bluetooth_adapter_.IsValid(); } - - BluetoothAdapter& GetBluetoothAdapter() { return bluetooth_adapter_; } - - private: - bool SetBluetoothState(bool enable); - bool IsInDesiredState(bool should_be_enabled) const; - // To be called in enable() and disable(). This will remember the - // original state of the radio before any radio state has been modified. - // Returns false if Bluetooth doesn't exist on the device and the state cannot - // be obtained. - bool SaveOriginalState(); - - // BluetoothAdapter::IsValid() will return false if BT is not supported. - BluetoothAdapter bluetooth_adapter_; - - // The Bluetooth radio's original state, before we modified it. True if - // originally enabled, false if originally disabled. - // We restore the radio to its original state in the destructor. - - AtomicBoolean originally_enabled_{false}; - // false if we never modified the radio state, true otherwise. - AtomicBoolean ever_saved_state_{false}; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_RADIO_H_ diff --git a/fastpair/internal/mediums/bluetooth_radio_test.cc b/fastpair/internal/mediums/bluetooth_radio_test.cc deleted file mode 100644 index 834aca8e95..0000000000 --- a/fastpair/internal/mediums/bluetooth_radio_test.cc +++ /dev/null @@ -1,48 +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. - -#include "fastpair/internal/mediums/bluetooth_radio.h" - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(BluetoothRadioTest, ConstructorDestructorWorks) { - BluetoothRadio radio; - EXPECT_TRUE(radio.IsAdapterValid()); -} - -TEST(BluetoothRadioTest, CanEnable) { - BluetoothRadio radio; - EXPECT_TRUE(radio.IsAdapterValid()); - EXPECT_TRUE(radio.IsEnabled()); - EXPECT_TRUE(radio.Disable()); - EXPECT_FALSE(radio.IsEnabled()); - EXPECT_TRUE(radio.Enable()); - EXPECT_TRUE(radio.IsEnabled()); -} - -TEST(BluetoothRadioTest, CanDisable) { - BluetoothRadio radio; - EXPECT_TRUE(radio.IsAdapterValid()); - EXPECT_TRUE(radio.IsEnabled()); - EXPECT_TRUE(radio.Disable()); - EXPECT_FALSE(radio.IsEnabled()); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/mediums.h b/fastpair/internal/mediums/mediums.h deleted file mode 100644 index f94a4eb3ad..0000000000 --- a/fastpair/internal/mediums/mediums.h +++ /dev/null @@ -1,60 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_MEDIUMS_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_MEDIUMS_H_ - -#include "fastpair/internal/mediums/ble.h" -#include "fastpair/internal/mediums/ble_v2.h" -#include "fastpair/internal/mediums/bluetooth_classic.h" -#include "fastpair/internal/mediums/bluetooth_radio.h" - -namespace nearby { -namespace fastpair { - -// Facilitates convenient and reliable usage of various wireless mediums. -class Mediums { - public: - Mediums() = default; - ~Mediums() = default; - - // Returns a handle to the Bluetooth radio. - BluetoothRadio& GetBluetoothRadio() { return bluetooth_radio_; } - - // Returns a handle to the Ble medium. - Ble& GetBle() { return ble_; } - - // Returns a handle to the Ble medium. - BleV2& GetBleV2() { return ble_v2_; } - - BluetoothClassic& GetBluetoothClassic() { return bluetooth_classic_; } - - private: - // The order of declaration is critical for both construction and - // destruction. - // - // 1) Construction: The individual mediums have a dependency on the - // corresponding radio, so the radio must be initialized first. - // - // 2) Destruction: The individual mediums should be shut down before the - // corresponding radio. - BluetoothRadio bluetooth_radio_; - Ble ble_{bluetooth_radio_}; - BleV2 ble_v2_{bluetooth_radio_}; - BluetoothClassic bluetooth_classic_{bluetooth_radio_}; -}; - -} // namespace fastpair -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_MEDIUMS_H_ diff --git a/fastpair/internal/mediums/mediums_test.cc b/fastpair/internal/mediums/mediums_test.cc deleted file mode 100644 index 664475864b..0000000000 --- a/fastpair/internal/mediums/mediums_test.cc +++ /dev/null @@ -1,33 +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. - -#include "fastpair/internal/mediums/mediums.h" - -#include "gtest/gtest.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(MediumTest, ConstructorWorks) { - Mediums medium; - EXPECT_TRUE(medium.GetBluetoothRadio().IsAdapterValid()); - EXPECT_FALSE(medium.GetBle().IsScanning()); - EXPECT_TRUE( - medium.GetBleV2().ConnectToGattServer("ble_address", {}, nullptr)); - EXPECT_TRUE(medium.GetBluetoothClassic().IsAvailable()); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/robust_gatt_client.cc b/fastpair/internal/mediums/robust_gatt_client.cc deleted file mode 100644 index 885db170a3..0000000000 --- a/fastpair/internal/mediums/robust_gatt_client.cc +++ /dev/null @@ -1,425 +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. - -#include "fastpair/internal/mediums/robust_gatt_client.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { -namespace {} // namespace - -RobustGattClient::~RobustGattClient() { - Stop(); - executor_.Shutdown(); -} - -void RobustGattClient::Stop() { - NEARBY_LOGS(INFO) << "Stopping gatt client"; - stopped_ = true; - executor_.Execute("cleanup", [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED( - executor_) { Cleanup(); }); -} - -void RobustGattClient::Connect() { - executor_.Execute("connect-gatt", - [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) { - NEARBY_LOGS(INFO) << "Connecting to Gatt server"; - status_ = TryConnect(); - if (!status_.ok()) { - NEARBY_LOGS(INFO) << status_; - NotifyClient(status_); - return; - } - NEARBY_LOGS(INFO) << "Discovering services"; - status_ = TryDiscoverServices(); - if (!status_.ok()) { - NEARBY_LOGS(INFO) << status_; - NotifyClient(status_); - return; - } - NEARBY_LOGS(INFO) << "Gatt connection ready"; - NotifyClient(absl::OkStatus()); - }); -} - -absl::Status RobustGattClient::TryConnect() { - ExpBackOff back_off(params_); - absl::Time start_time = SystemClock().ElapsedRealtime(); - while (!stopped_ && SystemClock().ElapsedRealtime() - start_time < - params_.connect_timeout) { - gatt_client_ = medium_.ConnectToGattServer( - peripheral_, params_.tx_power_level, {.disconnected_cb = [this]() { - if (stopped_) return; - NEARBY_LOGS(INFO) << "Gatt server disconnected. Reconnecting..."; - Connect(); - }}); - if (gatt_client_ != nullptr && gatt_client_->IsValid()) { - return absl::OkStatus(); - } - SystemClock().Sleep(back_off.NextBackOff()); - } - return absl::DeadlineExceededError("gatt connection time-out"); -} - -absl::Status RobustGattClient::TryDiscoverServices() { - ExpBackOff back_off(params_); - absl::Time start_time = SystemClock().ElapsedRealtime(); - while (!stopped_ && SystemClock().ElapsedRealtime() - start_time < - params_.discovery_timeout) { - if (DiscoverServices(params_.service_uuid, - GetPrimaryCharacteristicList()) || - DiscoverServices(params_.service_uuid, - GetFallbackCharacteristicList())) { - return absl::OkStatus(); - } - SystemClock().Sleep(back_off.NextBackOff()); - } - return absl::DeadlineExceededError("gatt discovery time-out"); -} - -bool RobustGattClient::DiscoverServices( - const Uuid& service_uuid, const std::vector& characteristic_uuids) { - if (service_uuid.IsEmpty() || characteristic_uuids.empty()) { - return false; - } - return gatt_client_->DiscoverServiceAndCharacteristics(service_uuid, - characteristic_uuids); -} - -std::optional -RobustGattClient::GetCharacteristic(const Uuid& service_id, - const UuidPair& characteristic_uuid_pair) { - if (stopped_) return std::nullopt; - std::optional characteristic = - gatt_client_->GetCharacteristic(service_id, - characteristic_uuid_pair.primary_uuid); - if (characteristic.has_value()) { - return characteristic; - } - if (characteristic_uuid_pair.fallback_uuid.IsEmpty() || stopped_) { - return std::nullopt; - } - return gatt_client_->GetCharacteristic( - service_id, characteristic_uuid_pair.fallback_uuid); -} - -const RobustGattClient::GattCharacteristic* RobustGattClient::GetCharacteristic( - int uuid_pair_index) { - auto it = characteristics_.find(uuid_pair_index); - if (it != characteristics_.end()) { - return &it->second; - } - const UuidPair& uuid_pair = params_.characteristic_uuids[uuid_pair_index]; - std::optional characteristic = - GetCharacteristic(params_.service_uuid, uuid_pair); - if (!characteristic.has_value()) { - NEARBY_LOGS(WARNING) << absl::StrFormat( - "Characteristic (%s, %s) not found on service %s", - std::string(uuid_pair.primary_uuid), - std::string(uuid_pair.fallback_uuid), - std::string(params_.service_uuid)); - } - characteristics_[uuid_pair_index] = *characteristic; - return &characteristics_[uuid_pair_index]; -} - -std::vector RobustGattClient::GetPrimaryCharacteristicList() { - std::vector result; - result.reserve(params_.characteristic_uuids.size()); - for (auto& uuid_pair : params_.characteristic_uuids) { - result.push_back(uuid_pair.primary_uuid); - } - return result; -} - -std::vector RobustGattClient::GetFallbackCharacteristicList() { - bool has_fallbacks = false; - std::vector result; - result.reserve(params_.characteristic_uuids.size()); - for (auto& uuid_pair : params_.characteristic_uuids) { - if (uuid_pair.fallback_uuid.IsEmpty()) { - // Some characteristics may have only one, primary UUID. - result.push_back(uuid_pair.primary_uuid); - } else { - has_fallbacks = true; - result.push_back(uuid_pair.fallback_uuid); - } - } - if (!has_fallbacks) result.clear(); - return result; -} - -void RobustGattClient::WriteCharacteristic( - int uuid_pair_index, absl::string_view value, - api::ble_v2::GattClient::WriteType write_type, WriteCallback callback) { - CHECK_LT(uuid_pair_index, params_.characteristic_uuids.size()); - Write({.uuid_pair_index = uuid_pair_index, - .value = std::string(value), - .write_type = write_type, - .callback = std::move(callback), - .time_left = params_.gatt_operation_timeout, - .back_off = ExpBackOff(params_)}); -} - -void RobustGattClient::CallRemoteFunction(int uuid_pair_index, - absl::string_view request, - NotifyCallback response) { - CHECK_LT(uuid_pair_index, params_.characteristic_uuids.size()); - Subscribe(uuid_pair_index, std::move(response), /*call_once=*/true); - WriteCharacteristic(uuid_pair_index, request, - api::ble_v2::GattClient::WriteType::kWithResponse, - [this, uuid_pair_index](absl::Status result) { - if (!result.ok()) { - NotifySubscriber(uuid_pair_index, result); - } else { - StartNotifyTimer(uuid_pair_index); - } - }); -} - -void RobustGattClient::StartNotifyTimer(int uuid_pair_index) { - if (stopped_) return; - MutexLock lock(&mutex_); - auto it = notify_callbacks_.find(uuid_pair_index); - if (it == notify_callbacks_.end()) return; - it->second.timer = std::make_unique(); - it->second.timer->Start( - absl::ToInt64Milliseconds(params_.gatt_operation_timeout), 0, - [this, uuid_pair_index]() { - NotifySubscriber(uuid_pair_index, - absl::DeadlineExceededError("gatt operation timeout")); - }); -} - -void RobustGattClient::Write(WriteRequest request) { - executor_.Execute( - "write-gatt", - [this, request = std::move(request)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) mutable { - absl::Time start_time = SystemClock::ElapsedRealtime(); - if (stopped_) return; - if (!status_.ok()) { - NEARBY_LOGS(WARNING) - << "Cannot write due to connection error " << status_; - std::move(request.callback)(status_); - return; - } - SystemClock().Sleep(request.back_off.NextBackOff()); - const GattCharacteristic* characteristic = - GetCharacteristic(request.uuid_pair_index); - bool result = false; - if (characteristic != nullptr) { - result = gatt_client_->WriteCharacteristic( - *characteristic, request.value, request.write_type); - } - if (stopped_) return; - if (result) { - std::move(request.callback)(absl::OkStatus()); - } else { - request.time_left -= SystemClock::ElapsedRealtime() - start_time; - if (request.time_left > absl::ZeroDuration()) { - Write(std::move(request)); - } else { - std::move(request.callback)( - absl::UnavailableError("gatt write failed")); - } - } - }); -} - -void RobustGattClient::Subscribe(int uuid_pair_index, NotifyCallback callback, - bool call_once) { - CHECK_LT(uuid_pair_index, params_.characteristic_uuids.size()); - MutexLock lock(&mutex_); - notify_callbacks_[uuid_pair_index] = NotifyCallbackInfo{ - .callback = std::move(callback), - .call_once = call_once, - }; - NEARBY_LOGS(INFO) << "Subscribe to characteristic no: " << uuid_pair_index; - Subscribe(SubscribeRequest{ - .uuid_pair_index = uuid_pair_index, - .time_left = params_.gatt_operation_timeout, - .back_off = ExpBackOff(params_), - }); -} - -void RobustGattClient::Subscribe(SubscribeRequest request) { - executor_.Execute( - "subscribe", - [this, request = std::move(request)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) mutable { - if (stopped_) return; - if (!HasSubsriberCallback(request.uuid_pair_index)) return; - if (!status_.ok()) { - NotifySubscriber(request.uuid_pair_index, status_); - return; - } - absl::Time start_time = SystemClock::ElapsedRealtime(); - SystemClock().Sleep(request.back_off.NextBackOff()); - const GattCharacteristic* characteristic = - GetCharacteristic(request.uuid_pair_index); - bool result = false; - if (characteristic != nullptr) { - result = gatt_client_->SetCharacteristicSubscription( - *characteristic, true, - [this, uuid_pair_index = - request.uuid_pair_index](absl::string_view value) { - NotifySubscriber(uuid_pair_index, value); - }); - } - if (stopped_) return; - if (!result) { - request.time_left -= SystemClock::ElapsedRealtime() - start_time; - if (request.time_left > absl::ZeroDuration()) { - Subscribe(std::move(request)); - } else { - NotifySubscriber( - request.uuid_pair_index, - absl::UnavailableError("gatt subscription failed")); - } - } - }); -} - -void RobustGattClient::Unsubscribe(int uuid_pair_index) { - CHECK_LT(uuid_pair_index, params_.characteristic_uuids.size()); - MutexLock lock(&mutex_); - int removed = notify_callbacks_.erase(uuid_pair_index); - if (removed == 0) { - NEARBY_LOGS(VERBOSE) << "Not subscribed for characteristic no: " - << uuid_pair_index; - } - UnsubscribeInternal(uuid_pair_index); -} - -void RobustGattClient::UnsubscribeInternal(int uuid_pair_index) { - executor_.Execute( - "unsubscribe", - [this, uuid_pair_index]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) { - if (stopped_) return; - if (!status_.ok()) { - return; - } - NEARBY_LOGS(INFO) << "Unsubscribe from characteristic no: " - << uuid_pair_index; - const GattCharacteristic* characteristic = - GetCharacteristic(uuid_pair_index); - if (characteristic != nullptr) { - gatt_client_->SetCharacteristicSubscription(*characteristic, false, - [](absl::string_view) {}); - } - }); -} - -bool RobustGattClient::HasSubsriberCallback(int uuid_pair_index) { - MutexLock lock(&mutex_); - return notify_callbacks_.find(uuid_pair_index) != notify_callbacks_.end(); -} - -void RobustGattClient::NotifySubscriber( - int uuid_pair_index, absl::StatusOr value) { - if (stopped_) return; - MutexLock lock(&mutex_); - auto it = notify_callbacks_.find(uuid_pair_index); - if (it != notify_callbacks_.end()) { - it->second.callback(value); - if (it->second.timer) { - it->second.timer->Stop(); - // NotifySubscriber could be called from the timer. We can't destroy the - // timer directly from the timer callback. - DestroyOnExecutor(std::move(it->second.timer), &executor_); - } - if (it->second.call_once) { - notify_callbacks_.erase(it); - UnsubscribeInternal(uuid_pair_index); - } - } -} - -void RobustGattClient::ReadCharacteristic(int uuid_pair_index, - ReadCallback callback) { - CHECK_LT(uuid_pair_index, params_.characteristic_uuids.size()); - Read(ReadRequest{ - .uuid_pair_index = uuid_pair_index, - .callback = std::move(callback), - .time_left = params_.gatt_operation_timeout, - .back_off = ExpBackOff(params_), - }); -} -void RobustGattClient::Read(ReadRequest request) { - executor_.Execute( - "read-gatt", - [this, request = std::move(request)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) mutable { - absl::Time start_time = SystemClock::ElapsedRealtime(); - if (stopped_) return; - if (!status_.ok()) { - std::move(request.callback)(status_); - return; - } - SystemClock().Sleep(request.back_off.NextBackOff()); - const GattCharacteristic* characteristic = - GetCharacteristic(request.uuid_pair_index); - absl::optional value; - if (characteristic != nullptr) { - value = gatt_client_->ReadCharacteristic(*characteristic); - } - - if (stopped_) return; - if (value.has_value()) { - std::move(request.callback)(value.value()); - } else { - request.time_left -= SystemClock::ElapsedRealtime() - start_time; - if (request.time_left > absl::ZeroDuration()) { - Read(std::move(request)); - } else { - std::move(request.callback)( - absl::UnavailableError("gatt read failed")); - } - } - }); -} - -void RobustGattClient::Cleanup() { - if (gatt_client_ != nullptr && gatt_client_->IsValid()) { - gatt_client_->Disconnect(); - } - gatt_client_.reset(); - characteristics_.clear(); - MutexLock lock(&mutex_); - notify_callbacks_.clear(); -} - -void RobustGattClient::NotifyClient(absl::Status status) { - if (stopped_) return; - if (connection_status_callback_ != nullptr) - connection_status_callback_(status); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/mediums/robust_gatt_client.h b/fastpair/internal/mediums/robust_gatt_client.h deleted file mode 100644 index f33944f3b5..0000000000 --- a/fastpair/internal/mediums/robust_gatt_client.h +++ /dev/null @@ -1,272 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_ROBUST_GATT_CLIENT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_ROBUST_GATT_CLIENT_H_ - -#include -#include -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/status/status.h" -#include "absl/time/time.h" -#include "internal/platform/ble_v2.h" -#include "internal/platform/implementation/ble_v2.h" -#include "internal/platform/single_thread_executor.h" -namespace nearby { -namespace fastpair { - -// Gatt client on top of nearby::GattClient with higher level API and built-in -// retry mechanism. All methods are not blocking unless stated otherwise. -// -// Callbacks and timeouts. -// The blocking platform calls are running on a dedicated thread. The callbacks -// are called when the platform calls have completed. The -// timeouts define for how long we will retry the platform calls before giving -// up. -// Example 1: -// `connect_timeout` is 10 seconds, `BleV2Medium::ConnectToGattServer()` fails -// after 15 seconds. In this case, we will not retry connecting, the client -// ConnectionStatusCallback will be called after 15 seconds. -// Example 2: -// `connect_timeout` is 10 seconds, `BleV2Medium::ConnectToGattServer()` fails -// after 6 seconds each time. In this case, we will retry once, the client -// ConnectionStatusCallback will be called after 12 seconds (6 + 6). -// Example 3: -// `BleV2Medium::ConnectToGattServer()` never returns. The callback will not be -// called. -class RobustGattClient { - public: - using WriteCallback = absl::AnyInvocable; - using ReadCallback = - absl::AnyInvocable value) &&>; - using NotifyCallback = - absl::AnyInvocable value)>; - using ConnectionStatusCallback = absl::AnyInvocable; - // Defines a characteristic on the server. - struct UuidPair { - // Preferred UUID, for example Fast Pair V1. - Uuid primary_uuid; - // Optional fallback UUID if the primary is not present on the server, for - // example Fast Pair V0. - Uuid fallback_uuid; - }; - struct ConnectionParams { - api::ble_v2::TxPowerLevel tx_power_level = - api::ble_v2::TxPowerLevel::kUnknown; - Uuid service_uuid; - std::vector characteristic_uuids; - // Timeout for retrying connection attempts. - absl::Duration connect_timeout = absl::Seconds(10); - // Timeout for retrying service discovery. - absl::Duration discovery_timeout = absl::Seconds(10); - // Timeout for retrying read/write/subscribe operations. - // Note, this timeout does not include the time needed to connect to the - // gatt server and discover services. - absl::Duration gatt_operation_timeout = absl::Seconds(15); - // Exponential back off parameters. They describe how long we will wait - // before retrying an operation. - absl::Duration initial_back_off_step = absl::Milliseconds(100); - absl::Duration max_back_off = absl::Seconds(3); - float back_off_multiplier = 1.5; - }; - - // Creates the GATT client, connects to the server, and discovers - // characteristics. The connection is established in the background. If the - // connection is interrupted, we will try to reconnect. The caller does not - // need to wait for connection before using the client. Instead, the caller - // should create an instance of `RobustGattClient` and immediately start - // calling other methods such as `CallRemoteFunction()`. - RobustGattClient(BleV2Medium& medium, BleV2Peripheral peripheral, - const ConnectionParams& params, - ConnectionStatusCallback callback = nullptr) - : medium_(medium), - peripheral_(peripheral), - params_(params), - connection_status_callback_(std::move(callback)) { - DCHECK_GT(params.initial_back_off_step, absl::ZeroDuration()); - DCHECK_GE(params.back_off_multiplier, 1.0); - DCHECK_GE(params.max_back_off, params.initial_back_off_step); - - Connect(); - } - - // The destructor will block if there are any ongoing platform BLE blocking - // calls. - ~RobustGattClient(); - - // Writes to the remote characteristic. - // - // `uuid_pair_index` is the index to `ConnectionParams::characteristic_uuids`. - // `callback` is called asynchronously with the result of the write call. If - // write fails with a status other than `absl::StatusCode::kUnavailable`, then - // it is a permanent failure. All future calls will likely fail too. - void WriteCharacteristic(int uuid_pair_index, absl::string_view value, - api::ble_v2::GattClient::WriteType write_type, - WriteCallback callback); - - // Performs write-and-response exchange. - // - // The call: - // * subscribes to the characteristic notifications, - // * writes to the remote characteristic, - // * waits for the response via a gatt notify call, - // * unsubsribes from the notification. - // - // `uuid_pair_index` is the index to `ConnectionParams::characteristic_uuids`. - // `response` is called asynchronously with the remote server response. If - // write fails with a status other than `absl::StatusCode::kUnavailable` or - // `absl::StatusCode::kDeadlineExceeded`, then it is a permanent failure. All - // future calls will likely fail too. - // The timeouts accumulate. If the gatt client is still connecting to the - // remote service, the call with wait for connection, discovery, - // characteristic subscription, write operation and gatt notification. Each of - // them have their own timeouts. Example: if connection takes 2 seconds, - // discovery takes 5 seconds, subscribing to the characteristic takes 3, - // writing to the characteristic takes 6 seconds but the provider never sends - // a response, then the call will time out no sooner than 2s + 5s + 3s + 6s + - // gatt_operation_timeout. - void CallRemoteFunction(int uuid_pair_index, absl::string_view request, - NotifyCallback response); - - // Reads remote characteristic. - // - // `uuid_pair_index` is the index to `ConnectionParams::characteristic_uuids`. - void ReadCharacteristic(int uuid_pair_index, ReadCallback callback); - - // Subscribes for remote characteristic updates. - // - // `uuid_pair_index` is the index to `ConnectionParams::characteristic_uuids`. - // If `call_once` is true, then the callback will be automatically - // unsubscribed after being called. - // - // Do not call `Subscribe()` or `Unsubscribe()` from the `callback`. It will - // lock up. - // Do not use `Subscribe()` and `CallRemoteFunction()` calls for the same - // characteristic at the same time. - void Subscribe(int uuid_pair_index, NotifyCallback callback, - bool call_once = false); - - // Unsubscribes from remote characteristic updates. - // - // `uuid_pair_index` is the index to `ConnectionParams::characteristic_uuids`. - void Unsubscribe(int uuid_pair_index); - - // Disables the gatt client and disconnects from the gatt server if - // connected. None of the callbacks will be triggered after `Stop()`, but if - // a callback is currently running, it may continue running after `Stop()` has - // returned. - void Stop(); - - private: - class ExpBackOff { - public: - explicit ExpBackOff(const ConnectionParams& params) - : back_off_step_(params.initial_back_off_step), - multiplier_(params.back_off_multiplier), - max_back_off_(params.max_back_off) {} - absl::Duration NextBackOff() { - absl::Duration result = back_off_; - back_off_ += std::min(back_off_ + back_off_step_, max_back_off_); - back_off_step_ *= multiplier_; - return result; - } - - private: - absl::Duration back_off_step_; - float multiplier_; - absl::Duration max_back_off_; - absl::Duration back_off_ = absl::ZeroDuration(); - }; - struct WriteRequest { - int uuid_pair_index; - std::string value; - api::ble_v2::GattClient::WriteType write_type; - WriteCallback callback; - absl::Duration time_left; - ExpBackOff back_off; - }; - struct SubscribeRequest { - int uuid_pair_index; - absl::Duration time_left; - ExpBackOff back_off; - }; - struct ReadRequest { - int uuid_pair_index; - ReadCallback callback; - absl::Duration time_left; - ExpBackOff back_off; - }; - - using GattCharacteristic = api::ble_v2::GattCharacteristic; - void Connect(); - absl::Status TryConnect() ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_); - absl::Status TryDiscoverServices() ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_); - std::vector GetPrimaryCharacteristicList(); - std::vector GetFallbackCharacteristicList(); - bool DiscoverServices(const Uuid& service_uuid, - const std::vector& characteristic_uuids) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_); - std::optional GetCharacteristic( - const Uuid& service_id, const UuidPair& characteristic_uuid_pair) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_); - // May return nullptr. - const GattCharacteristic* GetCharacteristic(int uuid_pair_index) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_); - void NotifySubscriber(int uuid_pair_index, - absl::StatusOr value); - void Cleanup() ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_); - void Write(WriteRequest request); - void Read(ReadRequest request); - void Subscribe(SubscribeRequest request); - void UnsubscribeInternal(int uuid_pair_index); - bool HasSubsriberCallback(int uuid_pair_index); - void NotifyClient(absl::Status status); - void StartNotifyTimer(int uuid_pair_index); - - // A thread for running blocking tasks. - SingleThreadExecutor executor_; - Mutex mutex_; - BleV2Medium& medium_; - BleV2Peripheral peripheral_; - ConnectionParams params_; - ConnectionStatusCallback connection_status_callback_; - std::unique_ptr gatt_client_ ABSL_GUARDED_BY(executor_); - // Mapping from `uuid_pair_index` to subscription callbacks. - // The entries are lazily initialized. - absl::flat_hash_map characteristics_ - ABSL_GUARDED_BY(executor_); - // Mapping from `uuid_pair_index` to subscription callbacks. - struct NotifyCallbackInfo { - NotifyCallback callback; - // If `call_once` is true, then the callback will be called only once, and - // then automatically unregistered. - bool call_once; - std::unique_ptr timer; - }; - absl::flat_hash_map notify_callbacks_ - ABSL_GUARDED_BY(mutex_); - std::atomic_bool stopped_ = false; - absl::Status status_ = absl::OkStatus(); -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_ROBUST_GATT_CLIENT_H_ diff --git a/fastpair/internal/mediums/robust_gatt_client_test.cc b/fastpair/internal/mediums/robust_gatt_client_test.cc deleted file mode 100644 index 37cb674578..0000000000 --- a/fastpair/internal/mediums/robust_gatt_client_test.cc +++ /dev/null @@ -1,635 +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. - -#include "fastpair/internal/mediums/robust_gatt_client.h" - -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "internal/platform/ble_v2.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" - -namespace nearby { -namespace fastpair { -namespace { - -using ::testing::status::StatusIs; -using Property = nearby::api::ble_v2::GattCharacteristic::Property; -using Permission = nearby::api::ble_v2::GattCharacteristic::Permission; -using GattCharacteristic = nearby::api::ble_v2::GattCharacteristic; - -// Short timeout for operation that we expect to timeout. -constexpr absl::Duration kFailureTimeout = absl::Milliseconds(100); -constexpr absl::string_view kModelId = "123456"; -constexpr Uuid kFastPairServiceUuid(0x0000FE2C00001000, 0x800000805F9B34FB); -constexpr Uuid kKeyBasedCharacteristicUuidV1(0x0000123400001000, - 0x800000805F9B34FB); -constexpr Uuid kKeyBasedCharacteristicUuidV2(0xFE2C123483664814, - 0x8EB001DE32100BEA); -constexpr Uuid kPasskeyCharacteristicUuidV1(0x0000123500001000, - 0x800000805F9B34FB); -constexpr Uuid kPasskeyCharacteristicUuidV2(0xFE2C123583664814, - 0x8EB001DE32100BEA); -constexpr Uuid kAccountKeyCharacteristicUuidV1(0x0000123600001000, - 0x800000805F9B34FB); -constexpr Uuid kAccountKeyCharacteristicUuidV2(0xFE2C123683664814, - 0x8EB001DE32100BEA); - -constexpr Uuid kModelIdCharacteristics(0xFE2C123383664814, 0x8EB001DE32100BEA); -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start({}); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -struct CharacteristicData { - // Write result returned to the gatt client. - absl::Status write_result = - absl::PermissionDeniedError("can't write characteristic"); - std::string written_data; - absl::StatusOr read_result = - absl::PermissionDeniedError("can't read characteristic"); - std::optional notify_response; -}; - -class RobustGattClientTest : public testing::Test { - protected: - void SetUp() override { StartGattServer(); } - - void StartGattServer() { - gatt_server_ = - provider_ble_.StartGattServer(/*ServerGattConnectionCallback=*/{ - .on_characteristic_read_cb = - [&](const api::ble_v2::BlePeripheral& remote_device, - const api::ble_v2::GattCharacteristic& characteristic, - int offset, - BleV2Medium::ServerGattConnectionCallback::ReadValueCallback - callback) { - MutexLock lock(&mutex_); - auto it = characteristics_.find(characteristic); - if (it == characteristics_.end()) { - callback(absl::NotFoundError("characteristic not found")); - return; - } - callback(it->second.read_result); - }, - .on_characteristic_write_cb = - [&](const api::ble_v2::BlePeripheral& remote_device, - const api::ble_v2::GattCharacteristic& characteristic, - int offset, absl::string_view data, - BleV2Medium::ServerGattConnectionCallback:: - WriteValueCallback callback) { - MutexLock lock(&mutex_); - auto it = characteristics_.find(characteristic); - if (it == characteristics_.end()) { - callback(absl::NotFoundError("characteristic not found")); - return; - } - it->second.written_data = data; - if (it->second.write_result.code() == - absl::StatusCode::kDeadlineExceeded) { - absl::SleepFor(kFailureTimeout); - } - callback(it->second.write_result); - if (it->second.notify_response.has_value()) { - auto ignored = gatt_server_->NotifyCharacteristicChanged( - characteristic, false, - ByteArray(*it->second.notify_response)); - } - }, - }); - provider_address_ = *gatt_server_->GetBlePeripheral().GetAddress(); - } - - void InsertCorrectV2GattCharacteristics() { - MutexLock lock(&mutex_); - key_based_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kKeyBasedCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*key_based_characteristic_].write_result = - absl::OkStatus(); - - passkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kPasskeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*passkey_characteristic_].write_result = absl::OkStatus(); - - accountkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kAccountKeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*accountkey_characteristic_].write_result = - absl::OkStatus(); - model_id_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kModelIdCharacteristics, Permission::kRead, - Property::kRead); - characteristics_[*model_id_characteristic_].read_result = kModelId; - } - - void InsertCorrectV1GattCharacteristics() { - MutexLock lock(&mutex_); - key_based_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kKeyBasedCharacteristicUuidV1, permissions_, - properties_); - characteristics_[*key_based_characteristic_].write_result = - absl::OkStatus(); - - passkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kPasskeyCharacteristicUuidV1, permissions_, - properties_); - characteristics_[*passkey_characteristic_].write_result = absl::OkStatus(); - - accountkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kAccountKeyCharacteristicUuidV1, permissions_, - properties_); - characteristics_[*accountkey_characteristic_].write_result = - absl::OkStatus(); - } - - absl::string_view GetWrittenData(GattCharacteristic characteristic) { - MutexLock lock(&mutex_); - CHECK(characteristics_.find(characteristic) != characteristics_.end()); - return characteristics_[characteristic].written_data; - } - - void SetWriteResult(GattCharacteristic characteristic, absl::Status status) { - MutexLock lock(&mutex_); - CHECK(characteristics_.find(characteristic) != characteristics_.end()); - characteristics_[characteristic].write_result = status; - } - - void SetNotifyResponse(GattCharacteristic characteristic, - absl::string_view response) { - MutexLock lock(&mutex_); - CHECK(characteristics_.find(characteristic) != characteristics_.end()); - characteristics_[characteristic].notify_response = response; - } - - MediumEnvironmentStarter env_; - Mutex mutex_; - BluetoothAdapter provider_adapter_; - BleV2Medium provider_ble_{provider_adapter_}; - BluetoothAdapter seeker_adapter_; - BleV2Medium seeker_ble_{seeker_adapter_}; - std::unique_ptr gatt_server_; - std::string provider_address_; - absl::flat_hash_map characteristics_ - ABSL_GUARDED_BY(mutex_); - Property properties_ = Property::kWrite | Property::kNotify; - Permission permissions_ = Permission::kWrite; - std::optional key_based_characteristic_; - std::optional passkey_characteristic_; - std::optional accountkey_characteristic_; - std::optional model_id_characteristic_; -}; - -TEST_F(RobustGattClientTest, Constructor) { - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - RobustGattClient gatt_client(seeker_ble_, provider, {}); -} - -TEST_F(RobustGattClientTest, ConnectToProviderWithoutServiceFails) { - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - params.connect_timeout = absl::Seconds(1); - params.discovery_timeout = absl::Seconds(1); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.WriteCharacteristic( - 0, "hello", api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { - EXPECT_THAT(status, StatusIs(absl::StatusCode::kDeadlineExceeded)); - latch.CountDown(); - }); - EXPECT_TRUE(latch.Await().Ok()); -} - -TEST_F(RobustGattClientTest, DiscoveryRetryWorks) { - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.WriteCharacteristic( - 0, "hello", api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { - EXPECT_OK(status); - latch.CountDown(); - }); - // The Gatt client is re-trying to discover the characteristics. - InsertCorrectV2GattCharacteristics(); - - EXPECT_TRUE(latch.Await().Ok()); -} - -TEST_F(RobustGattClientTest, SuccessfulWriteToPrimaryUuid) { - constexpr absl::string_view kData = "hello"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.WriteCharacteristic( - 0, kData, api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { - EXPECT_OK(status); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); - EXPECT_EQ(GetWrittenData(*key_based_characteristic_), kData); -} - -TEST_F(RobustGattClientTest, SuccessfulWriteToFallbackUuid) { - constexpr absl::string_view kData = "hello"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV1GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.WriteCharacteristic( - 0, kData, api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { - EXPECT_OK(status); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); - EXPECT_EQ(GetWrittenData(*key_based_characteristic_), kData); -} - -TEST_F(RobustGattClientTest, RejectedWrite) { - constexpr absl::string_view kData = "hello"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - SetWriteResult(*key_based_characteristic_, - absl::UnauthenticatedError("write rejected")); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - params.gatt_operation_timeout = kFailureTimeout; - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.WriteCharacteristic( - 0, kData, api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { - EXPECT_THAT(status, StatusIs(absl::StatusCode::kUnavailable)); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); -} - -TEST_F(RobustGattClientTest, SuccessfulCallRemoteFunctionToPrimaryUuid) { - constexpr absl::string_view kRequest = "request"; - constexpr absl::string_view kResponse = "response"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - SetNotifyResponse(*key_based_characteristic_, kResponse); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.CallRemoteFunction( - 0, kRequest, [&](absl::StatusOr response) { - EXPECT_OK(response); - EXPECT_EQ(*response, kResponse); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); - EXPECT_EQ(GetWrittenData(*key_based_characteristic_), kRequest); -} - -TEST_F(RobustGattClientTest, SuccessfulCallRemoteFunctionToFallbackUuid) { - constexpr absl::string_view kRequest = "request"; - constexpr absl::string_view kResponse = "response"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV1GattCharacteristics(); - SetNotifyResponse(*key_based_characteristic_, kResponse); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.CallRemoteFunction( - 0, kRequest, [&](absl::StatusOr response) { - EXPECT_OK(response); - EXPECT_EQ(*response, kResponse); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); - EXPECT_EQ(GetWrittenData(*key_based_characteristic_), kRequest); -} - -TEST_F(RobustGattClientTest, CallRemoteFunctionRejectedWrite) { - constexpr absl::string_view kRequest = "request"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - SetWriteResult(*key_based_characteristic_, - absl::InternalError("write rejected")); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - params.gatt_operation_timeout = kFailureTimeout; - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.CallRemoteFunction( - 0, kRequest, [&](absl::StatusOr response) { - EXPECT_THAT(response.status(), - StatusIs(absl::StatusCode::kUnavailable)); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); -} - -TEST_F(RobustGattClientTest, CallRemoteFunctionNoResponseTimesOut) { - constexpr absl::string_view kRequest = "request"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - params.gatt_operation_timeout = kFailureTimeout; - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.CallRemoteFunction( - 0, kRequest, [&](absl::StatusOr response) { - EXPECT_THAT(response.status(), - StatusIs(absl::StatusCode::kDeadlineExceeded)); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); -} - -TEST_F(RobustGattClientTest, WriteTimeout) { - constexpr absl::string_view kData = "hello"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - SetWriteResult(*key_based_characteristic_, - absl::DeadlineExceededError("write time out")); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - params.gatt_operation_timeout = kFailureTimeout; - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.WriteCharacteristic( - 0, kData, api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { - EXPECT_THAT(status, StatusIs(absl::StatusCode::kUnavailable)); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); -} - -TEST_F(RobustGattClientTest, ReconnectWorks) { - constexpr absl::string_view kData = "hello"; - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.WriteCharacteristic( - 0, "first", api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { - NEARBY_LOGS(INFO) << "First write completed with: " << status; - EXPECT_OK(status); - latch.CountDown(); - }); - EXPECT_TRUE(latch.Await().Ok()); - CountDownLatch write_after_reconnect(1); - gatt_client.WriteCharacteristic( - 0, kData, api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { - NEARBY_LOGS(INFO) << "Write after reconnect completed with: " << status; - EXPECT_OK(status); - write_after_reconnect.CountDown(); - }); - gatt_server_->Stop(); - gatt_server_.reset(); - StartGattServer(); - InsertCorrectV2GattCharacteristics(); - EXPECT_TRUE(write_after_reconnect.Await().Ok()); - EXPECT_EQ(GetWrittenData(*key_based_characteristic_), kData); -} - -TEST_F(RobustGattClientTest, SuccessfulSubscribeToPrimaryUuid) { - constexpr absl::string_view kData = "hello"; - constexpr int kKeyBasedCharacteristicIndex = 0; - CountDownLatch write_latch(1); - CountDownLatch notify_latch(1); - absl::StatusOr notify_data; - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.Subscribe(kKeyBasedCharacteristicIndex, - [&](absl::StatusOr data) { - notify_data = data; - notify_latch.CountDown(); - }); - gatt_client.WriteCharacteristic( - 0, "", api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { write_latch.CountDown(); }); - EXPECT_TRUE(write_latch.Await().Ok()); - EXPECT_OK(gatt_server_->NotifyCharacteristicChanged( - *key_based_characteristic_, - /*confirm=*/true, ByteArray(std::string(kData)))); - - EXPECT_TRUE(notify_latch.Await().Ok()); - EXPECT_OK(notify_data); - EXPECT_EQ(*notify_data, kData); -} - -TEST_F(RobustGattClientTest, SuccessfulSubscribeToFallbackUuid) { - constexpr absl::string_view kData = "hello"; - constexpr int kKeyBasedCharacteristicIndex = 0; - CountDownLatch write_latch(1); - CountDownLatch notify_latch(1); - absl::StatusOr notify_data; - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV1GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.Subscribe(kKeyBasedCharacteristicIndex, - [&](absl::StatusOr data) { - notify_data = data; - notify_latch.CountDown(); - }); - gatt_client.WriteCharacteristic( - 0, "", api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { write_latch.CountDown(); }); - EXPECT_TRUE(write_latch.Await().Ok()); - EXPECT_OK(gatt_server_->NotifyCharacteristicChanged( - *key_based_characteristic_, - /*confirm=*/true, ByteArray(std::string(kData)))); - - EXPECT_TRUE(notify_latch.Await().Ok()); - EXPECT_OK(notify_data); - EXPECT_EQ(*notify_data, kData); -} - -TEST_F(RobustGattClientTest, NoNotifyAfterUnsubscribe) { - constexpr absl::string_view kData = "hello"; - constexpr int kKeyBasedCharacteristicIndex = 0; - CountDownLatch write_latch(1); - CountDownLatch notify_latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.Subscribe(kKeyBasedCharacteristicIndex, - [&](absl::StatusOr data) { - NEARBY_LOGS(INFO) - << "Notified " << data.status() << ", " << *data; - notify_latch.CountDown(); - }); - gatt_client.WriteCharacteristic( - 0, "", api::ble_v2::GattClient::WriteType::kWithResponse, - [&](absl::Status status) { write_latch.CountDown(); }); - EXPECT_TRUE(write_latch.Await().Ok()); - - gatt_client.Unsubscribe(kKeyBasedCharacteristicIndex); - // Depending on the timing, the characteristic may still be subscribed on the - // server. `NotifyCharacteristicChanged()` may be successful or may fail. - // Neither is an error. - auto ignored = gatt_server_->NotifyCharacteristicChanged( - *key_based_characteristic_, - /*confirm=*/true, ByteArray(std::string(kData))); - - EXPECT_FALSE(notify_latch.Await(kFailureTimeout).result()); -} - -TEST_F(RobustGattClientTest, SuccessfulRead) { - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - params.characteristic_uuids.push_back({kModelIdCharacteristics, Uuid()}); - constexpr int kModelIdIndex = 1; - - RobustGattClient gatt_client(seeker_ble_, provider, params); - gatt_client.ReadCharacteristic(kModelIdIndex, - [&](absl::StatusOr value) { - EXPECT_OK(value); - EXPECT_EQ(*value, kModelId); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); -} - -TEST_F(RobustGattClientTest, ReadFromWrongCharacteristicFails) { - CountDownLatch latch(1); - BleV2Peripheral provider = seeker_ble_.GetRemotePeripheral(provider_address_); - InsertCorrectV2GattCharacteristics(); - RobustGattClient::ConnectionParams params; - params.tx_power_level = api::ble_v2::TxPowerLevel::kMedium; - params.service_uuid = kFastPairServiceUuid; - params.characteristic_uuids.push_back( - {kKeyBasedCharacteristicUuidV2, kKeyBasedCharacteristicUuidV1}); - params.characteristic_uuids.push_back({kModelIdCharacteristics, Uuid()}); - params.gatt_operation_timeout = kFailureTimeout; - constexpr int kKeyBasedCharacteristicIndex = 0; - - RobustGattClient gatt_client(seeker_ble_, provider, params); - // Key based pairing characteristic is write only, so read will fail. - gatt_client.ReadCharacteristic( - kKeyBasedCharacteristicIndex, - [&](absl::StatusOr value) { - EXPECT_THAT(value.status(), StatusIs(absl::StatusCode::kUnavailable)); - latch.CountDown(); - }); - - EXPECT_TRUE(latch.Await().Ok()); -} - -} // namespace - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/internal/test/BUILD b/fastpair/internal/test/BUILD deleted file mode 100644 index 86c35257e9..0000000000 --- a/fastpair/internal/test/BUILD +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2022 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. - -licenses(["notice"]) - -cc_library( - name = "nearby_fastpair_test", - hdrs = [ - "fast_pair_fake_http_client.h", - ], - copts = [ - "-Ithird_party", - ], - visibility = ["//visibility:private"], - deps = [ - "//internal/network:types", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - ], -) - -cc_test( - name = "nearby_fastpair_test_test", - size = "small", - timeout = "short", - srcs = [ - "fast_pair_fake_http_client_test.cc", - ], - copts = [ - "-Ithird_party", - ], - deps = [ - ":nearby_fastpair_test", - "//internal/network:types", - "//internal/platform/implementation/g3", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/internal/test/fast_pair_fake_http_client.h b/fastpair/internal/test/fast_pair_fake_http_client.h deleted file mode 100644 index 4723edf578..0000000000 --- a/fastpair/internal/test/fast_pair_fake_http_client.h +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_TEST_FAST_PAIR_FAKE_HTTP_CLIENT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_TEST_FAST_PAIR_FAKE_HTTP_CLIENT_H_ - -#include -#include -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "internal/network/http_client.h" -#include "internal/network/http_request.h" -#include "internal/network/http_response.h" -#include "internal/network/http_status_code.h" - -namespace nearby { -namespace network { - -class FastPairFakeHttpClient : public HttpClient { - public: - struct RequestInfo { - HttpRequest request; - absl::AnyInvocable&)> callback; - }; - - FastPairFakeHttpClient() = default; - explicit FastPairFakeHttpClient(const HttpRequest& request); - ~FastPairFakeHttpClient() override = default; - - FastPairFakeHttpClient(const FastPairFakeHttpClient&) = default; - FastPairFakeHttpClient& operator=(const FastPairFakeHttpClient&) = default; - FastPairFakeHttpClient(FastPairFakeHttpClient&&) = default; - FastPairFakeHttpClient& operator=(FastPairFakeHttpClient&&) = default; - - void StartRequest( - const HttpRequest& request, - absl::AnyInvocable&)> callback) - override { - RequestInfo request_info; - request_info.request = request; - request_info.callback = std::move(callback); - request_infos_.push_back(std::move(request_info)); - } - - void StartCancellableRequest( - std::unique_ptr request, - absl::AnyInvocable&)> callback) - override {} - - absl::StatusOr GetResponse( - const HttpRequest& request) override { - return absl::UnimplementedError("unimplemented"); - } - - // Mock methods - void CompleteRequest(const absl::StatusOr& response, - size_t pos = 0) { - if (pos >= request_infos_.size()) { - return; - } - - auto& request_info = request_infos_.at(pos); - if (request_info.callback) { - request_info.callback(response); - } - - request_infos_.erase(request_infos_.begin() + pos); - } - - void CompleteRequest( - int error, std::optional response_code = std::nullopt, - const std::optional& response_string = std::nullopt, - size_t pos = 0) { - absl::StatusOr result; - - HttpResponse response; - if (error == 0) { - absl::Status status = - HTTPCodeToStatus(static_cast(*response_code), ""); - if (status.ok()) { - if (response_code.has_value()) { - response.SetStatusCode(*response_code); - } - - if (response_string.has_value()) { - response.SetBody(*response_string); - } - - response.SetHeaders({{"Content-type", {"text/html"}}}); - result = response; - } else { - result = status; - } - } else { - result = absl::Status(absl::StatusCode::kFailedPrecondition, - std::to_string(error)); - } - - CompleteRequest(result, pos); - } - - absl::Status HTTPCodeToStatus(int status_code, - absl::string_view status_message) { - absl::Status status = absl::OkStatus(); - switch (status_code) { - case 400: - return absl::InvalidArgumentError(status_message); - case 401: - return absl::UnauthenticatedError(status_message); - case 403: - return absl::PermissionDeniedError(status_message); - case 404: - return absl::NotFoundError(status_message); - case 409: - return absl::AbortedError(status_message); - case 416: - return absl::OutOfRangeError(status_message); - case 429: - return absl::ResourceExhaustedError(status_message); - case 499: - return absl::CancelledError(status_message); - case 504: - return absl::DeadlineExceededError(status_message); - case 501: - return absl::UnimplementedError(status_message); - case 503: - return absl::UnavailableError(status_message); - default: - break; - } - if (status_code >= 200 && status_code < 300) { - return absl::OkStatus(); - } else if (status_code >= 400 && status_code < 500) { - return absl::FailedPreconditionError(status_message); - } else if (status_code >= 500 && status_code < 600) { - return absl::InternalError(status_message); - } - return absl::UnknownError(status_message); - } - - const std::vector& GetPendingRequest() { return request_infos_; } - - private: - std::vector request_infos_; -}; - -} // namespace network -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_TEST_FAST_PAIR_FAKE_HTTP_CLIENT_H_ diff --git a/fastpair/internal/test/fast_pair_fake_http_client_test.cc b/fastpair/internal/test/fast_pair_fake_http_client_test.cc deleted file mode 100644 index 3f1ba9ac24..0000000000 --- a/fastpair/internal/test/fast_pair_fake_http_client_test.cc +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/internal/test/fast_pair_fake_http_client.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "internal/network/http_status_code.h" -#include "gtest/gtest.h" -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" - -namespace nearby { -namespace network { -namespace { - -class FastPairFakeHttpClientTest : public ::testing::Test { - public: - void SetUp() override { - client_ = FastPairFakeHttpClient(); - response_ = HttpResponse(); - request_ = HttpRequest(); - } - - void StartRequest( - absl::string_view request_url, - std::function&)> callback) { - Url url; - url.SetUrlPath(request_url); - request_.SetUrl(std::move(url)); - request_.SetMethod(HttpRequestMethod::kPost); - request_.SetBody("request body"); - client_.StartRequest(request_, callback); - } - - void CompleteRequest( - HttpStatusCode status, std::string status_message = "", - absl::flat_hash_map> headers = {}, - std::string body = "", int pos = 0) { - response_.SetStatusCode(status); - response_.SetReasonPhrase(status_message); - response_.SetHeaders(headers); - response_.SetBody(body); - client_.CompleteRequest(response_, pos); - } - - void CompleteRequest(int error, int status = 200, int pos = 0) { - client_.CompleteRequest(error, static_cast(status), - std::nullopt, pos); - } - - void CheckHttpError(int status, absl::StatusCode expected_status) { - absl::StatusOr response; - StartRequest("http://www.google.com", - [&response](const absl::StatusOr& res) { - response = res; - }); - - client_.CompleteRequest(0, static_cast(status), - std::nullopt); - if (status >= 200 & status < 300) { - ASSERT_TRUE(response.ok()); - } else { - ASSERT_FALSE(response.ok()); - } - - EXPECT_EQ(response.status().code(), expected_status); - } - - private: - FastPairFakeHttpClient client_; - HttpResponse response_; - HttpRequest request_; -}; - -TEST_F(FastPairFakeHttpClientTest, TestMockHttpResponse) { - absl::StatusOr response; - StartRequest( - "http://www.google.com", - [&response](const absl::StatusOr& res) { response = res; }); - - CompleteRequest(HttpStatusCode::kHttpOk); - ASSERT_TRUE(response.ok()); - EXPECT_EQ(response->GetStatusCode(), HttpStatusCode::kHttpOk); -} - -TEST_F(FastPairFakeHttpClientTest, TestSystemError) { - absl::StatusOr response; - StartRequest( - "http://www.google.com", - [&response](const absl::StatusOr& res) { response = res; }); - - CompleteRequest(0xffff); - ASSERT_FALSE(response.ok()); - EXPECT_EQ(response.status().code(), absl::StatusCode::kFailedPrecondition); -} - -TEST_F(FastPairFakeHttpClientTest, TestHttpErrorCodes) { - CheckHttpError(200, absl::StatusCode::kOk); - CheckHttpError(400, absl::StatusCode::kInvalidArgument); - CheckHttpError(401, absl::StatusCode::kUnauthenticated); - CheckHttpError(403, absl::StatusCode::kPermissionDenied); - CheckHttpError(404, absl::StatusCode::kNotFound); - CheckHttpError(409, absl::StatusCode::kAborted); - CheckHttpError(416, absl::StatusCode::kOutOfRange); - CheckHttpError(429, absl::StatusCode::kResourceExhausted); - CheckHttpError(499, absl::StatusCode::kCancelled); - CheckHttpError(504, absl::StatusCode::kDeadlineExceeded); - CheckHttpError(501, absl::StatusCode::kUnimplemented); - CheckHttpError(503, absl::StatusCode::kUnavailable); - CheckHttpError(488, absl::StatusCode::kFailedPrecondition); - CheckHttpError(522, absl::StatusCode::kInternal); - CheckHttpError(777, absl::StatusCode::kUnknown); -} - -TEST_F(FastPairFakeHttpClientTest, TestCompleteNotExistingRequest) { - int count = 0; - StartRequest("http://www.google.com", - [&count](const absl::StatusOr& res) { ++count; }); - - CompleteRequest(0xffff); - EXPECT_EQ(count, 1); - CompleteRequest(0xffff); - EXPECT_EQ(count, 1); -} - -} // namespace -} // namespace network -} // namespace nearby diff --git a/fastpair/message_stream/BUILD b/fastpair/message_stream/BUILD deleted file mode 100644 index acc4504c10..0000000000 --- a/fastpair/message_stream/BUILD +++ /dev/null @@ -1,161 +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. - -licenses(["notice"]) - -cc_library( - name = "message_stream", - srcs = [ - "medium.cc", - "message_stream.cc", - ], - hdrs = [ - "medium.h", - "message.h", - "message_stream.h", - ], - visibility = [ - "//:__subpackages__", - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:types", - "//internal/platform/implementation:types", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/log:check", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - ], -) - -cc_library( - name = "fake_provider", - testonly = True, - srcs = ["fake_provider.cc"], - hdrs = [ - "fake_provider.h", - ], - visibility = [ - "//:__subpackages__", - "//fastpair:__subpackages__", - ], - deps = [ - ":fake_gatt_callbacks", - ":message_stream", - "//fastpair/common", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform:uuid", - "@boringssl//:crypto", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_for_library_testonly", - ], -) - -cc_library( - name = "fake_gatt_callbacks", - testonly = True, - hdrs = [ - "fake_gatt_callbacks.h", - ], - visibility = [ - "//:__subpackages__", - "//fastpair:__subpackages__", - ], - deps = [ - "//internal/platform:comm", - "//internal/platform:types", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - ], -) - -cc_library( - name = "fake_medium_observer", - testonly = True, - hdrs = [ - "fake_medium_observer.h", - ], - visibility = ["//fastpair:__subpackages__"], - deps = [ - ":message_stream", - "//fastpair/common", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_for_library_testonly", - ], -) - -cc_test( - name = "medium_test", - size = "small", - srcs = [ - "medium_test.cc", - ], - deps = [ - ":fake_medium_observer", - ":fake_provider", - ":message_stream", - "//fastpair/common", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//testing/fuzzing:fuzztest", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "message_stream_test", - size = "small", - srcs = [ - "message_stream_test.cc", - ], - deps = [ - ":fake_medium_observer", - ":fake_provider", - ":message_stream", - "//fastpair/common", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//testing/fuzzing:fuzztest", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/message_stream/fake_gatt_callbacks.h b/fastpair/message_stream/fake_gatt_callbacks.h deleted file mode 100644 index f2e6fbdacc..0000000000 --- a/fastpair/message_stream/fake_gatt_callbacks.h +++ /dev/null @@ -1,100 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_GATT_CALLBACKS_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_GATT_CALLBACKS_H_ - -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "internal/platform/ble_v2.h" -#include "internal/platform/future.h" - -namespace nearby { -namespace fastpair { - -// Fake GATT characteristic callbacks for tests. -// Register the callback returned by `GetGattCallback()` with the GattServer and -// then communicate with the GATT client via `characteristics_`. -class FakeGattCallbacks { - using GattCharacteristic = ::nearby::api::ble_v2::GattCharacteristic; - - public: - struct CharacteristicData { - // Value written to the characteristic by the gatt client - Future write_value; - // Write result returned to the gatt client. - absl::Status write_result = absl::OkStatus(); - // Value returned to the gatt client when they try to read the - // characteristic - absl::StatusOr read_value = - absl::FailedPreconditionError("characteristic not set"); - absl::AnyInvocable write_callback; - absl::AnyInvocable()> read_callback; - - absl::Status WriteCallback(absl::string_view data) { - if (write_callback) { - return write_callback(data); - } - write_value.Set(std::string(data)); - return write_result; - } - absl::StatusOr ReadCallback() { - if (read_callback) { - return read_callback(); - } - return read_value; - } - }; - - BleV2Medium::ServerGattConnectionCallback GetGattCallback() { - return BleV2Medium::ServerGattConnectionCallback{ - .on_characteristic_read_cb = - [&](const api::ble_v2::BlePeripheral& remote_device, - const GattCharacteristic& characteristic, int offset, - BleV2Medium::ServerGattConnectionCallback::ReadValueCallback - callback) { - auto it = characteristics_.find(characteristic); - if (it == characteristics_.end()) { - callback(absl::NotFoundError("characteristic not found")); - return; - } - callback(it->second.ReadCallback()); - }, - .on_characteristic_write_cb = - [&](const api::ble_v2::BlePeripheral& remote_device, - const GattCharacteristic& characteristic, int offset, - absl::string_view data, - BleV2Medium::ServerGattConnectionCallback::WriteValueCallback - callback) { - auto it = characteristics_.find(characteristic); - if (it == characteristics_.end()) { - callback(absl::NotFoundError("characteristic not found")); - return; - } - callback(it->second.WriteCallback(data)); - }}; - } - - absl::flat_hash_map characteristics_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_GATT_CALLBACKS_H_ diff --git a/fastpair/message_stream/fake_medium_observer.h b/fastpair/message_stream/fake_medium_observer.h deleted file mode 100644 index 5cf784c800..0000000000 --- a/fastpair/message_stream/fake_medium_observer.h +++ /dev/null @@ -1,90 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_MEDIUM_OBSERVER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_MEDIUM_OBSERVER_H_ - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/message_stream/medium.h" -#include "fastpair/message_stream/message.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -class FakeMediumObserver : public Medium::Observer { - public: - void OnConnectionResult(absl::Status result) override { - NEARBY_LOGS(INFO) << "OnConnectionResult " << result; - connection_result_.Set(result); - } - - void OnDisconnected(absl::Status status) override { - NEARBY_LOGS(INFO) << "OnDisconnected " << status; - disconnected_reason_.Set(status); - } - - void OnReceived(Message message) override { - NEARBY_LOGS(INFO) << "OnReceived " << message; - MutexLock lock(&messages_mutex_); - messages_.push_back(std::move(message)); - } - - std::vector GetMessages() { - MutexLock lock(&messages_mutex_); - return messages_; - } - - absl::Status WaitForMessages(int message_count, absl::Duration timeout) { - constexpr absl::Duration kStep = absl::Milliseconds(100); - while (timeout > absl::ZeroDuration()) { - std::vector messages = GetMessages(); - if (messages.size() >= message_count) { - return absl::OkStatus(); - } - timeout -= kStep; - absl::SleepFor(kStep); - } - return absl::DeadlineExceededError("timeout waiting for messages"); - } - - Future connection_result_; - Future disconnected_reason_; - - private: - std::vector messages_; - Mutex messages_mutex_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_MEDIUM_OBSERVER_H_ diff --git a/fastpair/message_stream/fake_provider.cc b/fastpair/message_stream/fake_provider.cc deleted file mode 100644 index 2c7030bd5a..0000000000 --- a/fastpair/message_stream/fake_provider.cc +++ /dev/null @@ -1,390 +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. -#include "fastpair/message_stream/fake_provider.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/strings/numbers.h" -#include "fastpair/common/constant.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/medium_environment.h" -#include -#include -#include - -namespace nearby { -namespace fastpair { - -namespace { - -constexpr uint8_t kKeyBasedPairingResponseCode = 1; -constexpr uint8_t kSeekerPasskeyResponseCode = 2; -constexpr uint8_t kProviderPasskeyResponseCode = 3; - -static EC_POINT *load_public_key(absl::string_view public_key) { - CHECK_EQ(public_key.size(), kPublicKeyByteSize); - BN_CTX *bn_ctx; - EC_KEY *key; - EC_POINT *point; - const EC_GROUP *group; - uint8_t oct_key[kPublicKeyByteSize + 1]; - - oct_key[0] = 0x04; - memcpy(oct_key + 1, public_key.data(), 64); - bn_ctx = BN_CTX_new(); - key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - group = EC_KEY_get0_group(key); - point = EC_POINT_new(group); - CHECK_EQ(EC_POINT_oct2point(group, point, oct_key, sizeof(oct_key), bn_ctx), - 1); - BN_CTX_free(bn_ctx); - EC_KEY_free(key); - return point; -} - -static BIGNUM *load_private_key(absl::string_view private_key) { - CHECK_EQ(private_key.length(), 32); - uint8_t buffer[37]; - buffer[0] = buffer[1] = buffer[2] = 0; - buffer[3] = 33; - buffer[4] = 0; - memcpy(buffer + 5, private_key.data(), 32); - return BN_mpi2bn(buffer, sizeof(buffer), nullptr); -} - -std::string Aes128Decrypt(absl::string_view input, absl::string_view key) { - CHECK_EQ(input.size(), kAesBlockByteSize); - CHECK_EQ(key.size(), kSharedSecretKeyByteSize); - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - int input_length = kAesBlockByteSize; - int output_length = kAesBlockByteSize; - std::string output(output_length, 0); - - CHECK_EQ( - EVP_DecryptInit(ctx, EVP_aes_128_ecb(), - reinterpret_cast(key.data()), nullptr), - 1); - CHECK_EQ(EVP_CIPHER_CTX_set_padding(ctx, 0), 1); - CHECK_EQ(EVP_EncryptUpdate( - ctx, reinterpret_cast(output.data()), &output_length, - reinterpret_cast(input.data()), input_length), - 1); - - EVP_CIPHER_CTX_free(ctx); - return output; -} - -std::string Aes128Encrypt(absl::string_view input, absl::string_view key) { - CHECK_EQ(input.size(), kAesBlockByteSize); - CHECK_EQ(key.size(), kSharedSecretKeyByteSize); - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - int input_length = kAesBlockByteSize; - int output_length = kAesBlockByteSize; - std::string output(output_length, 0); - - CHECK_EQ( - EVP_EncryptInit(ctx, EVP_aes_128_ecb(), - reinterpret_cast(key.data()), nullptr), - 1); - CHECK_EQ(EVP_CIPHER_CTX_set_padding(ctx, 0), 1); - CHECK_EQ(EVP_DecryptUpdate( - ctx, reinterpret_cast(output.data()), &output_length, - reinterpret_cast(input.data()), input_length), - 1); - - EVP_CIPHER_CTX_free(ctx); - return output; -} - -} // namespace - -void FakeProvider::LoadAntiSpoofingKey(absl::string_view private_key, - absl::string_view public_key) { - EC_KEY *key; - BIGNUM *prv; - EC_POINT *pub; - - prv = load_private_key(private_key); - CHECK_NE(prv, nullptr); - pub = load_public_key(public_key); - CHECK_NE(pub, nullptr); - - key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - - CHECK_EQ(EC_KEY_set_private_key(key, prv), 1); - CHECK_EQ(EC_KEY_set_public_key(key, pub), 1); - - anti_spoofing_key_.reset(EVP_PKEY_new()); - CHECK_EQ(EVP_PKEY_assign_EC_KEY(anti_spoofing_key_.get(), key), 1); - - BN_free(prv); - EC_POINT_free(pub); -} - -std::string FakeProvider::DecryptKbpRequest(absl::string_view request) { - NEARBY_LOGS(VERBOSE) << "Encrypted KBP request " - << absl::BytesToHexString(request); - CHECK_EQ(request.size(), kEncryptedDataByteSize + kPublicKeyByteSize); - absl::string_view encrypted = request.substr(0, kEncryptedDataByteSize); - absl::string_view remote_public_key = - request.substr(kEncryptedDataByteSize, kPublicKeyByteSize); - std::string shared_secret = CreateSharedSecret(remote_public_key); - std::string decrypted = Aes128Decrypt(encrypted, shared_secret); - NEARBY_LOGS(VERBOSE) << "Decrypted KBP request " - << absl::BytesToHexString(decrypted); - shared_secret_ = shared_secret; - return decrypted; -} - -std::string FakeProvider::Encrypt(absl::string_view data) { - return Aes128Encrypt(data, shared_secret_); -} - -std::string FakeProvider::GenSec256r1Secret( - absl::string_view remote_party_public_key) { - EVP_PKEY_CTX *ctx; - EVP_PKEY *peerkey; - EC_POINT *peer_point; - EC_KEY *ec_peer_key; - size_t secret_len; - std::string secret(32, 0); - - /* Create the context for the shared secret derivation */ - ctx = EVP_PKEY_CTX_new(anti_spoofing_key_.get(), nullptr); - CHECK_NE(ctx, nullptr); - - /* Initialise */ - CHECK_EQ(EVP_PKEY_derive_init(ctx), 1); - - peer_point = load_public_key(remote_party_public_key); - CHECK_NE(peer_point, nullptr); - - ec_peer_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - - CHECK_EQ(EC_KEY_set_public_key(ec_peer_key, peer_point), 1); - - peerkey = EVP_PKEY_new(); - CHECK_EQ(EVP_PKEY_assign_EC_KEY(peerkey, ec_peer_key), 1); - - /* Provide the peer public key */ - CHECK_EQ(EVP_PKEY_derive_set_peer(ctx, peerkey), 1); - - /* Determine buffer length for shared secret */ - CHECK_EQ(EVP_PKEY_derive(ctx, nullptr, &secret_len), 1); - - CHECK_EQ(secret_len, secret.size()); - - /* Derive the shared secret */ - CHECK_EQ(EVP_PKEY_derive(ctx, reinterpret_cast(secret.data()), - &secret_len), - 1); - - EVP_PKEY_CTX_free(ctx); - EC_POINT_free(peer_point); - EVP_PKEY_free(peerkey); - return secret; -} - -std::string FakeProvider::CreateSharedSecret( - absl::string_view remote_public_key) { - std::string secret = GenSec256r1Secret(remote_public_key); - return std::string( - Crypto::Sha256(secret).AsStringView().substr(0, kAccountKeySize)); -} - -void FakeProvider::StartGattServer(FakeGattCallbacks *fake_gatt_callbacks) { - fake_gatt_callbacks_ = fake_gatt_callbacks; - gatt_server_ = ble_.StartGattServer(fake_gatt_callbacks_->GetGattCallback()); -} - -absl::Status FakeProvider::NotifyKeyBasedPairing(ByteArray response) { - CHECK_NE(gatt_server_, nullptr); - CHECK(key_based_characteristic_.has_value()); - return gatt_server_->NotifyCharacteristicChanged(*key_based_characteristic_, - false, response); -} - -absl::Status FakeProvider::NotifyPasskey(ByteArray response) { - CHECK_NE(gatt_server_, nullptr); - CHECK(passkey_characteristic_.has_value()); - return gatt_server_->NotifyCharacteristicChanged(*passkey_characteristic_, - false, response); -} - -void FakeProvider::StartDiscoverableAdvertisement(absl::string_view model_id) { - advertising_ = true; - model_id_ = model_id; - ble_v1_.StartAdvertising(std::string(kServiceID), - ByteArray(absl::HexStringToBytes(model_id)), - std::string(kFastPairServiceUuid)); -} - -void FakeProvider::StopAdvertising() { - if (advertising_) { - advertising_ = false; - ble_v1_.StopAdvertising(std::string(kServiceID)); - } -} - -void FakeProvider::SetKeyBasedPairingCallback() { - CHECK_NE(fake_gatt_callbacks_, nullptr); - CHECK(key_based_characteristic_.has_value()); - fake_gatt_callbacks_->characteristics_[*key_based_characteristic_] - .write_callback = [this](absl::string_view request) { - NEARBY_LOGS(VERBOSE) << "Encrypted request: " - << absl::BytesToHexString(request); - std::string decrypted_request = DecryptKbpRequest(request); - NEARBY_LOGS(VERBOSE) << "KBP decrypted request " - << absl::BytesToHexString(decrypted_request); - fake_gatt_callbacks_->characteristics_[*key_based_characteristic_] - .write_value.Set(std::string(decrypted_request)); - std::string response; - response.push_back(kKeyBasedPairingResponseCode); - response.append(GetMacAddressAsBytes()); - response.resize(kEncryptedDataByteSize, 0); - absl::Status status = NotifyKeyBasedPairing(ByteArray(Encrypt(response))); - NEARBY_LOGS(VERBOSE) << "KBP notify result: " << status; - return absl::OkStatus(); - }; -} - -void FakeProvider::SetPasskeyCallback() { - CHECK_NE(fake_gatt_callbacks_, nullptr); - CHECK(passkey_characteristic_.has_value()); - fake_gatt_callbacks_->characteristics_[*passkey_characteristic_] - .write_callback = [this](absl::string_view request) { - NEARBY_LOGS(VERBOSE) << "Passkey Encrypted request: " - << absl::BytesToHexString(request); - std::string decrypted = Aes128Decrypt(request, shared_secret_); - NEARBY_LOGS(VERBOSE) << "Passkey decrypted request " - << absl::BytesToHexString(decrypted); - fake_gatt_callbacks_->characteristics_[*passkey_characteristic_] - .write_value.Set(std::string(decrypted)); - if (decrypted[0] != kSeekerPasskeyResponseCode) { - return absl::InvalidArgumentError( - absl::StrFormat("Invalid passkey response code: 0x%x", decrypted[0])); - } - - std::string response; - response.push_back(kProviderPasskeyResponseCode); - response.push_back(pass_key_ >> 16); - response.push_back(pass_key_ >> 8); - response.push_back(pass_key_); - response.resize(kEncryptedDataByteSize, 0); - absl::Status status = NotifyPasskey(ByteArray(Encrypt(response))); - NEARBY_LOGS(VERBOSE) << "Passkey notify result: " << status; - return absl::OkStatus(); - }; -} - -void FakeProvider::SetAccountkeyCallback() { - CHECK_NE(fake_gatt_callbacks_, nullptr); - CHECK(accountkey_characteristic_.has_value()); - fake_gatt_callbacks_->characteristics_[*accountkey_characteristic_] - .write_callback = [this](absl::string_view request) { - NEARBY_LOGS(VERBOSE) << "Account key encrypted request: " - << absl::BytesToHexString(request); - std::string decrypted = Aes128Decrypt(request, shared_secret_); - NEARBY_LOGS(VERBOSE) << "Account key decrypted request " - << absl::BytesToHexString(decrypted); - fake_gatt_callbacks_->characteristics_[*accountkey_characteristic_] - .write_value.Set(std::string(decrypted)); - - account_key_ = AccountKey(decrypted); - return absl::OkStatus(); - }; -} - -void FakeProvider::ConfigurePairingContext(absl::string_view pass_key) { - api::PairingParams pairing_params; - pairing_params.pairing_type = - api::PairingParams::PairingType::kConfirmPasskey; - pairing_params.passkey = pass_key; - auto device = MediumEnvironment::Instance().FindBluetoothDevice( - provider_medium_.GetMacAddress()); - CHECK_NE(device, nullptr); - MediumEnvironment::Instance().ConfigBluetoothPairingContext(device, - pairing_params); - CHECK(absl::SimpleAtoi(pass_key, &pass_key_)); -} - -void FakeProvider::SetPairedStatus(bool paired) { - auto device = MediumEnvironment::Instance().FindBluetoothDevice( - provider_medium_.GetMacAddress()); - CHECK_NE(device, nullptr); - MediumEnvironment::Instance().SetPairingState(device, paired); -} - -void FakeProvider::PrepareForInitialPairing( - PairingConfig config, FakeGattCallbacks *fake_gatt_callbacks) { - LoadAntiSpoofingKey(config.private_key, config.public_key); - StartGattServer(fake_gatt_callbacks); - InsertCorrectGattCharacteristics(); - SetKeyBasedPairingCallback(); - SetPasskeyCallback(); - SetAccountkeyCallback(); - provider_adapter_.SetScanMode( - BluetoothAdapter::ScanMode::kConnectableDiscoverable); - ConfigurePairingContext(config.pass_key); - StartDiscoverableAdvertisement(config.model_id); -} - -ByteArray FakeProvider::GetModelIdMessage(absl::string_view model_id) { - std::string binary_id = absl::HexStringToBytes(model_id); - std::array data = {3, 1, 0, 3, binary_id[0], binary_id[1], - binary_id[2]}; - return ByteArray(data); -} - -ByteArray FakeProvider::GetBleAddressMessage() { - std::string data = - absl::HexStringToBytes("03020006") + GetMacAddressAsBytes(); - return ByteArray(data); -} - -void FakeProvider::EnableProviderRfcommForRetro(PairingConfig &config) { - std::string service_name{"service"}; - std::string uuid(kRfcommUuid); - provider_server_socket_ = - provider_medium_.ListenForService(service_name, uuid); - model_id_ = config.model_id; - provider_thread_.Execute([this]() { - provider_socket_ = provider_server_socket_.Accept(); - if (provider_server_socket_.IsValid()) { - NEARBY_LOGS(VERBOSE) - << "Message stream connected. Sending Model Id and BLE address"; - provider_socket_.GetOutputStream().Write(GetModelIdMessage(model_id_)); - provider_socket_.GetOutputStream().Write(GetBleAddressMessage()); - } - }); -} - -void FakeProvider::PrepareForRetroactivePairing( - PairingConfig config, FakeGattCallbacks *fake_gatt_callbacks) { - LoadAntiSpoofingKey(config.private_key, config.public_key); - StartGattServer(fake_gatt_callbacks); - InsertCorrectGattCharacteristics(); - SetKeyBasedPairingCallback(); - SetAccountkeyCallback(); - EnableProviderRfcommForRetro(config); - provider_adapter_.SetScanMode(BluetoothAdapter::ScanMode::kConnectable); - SetPairedStatus(true); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/message_stream/fake_provider.h b/fastpair/message_stream/fake_provider.h deleted file mode 100644 index 36d71ac4b6..0000000000 --- a/fastpair/message_stream/fake_provider.h +++ /dev/null @@ -1,246 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_PROVIDER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_PROVIDER_H_ - -#include -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/message_stream/fake_gatt_callbacks.h" -#include "fastpair/message_stream/message.h" -#include "internal/platform/ble.h" -#include "internal/platform/ble_v2.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/bluetooth_utils.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/platform/uuid.h" -#include -#include - -namespace nearby { -namespace fastpair { - -// Fake BT device with the Provider role. Tailored to testing message stream. -class FakeProvider { - using Property = nearby::api::ble_v2::GattCharacteristic::Property; - using Permission = nearby::api::ble_v2::GattCharacteristic::Permission; - using GattCharacteristic = nearby::api::ble_v2::GattCharacteristic; - using WriteType = nearby::api::ble_v2::GattClient::WriteType; - - static constexpr inline Uuid kFastPairServiceUuid{0x0000FE2C00001000, - 0x800000805F9B34FB}; - static constexpr inline Uuid kKeyBasedCharacteristicUuidV2{ - 0xFE2C123483664814, 0x8EB001DE32100BEA}; - static constexpr inline Uuid kPasskeyCharacteristicUuidV2{0xFE2C123583664814, - 0x8EB001DE32100BEA}; - static constexpr inline Uuid kAccountKeyCharacteristicUuidV2{ - 0xFE2C123683664814, 0x8EB001DE32100BEA}; - static constexpr inline absl::string_view kServiceID = "Fast Pair"; - - static constexpr inline absl::string_view - kKeyBasedCharacteristicAdvertisementByte = "keyBasedCharacte"; - static constexpr inline absl::string_view - kPasskeyharacteristicAdvertisementByte = "passkeyCharacter"; - - public: - using KeyBasedPairingCallback = - absl::AnyInvocable; - struct PairingConfig { - std::string private_key; // binary, private Anti-Spoofing Key - std::string public_key; // binary, public Anti-Spoofing Key - std::string model_id; - std::string pass_key; - }; - ~FakeProvider() { Shutdown(); } - - // Sets the fake provider up for initial pairing - void PrepareForInitialPairing(PairingConfig config, - FakeGattCallbacks* fake_gatt_callbacks); - - // Sets the fake provider up for retroactive pairing - void PrepareForRetroactivePairing(PairingConfig config, - FakeGattCallbacks* fake_gatt_callbacks); - - void Shutdown() { - StopAdvertising(); - provider_thread_.Shutdown(); - } - - void DiscoverProvider(BluetoothClassicMedium& seeker_medium) { - CountDownLatch found_latch(1); - seeker_medium.StartDiscovery(BluetoothClassicMedium::DiscoveryCallback{ - .device_discovered_cb = - [&](BluetoothDevice& device) { - NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName(); - found_latch.CountDown(); - }, - }); - provider_adapter_.SetScanMode( - BluetoothAdapter::ScanMode::kConnectableDiscoverable); - ASSERT_TRUE(found_latch.Await().Ok()); - } - - void EnableProviderRfcomm() { - std::string service_name{"service"}; - std::string uuid(kRfcommUuid); - provider_server_socket_ = - provider_medium_.ListenForService(service_name, uuid); - provider_thread_.Execute( - [this]() { provider_socket_ = provider_server_socket_.Accept(); }); - } - - Future ReadProviderBytes(size_t num_bytes) { - Future result; - provider_thread_.Execute([this, result, num_bytes]() mutable { - if (!provider_socket_.IsValid()) { - result.SetException({Exception::kIo}); - return; - } - ExceptionOr bytes = - provider_socket_.GetInputStream().Read(num_bytes); - if (bytes.ok()) { - result.Set(std::string(bytes.GetResult().AsStringView())); - } else { - result.SetException(bytes.GetException()); - } - }); - return result; - } - - void WriteProviderBytes(std::string bytes) { - CountDownLatch latch(1); - provider_thread_.Execute([&, data = ByteArray(bytes)]() { - if (provider_socket_.IsValid()) { - provider_socket_.GetOutputStream().Write(data); - } - latch.CountDown(); - }); - latch.Await(); - } - - void DisableProviderRfcomm() { - if (provider_server_socket_.IsValid()) { - provider_server_socket_.Close(); - } - provider_thread_.Execute([this]() { - if (provider_socket_.IsValid()) { - provider_socket_.Close(); - } - }); - } - - std::string GetMacAddress() const { - return provider_adapter_.GetMacAddress(); - } - - std::string GetMacAddressAsBytes() const { - return std::string( - BluetoothUtils::FromString(provider_adapter_.GetMacAddress())); - } - - void StartGattServer(FakeGattCallbacks* fake_gatt_callbacks); - - void InsertCorrectGattCharacteristics() { - CHECK_NE(fake_gatt_callbacks_, nullptr); - - key_based_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kKeyBasedCharacteristicUuidV2, permissions_, - properties_); - CHECK(key_based_characteristic_.has_value()); - fake_gatt_callbacks_->characteristics_[*key_based_characteristic_] - .write_result = absl::OkStatus(); - - passkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kPasskeyCharacteristicUuidV2, permissions_, - properties_); - CHECK(passkey_characteristic_.has_value()); - fake_gatt_callbacks_->characteristics_[*passkey_characteristic_] - .write_result = absl::OkStatus(); - - accountkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kAccountKeyCharacteristicUuidV2, permissions_, - properties_); - CHECK(accountkey_characteristic_.has_value()); - fake_gatt_callbacks_->characteristics_[*accountkey_characteristic_] - .write_result = absl::OkStatus(); - } - - void LoadAntiSpoofingKey(absl::string_view private_key, - absl::string_view public_key); - - std::string DecryptKbpRequest(absl::string_view request); - std::string Encrypt(absl::string_view data); - - absl::Status NotifyKeyBasedPairing(ByteArray response); - absl::Status NotifyPasskey(ByteArray response); - - void StartDiscoverableAdvertisement(absl::string_view model_id); - void StopAdvertising(); - void ConfigurePairingContext(absl::string_view pass_key); - AccountKey& GetAccountKey() { return account_key_; } - std::optional key_based_characteristic_; - std::optional passkey_characteristic_; - std::optional accountkey_characteristic_; - - private: - void SetKeyBasedPairingCallback(); - void SetPasskeyCallback(); - void SetAccountkeyCallback(); - void SetPairedStatus(bool paired); - void EnableProviderRfcommForRetro(PairingConfig& config); - ByteArray GetModelIdMessage(absl::string_view model_id); - ByteArray GetBleAddressMessage(); - std::string GenSec256r1Secret(absl::string_view remote_party_public_key); - std::string CreateSharedSecret(absl::string_view remote_public_key); - BluetoothAdapter provider_adapter_; - BluetoothClassicMedium provider_medium_{provider_adapter_}; - BluetoothServerSocket provider_server_socket_; - BluetoothSocket provider_socket_; - BleV2Medium ble_{provider_adapter_}; - BleMedium ble_v1_{provider_adapter_}; - bool advertising_ = false; - std::unique_ptr gatt_server_; - Property properties_ = Property::kWrite | Property::kNotify; - Permission permissions_ = Permission::kWrite; - std::unique_ptr anti_spoofing_key_{ - nullptr, EVP_PKEY_free}; - std::string shared_secret_; - SingleThreadExecutor provider_thread_; - std::string model_id_; - FakeGattCallbacks* fake_gatt_callbacks_ = nullptr; - unsigned int pass_key_; - AccountKey account_key_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_FAKE_PROVIDER_H_ diff --git a/fastpair/message_stream/medium.cc b/fastpair/message_stream/medium.cc deleted file mode 100644 index 4d9fdcc44c..0000000000 --- a/fastpair/message_stream/medium.cc +++ /dev/null @@ -1,178 +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. - -#include "fastpair/message_stream/medium.h" - -#include -#include - -#include "absl/log/check.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/constant.h" -#include "fastpair/message_stream/message.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/future.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr int kHeaderSize = 4; -} - -absl::Status Medium::OpenRfcomm() { - if (!bt_classic_medium_.has_value()) { - return absl::FailedPreconditionError("BT classic unsupported"); - } - if (!device_.GetPublicAddress().has_value()) { - return absl::FailedPreconditionError( - "Connect open RFCOMM without public BT address"); - } - BluetoothClassicMedium* classic_medium = bt_classic_medium_.value(); - executor_.Execute("open-rfcomm", [this, classic_medium]() { - if (cancellation_flag_.Cancelled()) return; - BluetoothDevice device = - classic_medium->GetRemoteDevice(device_.GetPublicAddress().value()); - if (!device.IsValid()) { - observer_.OnConnectionResult(absl::UnavailableError( - absl::StrFormat("Remote BT device %s not found", - device_.GetPublicAddress().value()))); - return; - } - SetSocket(classic_medium->ConnectToService(device, kRfcommUuid, - &cancellation_flag_)); - BluetoothSocket socket = GetSocket(); - absl::Status status = socket.IsValid() - ? absl::OkStatus() - : absl::UnavailableError(absl::StrFormat( - "Failed to open RFCOMM with %s", - device_.GetPublicAddress().value())); - observer_.OnConnectionResult(status); - if (status.ok()) { - RunLoop(std::move(socket)); - } - }); - return absl::OkStatus(); -} - -// Opens L2CAP connection with the remote party. -// Returns an error if a connection attempt could not be made. -// Otherwise, `OnConnected()` will be called if the connection was successful, -// or `OnDisconnected()` if connection failed. -absl::Status Medium::OpenL2cap(absl::string_view ble_address) { - return absl::UnimplementedError("L2CAP unimplemented"); -} - -absl::Status Medium::Disconnect() { - NEARBY_LOGS(INFO) << "Disconnect"; - cancellation_flag_.Cancel(); - CloseSocket(); - return absl::OkStatus(); -} - -// Returns OK if the message was queued for delivery. It does not mean the -// message was delivered to the remote party. -absl::Status Medium::Send(Message message, bool compute_and_append_mac) { - BluetoothSocket socket = GetSocket(); - if (cancellation_flag_.Cancelled() || !socket.IsValid()) { - return absl::FailedPreconditionError("Not connected"); - } - ByteArray byte_array = Serialize(std::move(message), compute_and_append_mac); - if (socket.GetOutputStream().Write(byte_array).Ok()) { - return absl::OkStatus(); - } else { - cancellation_flag_.Cancel(); - return absl::DataLossError("Failed to send data to remote"); - } -} - -void Medium::RunLoop(BluetoothSocket socket) { - NEARBY_LOGS(INFO) << "Run loop"; - InputStream& input = socket.GetInputStream(); - while (!cancellation_flag_.Cancelled()) { - ExceptionOr header = input.ReadExactly(kHeaderSize); - if (!header.ok() || header.result().size() != kHeaderSize) { - break; - } - absl::string_view data = header.result().AsStringView(); - MessageGroup group = static_cast(data[0]); - MessageCode code = static_cast(data[1]); - int length = static_cast(data[2]) * 256 + - static_cast(data[3]); - ExceptionOr payload; - if (length > 0) { - payload = input.ReadExactly(length); - } else { - payload = ExceptionOr(ByteArray("")); - } - if (!payload.ok() || payload.result().size() != length) { - break; - } - observer_.OnReceived(Message{.message_group = group, - .message_code = code, - .payload = std::string(payload.result())}); - } - socket.Close(); - if (!cancellation_flag_.Cancelled()) { - observer_.OnDisconnected(absl::DataLossError("Failed to read from remote")); - } - NEARBY_LOGS(INFO) << "Run loop done"; -} - -ByteArray Medium::Serialize(Message message, bool compute_and_append_mac) { - DCHECK_EQ(compute_and_append_mac, false); - uint16_t payload_size = message.payload.size(); - int message_size = kHeaderSize + payload_size; - ByteArray byte_array = ByteArray(message_size); - uint8_t* data = reinterpret_cast(byte_array.data()); - data[0] = static_cast(message.message_group); - data[1] = static_cast(message.message_code); - data[2] = payload_size >> 8; - data[3] = payload_size & 0xFF; - memcpy(&data[kHeaderSize], message.payload.data(), payload_size); - return byte_array; -} - -void Medium::SetSocket(BluetoothSocket socket) { - if (!socket.IsValid()) return; - MutexLock lock(&mutex_); - NEARBY_LOGS(INFO) << "SetSocket 1"; - if (cancellation_flag_.Cancelled()) { - NEARBY_LOGS(INFO) << "Medium already closed. Closing socket"; - socket.Close(); - } else { - NEARBY_LOGS(INFO) << "SetSocket 2"; - socket_ = std::move(socket); - } -} - -BluetoothSocket Medium::GetSocket() { - MutexLock lock(&mutex_); - // Returns a stable copy of the socket. Both `socket_` and the returned copy - // refer to the same platform socket. - return socket_; -} - -void Medium::CloseSocket() { - MutexLock lock(&mutex_); - if (socket_.IsValid()) { - socket_.Close(); - socket_ = BluetoothSocket(); - } -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/message_stream/medium.h b/fastpair/message_stream/medium.h deleted file mode 100644 index b103587991..0000000000 --- a/fastpair/message_stream/medium.h +++ /dev/null @@ -1,108 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MEDIUM_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MEDIUM_H_ - -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/message_stream/message.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/future.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -class Medium { - public: - class Observer { - public: - virtual ~Observer() = default; - virtual void OnConnectionResult(absl::Status result) = 0; - - virtual void OnDisconnected(absl::Status reason) = 0; - - virtual void OnReceived(Message message) = 0; - }; - Medium(const FastPairDevice& device, - std::optional bt_classic, Observer& observer) - : device_(device), bt_classic_medium_(bt_classic), observer_(observer) {} - Medium(Medium&& other) = default; - - ~Medium() { - NEARBY_LOGS(INFO) << "Destructing FP Medium"; - { - MutexLock lock(&mutex_); - cancellation_flag_.Cancel(); - NEARBY_LOGS(INFO) << "Destructing FP Medium 1"; - if (socket_.IsValid()) { - socket_.Close(); - } - } - NEARBY_LOGS(INFO) << "Destructing FP Medium 2"; - executor_.Shutdown(); - NEARBY_LOGS(INFO) << "Destructed FP Medium"; - } - - // Opens RFCOMM connection with the remote party. - // Returns an error if a connection attempt could not be made. - // Otherwise, `OnConnectionResult()` will be called with the connection - // result. When the connection is successful, Medium starts processing - // messages coming in from the remote party, and calls `OnReceived()` for each - // complete message. - absl::Status OpenRfcomm(); - - // Opens L2CAP connection with the remote party. - // Returns an error if a connection attempt could not be made. - // Otherwise, `OnConnectionResult()` will be called with the connection - // result. When the connection is successful, Medium starts processing - // messages coming in from the remote party, and calls `OnReceived()` for each - // complete message. - absl::Status OpenL2cap(absl::string_view ble_address); - - absl::Status Disconnect(); - - // Returns OK if the message was queued for delivery. It does not mean the - // message was delivered to the remote party. - absl::Status Send(Message message, bool compute_and_append_mac = false); - - private: - void RunLoop(BluetoothSocket socket); - ByteArray Serialize(Message message, bool compute_and_append_mac); - void SetSocket(BluetoothSocket socket); - void CloseSocket(); - BluetoothSocket GetSocket(); - const FastPairDevice& device_; - std::optional bt_classic_medium_; - Observer& observer_; - BluetoothSocket socket_ ABSL_GUARDED_BY(mutex_); - Mutex mutex_; - CancellationFlag cancellation_flag_; - SingleThreadExecutor executor_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MEDIUM_H_ diff --git a/fastpair/message_stream/medium_test.cc b/fastpair/message_stream/medium_test.cc deleted file mode 100644 index a23208f6b2..0000000000 --- a/fastpair/message_stream/medium_test.cc +++ /dev/null @@ -1,249 +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. - -#include "fastpair/message_stream/medium.h" - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "testing/fuzzing/fuzztest.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/message_stream/fake_medium_observer.h" -#include "fastpair/message_stream/fake_provider.h" -#include "fastpair/message_stream/message.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -namespace { - -using ::testing::status::StatusIs; - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class MediumTest : public testing::Test { - protected: - void SetUp() override { MediumEnvironment::Instance().Start(); } - void TearDown() override { - provider_.Shutdown(); - MediumEnvironment::Instance().Stop(); - } - - // The medium environment must be initialized (started) before adding - // adapters. - MediumEnvironmentStarter env_; - BluetoothAdapter seeker_adapter_; - BluetoothClassicMedium seeker_medium_{seeker_adapter_}; - FakeProvider provider_; - FakeMediumObserver observer_; -}; - -TEST_F(MediumTest, ConnectWithNonExistingDeviceFails) { - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - fp_device.SetPublicAddress("11:22:33:44:55:66"); - Medium medium = - Medium(fp_device, std::optional(&seeker_medium_), - observer_); - - ASSERT_OK(medium.OpenRfcomm()); - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - EXPECT_THAT(observer_.connection_result_.Get().GetResult(), - StatusIs(absl::StatusCode::kUnavailable)); -} - -TEST_F(MediumTest, Connect) { - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - fp_device.SetPublicAddress(provider_.GetMacAddress()); - provider_.DiscoverProvider(seeker_medium_); - provider_.EnableProviderRfcomm(); - Medium medium = - Medium(fp_device, std::optional(&seeker_medium_), - observer_); - - ASSERT_OK(medium.OpenRfcomm()); - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - EXPECT_OK(observer_.connection_result_.Get().GetResult()); -} - -TEST_F(MediumTest, ProviderDisconnectsCallsOnDisconnectCallback) { - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - fp_device.SetPublicAddress(provider_.GetMacAddress()); - provider_.DiscoverProvider(seeker_medium_); - provider_.EnableProviderRfcomm(); - Medium medium = - Medium(fp_device, std::optional(&seeker_medium_), - observer_); - ASSERT_OK(medium.OpenRfcomm()); - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - - provider_.DisableProviderRfcomm(); - - ASSERT_TRUE(observer_.disconnected_reason_.Get().ok()); - EXPECT_THAT(observer_.disconnected_reason_.Get().GetResult(), - StatusIs(absl::StatusCode::kDataLoss)); -} - -TEST_F(MediumTest, DisconnectSendFails) { - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - fp_device.SetPublicAddress(provider_.GetMacAddress()); - provider_.DiscoverProvider(seeker_medium_); - provider_.EnableProviderRfcomm(); - Medium medium = - Medium(fp_device, std::optional(&seeker_medium_), - observer_); - ASSERT_OK(medium.OpenRfcomm()); - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - - ASSERT_OK(medium.Disconnect()); - - // Medium is disconnected, Send should fail - EXPECT_THAT(medium.Send(Message{}, false), - StatusIs(absl::StatusCode::kFailedPrecondition)); -} - -TEST_F(MediumTest, SendMessage) { - Message message = {.message_group = MessageGroup::kDeviceInformationEvent, - .message_code = MessageCode::kSessionNonce, - .payload = absl::HexStringToBytes("ABCDEF")}; - // See the format definition in - // https://developers.google.com/nearby/fast-pair/specifications/extensions/messagestreamhttps://developers.google.com/nearby/fast-pair/specifications/extensions/messagestream - std::string expected_result = absl::HexStringToBytes("030A0003ABCDEF"); - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - fp_device.SetPublicAddress(provider_.GetMacAddress()); - provider_.DiscoverProvider(seeker_medium_); - provider_.EnableProviderRfcomm(); - Medium medium = - Medium(fp_device, std::optional(&seeker_medium_), - observer_); - ASSERT_OK(medium.OpenRfcomm()); - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - - EXPECT_OK(medium.Send(message, false)); - - Future result = - provider_.ReadProviderBytes(expected_result.size()); - ASSERT_TRUE(result.Get().ok()); - EXPECT_EQ(result.Get().GetResult(), expected_result); -} - -TEST_F(MediumTest, ReceiveMessage) { - Message expected_message = { - .message_group = MessageGroup::kDeviceInformationEvent, - .message_code = MessageCode::kSessionNonce, - .payload = absl::HexStringToBytes("ABCDEF")}; - std::string input = absl::HexStringToBytes("030A0003ABCDEF"); - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - fp_device.SetPublicAddress(provider_.GetMacAddress()); - provider_.DiscoverProvider(seeker_medium_); - provider_.EnableProviderRfcomm(); - Medium medium = - Medium(fp_device, std::optional(&seeker_medium_), - observer_); - ASSERT_OK(medium.OpenRfcomm()); - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - - provider_.WriteProviderBytes(input); - - ASSERT_OK(observer_.WaitForMessages(1, absl::Seconds(10))); - std::vector messages = observer_.GetMessages(); - ASSERT_EQ(messages.size(), 1); - EXPECT_EQ(messages[0], expected_message); -} - -class MediumFuzzTest : public fuzztest::PerIterationFixtureAdapter { - public: - void HandlesAnyInput(absl::string_view input) { - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - fp_device.SetPublicAddress(provider_.GetMacAddress()); - provider_.DiscoverProvider(seeker_medium_); - provider_.EnableProviderRfcomm(); - Medium medium = Medium( - fp_device, std::optional(&seeker_medium_), - observer_); - ASSERT_OK(medium.OpenRfcomm()); - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - - provider_.WriteProviderBytes(std::string(input)); - provider_.DisableProviderRfcomm(); - } - - void HandlesValidInput(uint8_t group, uint8_t code, - absl::string_view payload) { - Message expected_message = { - .message_group = static_cast(group), - .message_code = static_cast(code), - .payload = std::string(payload)}; - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - fp_device.SetPublicAddress(provider_.GetMacAddress()); - provider_.DiscoverProvider(seeker_medium_); - provider_.EnableProviderRfcomm(); - Medium medium = Medium( - fp_device, std::optional(&seeker_medium_), - observer_); - ASSERT_OK(medium.OpenRfcomm()); - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - - provider_.WriteProviderBytes( - {static_cast(group), static_cast(code)}); - uint16_t length = payload.length(); - provider_.WriteProviderBytes( - {static_cast(length >> 8), static_cast(length)}); - provider_.WriteProviderBytes(std::string(payload)); - ASSERT_OK(observer_.WaitForMessages(1, absl::Seconds(10))); - std::vector messages = observer_.GetMessages(); - ASSERT_EQ(messages.size(), 1); - EXPECT_EQ(messages[0], expected_message); - provider_.DisableProviderRfcomm(); - } -}; - -FUZZ_TEST_F(MediumFuzzTest, HandlesAnyInput) - .WithDomains(fuzztest::Arbitrary()); - -FUZZ_TEST_F(MediumFuzzTest, HandlesValidInput) - .WithDomains(/*group=*/fuzztest::Arbitrary(), - /*code=*/fuzztest::Arbitrary(), - /*payload=*/fuzztest::Arbitrary()); - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/message_stream/message.h b/fastpair/message_stream/message.h deleted file mode 100644 index 2fcced41a9..0000000000 --- a/fastpair/message_stream/message.h +++ /dev/null @@ -1,103 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MESSAGE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MESSAGE_H_ - -#include - -#include -#include - -#include "absl/strings/escaping.h" -#include "internal/platform/byte_array.h" - -namespace nearby { -namespace fastpair { - -enum class MessageGroup { - kBluetooth = 1, - kCompanionAppEvent = 2, - kDeviceInformationEvent = 3, - kDeviceActionEvent = 4, - kSass = 7, - kAcknowledgement = 255 -}; - -// Note, message code values are not unique, because every message group has -// their own list of message codes. -enum class MessageCode { - // Message codes for kBluetooth message group - kEnableSilenceMode = 1, - kDisableSilenceMode = 2, - // Message codes for kCompanionAppEvent message group - kLogBufferFull = 1, - // Message codes for kDeviceInformationEvent message group - kModelId = 1, - kBleAddressUpdated = 2, - kBatteryUpdated = 3, - kRemainingBatteryTime = 4, - kActiveComponentRequest = 5, - kActiveComponentResponse = 6, - kCapabilites = 7, - kPlatformType = 8, - kSessionNonce = 0x0A, - // Message codes for kDeviceActionEvent message group - kRing = 1, - // Message codes for kSass message group - kSassGetCapability = 0x10, - kSassNotifyCapability = 0x11, - kSassSetMultipointState = 0x12, - kSassSetSwitchingPreference = 0x20, - kSassGetSwitchingPreference = 0x21, - kSassNotifySwitchingPreference = 0x22, - kSassSwitchActiveSourceCode = 0x30, - kSassSwitchBackAudioSource = 0x31, - kSassNotifyMultipointSwitchEvent = 0x32, - kSassGetConnectionStatus = 0x33, - kSassNotifyConnectionStatus = 0x34, - kSassNotifySassInitiatedConnection = 0x40, - kSassInUseAccountKey = 0x41, - kSassSendCustomData = 0x42, - kSassSetDropConnectionTarget = 0x43, - // Message codes for kAcknowledgement message group - kAck = 1, - kNack = 2 -}; - -struct Message { - MessageGroup message_group; - MessageCode message_code; - std::string payload; -}; - -inline std::ostream& operator<<(std::ostream& os, const Message& message) { - os << "Message{" << static_cast(message.message_group) << ", " - << static_cast(message.message_code); - if (!message.payload.empty()) { - os << ", '" << absl::BytesToHexString(message.payload) << "'"; - } - os << "}"; - - return os; -} - -inline bool operator==(const Message& a, const Message& b) { - return a.message_group == b.message_group && - a.message_code == b.message_code && a.payload == b.payload; -} -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MESSAGE_H_ diff --git a/fastpair/message_stream/message_stream.cc b/fastpair/message_stream/message_stream.cc deleted file mode 100644 index 33d76c4cf7..0000000000 --- a/fastpair/message_stream/message_stream.cc +++ /dev/null @@ -1,336 +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. - -#include "fastpair/message_stream/message_stream.h" - -#include -#include -#include -#include -#include -#include - -#include "absl/time/time.h" -#include "fastpair/message_stream/message.h" -#include "internal/platform/bluetooth_utils.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr uint8_t kCompanionInstalledBit = 0x02; -constexpr uint8_t kSupportsSilenceBit = 0x01; -// The default active components response. -constexpr uint8_t kDefaultComponents = 0; -constexpr int kModelIdSize = 3; -constexpr int kBleAddressSize = 6; -// We don't accept more than `kMaxBatteryLevels` battery values from the -// provider. -constexpr int kMaxBatteryLevels = 3; -constexpr int kUnknownBatteryLevel = 0x7F; -constexpr absl::Duration kActiveComponentsTimeout = absl::Seconds(1); -constexpr absl::Duration kRingAckTimeout = absl::Seconds(1); - -MessageStream::BatteryInfo ConvertBatteryInfo(uint8_t battery_value) { - // The highest bit represents `is_charging`, the rest the battery level (in - // %). - bool is_charging = battery_value & 0x80; - int level = battery_value & 0x7F; - MessageStream::BatteryInfo battery_info{.is_charging = is_charging}; - if (level != kUnknownBatteryLevel) { - battery_info.level = level; - } - return battery_info; -} -} // namespace - -MessageStream::MessageStream(const FastPairDevice& device, - std::optional bt_classic, - Observer& observer) - : observer_(observer), medium_(device, bt_classic, *this) {} - -absl::Status MessageStream::OpenRfcomm() { return medium_.OpenRfcomm(); } - -absl::Status MessageStream::OpenL2cap(absl::string_view ble_address) { - return medium_.OpenL2cap(ble_address); -} - -absl::Status MessageStream::Disconnect() { return medium_.Disconnect(); } - -Future MessageStream::GetActiveComponents() { - Future future(kActiveComponentsTimeout); - absl::Status status = medium_.Send( - Message{.message_group = MessageGroup::kDeviceInformationEvent, - .message_code = MessageCode::kActiveComponentRequest}); - if (status.ok()) { - MutexLock lock(&mutex_); - if (get_active_components_request_) { - get_active_components_request_->SetException({Exception::kInterrupted}); - } - get_active_components_request_ = std::make_unique>(future); - } else { - future.SetException({Exception::kIo}); - } - return future; -} - -absl::Status MessageStream::SendCapabilities(bool companion_app_installed, - bool supports_silence_mode) { - uint8_t capabilites = 0; - if (companion_app_installed) { - capabilites |= kCompanionInstalledBit; - } - if (supports_silence_mode) { - capabilites |= kSupportsSilenceBit; - } - return medium_.Send( - Message{.message_group = MessageGroup::kDeviceInformationEvent, - .message_code = MessageCode::kCapabilites, - .payload = {capabilites}}); -} - -absl::Status MessageStream::SendPlatformType( - api::DeviceInfo::OsType platform_type, uint8_t custom_code) { - return medium_.Send( - Message{.message_group = MessageGroup::kDeviceInformationEvent, - .message_code = MessageCode::kPlatformType, - .payload = {static_cast(platform_type), custom_code}}); -} - -// Asks the Provider to ring. -// Returns true if the Provider replies with an ACK. -Future MessageStream::Ring(uint8_t components, absl::Duration duration) { - constexpr MessageGroup kGroup = MessageGroup::kDeviceActionEvent; - constexpr MessageCode kCode = MessageCode::kRing; - Future future(kRingAckTimeout); - std::string payload = {components}; - uint8_t minutes = absl::ToInt64Minutes(duration); - if (minutes != 0) { - payload.append({minutes}); - } - { - MutexLock lock(&mutex_); - waiting_for_ack_.push_back(MessageWithAck{ - .message_group = kGroup, .message_code = kCode, .future = future}); - } - absl::Status status = medium_.Send(Message{ - .message_group = kGroup, .message_code = kCode, .payload = payload}); - if (!status.ok()) { - FinishCall(kGroup, kCode, false); - } - return future; -} - -void MessageStream::FinishCall(MessageGroup group, MessageCode code, - bool result) { - NEARBY_LOGS(INFO) << "Finish call " << static_cast(group) << ", " - << static_cast(code) << " with result: " << result; - MutexLock lock(&mutex_); - auto it = std::find_if(waiting_for_ack_.begin(), waiting_for_ack_.end(), - [&](const MessageWithAck& item) { - return item.message_group == group && - item.message_code == code; - }); - if (it != waiting_for_ack_.end()) { - NEARBY_LOGS(INFO) << "Finishing call with result: " << result; - it->future.Set(result); - waiting_for_ack_.erase(it); - } -} - -// Medium::Observer -void MessageStream::OnConnectionResult(absl::Status result) { - observer_.OnConnectionResult(result); -} -void MessageStream::OnDisconnected(absl::Status status) { - observer_.OnDisconnected(status); -} - -void MessageStream::OnReceived(Message message) { - bool handled = false; - NEARBY_LOGS(INFO) << "Received: " << message; - switch (message.message_group) { - case MessageGroup::kAcknowledgement: - handled = HandleAcknowledgement(message); - break; - case MessageGroup::kBluetooth: - handled = HandleBluetooth(message); - break; - case MessageGroup::kCompanionAppEvent: - handled = HandleCompanionAppEvent(message); - break; - case MessageGroup::kDeviceInformationEvent: - handled = HandleDeviceInformationEvent(message); - break; - case MessageGroup::kDeviceActionEvent: - handled = HandleDeviceActionEvent(message); - break; - case MessageGroup::kSass: - break; - default: - break; - } - if (!handled) { - NEARBY_LOGS(INFO) << "Unrecognized " << message; - } -} - -bool MessageStream::HandleDeviceInformationEvent(const Message& message) { - switch (message.message_code) { - case MessageCode::kModelId: { - if (message.payload.size() != kModelIdSize) { - NEARBY_LOGS(WARNING) << "Model id event size should be " << kModelIdSize - << " but is " << message.payload.size(); - break; - } - observer_.OnModelId(message.payload); - return true; - } - case MessageCode::kBleAddressUpdated: { - if (message.payload.size() != kBleAddressSize) { - NEARBY_LOGS(WARNING) - << "BLE address updated event size should be " << kBleAddressSize - << " but is " << message.payload.size(); - break; - } - ByteArray address(message.payload); - observer_.OnBleAddressUpdated(BluetoothUtils::ToString(address)); - return true; - } - case MessageCode::kBatteryUpdated: { - if (message.payload.size() > kMaxBatteryLevels) { - NEARBY_LOGS(WARNING) - << "Battery level event size should be <= " << kMaxBatteryLevels - << " but is " << message.payload.size(); - break; - } - std::vector battery_levels(message.payload.size()); - for (size_t i = 0; i < message.payload.size(); i++) { - battery_levels[i] = ConvertBatteryInfo(message.payload[i]); - } - observer_.OnBatteryUpdated(std::move(battery_levels)); - return true; - } - case MessageCode::kRemainingBatteryTime: { - int battery_time = 0; - if (message.payload.size() == 1) { - battery_time = static_cast(message.payload[0]); - } else if (message.payload.size() == 2) { - battery_time = 256 * static_cast(message.payload[0]) + - static_cast(message.payload[1]); - } else { - NEARBY_LOGS(WARNING) - << "Remaining battery event size should be 1 or 2 bytes but is " - << message.payload.size(); - break; - } - observer_.OnRemainingBatteryTime(absl::Minutes(battery_time)); - return true; - } - case MessageCode::kActiveComponentResponse: { - uint8_t components = message.payload.size() == 1 - ? message.payload.data()[0] - : kDefaultComponents; - MutexLock lock(&mutex_); - if (get_active_components_request_) { - get_active_components_request_->Set(components); - get_active_components_request_.reset(); - } - return true; - } - default: - break; - } - return false; -} - -bool MessageStream::HandleAcknowledgement(const Message& message) { - bool result; - if (message.message_code == MessageCode::kAck) { - result = true; - } else if (message.message_code == MessageCode::kNack) { - result = false; - } else { - return false; - } - // The payload of ACK/NACK message contains the group/code of the original - // message. - if (message.payload.size() < 2) { - NEARBY_LOGS(INFO) << "ACK/NACK too short: " << message; - return false; - } - MessageGroup group = static_cast(message.payload[0]); - MessageCode code = static_cast(message.payload[1]); - FinishCall(group, code, result); - return true; -} - -bool MessageStream::HandleBluetooth(const Message& message) { - switch (message.message_code) { - case MessageCode::kEnableSilenceMode: - observer_.OnEnableSilenceMode(true); - return true; - case MessageCode::kDisableSilenceMode: - observer_.OnEnableSilenceMode(false); - return true; - default: - break; - } - return false; -} - -bool MessageStream::HandleCompanionAppEvent(const Message& message) { - switch (message.message_code) { - case MessageCode::kLogBufferFull: - observer_.OnLogBufferFull(); - return true; - default: - break; - } - return false; -} - -bool MessageStream::HandleDeviceActionEvent(const Message& message) { - switch (message.message_code) { - case MessageCode::kRing: { - uint8_t components = 0; - absl::Duration duration = absl::ZeroDuration(); - if (!message.payload.empty()) { - components = static_cast(message.payload[0]); - } - if (message.payload.size() >= 2) { - duration = absl::Minutes(static_cast(message.payload[1])); - } - bool result = observer_.OnRing(components, duration); - SendAcknowledgement(message, result); - return true; - } - default: - break; - } - return false; -} - -void MessageStream::SendAcknowledgement(const Message& message, bool ack) { - absl::Status status = medium_.Send( - Message{.message_group = MessageGroup::kAcknowledgement, - .message_code = ack ? MessageCode::kAck : MessageCode::kNack, - .payload = {static_cast(message.message_group), - static_cast(message.message_code)}}); - if (!status.ok()) { - NEARBY_LOGS(WARNING) << "Failed to send ACK/NACK " << status; - } -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/message_stream/message_stream.h b/fastpair/message_stream/message_stream.h deleted file mode 100644 index c787d60850..0000000000 --- a/fastpair/message_stream/message_stream.h +++ /dev/null @@ -1,123 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MESSAGE_STREAM_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MESSAGE_STREAM_H_ - -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "fastpair/message_stream/medium.h" -#include "fastpair/message_stream/message.h" -#include "internal/platform/implementation/device_info.h" - -namespace nearby { -namespace fastpair { - -class MessageStream : public Medium::Observer { - public: - struct BatteryInfo { - bool is_charging; - std::optional level; - }; - class Observer { - public: - virtual ~Observer() = default; - virtual void OnConnectionResult(absl::Status result) = 0; - - virtual void OnDisconnected(absl::Status status) = 0; - - // `void' callbacks don't send acknowledgements to the Provider. - // 'bool' callbacks send ACK or NACK depending on the return value. - virtual void OnEnableSilenceMode(bool enable) = 0; - - virtual void OnLogBufferFull() = 0; - - virtual void OnModelId(absl::string_view model_id) = 0; - - // `address` is in canonical, human-readable format. - virtual void OnBleAddressUpdated(absl::string_view address) = 0; - - virtual void OnBatteryUpdated(std::vector battery_levels) = 0; - - virtual void OnRemainingBatteryTime(absl::Duration duration) = 0; - - // Note, there are no callbacks for Active Components Request and Active - // Components Response. Use `GetActiveComponents()` instead. - - virtual bool OnRing(uint8_t components, absl::Duration duration) = 0; - }; - - MessageStream(const FastPairDevice& device, - std::optional bt_classic, - Observer& observer); - MessageStream(MessageStream&& other) = default; - absl::Status OpenRfcomm(); - - absl::Status OpenL2cap(absl::string_view ble_address); - - absl::Status Disconnect(); - - // Asks the Provider for active components. - // Returns the active components bitmap. - Future GetActiveComponents(); - - absl::Status SendCapabilities(bool companion_app_installed, - bool supports_silence_mode); - - absl::Status SendPlatformType(api::DeviceInfo::OsType platform_type, - uint8_t custom_code); - - // Asks the Provider to ring. - // Returns true if the Provider replies with an ACK. - Future Ring(uint8_t components, absl::Duration duration); - - // Medium::Observer - void OnConnectionResult(absl::Status result) override; - - void OnDisconnected(absl::Status status) override; - - void OnReceived(Message message) override; - - private: - // Notifies the caller that message {group, code} was handled by the provider - // with the `result`. - void FinishCall(MessageGroup group, MessageCode code, bool result); - bool HandleBluetooth(const Message& message); - bool HandleCompanionAppEvent(const Message& message); - bool HandleDeviceActionEvent(const Message& message); - bool HandleAcknowledgement(const Message& message); - bool HandleDeviceInformationEvent(const Message& message); - void SendAcknowledgement(const Message& message, bool ack); - - struct MessageWithAck { - MessageGroup message_group; - MessageCode message_code; - Future future; - }; - // A list of messages waiting for ACK/NACK. - std::vector waiting_for_ack_ ABSL_GUARDED_BY(mutex_); - std::unique_ptr> get_active_components_request_ - ABSL_GUARDED_BY(mutex_); - Mutex mutex_; - Observer& observer_; - Medium medium_; -}; - -} // namespace fastpair -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_FASTPAIR_MESSAGE_STREAM_MESSAGE_STREAM_H_ diff --git a/fastpair/message_stream/message_stream_test.cc b/fastpair/message_stream/message_stream_test.cc deleted file mode 100644 index 3ec6fc8173..0000000000 --- a/fastpair/message_stream/message_stream_test.cc +++ /dev/null @@ -1,454 +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. - -#include "fastpair/message_stream/message_stream.h" - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "testing/fuzzing/fuzztest.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/message_stream/fake_medium_observer.h" -#include "fastpair/message_stream/fake_provider.h" -#include "fastpair/message_stream/message.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/implementation/device_info.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -namespace { - -using ::testing::status::StatusIs; - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class FakeObserver : public MessageStream::Observer { - public: - void OnConnectionResult(absl::Status result) override { - NEARBY_LOGS(INFO) << "OnConnectionResult " << result; - connection_result_.Set(result); - } - - void OnDisconnected(absl::Status status) override { - NEARBY_LOGS(INFO) << "OnDisconnected " << status; - disconnected_reason_.Set(status); - } - - void OnEnableSilenceMode(bool enable) override { silence_mode_.Set(enable); } - - void OnLogBufferFull() override { log_buffer_full_.Set(true); } - - void OnModelId(absl::string_view model_id) override { - model_id_.Set(std::string(model_id)); - } - - void OnBleAddressUpdated(absl::string_view address) override { - ble_address_updated_.Set(std::string(address)); - } - - void OnBatteryUpdated( - std::vector battery_levels) override { - battery_levels_.Set(battery_levels); - } - - void OnRemainingBatteryTime(absl::Duration duration) override { - remaining_battery_time_.Set(duration); - } - - bool OnRing(uint8_t components, absl::Duration duration) override { - on_ring_event_.Set({components, duration}); - // This allows us to test returning ACK/NACK to the seeker. - return components != 0xAB; - } - Future connection_result_; - Future disconnected_reason_; - Future model_id_; - Future ble_address_updated_; - Future> battery_levels_; - Future remaining_battery_time_; - Future silence_mode_; - Future log_buffer_full_; - struct OnRingData { - uint8_t components; - absl::Duration duration; - }; - Future on_ring_event_; -}; - -class MessageStreamTest : public testing::Test { - protected: - void SetUp() override { - MediumEnvironment::Instance().Start(); - - fp_device_.SetPublicAddress(provider_.GetMacAddress()); - provider_.DiscoverProvider(seeker_medium_); - provider_.EnableProviderRfcomm(); - } - void TearDown() override { - provider_.Shutdown(); - MediumEnvironment::Instance().Stop(); - } - - MessageStream OpenMessageStream() { - MessageStream message_stream = MessageStream( - fp_device_, std::optional(&seeker_medium_), - observer_); - CHECK_OK(message_stream.OpenRfcomm()); - CHECK(observer_.connection_result_.Get().ok()); - CHECK(observer_.connection_result_.Get().GetResult().ok()); - return message_stream; - } - - void VerifySentMessage(absl::string_view bytes) { - Future result = provider_.ReadProviderBytes(bytes.size()); - ASSERT_TRUE(result.Get().ok()); - ASSERT_EQ(result.Get().GetResult(), bytes); - } - // The medium environment must be initialized (started) before adding - // adapters. - MediumEnvironmentStarter env_; - BluetoothAdapter seeker_adapter_; - BluetoothClassicMedium seeker_medium_{seeker_adapter_}; - FakeProvider provider_; - FastPairDevice fp_device_{"model id", "ble address", - Protocol::kFastPairRetroactivePairing}; - - FakeObserver observer_; -}; - -TEST_F(MessageStreamTest, ConnectRfcomm) { - MessageStream message_stream = MessageStream( - fp_device_, std::optional(&seeker_medium_), - observer_); - - ASSERT_OK(message_stream.OpenRfcomm()); - - ASSERT_TRUE(observer_.connection_result_.Get().ok()); - EXPECT_OK(observer_.connection_result_.Get().GetResult()); -} - -TEST_F(MessageStreamTest, Disconnect) { - MessageStream message_stream = OpenMessageStream(); - - ASSERT_OK(message_stream.Disconnect()); - - ASSERT_THAT(message_stream.SendCapabilities(/*companion_app_installed=*/true, - /*supports_silence_mode=*/false), - StatusIs(absl::StatusCode::kFailedPrecondition)); -} - -TEST_F(MessageStreamTest, ProviderDisconnectCallsOnDisconnectCallback) { - MessageStream message_stream = OpenMessageStream(); - - provider_.DisableProviderRfcomm(); - - ASSERT_TRUE(observer_.disconnected_reason_.Get().ok()); - EXPECT_THAT(observer_.disconnected_reason_.Get().GetResult(), - StatusIs(absl::StatusCode::kDataLoss)); -} - -TEST_F(MessageStreamTest, SendCapabilites) { - MessageStream message_stream = OpenMessageStream(); - - ASSERT_OK(message_stream.SendCapabilities(/*companion_app_installed=*/true, - /*supports_silence_mode=*/false)); - VerifySentMessage(absl::HexStringToBytes("0307000102")); - - ASSERT_OK(message_stream.SendCapabilities(/*companion_app_installed=*/false, - /*supports_silence_mode=*/true)); - VerifySentMessage(absl::HexStringToBytes("0307000101")); - - ASSERT_OK(message_stream.SendCapabilities(/*companion_app_installed=*/true, - /*supports_silence_mode=*/true)); - VerifySentMessage(absl::HexStringToBytes("0307000103")); - - ASSERT_OK(message_stream.SendCapabilities(/*companion_app_installed=*/false, - /*supports_silence_mode=*/false)); - VerifySentMessage(absl::HexStringToBytes("0307000100")); -} - -TEST_F(MessageStreamTest, RingAcked) { - constexpr uint8_t kComponents = 0x50; - MessageStream message_stream = OpenMessageStream(); - - Future result = message_stream.Ring(kComponents, absl::Minutes(10)); - - VerifySentMessage(absl::HexStringToBytes("04010002500A")); - provider_.WriteProviderBytes(absl::HexStringToBytes("FF0100020401")); - ASSERT_TRUE(result.Get().ok()); - ASSERT_TRUE(result.Get().GetResult()); -} - -TEST_F(MessageStreamTest, RingNacked) { - constexpr uint8_t kComponents = 0x50; - MessageStream message_stream = OpenMessageStream(); - - Future result = message_stream.Ring(kComponents, absl::Minutes(10)); - - VerifySentMessage(absl::HexStringToBytes("04010002500A")); - provider_.WriteProviderBytes(absl::HexStringToBytes("FF0200020401")); - ASSERT_FALSE(result.Get().GetResult()); -} - -TEST_F(MessageStreamTest, RingNoResponse) { - constexpr uint8_t kComponents = 0x50; - MessageStream message_stream = OpenMessageStream(); - - Future result = message_stream.Ring(kComponents, absl::Minutes(10)); - - VerifySentMessage(absl::HexStringToBytes("04010002500A")); - ASSERT_FALSE(result.Get().ok()); - EXPECT_EQ(result.Get().exception(), Exception::kTimeout); -} - -TEST_F(MessageStreamTest, GetActiveComponents) { - MessageStream message_stream = OpenMessageStream(); - - Future result = message_stream.GetActiveComponents(); - - VerifySentMessage(absl::HexStringToBytes("0305")); - provider_.WriteProviderBytes(absl::HexStringToBytes("03060001AB")); - ASSERT_TRUE(result.Get().ok()); - ASSERT_EQ(result.Get().GetResult(), 0xAB); -} - -TEST_F(MessageStreamTest, GetActiveComponentsEmptyResponse) { - MessageStream message_stream = OpenMessageStream(); - - Future result = message_stream.GetActiveComponents(); - - VerifySentMessage(absl::HexStringToBytes("0305")); - provider_.WriteProviderBytes(absl::HexStringToBytes("03060000")); - ASSERT_TRUE(result.Get().ok()); - ASSERT_EQ(result.Get().GetResult(), 0); -} - -TEST_F(MessageStreamTest, GetActiveComponentsNoResponse) { - MessageStream message_stream = OpenMessageStream(); - - Future result = message_stream.GetActiveComponents(); - - VerifySentMessage(absl::HexStringToBytes("0305")); - ASSERT_FALSE(result.Get().ok()); - EXPECT_EQ(result.Get().exception(), Exception::kTimeout); -} - -TEST_F(MessageStreamTest, ReceiveModelId) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("03010003ABCDEF")); - - ASSERT_TRUE(observer_.model_id_.Get().ok()); - ASSERT_EQ(observer_.model_id_.Get().GetResult(), - absl::HexStringToBytes("ABCDEF")); -} - -TEST_F(MessageStreamTest, ReceiveEnableSilenceMode) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("01010000")); - - ASSERT_TRUE(observer_.silence_mode_.Get().ok()); - ASSERT_TRUE(observer_.silence_mode_.Get().GetResult()); -} - -TEST_F(MessageStreamTest, ReceiveDisableSilenceMode) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("01020000")); - - EXPECT_FALSE(observer_.silence_mode_.Get()); -} - -TEST_F(MessageStreamTest, ReceiveLogBufferFull) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("02010000")); - - ASSERT_TRUE(observer_.log_buffer_full_.Get().ok()); - ASSERT_TRUE(observer_.log_buffer_full_.Get().GetResult()); -} - -TEST_F(MessageStreamTest, ReceiveOnRingEmpty) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("04010000")); - - ASSERT_TRUE(observer_.on_ring_event_.Get().ok()); - ASSERT_EQ(observer_.on_ring_event_.Get().GetResult().components, 0); - ASSERT_EQ(observer_.on_ring_event_.Get().GetResult().duration, - absl::ZeroDuration()); - VerifySentMessage(absl::HexStringToBytes("FF0100020401")); -} - -TEST_F(MessageStreamTest, ReceiveOnRingWithComponents) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("04010001CD")); - - ASSERT_TRUE(observer_.on_ring_event_.Get().ok()); - ASSERT_EQ(observer_.on_ring_event_.Get().GetResult().components, 0xCD); - ASSERT_EQ(observer_.on_ring_event_.Get().GetResult().duration, - absl::ZeroDuration()); - VerifySentMessage(absl::HexStringToBytes("FF0100020401")); -} - -TEST_F(MessageStreamTest, ReceiveOnRingWithTimeout) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("04010002CDFE")); - - ASSERT_TRUE(observer_.on_ring_event_.Get().ok()); - ASSERT_EQ(observer_.on_ring_event_.Get().GetResult().components, 0xCD); - ASSERT_EQ(observer_.on_ring_event_.Get().GetResult().duration, - absl::Minutes(0xFE)); - VerifySentMessage(absl::HexStringToBytes("FF0100020401")); -} - -TEST_F(MessageStreamTest, OnRingFailSendsNack) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("04010002ABFE")); - - ASSERT_TRUE(observer_.on_ring_event_.Get().ok()); - ASSERT_EQ(observer_.on_ring_event_.Get().GetResult().components, 0xAB); - ASSERT_EQ(observer_.on_ring_event_.Get().GetResult().duration, - absl::Minutes(0xFE)); - VerifySentMessage(absl::HexStringToBytes("FF0200020401")); -} - -TEST_F(MessageStreamTest, SendPlatformType) { - MessageStream message_stream = OpenMessageStream(); - - ASSERT_OK( - message_stream.SendPlatformType(api::DeviceInfo::OsType::kAndroid, 0x1C)); - VerifySentMessage(absl::HexStringToBytes("03080002011C")); -} - -TEST_F(MessageStreamTest, ReceiveBleAddressUpdated) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("03020006AABBCCDDEEFF")); - - ASSERT_TRUE(observer_.ble_address_updated_.Get().ok()); - EXPECT_EQ(observer_.ble_address_updated_.Get().GetResult(), - "AA:BB:CC:DD:EE:FF"); -} - -TEST_F(MessageStreamTest, ReceiveBatteryUpdated) { - MessageStream message_stream = OpenMessageStream(); - - // The values copied from the specification. - provider_.WriteProviderBytes(absl::HexStringToBytes("0303000357417F")); - - ASSERT_TRUE(observer_.battery_levels_.Get().ok()); - ASSERT_EQ(observer_.battery_levels_.Get().result().size(), 3); - EXPECT_FALSE(observer_.battery_levels_.Get().result()[0].is_charging); - EXPECT_EQ(observer_.battery_levels_.Get().result()[0].level, 87); - EXPECT_FALSE(observer_.battery_levels_.Get().result()[1].is_charging); - EXPECT_EQ(observer_.battery_levels_.Get().result()[1].level, 65); - EXPECT_FALSE(observer_.battery_levels_.Get().result()[2].is_charging); - EXPECT_FALSE(observer_.battery_levels_.Get().result()[2].level.has_value()); -} - -TEST_F(MessageStreamTest, ReceiveBatteryUpdatedOneBattery) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("030300019A")); - - ASSERT_TRUE(observer_.battery_levels_.Get().ok()); - ASSERT_EQ(observer_.battery_levels_.Get().result().size(), 1); - EXPECT_TRUE(observer_.battery_levels_.Get().result()[0].is_charging); - EXPECT_EQ(observer_.battery_levels_.Get().result()[0].level, 0x1A); -} - -TEST_F(MessageStreamTest, ReceiveRemainingBatteryTime) { - MessageStream message_stream = OpenMessageStream(); - - // The values copied from the specification - provider_.WriteProviderBytes(absl::HexStringToBytes("03040001F0")); - - ASSERT_TRUE(observer_.remaining_battery_time_.Get().ok()); - EXPECT_EQ(observer_.remaining_battery_time_.Get().GetResult(), - absl::Minutes(240)); -} - -TEST_F(MessageStreamTest, ReceiveRemainingBatteryTimeHighValue) { - MessageStream message_stream = OpenMessageStream(); - - provider_.WriteProviderBytes(absl::HexStringToBytes("03040002ABCD")); - - ASSERT_TRUE(observer_.remaining_battery_time_.Get().ok()); - EXPECT_EQ(observer_.remaining_battery_time_.Get().GetResult(), - absl::Minutes(0xABCD)); -} - -template -std::vector GetAllEnums(int min_value, int max_value) { - int count = max_value - min_value + 1; - std::vector enums(count); - for (int i = 0; i < count; i++) { - enums[i] = static_cast(min_value + i); - } - return enums; -} - -// MessageGroup received over the wire is an 8-bit number. -auto AnyMessageGroup() { - return fuzztest::ElementOf(GetAllEnums(0, 255)); -} - -// MessageCode received over the wire is an 8-bit number. -auto AnyMessageCode() { - return fuzztest::ElementOf(GetAllEnums(0, 255)); -} - -void HandlesAnyMessage(MessageGroup group, MessageCode code, - absl::string_view payload) { - FastPairDevice fp_device("model id", "ble address", - Protocol::kFastPairRetroactivePairing); - FakeObserver observer; - MessageStream message_stream(fp_device, std::nullopt, observer); - message_stream.OnReceived(Message{.message_group = group, - .message_code = code, - .payload = std::string(payload)}); -} - -FUZZ_TEST(MessageStreamFuzzTest, HandlesAnyMessage) - .WithDomains(AnyMessageGroup(), AnyMessageCode(), - fuzztest::Arbitrary()); - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/mock_fast_pair_seeker.h b/fastpair/mock_fast_pair_seeker.h deleted file mode 100644 index 4bc4badd7a..0000000000 --- a/fastpair/mock_fast_pair_seeker.h +++ /dev/null @@ -1,51 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_MOCK_FAST_PAIR_SEEKER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_MOCK_FAST_PAIR_SEEKER_H_ - -#include "gmock/gmock.h" -#include "absl/status/status.h" -#include "fastpair/fast_pair_seeker.h" - -namespace nearby { -namespace fastpair { - -class MockFastPairSeeker : public FastPairSeeker { - public: - MOCK_METHOD(absl::Status, StartInitialPairing, - (const FastPairDevice& device, const InitialPairingParam& params, - PairingCallback callback), - (override)); - - MOCK_METHOD(absl::Status, StartSubsequentPairing, - (const FastPairDevice& device, - const SubsequentPairingParam& params, PairingCallback callback), - (override)); - - MOCK_METHOD(absl::Status, StartRetroactivePairing, - (const FastPairDevice& device, - const RetroactivePairingParam& param, PairingCallback callback), - (override)); - MOCK_METHOD(absl::Status, FinishRetroactivePairing, - (const FastPairDevice& device, - const FinishRetroactivePairingParam& param, - PairingCallback callback), - (override)); -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_MOCK_FAST_PAIR_SEEKER_H_ diff --git a/fastpair/pairing/BUILD b/fastpair/pairing/BUILD deleted file mode 100644 index 24c8cd809b..0000000000 --- a/fastpair/pairing/BUILD +++ /dev/null @@ -1,72 +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. - -licenses(["notice"]) - -cc_library( - name = "pairing", - srcs = [ - "pairer_broker_impl.cc", - ], - hdrs = [ - "pairer_broker.h", - "pairer_broker_impl.h", - ], - visibility = ["//fastpair:__subpackages__"], - deps = [ - "//fastpair/common", - "//fastpair/handshake", - "//fastpair/internal/mediums", - "//fastpair/pairing/fastpair:pairing", - "//internal/base", - "//internal/platform:types", - "//internal/platform/implementation:account_manager", - "//internal/platform/implementation:types", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/functional:bind_front", - "@com_google_absl//absl/synchronization", - ], -) - -cc_test( - name = "pairer_broker_impl_test", - size = "small", - srcs = [ - "pairer_broker_impl_test.cc", - ], - shard_count = 16, - deps = [ - ":pairing", - "//fastpair/common", - "//fastpair/crypto", - "//fastpair/handshake", - "//fastpair/handshake:test_support", - "//fastpair/internal/mediums", - "//fastpair/pairing/fastpair:pairing", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/repository:test_support", - "//internal/account", - "//internal/auth:credential", - "//internal/base:bluetooth_address", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test", - "@boringssl//:crypto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/functional:bind_front", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/pairing/fastpair/BUILD b/fastpair/pairing/fastpair/BUILD deleted file mode 100644 index b38927424b..0000000000 --- a/fastpair/pairing/fastpair/BUILD +++ /dev/null @@ -1,74 +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. - -licenses(["notice"]) - -cc_library( - name = "pairing", - srcs = [ - "fast_pair_pairer_impl.cc", - ], - hdrs = [ - "fast_pair_pairer.h", - "fast_pair_pairer_impl.h", - ], - visibility = ["//fastpair:__subpackages__"], - deps = [ - "//fastpair/common", - "//fastpair/crypto", - "//fastpair/handshake", - "//fastpair/internal/mediums", - "//fastpair/repository", - "//internal/platform:comm", - "//internal/platform:types", - "//internal/platform/implementation:account_manager", - "//internal/platform/implementation:types", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/time", - ], -) - -cc_test( - name = "fast_pair_pairer_impl_test", - size = "small", - srcs = [ - "fast_pair_pairer_impl_test.cc", - ], - shard_count = 16, - deps = [ - ":pairing", - "//fastpair/common", - "//fastpair/crypto", - "//fastpair/handshake", - "//fastpair/handshake:test_support", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/repository:test_support", - "//internal/account", - "//internal/auth:credential", - "//internal/base:bluetooth_address", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test", - "@boringssl//:crypto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/functional:bind_front", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/pairing/fastpair/fast_pair_pairer.h b/fastpair/pairing/fastpair/fast_pair_pairer.h deleted file mode 100644 index bd5de0a3f8..0000000000 --- a/fastpair/pairing/fastpair/fast_pair_pairer.h +++ /dev/null @@ -1,51 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_FASTPAIR_FAST_PAIR_PAIRER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_FASTPAIR_FAST_PAIR_PAIRER_H_ - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -namespace nearby { -namespace fastpair { - -// A FastPairPairer instance is responsible for the pairing procedure to a -// single device. Pairing begins on instantiation. -class FastPairPairer { - public: - // Triggered when paired with the remote device. - using OnPairedCallback = absl::AnyInvocable; - // Triggered when failed to pair with the remote device. - using OnPairingFailedCallback = - absl::AnyInvocable; - // Triggered when completed the whole pairing process, - // including pairing with the remote device and writing the accountkey to it. - using OnPairingCompletedCallback = - absl::AnyInvocable; - // Triggered when failed to write accountkey to the remote device. - using OnAccountKeyFailureCallback = - absl::AnyInvocable; - - virtual ~FastPairPairer() = default; - - virtual void StartPairing() = 0; - virtual bool IsPaired() = 0; - virtual bool CancelPairing() = 0; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_FASTPAIR_FAST_PAIR_PAIRER_H_ diff --git a/fastpair/pairing/fastpair/fast_pair_pairer_impl.cc b/fastpair/pairing/fastpair/fast_pair_pairer_impl.cc deleted file mode 100644 index e2c2113847..0000000000 --- a/fastpair/pairing/fastpair/fast_pair_pairer_impl.cc +++ /dev/null @@ -1,400 +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. - -#include "fastpair/pairing/fastpair/fast_pair_pairer_impl.h" - -#include -#include -#include -#include -#include -#include - -#include "absl/time/time.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/crypto/fast_pair_message_type.h" -#include "fastpair/handshake/fast_pair_handshake_lookup.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr absl::Duration kInitiatePairingTimeout = absl::Seconds(20); -} // namespace - -// static -FastPairPairerImpl::Factory* FastPairPairerImpl::Factory::g_test_factory_ = - nullptr; - -// static -std::unique_ptr FastPairPairerImpl::Factory::Create( - FastPairDevice& device, Mediums& medium, SingleThreadExecutor* executor, - AccountManager* account_manager, OnPairedCallback on_paired_cb, - OnPairingFailedCallback on_pair_failed_cb, - OnAccountKeyFailureCallback on_account_failure_cb, - OnPairingCompletedCallback on_pairing_completed_cb) { - if (g_test_factory_) { - return g_test_factory_->CreateInstance( - device, medium, executor, account_manager, std::move(on_paired_cb), - std::move(on_pair_failed_cb), std::move(on_account_failure_cb), - std::move(on_pairing_completed_cb)); - } - return std::make_unique( - device, medium, executor, account_manager, std::move(on_paired_cb), - std::move(on_pair_failed_cb), std::move(on_account_failure_cb), - std::move(on_pairing_completed_cb)); -} - -// static -void FastPairPairerImpl::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -FastPairPairerImpl::FastPairPairerImpl( - FastPairDevice& device, Mediums& medium, SingleThreadExecutor* executor, - AccountManager* account_manager, OnPairedCallback on_paired_cb, - OnPairingFailedCallback on_pair_failed_cb, - OnAccountKeyFailureCallback on_account_failure_cb, - OnPairingCompletedCallback on_pairing_completed_cb) - : device_(device), - mediums_(medium), - executor_(executor), - account_manager_(account_manager), - on_paired_cb_(std::move(on_paired_cb)), - on_pair_failed_cb_(std::move(on_pair_failed_cb)), - on_account_key_failure_cb_(std::move(on_account_failure_cb)), - on_pairing_completed_cb_(std::move(on_pairing_completed_cb)) { - if (device_.GetVersion().value() == DeviceFastPairVersion::kHigherThanV1) { - // Obtains the established GATT connection for use in the pairing process: - // confirm the passkey, write the account key, etc. - fast_pair_handshake_ = - FastPairHandshakeLookup::GetInstance()->Get(&device_); - CHECK(fast_pair_handshake_); - CHECK(fast_pair_handshake_->completed_successfully()); - fast_pair_gatt_service_client_ = - fast_pair_handshake_->fast_pair_gatt_service_client(); - } -} - -void FastPairPairerImpl::StartPairing() { - executor_->Execute( - "Start Pairing", [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NEARBY_LOGS(INFO) << __func__ << device_; - switch (device_.GetProtocol()) { - case Protocol::kFastPairInitialPairing: - case Protocol::kFastPairSubsequentPairing: - // This timer captures a pairing timeout. - initiate_pairing_timer_.Start( - kInitiatePairingTimeout / absl::Milliseconds(1), 0, [&]() { - NEARBY_LOGS(WARNING) - << __func__ - << ": Timeout while attempting to initiate " - "pairing with device."; - NotifyPairingFailed(PairFailure::kPairingTimeout); - }); - pairing_job_ = std::make_unique(); - pairing_job_->Execute("pair", [this]() { InitiatePairing(); }); - break; - case Protocol::kFastPairRetroactivePairing: - // Because the devices are already paired, we will directly write an - // account key to the Provider after a shared secret is established. - AttemptSendAccountKey(); - break; - } - }); -} - -// Blocking functions -void FastPairPairerImpl::InitiatePairing() { - NEARBY_LOGS(INFO) << __func__; - // TODO(b/278810942) : Check if device lost first - if (mediums_.GetBluetoothRadio().Enable() && - mediums_.GetBluetoothClassic().IsAvailable()) { - bluetooth_pairing_ = mediums_.GetBluetoothClassic().CreatePairing( - device_.GetPublicAddress().value()); - } - if (!bluetooth_pairing_) { - NotifyPairingFailed(PairFailure::kPairingAndConnect); - return; - } - // Unpair with the remote device before initializing a new pairing request - if (!bluetooth_pairing_->Unpair()) { - NotifyPairingFailed(PairFailure::kPairingAndConnect); - return; - } - if (!bluetooth_pairing_->InitiatePairing({ - .on_paired_cb = - [&]() { - if (!initiate_pairing_timer_.IsRunning()) { - NEARBY_LOGS(INFO) - << __func__ << " Initiating pairing has timed out."; - return; - } - initiate_pairing_timer_.Stop(); - NEARBY_LOGS(INFO) << __func__ << " Paired with " << device_; - // On Windows, Pair is exactly the same as Connect. - NotifyPaired(); - executor_->Execute( - "Write Accountkey", - [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - AttemptSendAccountKey(); - }); - }, - .on_pairing_error_cb = - [&](api::BluetoothPairingCallback::PairingError error) { - NEARBY_LOGS(INFO) - << __func__ << "Failed to pair with device due to error " - << static_cast(error); - NotifyPairingFailed(PairFailure::kPairingAndConnect); - }, - .on_pairing_initiated_cb = - [&](api::PairingParams pairingParams) { - if (!initiate_pairing_timer_.IsRunning()) { - NEARBY_LOGS(INFO) - << __func__ << " Initiating pairing has timed out."; - return; - } - NEARBY_LOGS(INFO) << __func__ << "Initiated pairing request."; - if (device_.GetVersion().value() == - DeviceFastPairVersion::kV1) { - NEARBY_LOGS(INFO) - << __func__ - << ": For v1 headset, skip passkey confirmation."; - bluetooth_pairing_->FinishPairing(std::nullopt); - } else { - NEARBY_LOGS(INFO) - << __func__ << ": For headsets higher than v1, " - << "confirm passkey before accepting pairing."; - ConfirmPasskey(pairingParams); - } - }, - })) { - NotifyPairingFailed(PairFailure::kPairingAndConnect); - } -} - -void FastPairPairerImpl::ConfirmPasskey(api::PairingParams pairingParams) { - if (!FastPairHandshakeLookup::GetInstance()->Get(&device_)) { - NEARBY_LOGS(ERROR) << __func__ - << ": BLE device instance lost during passkey exchange"; - bluetooth_pairing_->CancelPairing(); - NotifyPairingFailed(PairFailure::kDeviceLostMidPairing); - return; - } - expected_passkey_ = pairingParams.passkey; - NEARBY_LOGS(INFO) << __func__ - << " Star to confirm passkey: " << expected_passkey_; - fast_pair_gatt_service_client_->WritePasskeyAsync( - /*message_type=*/0x02, std::stoi(expected_passkey_), - *fast_pair_handshake_->fast_pair_data_encryptor(), - [&](absl::string_view response, - std::optional failure) { - OnPasskeyResponse(response, failure); - }); -} - -void FastPairPairerImpl::OnPasskeyResponse(absl::string_view response, - std::optional failure) { - NEARBY_LOGS(INFO) << __func__; - if (failure.has_value()) { - NotifyPairingFailed(failure.value()); - return; - } - std::vector response_bytes(response.begin(), response.end()); - fast_pair_handshake_->fast_pair_data_encryptor()->ParseDecryptPasskey( - response_bytes, [&](const std::optional passkey) { - OnParseDecryptedPasskey(passkey); - }); -} - -void FastPairPairerImpl::OnParseDecryptedPasskey( - std::optional passkey) { - if (!passkey.has_value()) { - NotifyPairingFailed(PairFailure::kPasskeyDecryptFailure); - return; - } - if (passkey->message_type != FastPairMessageType::kProvidersPasskey) { - NEARBY_LOGS(WARNING) - << "Incorrect message type from decrypted passkey. Expected: " - << FastPairMessageType::kProvidersPasskey - << ". Actual: " << passkey->message_type; - NotifyPairingFailed(PairFailure::kIncorrectPasskeyResponseType); - return; - } - - if (passkey->passkey != std::stoi(expected_passkey_)) { - NEARBY_LOGS(ERROR) << "Passkeys do not match. " - << "Expected: " << expected_passkey_ - << ". Actual: " << std::to_string(passkey->passkey); - NotifyPairingFailed(PairFailure::kPasskeyMismatch); - return; - } - // TODO(b/278810942) : Check if device lost - NEARBY_LOGS(INFO) << __func__ << ": Passkeys match, confirming pairing"; - bluetooth_pairing_->FinishPairing(std::nullopt); -} - -bool FastPairPairerImpl::CancelPairing() { - if (!bluetooth_pairing_) { - NEARBY_LOGS(WARNING) << __func__ << ": No on-going pairing process."; - return false; - } - return bluetooth_pairing_->CancelPairing(); -} - -bool FastPairPairerImpl::IsPaired() { - if (!bluetooth_pairing_) { - return false; - } - return bluetooth_pairing_->IsPaired(); -} - -void FastPairPairerImpl::AttemptSendAccountKey() { - if (device_.GetVersion().value() == DeviceFastPairVersion::kV1) { - NotifyPairingCompleted(); - return; - } - - // We only send the account key if we're doing an initial or retroactive - // pairing. For subsequent pairing, we have to save the account key - // locally so that we can refer to it in API calls to the server. - if (device_.GetProtocol() == Protocol::kFastPairSubsequentPairing) { - NEARBY_LOGS(VERBOSE) << __func__ - << ": Saving Account Key locally for subsequent pair"; - // TODO(b/278807993): Saving Account Key locally for subsequent pair - NotifyPairingCompleted(); - return; - } - - if (!account_manager_->GetCurrentAccount().has_value()) { - NEARBY_LOGS(INFO) - << __func__ - << ": No need to write accountkey because no logged in user."; - NotifyPairingCompleted(); - return; - } - - // It's possible that the user has opted to initial pair to a device that - // already has an account key saved. We check to see if this is the case - // before writing a new account key. - if (device_.GetProtocol() == Protocol::kFastPairInitialPairing) { - FastPairRepository::Get()->IsDeviceSavedToAccount( - device_.GetPublicAddress().value(), [this](absl::Status status) { - if (status.ok()) { - NEARBY_LOGS(VERBOSE) - << __func__ - << ": Device is already saved, skipping write account key. " - "Pairing procedure complete."; - NotifyPairingCompleted(); - return; - } - WriteAccountKey(); - }); - } else { - // TODO(b/281782018) : Handle BLE address rotation - WriteAccountKey(); - } -} - -void FastPairPairerImpl::WriteAccountKey() { - fast_pair_gatt_service_client_->WriteAccountKey( - *fast_pair_handshake_->fast_pair_data_encryptor(), - [&](const std::optional account_key, - const std::optional failure) { - OnWriteAccountKey(account_key, failure); - }); -} - -void FastPairPairerImpl::OnWriteAccountKey( - std::optional account_key, std::optional failure) { - if (failure.has_value()) { - NEARBY_LOGS(WARNING) - << __func__ << "Failed to write account key to device due to error: " - << failure.value(); - NotifyAccountKeyFailure(failure.value()); - return; - } - if (!account_key.has_value()) { - NotifyAccountKeyFailure(PairFailure::kAccountKeyCharacteristicWrite); - return; - } - device_.SetAccountKey(account_key.value()); - - // Devices in the Retroactive Pair scenario are not written to Footprints - // on account key write, but when the user hits 'Save' on the retroactive pair - // notification. - if (device_.GetProtocol() == Protocol::kFastPairRetroactivePairing) { - NotifyPairingCompleted(); - return; - } - - FastPairRepository::Get()->WriteAccountAssociationToFootprints( - device_, [&](absl::Status status) { - if (status.ok()) { - NotifyPairingCompleted(); - } else { - NotifyAccountKeyFailure(PairFailure::kWriteAccountKeyToFootprints); - } - }); -} - -void FastPairPairerImpl::NotifyPaired() { - NEARBY_LOGS(INFO) << __func__ << device_; - executor_->Execute("NotifyPaired", - [&, on_paired_cb = std::move(on_paired_cb_)]() mutable { - on_paired_cb(device_); - }); -} - -void FastPairPairerImpl::NotifyPairingFailed(PairFailure failure) { - NEARBY_LOGS(WARNING) << __func__ << ": " << failure; - // Stop initiate pairing timer as piaring is terminate this time. - initiate_pairing_timer_.Stop(); - if (!on_pair_failed_cb_) return; - executor_->Execute("NotifyPairingFailed", - [&, on_pair_failed_cb = std::move(on_pair_failed_cb_), - failure = std::move(failure)]() mutable { - on_pair_failed_cb(device_, failure); - }); -} - -void FastPairPairerImpl::NotifyPairingCompleted() { - NEARBY_LOGS(INFO) - << __func__ - << "Account key written to device. Pairing procedure complete."; - executor_->Execute("Notify Pairing Completed", - [&, on_pairing_completed_cb = - std::move(on_pairing_completed_cb_)]() mutable { - on_pairing_completed_cb(device_); - }); -} - -void FastPairPairerImpl::NotifyAccountKeyFailure(PairFailure failure) { - NEARBY_LOGS(WARNING) << __func__ - << "Failed to write account key to device due to error: " - << failure; - executor_->Execute( - "Notify AccountKey Failure", - [&, on_account_key_failure_cb = std::move(on_account_key_failure_cb_), - failure = std::move(failure)]() mutable { - on_account_key_failure_cb(device_, failure); - }); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/pairing/fastpair/fast_pair_pairer_impl.h b/fastpair/pairing/fastpair/fast_pair_pairer_impl.h deleted file mode 100644 index dd7d87c98f..0000000000 --- a/fastpair/pairing/fastpair/fast_pair_pairer_impl.h +++ /dev/null @@ -1,124 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_FASTPAIR_FAST_PAIR_PAIRER_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_FASTPAIR_FAST_PAIR_PAIRER_IMPL_H_ - -#include -#include -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/crypto/decrypted_passkey.h" -#include "fastpair/handshake/fast_pair_gatt_service_client.h" -#include "fastpair/handshake/fast_pair_handshake.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/pairing/fastpair/fast_pair_pairer.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/platform/timer_impl.h" - -namespace nearby { -namespace fastpair { - -class FastPairPairerImpl : public FastPairPairer { - public: - class Factory { - public: - static std::unique_ptr Create( - FastPairDevice& device, Mediums& medium, SingleThreadExecutor* executor, - AccountManager* account_manager, OnPairedCallback on_paired_cb, - OnPairingFailedCallback on_pair_failed_cb, - OnAccountKeyFailureCallback on_account_failure_cb, - OnPairingCompletedCallback on_pairing_completed_cb); - - static void SetFactoryForTesting(Factory* test_factory); - - protected: - virtual ~Factory() = default; - - virtual std::unique_ptr CreateInstance( - FastPairDevice& device, Mediums& medium, SingleThreadExecutor* executor, - AccountManager* account_manager, OnPairedCallback on_paired_cb, - OnPairingFailedCallback on_pair_failed_cb, - OnAccountKeyFailureCallback on_account_failure_cb, - OnPairingCompletedCallback on_pairing_completed_cb) = 0; - - private: - static Factory* g_test_factory_; - }; - - FastPairPairerImpl(FastPairDevice& device, Mediums& medium, - SingleThreadExecutor* executor, - AccountManager* account_manager, - OnPairedCallback on_paired_cb, - OnPairingFailedCallback on_pair_failed_cb, - OnAccountKeyFailureCallback on_account_failure_cb, - OnPairingCompletedCallback on_pairing_completed_cb); - FastPairPairerImpl(const FastPairPairerImpl&) = delete; - FastPairPairerImpl& operator=(const FastPairPairerImpl&) = delete; - FastPairPairerImpl(FastPairPairerImpl&&) = delete; - FastPairPairerImpl& operator=(FastPairPairerImpl&&) = delete; - bool CancelPairing() override; - bool IsPaired() override; - void StartPairing() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) override; - - private: - void InitiatePairing(); - - void ConfirmPasskey(api::PairingParams pairingParams); - // FastPairGattServiceClient::WritePasskey callback - void OnPasskeyResponse(absl::string_view response, - std::optional failure); - // FastPairDataEncryptor::ParseDecryptedPasskey callback - void OnParseDecryptedPasskey(std::optional passkey); - - // Attempts to write account key to remote device - void AttemptSendAccountKey() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void WriteAccountKey(); - // FastPairDataEncryptor::WriteAccountKey callback - void OnWriteAccountKey(std::optional account_key, - std::optional failure); - - // Notify the result of pairing and writing accoutkey. - void NotifyPaired(); - void NotifyPairingFailed(PairFailure failure); - void NotifyPairingCompleted(); - void NotifyAccountKeyFailure(PairFailure failure); - - std::string expected_passkey_; - FastPairHandshake* fast_pair_handshake_; - FastPairGattServiceClient* fast_pair_gatt_service_client_; - std::unique_ptr bluetooth_pairing_; - FastPairDevice& device_; - Mediums& mediums_; - SingleThreadExecutor* executor_; - AccountManager* account_manager_; - OnPairedCallback on_paired_cb_ ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - OnPairingFailedCallback on_pair_failed_cb_ - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - OnAccountKeyFailureCallback on_account_key_failure_cb_ - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - OnPairingCompletedCallback on_pairing_completed_cb_ - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - TimerImpl initiate_pairing_timer_; - std::unique_ptr pairing_job_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_FASTPAIR_FAST_PAIR_PAIRER_IMPL_H_ diff --git a/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc b/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc deleted file mode 100644 index 19e31b5d79..0000000000 --- a/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc +++ /dev/null @@ -1,941 +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. - -#include "fastpair/pairing/fastpair/fast_pair_pairer_impl.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/functional/any_invocable.h" -#include "absl/functional/bind_front.h" -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "fastpair//handshake/fast_pair_handshake_lookup.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/fast_pair_version.h" -#include "fastpair/common/protocol.h" -#include "fastpair/crypto/decrypted_passkey.h" -#include "fastpair/crypto/decrypted_response.h" -#include "fastpair/crypto/fast_pair_message_type.h" -#include "fastpair/handshake/fake_fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_data_encryptor_impl.h" -#include "fastpair/handshake/fast_pair_handshake_impl.h" -#include "fastpair/pairing/fastpair/fast_pair_pairer.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/repository/fake_fast_pair_repository.h" -#include "internal/base/bluetooth_address.h" -#include "internal/platform/ble_v2.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/test/fake_account_manager.h" - -namespace nearby { -namespace fastpair { -namespace { -using Property = nearby::api::ble_v2::GattCharacteristic::Property; -using Permission = nearby::api::ble_v2::GattCharacteristic::Permission; -using ::nearby::api::ble_v2::GattCharacteristic; -using DiscoveryCallback = BluetoothClassicMedium::DiscoveryCallback; - -constexpr absl::Duration kWaitTimeout = absl::Milliseconds(200); -constexpr absl::string_view kFastPairPreferencesFilePath = - "Google/Nearby/FastPair"; -constexpr absl::string_view kTestAccountId = "test_account_id"; -constexpr absl::string_view kMetadataId("718c17"); -constexpr absl::string_view kPublicAntiSpoof = - "Wuyr48lD3txnUhGiMF1IfzlTwRxxe+wMB1HLzP+" - "0wVcljfT3XPoiy1fntlneziyLD5knDVAJSE+RM/zlPRP/Jg=="; -constexpr Uuid kFastPairServiceUuid(0x0000FE2C00001000, 0x800000805F9B34FB); -constexpr Uuid kKeyBasedCharacteristicUuidV2(0xFE2C123483664814, - 0x8EB001DE32100BEA); -constexpr Uuid kPasskeyCharacteristicUuidV2(0xFE2C123583664814, - 0x8EB001DE32100BEA); -constexpr Uuid kAccountKeyCharacteristicUuidV2(0xFE2C123683664814, - 0x8EB001DE32100BEA); -constexpr absl::string_view kKeyBasedResponse("keybasedresponse"); -constexpr absl::string_view kPasskeyResponse("passkeyresponse"); -constexpr absl::string_view kWrongResponse("wrongresponse"); -constexpr absl::string_view kPasskey("123456"); -constexpr std::array salt = {0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x00}; -} // namespace - -class FastPairFakeDataEncryptorImplFactory - : public FastPairDataEncryptorImpl::Factory { - public: - void CreateInstance( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback) override { - if (!successful_retrieval_) { - std::move(on_get_instance_callback)(nullptr); - return; - } - - auto data_encryptor = std::make_unique(); - data_encryptor_ = data_encryptor.get(); - data_encryptor->SetResponse(response_); - data_encryptor->SetPasskey(passkey_); - std::move(on_get_instance_callback)(std::move(data_encryptor)); - } - - FakeFastPairDataEncryptor* data_encryptor() { return data_encryptor_; } - - void SetFailedRetrieval() { successful_retrieval_ = false; } - - void SetResponse(std::optional response) { - response_ = std::move(response); - } - - void SetPasskey(std::optional passkey) { - passkey_ = std::move(passkey); - } - - private: - FakeFastPairDataEncryptor* data_encryptor_ = nullptr; - bool successful_retrieval_ = true; - std::optional response_; - std::optional passkey_; -}; - -struct CharacteristicData { - // Write result returned to the gatt client. - absl::Status write_result; - std::optional notify_response; -}; - -class FastPairPairerImplTest : public testing::Test { - public: - FastPairPairerImplTest() { - FastPairDataEncryptorImpl::Factory::SetFactoryForTesting( - &fake_data_encryptor_factory_); - } - void SetUp() override { - env_.Start(); - // Setups seeker device. - mediums_ = std::make_unique(); - account_manager_ = std::make_unique(); - - // Setups provider device. - adapter_provider_ = std::make_unique(); - adapter_provider_->SetStatus(BluetoothAdapter::Status::kEnabled); - adapter_provider_->SetName("Device-Provider"); - adapter_provider_->SetScanMode( - BluetoothAdapter::ScanMode::kConnectableDiscoverable); - bt_provider_ = std::make_unique(*adapter_provider_); - - // Discovering provider device. - CountDownLatch found_latch(1); - mediums_->GetBluetoothClassic().GetMedium().StartDiscovery( - DiscoveryCallback{.device_discovered_cb = [&](BluetoothDevice& device) { - remote_device_ = &device; - found_latch.CountDown(); - }}); - found_latch.Await(); - SetTryToCancelOngoingPairing(false); - env_.Sync(); - } - - void TearDown() override { - env_.Sync(false); - executor_.Shutdown(); - fast_pair_pairer_.reset(); - FastPairHandshakeLookup::GetInstance()->Clear(); - mediums_.reset(); - account_manager_.reset(); - device_.reset(); - remote_device_ = nullptr; - key_based_characteristic_ = std::nullopt; - passkey_characteristic_ = std::nullopt; - SetTryToCancelOngoingPairing(false); - - adapter_provider_->SetStatus(BluetoothAdapter::Status::kDisabled); - gatt_server_->Stop(); - gatt_server_.reset(); - bt_provider_.reset(); - ble_provider_.reset(); - env_.Sync(false); - adapter_provider_.reset(); - env_.Stop(); - } - - void LogInAccount() { - AccountManager::Account account; - account.id = kTestAccountId; - account_manager_->SetAccount(account); - } - - void CreateMockDevice(DeviceFastPairVersion version, Protocol protocol) { - device_ = std::make_unique( - kMetadataId, remote_device_->GetMacAddress(), protocol); - proto::GetObservedDeviceResponse response; - auto metadata = response.mutable_device(); - if (version == DeviceFastPairVersion::kHigherThanV1) { - std::string decoded_key; - absl::Base64Unescape(kPublicAntiSpoof, &decoded_key); - CHECK_EQ(decoded_key.length(), kPublicKeyByteSize); - metadata->mutable_anti_spoofing_key_pair()->set_public_key(decoded_key); - } - device_->SetMetadata(DeviceMetadata(response)); - if (version == DeviceFastPairVersion::kV1) { - device_->SetPublicAddress(remote_device_->GetMacAddress()); - } - if (protocol == Protocol::kFastPairSubsequentPairing) { - device_->SetAccountKey(AccountKey(account_key_)); - } - } - - void ConfigurePairingContext() { - api::PairingParams pairing_params; - pairing_params.pairing_type = - api::PairingParams::PairingType::kConfirmPasskey; - pairing_params.passkey = kPasskey; - env_.ConfigBluetoothPairingContext(&remote_device_->GetImpl(), - pairing_params); - } - - void CreateFastPairHandshakeInstanceForDevice() { - FastPairHandshakeLookup::SetCreateFunctionForTesting(absl::bind_front( - &FastPairPairerImplTest::CreateConnectedHandshake, this)); - - CountDownLatch latch(1); - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Create( - *device_, *mediums_, - [&](FastPairDevice& cb_device, std::optional failure) { - latch.CountDown(); - }, - &executor_)); - latch.Await(); - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_.get())); - } - - std::unique_ptr CreateConnectedHandshake( - FastPairDevice& device, Mediums& mediums, - FastPairHandshake::OnCompleteCallback callback) { - CountDownLatch latch(1); - auto handshake = std::make_unique( - device, mediums, - [&](FastPairDevice& callback_device, - std::optional failure) { - EXPECT_EQ(device_.get(), &callback_device); - EXPECT_EQ(failure, std::nullopt); - callback(callback_device, failure); - latch.CountDown(); - }, - &executor_); - latch.Await(); - EXPECT_TRUE(handshake->completed_successfully()); - EXPECT_EQ( - device_->GetPublicAddress().value(), - device::CanonicalizeBluetoothAddress(remote_device_->GetMacAddress())); - return handshake; - } - - // Sets upprovider's gatt_server. - void SetupProviderGattServer() { - ble_provider_ = std::make_unique(*adapter_provider_); - gatt_server_ = ble_provider_->StartGattServer( - /*ServerGattConnectionCallback=*/{ - .on_characteristic_write_cb = - [&](const api::ble_v2::BlePeripheral& remote_device, - const api::ble_v2::GattCharacteristic& characteristic, - int offset, absl::string_view data, - BleV2Medium::ServerGattConnectionCallback:: - WriteValueCallback callback) { - MutexLock lock(&mutex_); - auto it = characteristics_.find(characteristic); - if (it == characteristics_.end()) { - callback(absl::NotFoundError("characteristic not found")); - return; - } - // Try to cancel an ongoing pairing - if (try_to_cancel_ongoing_pairing_ && - characteristic == *passkey_characteristic_) { - fast_pair_pairer_->CancelPairing(); - } - callback(it->second.write_result); - if (it->second.notify_response.has_value()) { - auto ignored = gatt_server_->NotifyCharacteristicChanged( - characteristic, false, - ByteArray(*it->second.notify_response)); - } - }}); - // Insert fast pair related gatt characteristics - MutexLock lock(&mutex_); - key_based_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kKeyBasedCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*key_based_characteristic_].write_result = - absl::OkStatus(); - - passkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kPasskeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*passkey_characteristic_].write_result = absl::OkStatus(); - - accountkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kAccountKeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*accountkey_characteristic_].write_result = - absl::OkStatus(); - } - - void SetNotifyResponse(GattCharacteristic characteristic, - absl::string_view response) { - MutexLock lock(&mutex_); - CHECK(characteristics_.find(characteristic) != characteristics_.end()); - characteristics_[characteristic].notify_response = response; - } - - void SetDecryptedResponse() { - std::array address_bytes; - device::ParseBluetoothAddress( - device::CanonicalizeBluetoothAddress(remote_device_->GetMacAddress()), - absl::MakeSpan(address_bytes.data(), address_bytes.size())); - DecryptedResponse decrypted_response( - FastPairMessageType::kKeyBasedPairingResponse, address_bytes, salt); - fake_data_encryptor_factory_.SetResponse(std::move(decrypted_response)); - } - - void SetDecryptedPasskey(absl::string_view passkey = kPasskey, - FastPairMessageType message_type = - FastPairMessageType::kProvidersPasskey) { - // Random salt - std::array salt = {0x08, 0x09, 0x0A, 0x08, 0x09, 0x0E, - 0x0A, 0x0C, 0x0D, 0x0E, 0x05, 0x02}; - - DecryptedPasskey decrypted_passkey(message_type, - std::stoi(std::string(passkey)), salt); - fake_data_encryptor_factory_.SetPasskey(std::move(decrypted_passkey)); - } - - bool SetPairingResult( - std::optional error) { - return env_.SetPairingResult(&remote_device_->GetImpl(), error); - } - - void SetPasskeyCharacteristicsWriteResultToFailure() { - MutexLock lock(&mutex_); - auto it = characteristics_.find(*passkey_characteristic_); - it->second.write_result = absl::UnknownError("Failed to write account key"); - } - - void SetAccountkeyCharacteristicsWriteResultToFailure() { - MutexLock lock(&mutex_); - auto it = characteristics_.find(*accountkey_characteristic_); - it->second.write_result = absl::UnknownError("Failed to write account key"); - } - - void SetTryToCancelOngoingPairing(bool enable) { - MutexLock lock(&mutex_); - try_to_cancel_ongoing_pairing_ = enable; - } - - protected: - const std::vector account_key_{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, - 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, - 0xCC, 0xDD, 0xEE, 0xFF}; - std::unique_ptr mediums_; - std::unique_ptr device_; - BluetoothDevice* remote_device_ = nullptr; - std::unique_ptr fast_pair_pairer_; - FastPairFakeDataEncryptorImplFactory fake_data_encryptor_factory_; - SingleThreadExecutor executor_; - std::unique_ptr account_manager_; - std::optional key_based_characteristic_; - std::optional passkey_characteristic_; - std::optional accountkey_characteristic_; - bool try_to_cancel_ongoing_pairing_ ABSL_GUARDED_BY(mutex_); - - private: - MediumEnvironment& env_{MediumEnvironment::Instance()}; - Mutex mutex_; - std::unique_ptr bt_provider_; - std::unique_ptr adapter_provider_; - std::unique_ptr gatt_server_; - std::unique_ptr ble_provider_; - - absl::flat_hash_map characteristics_ - ABSL_GUARDED_BY(mutex_); - Property properties_ = Property::kWrite | Property::kNotify; - Permission permissions_ = Permission::kWrite; -}; - -TEST_F(FastPairPairerImplTest, - SuccessInitialPairingWithDeviceVersionHigherThanV1) { - LogInAccount(); - auto repository = std::make_unique(); - repository->SetResultOfIsDeviceSavedToAccount( - absl::NotFoundError("not found")); - repository->SetResultOfWriteAccountAssociationToFootprints(absl::OkStatus()); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch paired_latch(1); - CountDownLatch complete_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { paired_latch.CountDown(); }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { - EXPECT_TRUE(device.GetAccountKey().Ok()); - complete_latch.CountDown(); - }); - fast_pair_pairer_->StartPairing(); - - paired_latch.Await(); - complete_latch.Await(); - EXPECT_TRUE(fast_pair_pairer_->IsPaired()); - EXPECT_TRUE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, SuccessInitialPairingWithDeviceV1) { - LogInAccount(); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - - CountDownLatch paired_latch(1); - CountDownLatch complete_latch(1); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { paired_latch.CountDown(); }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { - EXPECT_FALSE(device.GetAccountKey().Ok()); - complete_latch.CountDown(); - }); - fast_pair_pairer_->StartPairing(); - - paired_latch.Await(); - complete_latch.Await(); - EXPECT_TRUE(fast_pair_pairer_->IsPaired()); -} - -TEST_F(FastPairPairerImplTest, SuccessSubsequentPairingWithDevice) { - LogInAccount(); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairSubsequentPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch paired_latch(1); - CountDownLatch complete_latch(1); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { paired_latch.CountDown(); }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { - EXPECT_TRUE(device.GetAccountKey().Ok()); - complete_latch.CountDown(); - }); - fast_pair_pairer_->StartPairing(); - - paired_latch.Await(); - complete_latch.Await(); - EXPECT_TRUE(fast_pair_pairer_->IsPaired()); -} - -TEST_F(FastPairPairerImplTest, SuccessRetroactivePairingWithDevice) { - LogInAccount(); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairRetroactivePairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetDecryptedResponse(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch complete_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { FAIL() << "Unexpected callback"; }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { - EXPECT_TRUE(device.GetAccountKey().Ok()); - complete_latch.CountDown(); - }); - fast_pair_pairer_->StartPairing(); - - complete_latch.Await(); - EXPECT_TRUE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, FailedToUnPair) { - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetDecryptedResponse(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch failure_latch(1); - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { FAIL() << "Unexpected callback"; }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kPairingAndConnect); - failure_latch.CountDown(); - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { - EXPECT_TRUE(device.GetAccountKey().Ok()); - FAIL() << "Unexpected callback"; - }); - fast_pair_pairer_->StartPairing(); - - failure_latch.Await(); - - EXPECT_FALSE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, FailedToPairingWithAuthTimeout) { - ConfigurePairingContext(); - SetPairingResult(api::BluetoothPairingCallback::PairingError::kAuthTimeout); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { FAIL() << "Unexpected callback"; }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kPairingAndConnect); - failure_latch.CountDown(); - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { FAIL() << "Unexpected callback"; }); - fast_pair_pairer_->StartPairing(); - - failure_latch.Await(); - - EXPECT_FALSE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, NoPasskeyResponse) { - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetDecryptedResponse(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { FAIL() << "Unexpected callback"; }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kPasskeyResponseTimeout); - failure_latch.CountDown(); - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { FAIL() << "Unexpected callback"; }); - fast_pair_pairer_->StartPairing(); - - failure_latch.Await(); - - EXPECT_FALSE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, PasskeyMismatch) { - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey("654321"); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { FAIL() << "Unexpected callback"; }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kPasskeyMismatch); - failure_latch.CountDown(); - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { FAIL() << "Unexpected callback"; }); - fast_pair_pairer_->StartPairing(); - - failure_latch.Await(); - - EXPECT_FALSE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, ReceiveWithWrongPasskeyResponse) { - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kWrongResponse); - SetDecryptedResponse(); - CreateFastPairHandshakeInstanceForDevice(); - - SetPairingResult(std::nullopt); - - CountDownLatch failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { FAIL() << "Unexpected callback"; }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kPasskeyDecryptFailure); - failure_latch.CountDown(); - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { FAIL() << "Unexpected callback"; }); - fast_pair_pairer_->StartPairing(); - - failure_latch.Await(); - - EXPECT_FALSE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, ReceiveWithWrongPasskeyMessageType) { - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(kPasskey, FastPairMessageType::kSeekersPasskey); - CreateFastPairHandshakeInstanceForDevice(); - - SetPairingResult(std::nullopt); - - CountDownLatch failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { FAIL() << "Unexpected callback"; }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kIncorrectPasskeyResponseType); - failure_latch.CountDown(); - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { FAIL() << "Unexpected callback"; }); - fast_pair_pairer_->StartPairing(); - - failure_latch.Await(); - - EXPECT_FALSE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, SkipWriteAccountKeyBecauseNoLoggedInUser) { - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch paired_latch(1); - CountDownLatch complete_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { paired_latch.CountDown(); }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { - EXPECT_FALSE(device.GetAccountKey().Ok()); - complete_latch.CountDown(); - }); - fast_pair_pairer_->StartPairing(); - paired_latch.Await(); - complete_latch.Await(kWaitTimeout).result(); - EXPECT_TRUE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, - SkipWriteAccountKeyBecauseDeviceAlreadySavedToAccount) { - LogInAccount(); - auto repository = std::make_unique(); - repository->SetResultOfIsDeviceSavedToAccount(absl::OkStatus()); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch paired_latch(1); - CountDownLatch complete_latch(1); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { paired_latch.CountDown(); }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { - EXPECT_FALSE(device.GetAccountKey().Ok()); - complete_latch.CountDown(); - }); - fast_pair_pairer_->StartPairing(); - paired_latch.Await(); - complete_latch.Await(); - EXPECT_TRUE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, - SuccessPairingWithDeviceButFailedToWriteAccountkeyToRemoteDevice) { - LogInAccount(); - auto repository = std::make_unique(); - repository->SetResultOfIsDeviceSavedToAccount( - absl::NotFoundError("not found")); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - SetAccountkeyCharacteristicsWriteResultToFailure(); - - CountDownLatch paired_latch(1); - CountDownLatch complete_latch(1); - CountDownLatch failure_latch(1); - CountDownLatch account_failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { paired_latch.CountDown(); }, - [&](FastPairDevice& device, PairFailure failure) { - failure_latch.CountDown(); - }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kAccountKeyCharacteristicWrite); - account_failure_latch.CountDown(); - }, - [&](FastPairDevice& device) { - EXPECT_TRUE(device.GetAccountKey().Ok()); - complete_latch.CountDown(); - }); - fast_pair_pairer_->StartPairing(); - paired_latch.Await(); - EXPECT_FALSE(failure_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(complete_latch.Await(kWaitTimeout).result()); - account_failure_latch.Await(); - EXPECT_TRUE(fast_pair_pairer_->IsPaired()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, - SuccessPairingWithDeviceButFailedToWriteAccountkeyToFootprints) { - LogInAccount(); - auto repository = std::make_unique(); - repository->SetResultOfIsDeviceSavedToAccount( - absl::NotFoundError("not found")); - repository->SetResultOfWriteAccountAssociationToFootprints( - absl::InternalError("Failed to write account key to foot prints")); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch paired_latch(1); - CountDownLatch account_failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { paired_latch.CountDown(); }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kWriteAccountKeyToFootprints); - account_failure_latch.CountDown(); - }, - [&](FastPairDevice& device) { FAIL() << "Unexpected callback"; }); - fast_pair_pairer_->StartPairing(); - - paired_latch.Await(); - account_failure_latch.Await(); - EXPECT_TRUE(fast_pair_pairer_->IsPaired()); - EXPECT_TRUE(device_->GetAccountKey().Ok()); -} - -TEST_F(FastPairPairerImplTest, TestCancelPairing) { - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetDecryptedResponse(); - CreateFastPairHandshakeInstanceForDevice(); - SetTryToCancelOngoingPairing(true); - - CountDownLatch failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - fast_pair_pairer_ = FastPairPairerImpl::Factory::Create( - *device_, *mediums_, &executor_, account_manager_.get(), - [&](FastPairDevice& cb_device) { FAIL() << "Unexpected callback"; }, - [&](FastPairDevice& device, PairFailure failure) { - EXPECT_EQ(failure, PairFailure::kPairingAndConnect); - failure_latch.CountDown(); - }, - [&](FastPairDevice& device, PairFailure failure) { - FAIL() << "Unexpected pairing failure " << failure; - }, - [&](FastPairDevice& device) { FAIL() << "Unexpected callback"; }); - fast_pair_pairer_->StartPairing(); - - failure_latch.Await(); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/pairing/pairer_broker.h b/fastpair/pairing/pairer_broker.h deleted file mode 100644 index 0020a52da5..0000000000 --- a/fastpair/pairing/pairer_broker.h +++ /dev/null @@ -1,55 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_PAIRER_BROKER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_PAIRER_BROKER_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/pair_failure.h" - -namespace nearby { -namespace fastpair { - -// The PairerBroker is the entry point for the Fast Pair Pairing component. -// It is responsible for brokering the 'pair to device' calls to -// the correct concrete Pairer implementation, and exposing an observer pattern -// for other components to become aware of pairing results. - -class PairerBroker { - public: - class Observer { - public: - virtual ~Observer() = default; - virtual void OnHandshakeComplete(FastPairDevice& device) {} - virtual void OnDevicePaired(FastPairDevice& device) {} - virtual void OnAccountKeyWrite(FastPairDevice& device, - std::optional error) {} - virtual void OnPairingComplete(FastPairDevice& device) {} - virtual void OnPairFailure(FastPairDevice& device, PairFailure failure) {} - }; - - virtual ~PairerBroker() = default; - - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; - virtual void PairDevice(FastPairDevice& device) = 0; - virtual bool IsPairing() = 0; - virtual void StopPairing() = 0; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_PAIRER_BROKER_H_ diff --git a/fastpair/pairing/pairer_broker_impl.cc b/fastpair/pairing/pairer_broker_impl.cc deleted file mode 100644 index 12ba5a191e..0000000000 --- a/fastpair/pairing/pairer_broker_impl.cc +++ /dev/null @@ -1,338 +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. - -#include "fastpair/pairing/pairer_broker_impl.h" - -#include -#include -#include -#include - -#include "absl/synchronization/mutex.h" -#include "fastpair//handshake/fast_pair_handshake_lookup.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/pairing/fastpair/fast_pair_pairer_impl.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/platform/timer_impl.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr int kMaxFailureRetryCount = 3; -constexpr int kMaxNumHandshakeAttempts = 3; -constexpr absl::Duration kCancelPairingRetryDelay = absl::Seconds(1); -constexpr absl::Duration kRetryHandshakeDelay = absl::Seconds(1); -} // namespace - -PairerBrokerImpl::PairerBrokerImpl(Mediums& medium, - SingleThreadExecutor* executor, - AccountManager* account_manager) - : medium_(medium), executor_(executor), account_manager_(account_manager) {} - -void PairerBrokerImpl::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void PairerBrokerImpl::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -void PairerBrokerImpl::PairDevice(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": Start to pair with device=" << device; - { - MutexLock lock(&mutex_); - model_id_to_current_ble_address_map_.insert_or_assign( - std::string(device.GetModelId()), std::string(device.GetBleAddress())); - did_handshake_previously_complete_successfully_map_.insert_or_assign( - std::string(device.GetModelId()), false); - } - PairFastPairDevice(device); -} - -void PairerBrokerImpl::PairFastPairDevice(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__; - { - MutexLock lock(&mutex_); - if (fast_pair_pairers_.contains(device.GetModelId())) { - NEARBY_LOGS(WARNING) << __func__ << ": Already pairing with device" - << device; - return; - } - } - - CHECK(device.GetVersion().has_value()); - if (device.GetVersion().value() == DeviceFastPairVersion::kV1) { - // For v1 headsets, the ble address is the same as the public address. - // So skip straight to 'StartBondingAttempt'. - NEARBY_LOGS(INFO) << __func__ << " : Pairing with v1 device."; - device.SetPublicAddress(device.GetBleAddress()); - StartPairingAttempt(device); - return; - } - NEARBY_LOGS(INFO) << __func__ << " : Pairing with device higher than v1."; - // For headsets higher than v1, try to create a handshake with the remote - // device to request its public address. - CreateHandshake(device); -} - -void PairerBrokerImpl::CreateHandshake(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__; - { - MutexLock lock(&mutex_); - if (device.GetBleAddress() != - model_id_to_current_ble_address_map_[device.GetModelId()]) { - // If the current |device| has a different BLE Address than the address in - // the map, abort creating the handshake and return early; - NEARBY_LOGS(INFO) - << __func__ - << ": The device's BLE did not match the expected value, returning."; - return; - } - } - - auto* fast_pair_handshake = - FastPairHandshakeLookup::GetInstance()->Get(&device); - if (fast_pair_handshake) { - if (fast_pair_handshake->completed_successfully()) { - NEARBY_LOGS(INFO) << __func__ - << ": Reusing existing handshake for pair attempt."; - StartPairingAttempt(device); - return; - } - // If the previous handshake did not complete successfully, erase it - // before attempting to create a new handshake for the device. - FastPairHandshakeLookup::GetInstance()->Erase(&device); - } - - NEARBY_LOGS(INFO) << __func__ << ": Creating new handshake for pair attempt."; - FastPairHandshakeLookup::GetInstance()->Create( - device, medium_, - [&](FastPairDevice& cb_device, std::optional failure) { - executor_->Execute("OnHandshakeComplete", - [&, failure = std::move(failure)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnHandshakeComplete(cb_device, failure); - }); - }, - executor_); -} - -void PairerBrokerImpl::OnHandshakeComplete(FastPairDevice& device, - std::optional failure) { - NEARBY_LOGS(INFO) << __func__; - if (failure.has_value()) { - OnHandshakeFailure(device, failure.value()); - return; - } - if (!device.GetPublicAddress().has_value()) { - NEARBY_LOGS(WARNING) << __func__ << ": Device lost during handshake."; - OnHandshakeFailure(device, PairFailure::kDeviceLostMidPairing); - return; - } - { - MutexLock lock(&mutex_); - if (!did_handshake_previously_complete_successfully_map_ - [device.GetModelId()]) { - for (auto& observer : observers_.GetObservers()) { - observer->OnHandshakeComplete(device); - } - - did_handshake_previously_complete_successfully_map_.insert_or_assign( - device.GetModelId(), true); - } - // Reset |num_handshake_attempts_| - num_handshake_attempts_[device.GetModelId()] = 0; - } - StartPairingAttempt(device); -} - -void PairerBrokerImpl::OnHandshakeFailure(FastPairDevice& device, - PairFailure failure) { - NEARBY_LOGS(WARNING) << __func__ - << ": Handshake failed with device because: " << failure; - { - MutexLock lock(&mutex_); - if (++num_handshake_attempts_[device.GetModelId()] < - kMaxNumHandshakeAttempts) { - retry_handshake_timer_ = std::make_unique(); - retry_handshake_timer_->Start( - kRetryHandshakeDelay / absl::Milliseconds(1), 0, - [&]() { CreateHandshake(device); }); - return; - } - } - NEARBY_LOGS(WARNING) - << __func__ << ": Handshake failed to be created. Notifying observers."; - for (auto& observer : observers_.GetObservers()) { - observer->OnPairFailure(device, failure); - } - FastPairHandshakeLookup::GetInstance()->Erase(&device); -} - -void PairerBrokerImpl::StartPairingAttempt(FastPairDevice& device) { - { - MutexLock lock(&mutex_); - if (!pair_failure_counts_.contains(device.GetModelId())) { - pair_failure_counts_[device.GetModelId()] = 0; - } - } - - NEARBY_LOGS(INFO) << __func__ << ": " << device; - MutexLock lock(&mutex_); - // Create FastPairPairer instance and start pairing. - fast_pair_pairers_[device.GetModelId()] = FastPairPairerImpl::Factory::Create( - device, medium_, executor_, account_manager_, - [&](FastPairDevice& cb_device) { - executor_->Execute("OnFastPairDevicePaired", - [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnFastPairDevicePaired(cb_device); - }); - }, - [&](FastPairDevice& cb_device, PairFailure failure) { - executor_->Execute("OnFastPairPairingFailure", - [&, failure = std::move(failure)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnFastPairPairingFailure(cb_device, failure); - }); - }, - [&](FastPairDevice& cb_device, PairFailure failure) { - executor_->Execute("OnAccountKeyFailure", - [&, failure = std::move(failure)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnAccountKeyFailure(cb_device, failure); - }); - }, - [&](FastPairDevice& cb_device) { - executor_->Execute("OnFastPairProcedureComplete", - [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnFastPairProcedureComplete(cb_device); - }); - }); - fast_pair_pairers_[device.GetModelId()]->StartPairing(); -} - -void PairerBrokerImpl::OnFastPairDevicePaired(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": Device=" << device; - for (auto& observer : observers_.GetObservers()) { - observer->OnDevicePaired(device); - } - MutexLock lock(&mutex_); - pair_failure_counts_.erase(device.GetModelId()); -} - -void PairerBrokerImpl::OnFastPairPairingFailure(FastPairDevice& device, - PairFailure failure) { - { - MutexLock lock(&mutex_); - ++pair_failure_counts_[device.GetModelId()]; - NEARBY_LOGS(INFO) << __func__ << ": Device=" << device - << ", Failure=" << failure << ", Failure Count = " - << pair_failure_counts_[device.GetModelId()]; - if (pair_failure_counts_[device.GetModelId()] == kMaxFailureRetryCount) { - if (!fast_pair_pairers_[device.GetModelId()]->IsPaired()) { - fast_pair_pairers_[device.GetModelId()]->CancelPairing(); - } - executor_->Execute("EraseHandshakeAndPairers", - [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - EraseHandshakeAndPairers(device); - }); - NEARBY_LOGS(INFO) << __func__ - << ": Reached max failure count. Notifying observers."; - for (auto& observer : observers_.GetObservers()) { - observer->OnPairFailure(device, failure); - } - return; - } - - if (!fast_pair_pairers_[device.GetModelId()]->IsPaired()) { - NEARBY_LOGS(INFO) << __func__ - << ": Cancelling pairing and scheduling retry " - "for failed pair attempt."; - fast_pair_pairers_[device.GetModelId()]->CancelPairing(); - fast_pair_pairers_.erase(device.GetModelId()); - // Create a timer to wait |kCancelPairingRetryDelay| after cancelling - // pairing to retry the pairing attempt. - cancel_pairing_timer_ = std::make_unique(); - cancel_pairing_timer_->Start( - kCancelPairingRetryDelay / absl::Milliseconds(1), 0, - [&]() { PairFastPairDevice(device); }); - return; - } - fast_pair_pairers_.erase(device.GetModelId()); - } - PairFastPairDevice(device); -} - -void PairerBrokerImpl::OnAccountKeyFailure(FastPairDevice& device, - PairFailure failure) { - NEARBY_LOGS(INFO) << __func__ << ": Device=" << device - << ", Failure=" << failure; - executor_->Execute("EraseHandshakeAndPairers", - [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - EraseHandshakeAndPairers(device); - }); - for (auto& observer : observers_.GetObservers()) { - observer->OnAccountKeyWrite(device, failure); - } -} - -void PairerBrokerImpl::OnFastPairProcedureComplete(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": Device=" << device; - executor_->Execute("EraseHandshakeAndPairers", - [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - EraseHandshakeAndPairers(device); - }); - for (auto& observer : observers_.GetObservers()) { - observer->OnPairingComplete(device); - } - // If we get to this point in the flow for the initial and retroactive - // pairing scenarios, this means that the account key has successfully - // been written for devices with a version of V2 or higher. - if (device.GetVersion().has_value() && - device.GetVersion().value() == DeviceFastPairVersion::kHigherThanV1 && - device.GetAccountKey().Ok() && - (device.GetProtocol() == Protocol::kFastPairInitialPairing || - device.GetProtocol() == Protocol::kFastPairRetroactivePairing)) { - for (auto& observer : observers_.GetObservers()) { - observer->OnAccountKeyWrite(device, /*error=*/std::nullopt); - } - } -} - -void PairerBrokerImpl::EraseHandshakeAndPairers(FastPairDevice& device) { - MutexLock lock(&mutex_); - NEARBY_LOGS(WARNING) << __func__; - // |fast_pair_pairers_| and its children objects depend on the handshake - // instance. Shut them down before destroying the handshake. - pair_failure_counts_.erase(device.GetModelId()); - fast_pair_pairers_.erase(device.GetModelId()); - FastPairHandshakeLookup::GetInstance()->Erase(&device); - did_handshake_previously_complete_successfully_map_.insert_or_assign( - std::string(device.GetModelId()), false); -} - -bool PairerBrokerImpl::IsPairing() { - MutexLock lock(&mutex_); - // We are guaranteed to not be pairing when the following two maps are - // empty. - return !fast_pair_pairers_.empty() || !pair_failure_counts_.empty(); -} - -void PairerBrokerImpl::StopPairing() { - MutexLock lock(&mutex_); - fast_pair_pairers_.clear(); - pair_failure_counts_.clear(); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/pairing/pairer_broker_impl.h b/fastpair/pairing/pairer_broker_impl.h deleted file mode 100644 index 3fc28106f1..0000000000 --- a/fastpair/pairing/pairer_broker_impl.h +++ /dev/null @@ -1,104 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_PAIRER_BROKER_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_PAIRER_BROKER_IMPL_H_ - -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/pairing/fastpair/fast_pair_pairer.h" -#include "fastpair/pairing/pairer_broker.h" -#include "internal/base/observer_list.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/platform/timer_impl.h" - -namespace nearby { -namespace fastpair { - -class PairerBrokerImpl : public PairerBroker { - public: - explicit PairerBrokerImpl(Mediums& medium, SingleThreadExecutor* executor, - AccountManager* account_manager); - PairerBrokerImpl(const PairerBrokerImpl&) = delete; - PairerBrokerImpl& operator=(const PairerBrokerImpl&) = delete; - - // PairingBroker: - void AddObserver(Observer* observer) override; - // The `observer` can still be called after removing if it has already - // been scheduled to run (or is running) on the background thread. - void RemoveObserver(Observer* observer) override; - void PairDevice(FastPairDevice& device) override; - bool IsPairing() override; - void StopPairing() override; - - friend class PairerBrokerImplTest; - - private: - mutable Mutex mutex_; - void PairFastPairDevice(FastPairDevice& device); - void CreateHandshake(FastPairDevice& device); - void OnHandshakeComplete(FastPairDevice& device, - std::optional failure) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void OnHandshakeFailure(FastPairDevice& device, PairFailure failure) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - - void StartPairingAttempt(FastPairDevice& device); - - void OnFastPairDevicePaired(FastPairDevice& device) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void OnFastPairPairingFailure(FastPairDevice& device, PairFailure failure) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void OnFastPairProcedureComplete(FastPairDevice& device) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void OnAccountKeyFailure(FastPairDevice& device, PairFailure failure) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - - void EraseHandshakeAndPairers(FastPairDevice& device) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - - Mediums& medium_; - SingleThreadExecutor* executor_; - AccountManager* account_manager_; - - // The key for all the following maps is a device model id. - absl::flat_hash_map> - fast_pair_pairers_ ABSL_GUARDED_BY(mutex_); - absl::flat_hash_map pair_failure_counts_ - ABSL_GUARDED_BY(mutex_); - absl::flat_hash_map - did_handshake_previously_complete_successfully_map_ - ABSL_GUARDED_BY(mutex_); - absl::flat_hash_map num_handshake_attempts_ - ABSL_GUARDED_BY(mutex_); - absl::flat_hash_map - model_id_to_current_ble_address_map_ ABSL_GUARDED_BY(mutex_); - - // Timer - std::unique_ptr cancel_pairing_timer_; - std::unique_ptr retry_handshake_timer_; - - ObserverList observers_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_PAIRING_PAIRER_BROKER_IMPL_H_ diff --git a/fastpair/pairing/pairer_broker_impl_test.cc b/fastpair/pairing/pairer_broker_impl_test.cc deleted file mode 100644 index 4a138f3163..0000000000 --- a/fastpair/pairing/pairer_broker_impl_test.cc +++ /dev/null @@ -1,760 +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. - -#include "fastpair/pairing/pairer_broker_impl.h" - -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/functional/bind_front.h" -#include "fastpair//handshake/fast_pair_handshake_lookup.h" -#include "fastpair/common/pair_failure.h" -#include "fastpair/crypto/decrypted_passkey.h" -#include "fastpair/crypto/decrypted_response.h" -#include "fastpair/crypto/fast_pair_message_type.h" -#include "fastpair/handshake/fake_fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_data_encryptor.h" -#include "fastpair/handshake/fast_pair_data_encryptor_impl.h" -#include "fastpair/handshake/fast_pair_handshake_impl.h" -#include "fastpair/handshake/fast_pair_handshake_lookup.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/repository/fake_fast_pair_repository.h" -#include "internal/base/bluetooth_address.h" -#include "internal/platform/ble_v2.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" -#include "internal/test/fake_account_manager.h" - -namespace nearby { -namespace fastpair { -namespace { -using Property = nearby::api::ble_v2::GattCharacteristic::Property; -using Permission = nearby::api::ble_v2::GattCharacteristic::Permission; -using ::nearby::api::ble_v2::GattCharacteristic; -using DiscoveryCallback = BluetoothClassicMedium::DiscoveryCallback; - -constexpr absl::string_view kFastPairPreferencesFilePath = - "Google/Nearby/FastPair"; -constexpr absl::string_view kTestAccountId = "test_account_id"; -constexpr absl::string_view kMetadataId("718c17"); -constexpr absl::string_view kPublicAntiSpoof = - "Wuyr48lD3txnUhGiMF1IfzlTwRxxe+wMB1HLzP+" - "0wVcljfT3XPoiy1fntlneziyLD5knDVAJSE+RM/zlPRP/Jg=="; -constexpr Uuid kFastPairServiceUuid(0x0000FE2C00001000, 0x800000805F9B34FB); -constexpr Uuid kKeyBasedCharacteristicUuidV2(0xFE2C123483664814, - 0x8EB001DE32100BEA); -constexpr Uuid kPasskeyCharacteristicUuidV2(0xFE2C123583664814, - 0x8EB001DE32100BEA); -constexpr Uuid kAccountKeyCharacteristicUuidV2(0xFE2C123683664814, - 0x8EB001DE32100BEA); -constexpr absl::string_view kKeyBasedResponse("keybasedresponse"); -constexpr absl::string_view kPasskeyResponse("passkeyresponse"); -constexpr absl::string_view kPasskey("123456"); -constexpr std::array salt = {0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x00}; -constexpr absl::Duration kWaitTimeout = absl::Milliseconds(200); -} // namespace - -class FastPairFakeDataEncryptorImplFactory - : public FastPairDataEncryptorImpl::Factory { - public: - void CreateInstance( - const FastPairDevice& device, - absl::AnyInvocable)> - on_get_instance_callback) override { - if (!successful_retrieval_) { - std::move(on_get_instance_callback)(nullptr); - return; - } - - auto data_encryptor = std::make_unique(); - data_encryptor_ = data_encryptor.get(); - data_encryptor->SetResponse(response_); - data_encryptor->SetPasskey(passkey_); - std::move(on_get_instance_callback)(std::move(data_encryptor)); - } - - FakeFastPairDataEncryptor* data_encryptor() { return data_encryptor_; } - - void SetFailedRetrieval() { successful_retrieval_ = false; } - - void SetResponse(std::optional response) { - response_ = std::move(response); - } - - void SetPasskey(std::optional passkey) { - passkey_ = std::move(passkey); - } - - private: - FakeFastPairDataEncryptor* data_encryptor_ = nullptr; - bool successful_retrieval_ = true; - std::optional response_; - std::optional passkey_; -}; - -struct CharacteristicData { - // Write result returned to the gatt client. - absl::Status write_result; - std::optional notify_response; -}; - -class PairerBrokerObserver : public PairerBroker::Observer { - public: - PairerBrokerObserver(PairerBroker* pairer_broker, - CountDownLatch* device_paired_latch, - CountDownLatch* account_key_writed_latch, - CountDownLatch* pairing_completed_latch, - CountDownLatch* pairing_failure_latch) - : pairer_broker_(pairer_broker), - device_paired_latch_(device_paired_latch), - account_key_writed_latch_(account_key_writed_latch), - pairing_completed_latch_(pairing_completed_latch), - pairing_failure_latch_(pairing_failure_latch) { - pairer_broker_->AddObserver(this); - } - - ~PairerBrokerObserver() override { pairer_broker_->RemoveObserver(this); } - - void OnHandshakeComplete(FastPairDevice& device) override { - NEARBY_LOGS(INFO) << __func__; - handshake_completed_ = true; - } - - void OnDevicePaired(FastPairDevice& device) override { - NEARBY_LOGS(INFO) << __func__; - device_paired_latch_->CountDown(); - } - - void OnAccountKeyWrite(FastPairDevice& device, - std::optional error) override { - NEARBY_LOGS(INFO) << __func__; - if (error.has_value()) { - account_key_failure_ = error.value(); - } - account_key_writed_latch_->CountDown(); - } - - void OnPairingComplete(FastPairDevice& device) override { - NEARBY_LOGS(INFO) << __func__; - pairing_completed_latch_->CountDown(); - } - - void OnPairFailure(FastPairDevice& device, PairFailure failure) override { - pair_failure_ = failure; - pairing_failure_latch_->CountDown(); - } - - PairerBroker* pairer_broker_; - bool handshake_completed_ = false; - CountDownLatch* device_paired_latch_ = nullptr; - CountDownLatch* account_key_writed_latch_ = nullptr; - CountDownLatch* pairing_completed_latch_ = nullptr; - CountDownLatch* pairing_failure_latch_ = nullptr; - PairFailure account_key_failure_ = PairFailure::kUnknown; - PairFailure pair_failure_ = PairFailure::kUnknown; -}; - -class PairerBrokerImplTest : public testing::Test { - public: - PairerBrokerImplTest() { - FastPairDataEncryptorImpl::Factory::SetFactoryForTesting( - &fake_data_encryptor_factory_); - } - - void SetUp() override { - env_.Start(); - // Setups seeker device. - mediums_ = std::make_unique(); - account_manager_ = std::make_unique(); - - // Setups provider device. - adapter_provider_ = std::make_unique(); - adapter_provider_->SetStatus(BluetoothAdapter::Status::kEnabled); - adapter_provider_->SetName("Device-Provider"); - adapter_provider_->SetScanMode( - BluetoothAdapter::ScanMode::kConnectableDiscoverable); - bt_provider_ = std::make_unique(*adapter_provider_); - - // Discovering provider device. - CountDownLatch found_latch(1); - mediums_->GetBluetoothClassic().GetMedium().StartDiscovery( - DiscoveryCallback{.device_discovered_cb = [&](BluetoothDevice& device) { - remote_device_ = &device; - found_latch.CountDown(); - }}); - found_latch.Await(); - env_.Sync(); - } - - void TearDown() override { - env_.Sync(false); - executor_.Shutdown(); - pairer_broker_.reset(); - FastPairHandshakeLookup::GetInstance()->Clear(); - mediums_.reset(); - account_manager_.reset(); - device_.reset(); - remote_device_ = nullptr; - key_based_characteristic_ = std::nullopt; - passkey_characteristic_ = std::nullopt; - - adapter_provider_->SetStatus(BluetoothAdapter::Status::kDisabled); - gatt_server_->Stop(); - gatt_server_.reset(); - bt_provider_.reset(); - ble_provider_.reset(); - env_.Sync(false); - adapter_provider_.reset(); - env_.Stop(); - } - - void LogInAccount() { - AccountManager::Account account; - account.id = kTestAccountId; - account_manager_->SetAccount(account); - } - - void CreateMockDevice(DeviceFastPairVersion version, Protocol protocol) { - device_ = std::make_unique( - kMetadataId, remote_device_->GetMacAddress(), protocol); - proto::GetObservedDeviceResponse response; - auto metadata = response.mutable_device(); - if (version == DeviceFastPairVersion::kHigherThanV1) { - std::string decoded_key; - absl::Base64Unescape(kPublicAntiSpoof, &decoded_key); - CHECK_EQ(decoded_key.length(), kPublicKeyByteSize); - metadata->mutable_anti_spoofing_key_pair()->set_public_key(decoded_key); - } - device_->SetMetadata(DeviceMetadata(response)); - if (version == DeviceFastPairVersion::kV1) { - device_->SetPublicAddress(remote_device_->GetMacAddress()); - } - if (protocol == Protocol::kFastPairSubsequentPairing) { - device_->SetAccountKey(AccountKey(account_key_)); - } - } - - void ConfigurePairingContext() { - api::PairingParams pairing_params; - pairing_params.pairing_type = - api::PairingParams::PairingType::kConfirmPasskey; - pairing_params.passkey = kPasskey; - env_.ConfigBluetoothPairingContext(&remote_device_->GetImpl(), - pairing_params); - } - - void CreateFastPairHandshakeInstanceForDevice() { - FastPairHandshakeLookup::SetCreateFunctionForTesting(absl::bind_front( - &PairerBrokerImplTest::CreateConnectedHandshake, this)); - - CountDownLatch latch(1); - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Create( - *device_, *mediums_, - [&](FastPairDevice& cb_device, std::optional failure) { - latch.CountDown(); - }, - &executor_)); - latch.Await(); - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_.get())); - } - - std::unique_ptr CreateConnectedHandshake( - FastPairDevice& device, Mediums& mediums, - FastPairHandshake::OnCompleteCallback callback) { - CountDownLatch latch(1); - auto handshake = std::make_unique( - device, mediums, - [&](FastPairDevice& callback_device, - std::optional failure) { - EXPECT_EQ(device_.get(), &callback_device); - EXPECT_EQ(failure, std::nullopt); - callback(callback_device, failure); - latch.CountDown(); - }, - &executor_); - latch.Await(); - EXPECT_TRUE(handshake->completed_successfully()); - EXPECT_EQ( - device_->GetPublicAddress().value(), - device::CanonicalizeBluetoothAddress(remote_device_->GetMacAddress())); - return handshake; - } - - // Sets upprovider's gatt_server. - void SetupProviderGattServer() { - ble_provider_ = std::make_unique(*adapter_provider_); - gatt_server_ = ble_provider_->StartGattServer( - /*ServerGattConnectionCallback=*/{ - .on_characteristic_write_cb = - [&](const api::ble_v2::BlePeripheral& remote_device, - const api::ble_v2::GattCharacteristic& characteristic, - int offset, absl::string_view data, - BleV2Medium::ServerGattConnectionCallback:: - WriteValueCallback callback) { - MutexLock lock(&mutex_); - auto it = characteristics_.find(characteristic); - if (it == characteristics_.end()) { - callback(absl::NotFoundError("characteristic not found")); - return; - } - callback(it->second.write_result); - if (it->second.notify_response.has_value()) { - auto ignored = gatt_server_->NotifyCharacteristicChanged( - characteristic, false, - ByteArray(*it->second.notify_response)); - } - }}); - - // Insert fast pair related gatt characteristics - MutexLock lock(&mutex_); - key_based_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kKeyBasedCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*key_based_characteristic_].write_result = - absl::OkStatus(); - - passkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kPasskeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*passkey_characteristic_].write_result = absl::OkStatus(); - - accountkey_characteristic_ = gatt_server_->CreateCharacteristic( - kFastPairServiceUuid, kAccountKeyCharacteristicUuidV2, permissions_, - properties_); - characteristics_[*accountkey_characteristic_].write_result = - absl::OkStatus(); - } - - bool SetPairingResult( - std::optional error) { - return env_.SetPairingResult(&remote_device_->GetImpl(), error); - } - - void SetNotifyResponse(GattCharacteristic characteristic, - absl::string_view response) { - MutexLock lock(&mutex_); - CHECK(characteristics_.find(characteristic) != characteristics_.end()); - characteristics_[characteristic].notify_response = response; - } - - void SetDecryptedResponse() { - std::array address_bytes; - device::ParseBluetoothAddress( - device::CanonicalizeBluetoothAddress(remote_device_->GetMacAddress()), - absl::MakeSpan(address_bytes.data(), address_bytes.size())); - DecryptedResponse decrypted_response( - FastPairMessageType::kKeyBasedPairingResponse, address_bytes, salt); - fake_data_encryptor_factory_.SetResponse(std::move(decrypted_response)); - } - - void SetDecryptedPasskey(absl::string_view passkey = kPasskey, - FastPairMessageType message_type = - FastPairMessageType::kProvidersPasskey) { - // Random salt - std::array salt = {0x08, 0x09, 0x0A, 0x08, 0x09, 0x0E, - 0x0A, 0x0C, 0x0D, 0x0E, 0x05, 0x02}; - - DecryptedPasskey decrypted_passkey(message_type, - std::stoi(std::string(passkey)), salt); - fake_data_encryptor_factory_.SetPasskey(std::move(decrypted_passkey)); - } - - void SetPasskeyCharacteristicsWriteResultToFailure() { - MutexLock lock(&mutex_); - auto it = characteristics_.find(*passkey_characteristic_); - it->second.write_result = absl::UnknownError("Failed to write account key"); - } - - void SetAccountkeyCharacteristicsWriteResultToFailure() { - MutexLock lock(&mutex_); - auto it = characteristics_.find(*accountkey_characteristic_); - it->second.write_result = absl::UnknownError("Failed to write account key"); - } - - protected: - const std::vector account_key_{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, - 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, - 0xCC, 0xDD, 0xEE, 0xFF}; - std::unique_ptr mediums_; - std::unique_ptr device_; - BluetoothDevice* remote_device_ = nullptr; - SingleThreadExecutor executor_; - std::unique_ptr account_manager_; - std::unique_ptr pairer_broker_; - std::optional key_based_characteristic_; - std::optional passkey_characteristic_; - std::optional accountkey_characteristic_; - FastPairFakeDataEncryptorImplFactory fake_data_encryptor_factory_; - - private: - MediumEnvironment& env_{MediumEnvironment::Instance()}; - Mutex mutex_; - std::unique_ptr bt_provider_; - std::unique_ptr adapter_provider_; - std::unique_ptr gatt_server_; - std::unique_ptr ble_provider_; - absl::flat_hash_map characteristics_ - ABSL_GUARDED_BY(mutex_); - Property properties_ = Property::kWrite | Property::kNotify; - Permission permissions_ = Permission::kWrite; -}; - -TEST_F(PairerBrokerImplTest, SuccessInitialPairingWithDeviceV1) { - LogInAccount(); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - device_paired_latch.Await(); - pairing_completed_latch.Await(); - EXPECT_FALSE(account_key_writed_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(pairing_failure_latch.Await(kWaitTimeout).result()); -} - -TEST_F(PairerBrokerImplTest, SuccessInitialPairingWithDevice) { - LogInAccount(); - auto repository = std::make_unique(); - repository->SetResultOfIsDeviceSavedToAccount( - absl::NotFoundError("not found")); - repository->SetResultOfWriteAccountAssociationToFootprints(absl::OkStatus()); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - device_paired_latch.Await(); - pairing_completed_latch.Await(); - account_key_writed_latch.Await(); - EXPECT_FALSE(pairing_failure_latch.Await(kWaitTimeout).result()); - EXPECT_TRUE(device_->GetAccountKey().Ok()); - - pairer_broker_->StopPairing(); - EXPECT_FALSE(pairer_broker_->IsPairing()); -} - -TEST_F(PairerBrokerImplTest, SuccessSubsequentPairingWithDevice) { - LogInAccount(); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairSubsequentPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - device_paired_latch.Await(); - pairing_completed_latch.Await(); - EXPECT_FALSE(account_key_writed_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(pairing_failure_latch.Await(kWaitTimeout).result()); - EXPECT_TRUE(pairer_broker_observer.handshake_completed_); -} - -TEST_F(PairerBrokerImplTest, SuccessRetroactivePairingWithDevice) { - LogInAccount(); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairRetroactivePairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetDecryptedResponse(); - CreateFastPairHandshakeInstanceForDevice(); - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - EXPECT_FALSE(device_paired_latch.Await(kWaitTimeout).result()); - pairing_completed_latch.Await(); - account_key_writed_latch.Await(); - EXPECT_FALSE(pairing_failure_latch.Await(kWaitTimeout).result()); - EXPECT_TRUE(device_->GetAccountKey().Ok()); -} - -TEST_F(PairerBrokerImplTest, FaileToCreateHandshakeRetryThreeTimes) { - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairSubsequentPairing); - SetupProviderGattServer(); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - EXPECT_FALSE(device_paired_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(pairing_completed_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(account_key_writed_latch.Await(kWaitTimeout).result()); - pairing_failure_latch.Await(); - EXPECT_FALSE(pairer_broker_observer.handshake_completed_); - - EXPECT_EQ(pairer_broker_observer.pair_failure_, - PairFailure::kKeyBasedPairingResponseTimeout); -} - -TEST_F(PairerBrokerImplTest, SkipWriteAccountKeyBecauseNoLoggedInUser) { - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - device_paired_latch.Await(); - pairing_completed_latch.Await(); - EXPECT_FALSE(account_key_writed_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(pairing_failure_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); -} - -TEST_F(PairerBrokerImplTest, - SkipWriteAccountKeyBecauseDeviceAlreadySavedToAccount) { - LogInAccount(); - auto repository = std::make_unique(); - repository->SetResultOfIsDeviceSavedToAccount(absl::OkStatus()); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - device_paired_latch.Await(); - pairing_completed_latch.Await(); - EXPECT_FALSE(account_key_writed_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(pairing_failure_latch.Await(kWaitTimeout).result()); -} - -TEST_F(PairerBrokerImplTest, FaileToWriteAccountkeyToRemoteDevice) { - LogInAccount(); - auto repository = std::make_unique(); - repository->SetResultOfIsDeviceSavedToAccount( - absl::NotFoundError("not found")); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - SetAccountkeyCharacteristicsWriteResultToFailure(); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - device_paired_latch.Await(); - EXPECT_FALSE(pairing_completed_latch.Await(kWaitTimeout).result()); - account_key_writed_latch.Await(); - EXPECT_FALSE(pairing_failure_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(device_->GetAccountKey().Ok()); - EXPECT_EQ(pairer_broker_observer.account_key_failure_, - PairFailure::kAccountKeyCharacteristicWrite); -} - -TEST_F(PairerBrokerImplTest, FaileToWriteAccountkeyToFootprints) { - LogInAccount(); - auto repository = std::make_unique(); - repository->SetResultOfIsDeviceSavedToAccount( - absl::NotFoundError("not found")); - repository->SetResultOfWriteAccountAssociationToFootprints( - absl::InternalError("Failed to write account key to foot prints")); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey(); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - device_paired_latch.Await(); - EXPECT_FALSE(pairing_completed_latch.Await(kWaitTimeout).result()); - account_key_writed_latch.Await(); - EXPECT_FALSE(pairing_failure_latch.Await(kWaitTimeout).result()); - EXPECT_TRUE(device_->GetAccountKey().Ok()); - EXPECT_EQ(pairer_broker_observer.account_key_failure_, - PairFailure::kWriteAccountKeyToFootprints); -} - -TEST_F(PairerBrokerImplTest, FailToPairRetryThreeTimes) { - LogInAccount(); - ConfigurePairingContext(); - SetPairingResult(std::nullopt); - CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, - Protocol::kFastPairInitialPairing); - SetupProviderGattServer(); - SetNotifyResponse(*key_based_characteristic_, kKeyBasedResponse); - SetNotifyResponse(*passkey_characteristic_, kPasskeyResponse); - SetDecryptedResponse(); - SetDecryptedPasskey("654321"); - CreateFastPairHandshakeInstanceForDevice(); - - CountDownLatch device_paired_latch(1); - CountDownLatch account_key_writed_latch(1); - CountDownLatch pairing_completed_latch(1); - CountDownLatch pairing_failure_latch(1); - - EXPECT_FALSE(device_->GetAccountKey().Ok()); - - pairer_broker_ = std::make_unique(*mediums_, &executor_, - account_manager_.get()); - PairerBrokerObserver pairer_broker_observer( - pairer_broker_.get(), &device_paired_latch, &account_key_writed_latch, - &pairing_completed_latch, &pairing_failure_latch); - pairer_broker_->PairDevice(*device_); - - EXPECT_FALSE(device_paired_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(pairing_completed_latch.Await(kWaitTimeout).result()); - EXPECT_FALSE(account_key_writed_latch.Await(kWaitTimeout).result()); - pairing_failure_latch.Await(); - EXPECT_FALSE(device_->GetAccountKey().Ok()); - EXPECT_EQ(pairer_broker_observer.pair_failure_, - PairFailure::kPairingAndConnect); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/plugins/BUILD b/fastpair/plugins/BUILD deleted file mode 100644 index 473b84be6c..0000000000 --- a/fastpair/plugins/BUILD +++ /dev/null @@ -1,85 +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. - -package_group( - name = "nearby_fastpair", - packages = [ - "//fastpair/...", - ], -) - -cc_library( - name = "fake_initial_pair_plugin", - hdrs = ["fake_initial_pair_plugin.h"], - visibility = ["//visibility:private"], - deps = [ - "//fastpair:fast_pair_events", - "//fastpair:fast_pair_plugin", - "//fastpair:fast_pair_seeker", - "//fastpair/common", - "//internal/platform:types", - ], -) - -cc_library( - name = "windows_admin_plugin", - srcs = ["windows_admin_plugin.cc"], - hdrs = ["windows_admin_plugin.h"], - visibility = ["//:__subpackages__"], - deps = [ - "//fastpair:fast_pair_events", - "//fastpair:fast_pair_plugin", - "//fastpair:fast_pair_seeker", - "//fastpair:fast_pair_service", - "//fastpair/common", - "//fastpair/ui:fast_pair_ui", - "//internal/platform:types", - ], -) - -cc_test( - name = "fake_initial_pair_plugin_test", - size = "small", - srcs = [ - "fake_initial_pair_plugin_test.cc", - ], - deps = [ - ":fake_initial_pair_plugin", - "//fastpair:test_support", - "//fastpair/common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_googletest//:gtest_main", - ], -) - -cc_library( - name = "fake_fast_pair_plugin", - testonly = True, - srcs = ["fake_fast_pair_plugin.cc"], - hdrs = [ - "fake_fast_pair_plugin.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair:fast_pair_events", - "//fastpair:fast_pair_plugin", - "//fastpair:fast_pair_seeker", - "//fastpair/common", - "@com_google_absl//absl/functional:any_invocable", - ], -) diff --git a/fastpair/plugins/fake_fast_pair_plugin.cc b/fastpair/plugins/fake_fast_pair_plugin.cc deleted file mode 100644 index 9069a0e94f..0000000000 --- a/fastpair/plugins/fake_fast_pair_plugin.cc +++ /dev/null @@ -1,34 +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. - -#include "fastpair/plugins/fake_fast_pair_plugin.h" - -namespace nearby { -namespace fastpair { - -void FakeFastPairPlugin::OnInitialDiscoveryEvent( - const InitialDiscoveryEvent& event) { - if (provider_->on_initial_discovery_event_ != nullptr) { - provider_->on_initial_discovery_event_(device_, event); - } -} - -void FakeFastPairPlugin::OnScreenEvent(const ScreenEvent& event) { - if (provider_->on_screen_event_ != nullptr) { - provider_->on_screen_event_(event); - } -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/plugins/fake_fast_pair_plugin.h b/fastpair/plugins/fake_fast_pair_plugin.h deleted file mode 100644 index 10831e11e0..0000000000 --- a/fastpair/plugins/fake_fast_pair_plugin.h +++ /dev/null @@ -1,61 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_FAKE_FAST_PAIR_PLUGIN_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_FAKE_FAST_PAIR_PLUGIN_H_ - -#include - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/fast_pair_events.h" -#include "fastpair/fast_pair_plugin.h" -#include "fastpair/fast_pair_seeker.h" - -namespace nearby { -namespace fastpair { - -class FakeFastPairPluginProvider; -class FakeFastPairPlugin : public FastPairPlugin { - public: - FakeFastPairPlugin(FastPairSeeker* seeker, const FastPairDevice* device, - FakeFastPairPluginProvider* provider) - : seeker_(seeker), device_(device), provider_(provider) {} - - void OnInitialDiscoveryEvent(const InitialDiscoveryEvent& event) override; - void OnScreenEvent(const ScreenEvent& event) override; - - private: - FastPairSeeker* seeker_; - const FastPairDevice* device_; - FakeFastPairPluginProvider* provider_; -}; - -class FakeFastPairPluginProvider : public FastPairPluginProvider { - public: - std::unique_ptr GetPlugin( - FastPairSeeker* seeker, const FastPairDevice* device) override { - return std::make_unique(seeker, device, this); - } - - absl::AnyInvocable - on_initial_discovery_event_ = nullptr; - absl::AnyInvocable on_screen_event_ = nullptr; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_FAKE_FAST_PAIR_PLUGIN_H_ diff --git a/fastpair/plugins/fake_initial_pair_plugin.h b/fastpair/plugins/fake_initial_pair_plugin.h deleted file mode 100644 index 6f4da38c43..0000000000 --- a/fastpair/plugins/fake_initial_pair_plugin.h +++ /dev/null @@ -1,61 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_INITIAL_PAIR_PLUGIN_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_INITIAL_PAIR_PLUGIN_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/fast_pair_events.h" -#include "fastpair/fast_pair_plugin.h" -#include "fastpair/fast_pair_seeker.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -// Simple plugin that starts pairing when it sees a discoverable advertisement. -class FakeInitialPairPlugin : public FastPairPlugin { - public: - class Provider : public FastPairPluginProvider { - public: - std::unique_ptr GetPlugin( - FastPairSeeker* seeker, const FastPairDevice* device) override { - return std::make_unique(seeker, device); - } - }; - - FakeInitialPairPlugin(FastPairSeeker* seeker, const FastPairDevice* device) - : seeker_(seeker), device_(device) {} - - void OnInitialDiscoveryEvent(const InitialDiscoveryEvent& event) override { - absl::Status status = seeker_->StartInitialPairing( - *device_, InitialPairingParam{}, - {.on_pairing_result = [](const FastPairDevice& device, - absl::Status status) { - NEARBY_LOGS(INFO) << "Pairing result: " << status; - }}); - NEARBY_LOGS(INFO) << "StartInitialPairing: " << status; - } - - private: - FastPairSeeker* seeker_; - const FastPairDevice* device_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_INITIAL_PAIR_PLUGIN_H_ diff --git a/fastpair/plugins/fake_initial_pair_plugin_test.cc b/fastpair/plugins/fake_initial_pair_plugin_test.cc deleted file mode 100644 index 0a8856279d..0000000000 --- a/fastpair/plugins/fake_initial_pair_plugin_test.cc +++ /dev/null @@ -1,51 +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. - -#include "fastpair/plugins/fake_initial_pair_plugin.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "fastpair/common/protocol.h" -#include "fastpair/mock_fast_pair_seeker.h" - -namespace nearby { -namespace fastpair { -namespace { - -using ::testing::Return; - -} // namespace - -TEST(FakeInitialPairPluginTest, InitialPair) { - constexpr absl::string_view kModelId = "123456"; - constexpr absl::string_view kBleAddress = "F1:F2:F3:F4:F5:F6"; - MockFastPairSeeker seeker; - FastPairDevice device(kModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - EXPECT_CALL(seeker, StartInitialPairing) - .Times(1) - .WillOnce(Return(absl::OkStatus())); - - FakeInitialPairPlugin::Provider provider; - std::unique_ptr plugin = provider.GetPlugin(&seeker, &device); - plugin->OnInitialDiscoveryEvent(InitialDiscoveryEvent{}); - - plugin.reset(); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/plugins/windows_admin_plugin.cc b/fastpair/plugins/windows_admin_plugin.cc deleted file mode 100644 index 4877309b29..0000000000 --- a/fastpair/plugins/windows_admin_plugin.cc +++ /dev/null @@ -1,130 +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. - -#include "fastpair/plugins/windows_admin_plugin.h" - -#include "fastpair/internal/fast_pair_seeker_impl.h" - -namespace nearby { -namespace fastpair { - -void WindowsAdminPlugin::PluginState::DiscoveryClicked(DiscoveryAction action) { - NEARBY_LOGS(INFO) << __func__; - if (device == nullptr || fast_pair_service == nullptr) return; - switch (action) { - case DiscoveryAction::kPairToDevice: { - NEARBY_LOGS(INFO) << __func__ << ": Action = kPairToDevice"; - absl::Status status = fast_pair_service->GetSeeker()->StartInitialPairing( - *device, InitialPairingParam{}, - {.on_pairing_result = [this](const FastPairDevice& callback_device, - absl::Status status) { - NEARBY_LOGS(INFO) << "Show pairing result: " << status; - for (auto* observer : observers.GetObservers()) { - observer->OnPairingResult( - const_cast(callback_device), status.ok()); - } - }}); - NEARBY_LOGS(INFO) << "StartInitialPairing: " << status; - } break; - case DiscoveryAction::kSaveDeviceToAccount: { - NEARBY_LOGS(INFO) << __func__ << ": Action = kSaveDeviceToAccount"; - absl::Status status = - fast_pair_service->GetSeeker()->FinishRetroactivePairing( - *device, FinishRetroactivePairingParam{.save_account_key = true}, - {.on_pairing_result = [](const FastPairDevice& device, - absl::Status status) { - NEARBY_LOGS(INFO) << "Finish retro result: " << status; - }}); - foreground_currently_showing_notification = false; - NEARBY_LOGS(INFO) << "FinishRetroactivePairing: " << status; - } break; - case DiscoveryAction::kDismissedByOs: - NEARBY_LOGS(INFO) << __func__ << ": Action = kDismissedByOs"; - break; - case DiscoveryAction::kDismissedByUser: - // When the user explicitly dismisses the discovery notification, update - // the device's block-list value accordingly. - NEARBY_LOGS(INFO) << __func__ << ": Action = kDismissedByUser"; - foreground_currently_showing_notification = false; - break; - case DiscoveryAction::kDismissedByTimeout: - NEARBY_LOGS(INFO) << __func__ << ": Action = kDismissedByTimeout"; - foreground_currently_showing_notification = false; - break; - case DiscoveryAction::kLearnMore: - NEARBY_LOGS(INFO) << __func__ << ": Action = kLearnMore"; - break; - case DiscoveryAction::kDone: - NEARBY_LOGS(INFO) << __func__ << ": Action = kDone"; - foreground_currently_showing_notification = false; - break; - default: - NEARBY_LOGS(INFO) << __func__ << ": Action = Unknown"; - break; - } -} - -void WindowsAdminPlugin::PluginState::SetIsScreenLocked(bool is_locked) { - NEARBY_LOGS(INFO) << __func__; - if (device == nullptr || fast_pair_service == nullptr) return; - FastPairSeekerExt* seeker = - static_cast(fast_pair_service->GetSeeker()); - seeker->SetIsScreenLocked(is_locked); -} - -void WindowsAdminPlugin::OnInitialDiscoveryEvent( - const InitialDiscoveryEvent& event) { - NEARBY_LOGS(INFO) << "Received on initial discovery event"; - auto metadata = device_->GetMetadata(); - if (!metadata) { - NEARBY_LOGS(INFO) - << "Ignoring initial discovery event because metadata is missing"; - return; - } - if (device_->ShouldShowUiNotification().has_value() && - !device_->ShouldShowUiNotification().value()) { - NEARBY_LOGS(INFO) << __func__ << ": Ignoring because show UI flag is false"; - return; - } - if (state_->foreground_currently_showing_notification) { - NEARBY_LOGS(VERBOSE) << __func__ - << ": Already showing a notification for a device"; - return; - } - NotifyShowNotification(*device_); -} - -void WindowsAdminPlugin::OnPairEvent(const PairEvent& event) { - NEARBY_LOGS(INFO) << "Received on pair event"; - absl::Status status = seeker_->StartRetroactivePairing( - *device_, RetroactivePairingParam{}, - {.on_pairing_result = [this](const FastPairDevice& device, - absl::Status status) { - NEARBY_LOGS(INFO) << "Retroactive Pairing result: " << status; - if (!status.ok()) return; - NotifyShowNotification(device); - }}); - NEARBY_LOGS(INFO) << "StartRetroactivePairing: " << status; -} - -void WindowsAdminPlugin::NotifyShowNotification(const FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__; - state_->foreground_currently_showing_notification = true; - state_->device = &device; - for (auto* observer : state_->observers.GetObservers()) { - observer->OnUpdateDevice(const_cast(device)); - } -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/plugins/windows_admin_plugin.h b/fastpair/plugins/windows_admin_plugin.h deleted file mode 100644 index 673ae2e22b..0000000000 --- a/fastpair/plugins/windows_admin_plugin.h +++ /dev/null @@ -1,72 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_WINDOWS_ADMIN_PLUGIN_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_WINDOWS_ADMIN_PLUGIN_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/fast_pair_events.h" -#include "fastpair/fast_pair_plugin.h" -#include "fastpair/fast_pair_seeker.h" -#include "fastpair/fast_pair_service.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -class WindowsAdminPlugin : public FastPairPlugin { - public: - struct PluginState { - void DiscoveryClicked(DiscoveryAction action); - void SetIsScreenLocked(bool is_locked); - ObserverList observers; - const FastPairDevice* device = nullptr; - std::unique_ptr fast_pair_service; - bool foreground_currently_showing_notification = false; - }; - - class Provider : public FastPairPluginProvider { - public: - explicit Provider(PluginState* state) : state_(state) {} - std::unique_ptr GetPlugin( - FastPairSeeker* seeker, const FastPairDevice* device) override { - return std::make_unique(seeker, device, state_); - } - - private: - PluginState* state_; - }; - - WindowsAdminPlugin(FastPairSeeker* seeker, const FastPairDevice* device, - PluginState* state) - : seeker_(seeker), device_(device), state_(state) {} - - void OnInitialDiscoveryEvent(const InitialDiscoveryEvent& event) override; - void OnPairEvent(const PairEvent& event) override; - - private: - void NotifyShowNotification(const FastPairDevice& device); - FastPairSeeker* seeker_; - const FastPairDevice* device_; - PluginState* state_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_WINDOWS_ADMIN_PLUGIN_H_ diff --git a/fastpair/proto/BUILD b/fastpair/proto/BUILD deleted file mode 100644 index 3c80774ad2..0000000000 --- a/fastpair/proto/BUILD +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright 2022 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. - -load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") -load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") - -licenses(["notice"]) - -proto_library( - name = "fastpair_proto", - srcs = [ - "cache.proto", - "data.proto", - "enum.proto", - "fast_pair_string.proto", - "fastpair_rpcs.proto", - ], - visibility = [ - "//fastpair:__subpackages__", - ], -) - -cc_proto_library( - name = "fastpair_cc_proto", - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [":fastpair_proto"], -) - -cc_library( - name = "proto_to_json", - srcs = [ - "proto_to_json.cc", - ], - hdrs = [ - "proto_to_json.h", - ], - visibility = ["//visibility:public"], - deps = [ - ":fastpair_cc_proto", - "//fastpair/common", - "//internal/platform:types", - "@com_google_absl//absl/strings", - "@nlohmann_json//:json", - ], -) - -cc_library( - name = "proto_builder", - srcs = [ - "proto_builder.cc", - ], - hdrs = [ - "proto_builder.h", - ], - visibility = ["//visibility:public"], - deps = [ - ":fastpair_cc_proto", - "//fastpair/common", - "//fastpair/repository", - "//internal/platform:types", - "@com_google_absl//absl/time", - ], -) - -cc_test( - name = "proto_builder_test", - srcs = [ - "proto_builder_test.cc", - ], - copts = [ - "-Ithird_party", - ], - deps = [ - ":fastpair_cc_proto", - ":proto_builder", - "//fastpair/common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/proto/cache.proto b/fastpair/proto/cache.proto deleted file mode 100644 index 9ad4c2f6b2..0000000000 --- a/fastpair/proto/cache.proto +++ /dev/null @@ -1,93 +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. - -syntax = "proto3"; - -package nearby.fastpair.proto; - -import "fastpair/proto/enum.proto"; - -option java_multiple_files = true; - -// The buffer size range of a Fast Pair devices support dynamic buffer size. -message BufferSizeRange { - // The max buffer size in ms. - optional int32 max_size = 1; - - // The min buffer size in ms. - optional int32 min_size = 2; - - // The default buffer size in ms. - optional int32 default_size = 3; - - // The codec of this buffer size range. - optional int32 codec = 4; -} - -// A locally cached Fast Pair device associating an account key with the -// bluetooth address of the device. -message StoredFastPairItem { - // The device's public mac address. - string mac_address = 1; - - // The account key written to the device. - bytes account_key = 2; - - // When user need to update provider name, enable this value to trigger - // writing new name to provider. - optional bool need_to_update_provider_name = 3; - - // The retry times to update name into provider. - optional int32 update_name_retries = 4; - - // Latest firmware version from the server. - optional string latest_firmware_version = 5; - - // The firmware version that is on the device. - optional string device_firmware_version = 6; - - // The timestamp from the last time we fetched the firmware version from the - // device. - optional int64 last_check_firmware_timestamp_millis = 7; - - // The timestamp from the last time we fetched the firmware version from - // server. - optional int64 last_server_query_timestamp_millis = 8; - - // Only allows one bloom filter check process to create gatt connection and - // try to read the firmware version value. - optional bool can_read_firmware = 9; - - // Device's model id. - string model_id = 10; - - // Features that this Fast Pair device supports. - repeated FastPairFeature features = 11; - - // When true, the latest uploaded event to FMA is connected. We use - // it as the previous ACL state when getting the BluetoothAdapter STATE_OFF to - // determine if need to upload the disconnect event to FMA. - optional bool fma_state_is_connected = 13; - - // Device's buffer size range. - repeated BufferSizeRange buffer_size_ranges = 18; - - // The additional account key if this device could be associated with multiple - // accounts. Notes that for this device, the account_key field is the basic - // one which will not be associated with the accounts. - repeated bytes additional_account_keys = 19; - - // Deprecated fields. - reserved 14, 15, 16, 17; -} diff --git a/fastpair/proto/data.proto b/fastpair/proto/data.proto deleted file mode 100644 index cd3f875187..0000000000 --- a/fastpair/proto/data.proto +++ /dev/null @@ -1,277 +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. - -syntax = "proto3"; - -package nearby.fastpair.proto; - -import "fastpair/proto/enum.proto"; -import "fastpair/proto/fast_pair_string.proto"; - -option java_multiple_files = true; - -// Information about Fast Pair. This will either contain a Fast Pair device -// or an opt in status. -message FastPairInfo { - oneof info { - OptInStatus opt_in_status = 1; - FastPairDevice device = 2; - } -} - -// A device that has been Fast Paired with. -message FastPairDevice { - // The account key which was written to the device after pairing completed. - bytes account_key = 1; - - // The stored discovery item which represents the notification that should be - // associated with the device. Note, this is stored as a raw byte array - // instead of StoredDiscoveryItem because icing only supports proto lite and - // StoredDiscoveryItem is handed around as a nano proto in implementation, - // which are not compatible with each other. - bytes discovery_item_bytes = 3; - - // SHA256 of "account key + headset's public address", this is used to - // identify the paired headset. Because of adding account key to generate the - // hash value, it makes the information anonymous, even for the same headset, - // different accounts have different values. - bytes sha256_account_key_public_address = 4; - - // Deprecated fields. - reserved 2; -} - -// Additional images for True Wireless Fast Pair devices. -message TrueWirelessHeadsetImages { - // Image URL for the left bud. - optional string left_bud_url = 1; - - // Image URL for the right bud. - optional string right_bud_url = 2; - - // Image URL for the case. - optional string case_url = 3; -} - -// Relevance indicates how relevant the item is to the user. -message Relevance { - // Whether the item is good, ok, poor, etc. Corresponds to levels found in - // the Discoverer Notification Policy Worksheet: - // https://docs.google.com/a/google.com/spreadsheets/d/1atc1-RNLb7fAGvGdWXlh86Qy2IY9T_dj2v4gFUhdPF0/edit?usp=sharing - Evaluation evaluation = 1; - - // To get this relevance, the item can be at most this far away. - // Note: Supported in v11+. - // TODO(jfarfel): Replace with Targeting. - optional double max_distance = 2; -} - -message StoredRelevance { - Relevance relevance = 1; - - // The last time that this relevance passed targeting. A relevance with no - // targeting always passes. Null if it failed, or we haven't checked yet. - optional int64 targeting_true_millis = 2; -} - -// Additional information relevant only for Fast Pair devices. -message FastPairInformation { - // When true, Fast Pair will only create a bond with the device and not - // attempt to connect any profiles (for example, A2DP or HFP). - // TODO(b/128545971): Transition this to a feature. - optional bool data_only_connection = 1; - - // Additional images that are attached specifically for true wireless Fast - // Pair devices. - optional TrueWirelessHeadsetImages true_wireless_images = 3; -} - -// Data for a DiscoveryItem created from server response and client scan result. -// Only caching original data from scan result, server response, timestamps -// and user actions. Do not save generated data in this object. -// Next ID: 51 -message StoredDiscoveryItem { - enum State { - // Default unknown state. - STATE_UNKNOWN = 0; - - // The item is normal. - STATE_ENABLED = 1; - - // The item has been muted by user. - STATE_MUTED = 2; - - // The item has been disabled by us (likely temporarily). - STATE_DISABLED_BY_SYSTEM = 3; - } - - // The status of the item. - enum DebugMessageCategory { - // Default unknown state. - STATUS_UNKNOWN = 0; - - // The item is valid and visible in notification. - STATUS_VALID_NOTIFICATION = 1; - - // The item made it to list but not to notification. - STATUS_VALID_LIST_VIEW = 2; - - // The item is filtered out on client. Never made it to list view. - STATUS_DISABLED_BY_CLIENT = 3; - - // The item is filtered out by server. Never made it to client. - STATUS_DISABLED_BY_SERVER = 4; - } - - enum ExperienceType { - EXPERIENCE_UNKNOWN = 0; - EXPERIENCE_GOOD = 1; - EXPERIENCE_BAD = 2; - } - - // REQUIRED - // Offline item: unique ID generated on client. - // Online item: unique ID generated on server. - optional string id = 1; - - // REQUIRED - optional NearbyType type = 2; - - // REQUIRED - // The most recent all upper case mac associated with this item. - // (Mac-to-DiscoveryItem is a many-to-many relationship) - optional string mac_address = 4; - - // REQUIRED - optional string action_url = 5; - - // The bluetooth device name from advertisment - optional string device_name = 6; - - // REQUIRED - // Item's title - optional string title = 7; - - // Item's description. - optional string description = 8; - - // The URL for display - optional string display_url = 9; - - // REQUIRED - // Client timestamp when the beacon was last observed in BLE scan. - optional int64 last_observation_timestamp_millis = 10; - - // REQUIRED - // Client timestamp when the beacon was first observed in BLE scan. - optional int64 first_observation_timestamp_millis = 11; - - // REQUIRED - // Item's current state. e.g. if the item is blocked. - optional State state = 17; - - // The resolved url type for the action_url. - optional ResolvedUrlType action_url_type = 19; - - // The timestamp when the user is redirected to Play Store after clicking on - // the item. - optional int64 pending_app_install_timestamp_millis = 20; - - // Beacon's RSSI value - optional int32 rssi = 22; - - // Beacon's tx power - optional int32 tx_power = 23; - - // Human readable name of the app designated to open the uri - // Used in the second line of the notification, "Open in {} app" - optional string app_name = 25; - - // ID used for associating several DiscoveryItems. These items may be - // visually displayed together. - optional string group_id = 26; - - // The timestamp when the attachment was created on PBS server. In case there - // are duplicate - // items with the same scanId/groupID, only show the one with the latest - // timestamp. - optional int64 attachment_creation_sec = 28; - - // Package name of the App that owns this item. - optional string package_name = 30; - - // The average star rating of the app. - optional float star_rating = 31; - - // The "feature" graphic image url used for large sized list view entries. - optional string feature_graphic_url = 32; - - // TriggerId identifies the trigger/beacon that is attached with a message. - // It's generated from server for online messages to synchronize formatting - // across client versions. - // Example: - // * BLE_UID: 3||deadbeef - // * BLE_URL: http://trigger.id - // See go/discovery-store-message-and-trigger-id for more details. - optional string trigger_id = 34; - - // Bytes of item icon in PNG format displayed in Discovery item list. - optional bytes icon_png = 36; - - // How relevant the message is to the user. May be used by the client to - // determine how to display the NearbyItem. >1 relevance makes sense only if - // each has targeting (e.g., a maximum distance threshold). In that case, the - // item's relevance is the maximum one where the targeting is satisfied. - repeated StoredRelevance stored_relevances = 40; - - // A FIFE URL of the item icon displayed in Discovery item list. - optional string icon_fife_url = 49; - - // Message written to bugreport for 3P developers.(No sensitive info) - // null if the item is valid - optional string debug_message = 37; - - // Weather the item is filtered out on server. - optional DebugMessageCategory debug_category = 38; - - // Client timestamp when the trigger (e.g. beacon) was last lost (e.g. when - // Messages told us the beacon's no longer nearby). - optional int64 lost_millis = 41; - - // The kind of expereince the user last had with this (e.g. if they dismissed - // the notification, that's bad; but if they tapped it, that's good). - optional ExperienceType last_user_experience = 42; - - // The most recent BLE advertisement related to this item. - optional bytes ble_record_bytes = 43; - - // An ID generated on the server to uniquely identify content. - optional string entity_id = 44; - - // See equivalent field in NearbyItem. - optional bytes authentication_public_key_secp256r1 = 45; - - // See equivalent field in NearbyItem. - optional FastPairInformation fast_pair_information = 46; - - // Fast pair strings - optional FastPairStrings fast_pair_strings = 48; - - // The time of the account key's association. - // We use device local time for this field, so could be inaccurate. - optional int64 account_key_association_local_timestamp_ms = 50; - - // Deprecated fields. - reserved 3, 12, 13, 14, 15, 16, 18, 21, 24, 27, 33, 35, 39; -} diff --git a/fastpair/proto/enum.proto b/fastpair/proto/enum.proto deleted file mode 100644 index 1c33c0674c..0000000000 --- a/fastpair/proto/enum.proto +++ /dev/null @@ -1,78 +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. - -syntax = "proto3"; - -package nearby.fastpair.proto; - -option java_multiple_files = true; - -// Features that can be enabled for a Fast Pair device. -enum FastPairFeature { - FAST_PAIR_FEATURE_UNKNOWN = 0; - FAST_PAIR_FEATURE_SILENCE_MODE = 1; - FAST_PAIR_FEATURE_WIRELESS_CHARGING = 2; - FAST_PAIR_FEATURE_DYNAMIC_BUFFER_SIZE = 3; - FAST_PAIR_FEATURE_NO_PERSONALIZED_NAME = 4; - FAST_PAIR_FEATURE_EDDYSTONE_TRACKING = 5; - FAST_PAIR_FEATURE_SMART_AUDIO_SOURCE_SWITCHING = 6; - FAST_PAIR_FEATURE_NOT_SUPPORTED_RING = 7; -} - -// The status of the user's consent opt-in. -enum OptInStatus { - OPT_IN_STATUS_UNKNOWN = 0; - OPT_IN_STATUS_OPTED_IN = 1; - OPT_IN_STATUS_OPTED_OUT = 2; - OPT_IN_STATUS_ERROR_RETRIEVING_FROM_FOOTPRINTS_SERVER = 3; -} - -// The type of a NearbyItem. Determines how the item is handled (e.g. we may -// display a different notification style for different types). It may not -// indicate the source of the data (e.g., an attachment on the Proximity Beacon -// Service that represents a device needing to be set up might become a -// NearbyItem with type=DEVICE). -enum NearbyType { - NEARBY_TYPE_UNKNOWN = 0; - // Proximity Beacon Service (PBS). This is the only type of nearbyItems which - // can be customized by 3p and therefore the intents passed should not be - // completely trusted. Deprecated already. - NEARBY_TYPE_PROXIMITY_BEACON = 1; - // Physical Web URL beacon. Deprecated already. - NEARBY_TYPE_PHYSICAL_WEB = 2; - NEARBY_TYPE_CHROMECAST = 3; - NEARBY_TYPE_WEAR = 4; - NEARBY_TYPE_DEVICE = 6; - NEARBY_TYPE_POPULAR_HERE = 7; -} - -enum ResolvedUrlType { - RESOLVED_URL_TYPE_UNKNOWN = 0; - RESOLVED_URL_TYPE_WEBPAGE = 1; - RESOLVED_URL_TYPE_APP = 2; -} - -// Used when evaluating Relevance of a NearbyItem -// Values correspond to levels in the Discoverer Notification Policy Worksheet: -// https://docs.google.com/a/google.com/spreadsheets/d/1atc1-RNLb7fAGvGdWXlh86Qy2IY9T_dj2v4gFUhdPF0/edit?usp=sharing -enum Evaluation { - EVALUATION_UNKNOWN = 0; - EVALUATION_BAD = 100; - EVALUATION_POOR = 200; - EVALUATION_NEUTRAL = 300; - EVALUATION_OK = 400; - EVALUATION_GOOD = 500; - EVALUATION_GREAT = 600; - EVALUATION_AMAZING = 700; -} diff --git a/fastpair/proto/fast_pair_string.proto b/fastpair/proto/fast_pair_string.proto deleted file mode 100644 index 8d19aafb7d..0000000000 --- a/fastpair/proto/fast_pair_string.proto +++ /dev/null @@ -1,205 +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. - -syntax = "proto3"; - -package nearby.fastpair.proto; - -option java_multiple_files = true; - -// Data for Fast Pair related string -message FastPairStrings { - // Required for initial pairing, used when there is a Google account on the - // device - string tap_to_pair_with_account = 1; - - // Required for initial pairing, used when there is no Google account on the - // device - string tap_to_pair_without_account = 2; - - // Description for initial pairing - optional string initial_pairing_description = 3; - - // Description after successfully paired the device with companion app - // installed - optional string pairing_finished_companion_app_installed = 4; - - // Description after successfully paired the device with companion app not - // installed - optional string pairing_finished_companion_app_not_installed = 5; - - // Description when phone found the device that associates with user's account - // before remind user to pair with new device. - optional string subsequent_pairing_description = 6; - - // TV Description when phone found the device that associates with user's - // account before remind user to pair with new device. - optional string subsequent_pairing_description_on_tv = 65; - - // Description when fast pair finds the user paired with device manually - // reminds user to opt the device into cloud. - optional string retroactive_pairing_description = 7; - - // Description when user click setup device while device is still pairing - optional string wait_app_launch_description = 8; - - // Description when user fail to pair with device - optional string pairing_fail_description = 9; - - // Title to ask the user to confirm the pin code. - optional string confirm_pin_title = 10; - - // Description to ask the user to confirm the pin code. - optional string confirm_pin_description = 11; - - // The title of the UI to ask the user to confirm to sync contacts. - optional string sync_contacts_title = 12; - - // The description of the UI to ask the user to confirm to sync contacts. - optional string sync_contacts_description = 13; - - // The title of the UI to ask the user to confirm to sync SMS. - optional string sync_sms_title = 14; - - // The description of the UI to ask the user to confirm to sync SMS. - optional string sync_sms_description = 15; - - // The description for half sheet to ask user to setup google assistant. - optional string assistant_half_sheet_description = 16; - - // The description for notification to ask user to setup google assistant. - optional string assistant_notification_description = 17; - - // Description of the connect device action on TV, when user is not logged in. - optional string fast_pair_tv_connect_device_no_account_description = 18; - - // Description for wear os pairing on the slice. - optional string wear_os_tap_to_set_up = 19; - - // If present then this title will be used for the initial connect half sheet. - optional string initial_connect_sheet_title = 30; - - optional string finder_enable_sheet_title = 20; - optional string finder_enable_sheet_find_device_toggle = 21; - optional string finder_enable_sheet_finder_network_title = 22; - optional string finder_enable_sheet_finder_network_toggle = 23; - optional string finder_enable_sheet_description_find_nearby_devices_info = 24; - optional string finder_enable_sheet_description_location_anonymous_info = 25; - optional string finder_enable_sheet_description_location_encrypted_info = 26; - optional string finder_enable_sheet_description_turn_off_in_settings = 27; - optional string finder_enable_sheet_beacon_description = 31; - optional string finder_enable_sheet_add_tracking = 32; - optional string finder_enable_sheet_location_encrypted = 33; - optional string finder_enable_sheet_add_to_find_my_device_button = 34; - optional string finder_enable_sheet_adding_device = 35; - optional string finder_enable_sheet_download_device_app = 36; - optional string finder_enable_sheet_download_find_my_device = 37; - optional string finder_enable_sheet_download_find_my_device_description = 38; - optional string finder_enable_sheet_added_device = 39; - optional string finder_enable_sheet_generic_failure_title = 40; - optional string finder_enable_sheet_generic_failure_details = 41; - optional string finder_enable_sheet_device_already_provisioned_title = 42; - optional string finder_enable_sheet_device_already_provisioned_description = - 43; - optional string finder_enable_sheet_use_find_my_device_description = 44; - optional string finder_enable_sheet_use_find_my_device_button = 45; - optional string finder_enable_sheet_enable_last_known_location_description = - 46; - optional string finder_enable_sheet_enable_last_known_location_learn_more = - 112; - optional string finder_enable_sheet_enable_last_known_location_button = 47; - optional string finder_enable_sheet_leave_dialog_title = 48; - optional string finder_enable_sheet_leave_dialog_content = 49; - optional string finder_enable_sheet_leave_dialog_continue_setup_button = 50; - optional string finder_enable_sheet_leave_dialog_leave_button = 51; - optional string finder_enable_sheet_device_added_toast = 52; - optional string - finder_enable_sheet_already_provisioned_shared_device_button_title = 53; - optional string - finder_enable_sheet_already_provisioned_shared_device_button_subtitle = - 54; - optional string - finder_enable_sheet_already_provisioned_take_ownership_button_title = 55; - optional string - finder_enable_sheet_already_provisioned_take_ownership_button_subtitle = - 56; - optional string finder_enable_sheet_shared_device_title = 57; - optional string finder_enable_sheet_shared_device_description = 58; - optional string finder_enable_sheet_take_ownership_title = 59; - optional string finder_enable_sheet_take_ownership_forget_device_title = 60; - optional string finder_enable_sheet_take_ownership_forget_device_subtitle = - 61; - optional string finder_enable_sheet_take_ownership_factory_reset_title = 62; - optional string finder_enable_sheet_take_ownership_factory_reset_subtitle = - 63; - optional string finder_enable_sheet_take_ownership_pair_device_title = 64; - optional string finder_enable_sheet_fast_pair_prompt_sub_image_text = 66; - optional string finder_enable_sheet_pairing_failure_title = 67; - optional string finder_enable_sheet_pairing_failure_subtitle = 68; - optional string finder_enable_sheet_too_many_failures_subtitle = 69; - optional string finder_enable_sheet_too_many_failures_button = 70; - optional string finder_enable_sheet_provisioning_prompt_description = 71; - optional string finder_enable_sheet_provisioning_learn_more = 72; - optional string finder_enable_sheet_take_ownership_positive_button = 73; - optional string finder_enable_sheet_factory_reset_positive_button = 74; - optional string finder_enable_sheet_use_find_my_device_title = 75; - optional string finder_enable_sheet_enable_location_title = 76; - optional string finder_enable_sheet_enable_location_description = 77; - optional string finder_enable_sheet_enable_last_known_location_title = 78; - optional string - finder_enable_sheet_pairing_and_provisioning_completed_description = 79; - optional string finder_enable_sheet_start_using_device_title = 80; - optional string finder_enable_sheet_retroactive_pair_description = 82; - optional string finder_enable_sheet_shared_device_learn_more = 83; - optional string finder_enable_sheet_provisioning_failure_title = 84; - optional string finder_enable_sheet_provisioning_failure_subtitle = 85; - optional string finder_enable_sheet_too_many_failures_title = 86; - optional string finder_upgrade_notification_title = 87; - optional string finder_upgrade_notification_content = 88; - optional string - finder_enable_sheet_retroactive_pairing_already_provisioned_sub_image_text = - 89; - optional string finder_enable_sheet_retroactive_provisioning_title = 90; - optional string finder_enable_sheet_retroactive_provisioning_description = 91; - optional string finder_enable_sheet_retroactive_provisioning_learn_more = 92; - optional string finder_enable_sheet_retroactive_provisioning_sub_image_text = - 93; - optional string finder_enable_sheet_invalid_android_version_title = 94; - optional string finder_enable_sheet_invalid_android_version_description = 95; - optional string finder_enable_sheet_open_companion_app_title = 96; - optional string finder_enable_sheet_open_companion_app_description = 97; - optional string finder_enable_sheet_lock_screen_title = 98; - optional string finder_enable_sheet_lock_screen_description = 99; - optional string finder_enable_sheet_lock_screen_dialog_title = 100; - optional string finder_enable_sheet_lock_screen_dialog_content = 101; - optional string finder_enable_sheet_lock_screen_set_button = 109; - optional string finder_enable_sheet_lock_screen_dialog_continue_setup_button = - 102; - optional string finder_enable_sheet_lock_screen_dialog_leave_button = 103; - optional string finder_enable_sheet_lock_screen_learn_more = 111; - optional string finder_enable_sheet_finder_network_prompt_title = 104; - optional string finder_enable_sheet_finder_network_prompt_description = 105; - optional string finder_enable_sheet_finder_network_prompt_join_button = 113; - optional string finder_enable_sheet_finder_network_prompt_learn_more = 114; - optional string finder_enable_sheet_acceptable_use_prompt_title = 106; - optional string finder_enable_sheet_acceptable_use_prompt_description = 107; - optional string finder_enable_sheet_acceptable_use_learn_more = 108; - optional string finder_enable_sheet_acceptable_use_agree_button = 110; - // Description that teaches screen-reader users to turn on the talkback on - // their watches. - optional string - accessibility_instruction_of_turning_on_talkback_on_pixel_watch = 81; - // Deleted fields. - reserved 28, 29; -} diff --git a/fastpair/proto/fastpair_rpcs.proto b/fastpair/proto/fastpair_rpcs.proto deleted file mode 100644 index a5015203e4..0000000000 --- a/fastpair/proto/fastpair_rpcs.proto +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2022 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. - -syntax = "proto3"; - -package nearby.fastpair.proto; - -// import "storage/datapol/annotations/proto/semantic_annotations.proto"; -import "fastpair/proto/data.proto"; - -// Represents the type of device that is being registered. -enum DeviceType { - // Unspecified device type. - DEVICE_TYPE_UNSPECIFIED = 0; - // Headphones or Earbuds. - HEADPHONES = 1; - // Speaker. - SPEAKER = 2; - // Wearable such as a watch. - WEARABLE = 3; - // Input devices such as keyboards, mice, etc. - INPUT_DEVICE = 4; - // Cars. - AUTOMOTIVE = 5; - // OTHER (referencing how Status is structured). - OTHER = 6; - // True Wireless headphones (these include additional configuration options). - TRUE_WIRELESS_HEADPHONES = 7; - // WearOS watch. This should trigger explicit functionality on clients when - // used, such as specifying BR/EDR transport type when creating a bond. It is - // a subset of wearables working around specific issues on that platform. - WEAR_OS = 8; - // Android Auto has the particular Fast Pair UX flows which may not be bought - // in by some car manufacturers (e.g. BMW). Sees go/fastpair-android-auto for - // more details. - ANDROID_AUTO = 9; - // Glass has the particular Fast Pair UX requiring passkey confirmation - // to show up on the screen in order to pair it with a smartphone. - GLASS = 10; - // Locator tags. - LOCATOR_TAG = 11; - // ChromeOS device. - CHROME_OS = 12; - // Android phone. - ANDROID_PHONE = 13; -} - -// Represents the format of the final device notification (which is directly -// correlated to the action taken by the notification). -enum NotificationType { - // Unspecified notification type. - NOTIFICATION_TYPE_UNSPECIFIED = 0; - // Notification launches the fast pair intent. - // Example Notification Title: "Bose SoundLink II" - // Notification Description: "Tap to pair with this device" - FAST_PAIR = 1; - // Notification launches an app. - // Notification Title: "[X]" where X is type/name of the device. - // Notification Description: "Tap to setup this device" - APP_LAUNCH = 2; - // Notification launches for Nearby Setup. The notification title and - // description is the same as APP_LAUNCH. - NEARBY_SETUP = 3; - // Notification launches the fast pair intent, but doesn't include an anti- - // spoofing key. The notification title and description is the same as - // FAST_PAIR. - FAST_PAIR_ONE = 4; - // Notification launches Smart Setup on devices. - // These notifications are identical to APP_LAUNCH except that they always - // launch Smart Setup intents within GMSCore. - SMART_SETUP = 5; -} - -message Device { - // Output only. The server-generated ID of the device. - int64 id = 1; - - // The pantheon project number the device is created under. Only Nearby admins - // can change this. - int64 project_number = 2; - - // How the notification will be displayed to the user - NotificationType notification_type = 3; - - // The image to show on the notification. - string image_url = 4; - - // The name of the device. - string name = 5; - - // The intent that will be launched via the notification. - string intent_uri = 6; - - // The transmit power of the device's BLE chip. - int32 ble_tx_power = 7; - - // The distance that the device must be within to show a notification. - // If no distance is set, we default to 0.6 meters. Only Nearby admins can - // change this. - float trigger_distance = 8; - - // Output only. Fast Pair only - The anti-spoofing key pair for the device. - AntiSpoofingKeyPair anti_spoofing_key_pair = 9; - - // Fast Pair only - The type of device being registered. - DeviceType device_type = 13; - - // Fast Pair only - Additional images for true wireless headsets. - TrueWirelessHeadsetImages true_wireless_images = 15; - - // Name of the device that is displayed on the console. - string display_name = 21; -} - -// An anti-spoofing key pair for a device that allows us to verify the device is -// broadcasting legitimately. -message AntiSpoofingKeyPair { - // The private key (restricted to only be viewable by trusted clients). - bytes private_key = 1 /* type = ST_SECURITY_KEY */; - - // The public key. - bytes public_key = 2; -} - -// Strings to be displayed in notifications surfaced for a device. -message ObservedDeviceStrings { - // The locale of all of the strings. - string locale = 1; - - // The notification description for when the device is initially discovered. - string initial_notification_description = 2; - - // The notification description for when the device is initially discovered - // and no account is logged in. - string initial_notification_description_no_account = 3; - - // The notification description for once we have finished pairing and the - // companion app has been opened. For Bisto devices, this string will point - // users to setting up the assistant. - string open_companion_app_description = 4; - - // The notification description for once we have finished pairing and the - // companion app needs to be updated before use. - string update_companion_app_description = 5; - - // The notification description for once we have finished pairing and the - // companion app needs to be installed. - string download_companion_app_description = 6; - - // The notification title when a pairing fails. - string unable_to_connect_title = 7; - - // The notification summary when a pairing fails. - string unable_to_connect_description = 8; - - // The description that helps user initially paired with device. - string initial_pairing_description = 9; - - // The description that let user open the companion app. - string connect_success_companion_app_installed = 10; - - // The description that let user download the companion app. - string connect_success_companion_app_not_installed = 11; - - // The description that reminds user there is a paired device nearby. - string subsequent_pairing_description = 12; - - // The description that reminds users opt in their device. - string retroactive_pairing_description = 13; - - // The description that indicates companion app is about to launch. - string wait_launch_companion_app_description = 14; - - // The description that indicates go to bluetooth settings when connection - // fail. - string fail_connect_go_to_settings_description = 15; - - // The title of the UI to ask the user to confirm the pin code. - string confirm_pin_title = 16; - - // The description of the UI to ask the user to confirm the pin code. - string confirm_pin_description = 17; - - // The title of the UI to ask the user to confirm to sync contacts. - string sync_contacts_title = 18; - - // The description of the UI to ask the user to confirm to sync contacts. - string sync_contacts_description = 19; - - // The title of the UI to ask the user to confirm to sync SMS. - string sync_sms_title = 20; - - // The description of the UI to ask the user to confirm to sync SMS. - string sync_sms_description = 21; - - // The description in half sheet to ask user setup google assistant - string assistant_setup_half_sheet = 22; - - // The description in notification to ask user setup google assistant - string assistant_setup_notification = 23; - - // Description of the connect device action on TV, when user is not logged in. - string fast_pair_tv_connect_device_no_account_description = 24; - - // The description of the slice to ask user setup the wear os. - string wear_os_tap_to_set_up = 25; - - string finder_enable_sheet_title = 26; - - string finder_enable_sheet_find_device_toggle = 27; - - string finder_enable_sheet_finder_network_title = 28; - - string finder_enable_sheet_finder_network_toggle = 29; - - string finder_enable_sheet_description_find_nearby_devices_info = 30; - - string finder_enable_sheet_description_location_anonymous_info = 31; - - string finder_enable_sheet_description_location_encrypted_info = 32; - - string finder_enable_sheet_description_turn_off_in_settings = 33; - - // If present then this title will be used for the initial connect half sheet. - string initial_connect_sheet_title = 36; - - // Deleted fields. - reserved 34, 35; -} - -// Request for getting an observed device. -message GetObservedDeviceRequest { - // The mode the requesting device is currently in, eg release or debug. - enum Mode { - // Unknown mode. - MODE_UNKNOWN = 0; - - // Release mode. - MODE_RELEASE = 1; - - // Debug mode. - MODE_DEBUG = 2; - } - - // The ID of the device to find. - int64 device_id = 1; - - // The request mode for the device. - Mode mode = 2; - - // The locale to get a translated description for. - string locale = 3; - - // 6-hexdigit Device Id and will be auto-converted and used instead of - // device_id. If both device_id and hex_device_id, device_id will be used and - // hex_device_id will be ignored - string hex_device_id = 4; - - // The max size of an icon to be displayed in pixels. - int64 max_icon_size_pixels = 5; -} - -// Response containing an observed device. -message GetObservedDeviceResponse { - // The device from the request. - Device device = 1; - - // The image icon that shows in the notification - bytes image = 3; - - ObservedDeviceStrings strings = 4; - - reserved 2; -} - -// Request to read the user's devices. -message UserReadDevicesRequest { - // Optional secondary ID that can be used for lookups. - bytes secondary_id = 1; -} - -// Response containing the list of devices for a user. -message UserReadDevicesResponse { - repeated .nearby.fastpair.proto.FastPairInfo fast_pair_info = 1; -} - -// Request to write a new device to a user. -message UserWriteDeviceRequest { - .nearby.fastpair.proto.FastPairInfo fast_pair_info = 1; -} - -// Response to writing a new device to a user. -message UserWriteDeviceResponse {} - -// Request to delete an existing device from a user's account. -message UserDeleteDeviceRequest { - // The account key to be deleted, encoded in base16 (hex). This should use - // all upper-case letters with no padding or prefex (i.e. 0123456789ABCDEF). - string hex_account_key = 2; -} - -// Response to deleting a new device from a user's account. -message UserDeleteDeviceResponse { - bool success = 1; - repeated string error_messages = 2; -} diff --git a/fastpair/proto/proto_builder.cc b/fastpair/proto/proto_builder.cc deleted file mode 100644 index 738aaf5a6d..0000000000 --- a/fastpair/proto/proto_builder.cc +++ /dev/null @@ -1,133 +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. - -#include "fastpair/proto/proto_builder.h" - -#include -#include - -#include "absl/time/time.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/enum.proto.h" -#include "fastpair/proto/fast_pair_string.proto.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -void BuildFastPairInfo(::nearby::fastpair::proto::FastPairInfo* fast_pair_info, - const FastPairDevice& fast_pair_device) { - NEARBY_LOGS(VERBOSE) << __func__; - const AccountKey& account_key = fast_pair_device.GetAccountKey(); - auto& metadata = fast_pair_device.GetMetadata(); - DCHECK(metadata); - DCHECK(account_key.Ok()); - - // Sets FastPairDevice of FastPairInfo - auto* device = fast_pair_info->mutable_device(); - device->set_account_key(account_key.GetAsBytes()); - // Create a SHA256 hash of the |mac_address| with the |account_key| as salt. - // The hash is used to identify devices via non discoverable advertisements. - if (fast_pair_device.GetPublicAddress().has_value()) { - device->set_sha256_account_key_public_address( - FastPairRepository::GenerateSha256OfAccountKeyAndMacAddress( - account_key, fast_pair_device.GetPublicAddress().value())); - } - - auto& details = metadata->GetDetails(); - auto& strings = metadata->GetResponse().strings(); - - // Sets proto::StoredDiscoveryItem to FastPairDevice - proto::StoredDiscoveryItem discovery_item; - discovery_item.set_id(fast_pair_device.GetModelId()); - discovery_item.set_trigger_id(fast_pair_device.GetModelId()); - - std::optional display_name = fast_pair_device.GetDisplayName(); - if (display_name.has_value()) { - discovery_item.set_title(display_name.value()); - } else { - discovery_item.set_title(details.name()); - } - - discovery_item.set_description(strings.initial_notification_description()); - discovery_item.set_type(proto::NearbyType::NEARBY_TYPE_DEVICE); - discovery_item.set_action_url_type( - proto::ResolvedUrlType::RESOLVED_URL_TYPE_APP); - discovery_item.set_action_url(details.intent_uri()); - discovery_item.set_last_observation_timestamp_millis( - absl::ToInt64Milliseconds(absl::Now() - absl::UnixEpoch())); - discovery_item.set_first_observation_timestamp_millis( - absl::ToInt64Milliseconds(absl::Now() - absl::UnixEpoch())); - discovery_item.set_state(proto::StoredDiscoveryItem::STATE_ENABLED); - discovery_item.set_icon_fife_url( - metadata->GetResponse().device().image_url()); - discovery_item.set_icon_png(metadata->GetResponse().image()); - discovery_item.add_stored_relevances()->mutable_relevance()->set_evaluation( - proto::Evaluation::EVALUATION_GREAT); - discovery_item.set_last_user_experience( - proto::StoredDiscoveryItem::EXPERIENCE_GOOD); - if (details.has_anti_spoofing_key_pair()) { - discovery_item.set_authentication_public_key_secp256r1( - details.anti_spoofing_key_pair().public_key()); - } - if (details.has_true_wireless_images()) { - auto* images = discovery_item.mutable_fast_pair_information() - ->mutable_true_wireless_images(); - images->set_left_bud_url(details.true_wireless_images().left_bud_url()); - images->set_right_bud_url(details.true_wireless_images().right_bud_url()); - images->set_case_url(details.true_wireless_images().case_url()); - } - - auto* fast_pair_strings = discovery_item.mutable_fast_pair_strings(); - fast_pair_strings->set_tap_to_pair_with_account( - strings.initial_notification_description()); - fast_pair_strings->set_tap_to_pair_without_account( - strings.initial_notification_description_no_account()); - fast_pair_strings->set_initial_pairing_description( - strings.initial_pairing_description()); - fast_pair_strings->set_pairing_finished_companion_app_installed( - strings.connect_success_companion_app_installed()); - fast_pair_strings->set_pairing_finished_companion_app_not_installed( - strings.connect_success_companion_app_not_installed()); - fast_pair_strings->set_subsequent_pairing_description( - strings.subsequent_pairing_description()); - fast_pair_strings->set_retroactive_pairing_description( - strings.retroactive_pairing_description()); - fast_pair_strings->set_wait_app_launch_description( - strings.wait_launch_companion_app_description()); - fast_pair_strings->set_pairing_fail_description( - strings.fail_connect_go_to_settings_description()); - fast_pair_strings->set_confirm_pin_title(strings.confirm_pin_title()); - fast_pair_strings->set_confirm_pin_description( - strings.confirm_pin_description()); - fast_pair_strings->set_sync_contacts_title(strings.sync_contacts_title()); - fast_pair_strings->set_sync_contacts_description( - strings.sync_contacts_description()); - fast_pair_strings->set_sync_sms_title(strings.sync_sms_title()); - fast_pair_strings->set_sync_sms_description(strings.sync_sms_description()); - - device->set_discovery_item_bytes(discovery_item.SerializeAsString()); -} - -void BuildFastPairInfo(::nearby::fastpair::proto::FastPairInfo* fast_pair_info, - proto::OptInStatus opt_in_status) { - fast_pair_info->set_opt_in_status(opt_in_status); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/proto/proto_builder.h b/fastpair/proto/proto_builder.h deleted file mode 100644 index f1fd644579..0000000000 --- a/fastpair/proto/proto_builder.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_BUILDER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_BUILDER_H_ - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/proto/data.proto.h" - -namespace nearby { -namespace fastpair { - -// Builds FastPairInfo proto from a FastPairDevice instance -void BuildFastPairInfo(::nearby::fastpair::proto::FastPairInfo* fast_pair_info, - const FastPairDevice& fast_pair_device); - -// Builds FastPairInfo proto from OptInStatus -void BuildFastPairInfo(::nearby::fastpair::proto::FastPairInfo* fast_pair_info, - proto::OptInStatus opt_in_status); - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_BUILDER_H_ diff --git a/fastpair/proto/proto_builder_test.cc b/fastpair/proto/proto_builder_test.cc deleted file mode 100644 index f00bf419cc..0000000000 --- a/fastpair/proto/proto_builder_test.cc +++ /dev/null @@ -1,82 +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. - -#include "fastpair/proto/proto_builder.h" - -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/protocol.h" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/enum.proto.h" -#include "fastpair/proto/fast_pair_string.proto.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr char kModelId[] = "9adb11"; -constexpr char kBleAddress[] = "11::22::33::44::55::66"; -constexpr char kPublicAddress[] = "20:64:DE:40:F8:93"; -constexpr char kDisplayName[] = "Test Device"; -constexpr char kInitialPairingdescription[] = "InitialPairingdescription"; -constexpr char kAccountKey[] = "04b85786180add47fb81a04a8ce6b0de"; -constexpr char kExpectedSha256Hash[] = - "6353c0075a35b7d81bb30a6190ab246da4b8c55a6111d387400579133c090ed8"; -TEST(ProtoBuilderTest, BuildFastPairInfo) { - // Creates a FastPaireDevice instance. - FastPairDevice device(kModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - device.SetAccountKey(account_key); - device.SetPublicAddress(kPublicAddress); - device.SetDisplayName(kDisplayName); - proto::GetObservedDeviceResponse response; - auto* observed_device_strings = response.mutable_strings(); - observed_device_strings->set_initial_pairing_description( - kInitialPairingdescription); - DeviceMetadata device_metadata(response); - device.SetMetadata(device_metadata); - - // Builds FastPairInfo from the created FastPairDevice - proto::FastPairInfo fast_proto_info; - BuildFastPairInfo(&fast_proto_info, device); - - EXPECT_EQ(fast_proto_info.device().account_key(), account_key.GetAsBytes()); - EXPECT_EQ(absl::BytesToHexString( - fast_proto_info.device().sha256_account_key_public_address()), - kExpectedSha256Hash); - proto::StoredDiscoveryItem stored_discovery_item; - EXPECT_TRUE(stored_discovery_item.ParseFromString( - fast_proto_info.device().discovery_item_bytes())); - EXPECT_EQ(stored_discovery_item.title(), kDisplayName); - proto::FastPairStrings fast_pair_strings = - stored_discovery_item.fast_pair_strings(); - EXPECT_EQ(fast_pair_strings.initial_pairing_description(), - kInitialPairingdescription); -} - -TEST(ProtoBuilderTest, BuildFastPairInfoForOptIn) { - proto::FastPairInfo fast_proto_info; - BuildFastPairInfo(&fast_proto_info, - proto::OptInStatus::OPT_IN_STATUS_OPTED_IN); - EXPECT_EQ(fast_proto_info.opt_in_status(), - proto::OptInStatus::OPT_IN_STATUS_OPTED_IN); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/proto/proto_to_json.cc b/fastpair/proto/proto_to_json.cc deleted file mode 100644 index faaae014bd..0000000000 --- a/fastpair/proto/proto_to_json.cc +++ /dev/null @@ -1,149 +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. - -#include "fastpair/proto/proto_to_json.h" - -#include -#include - -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "nlohmann/json.hpp" -#include "nlohmann/json_fwd.hpp" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { -namespace { -using json = ::nlohmann::json; -std::string Encode(absl::string_view str) { - return absl::WebSafeBase64Escape(str); -} - -std::string TruncateString(absl::string_view str) { - if (str.length() <= 10) return std::string(str); - return absl::StrCat(str.substr(0, 5), "...", - str.substr(str.length() - 5, str.length())); -} -} // namespace - -// GetObservedDeviceRequest/Response -json FastPairProtoToJson( - const nearby::fastpair::proto::GetObservedDeviceRequest& request) { - json dict = json::object(); - dict["device_id"] = request.device_id(); - dict["mode"] = request.mode(); - dict["locale"] = request.locale(); - dict["hex_device_id"] = request.hex_device_id(); - dict["max_icon_size_pixels"] = request.max_icon_size_pixels(); - return dict; -} - -json FastPairProtoToJson( - const nearby::fastpair::proto::GetObservedDeviceResponse& response) { - json dict = json::object(); - dict["device"] = FastPairProtoToJson(response.device()); - dict["observed_device_strings "] = FastPairProtoToJson(response.strings()); - return dict; -} - -// UserReadDevicesRequest/Response -json FastPairProtoToJson( - const nearby::fastpair::proto::UserReadDevicesRequest& request) { - json dict = json::object(); - dict["secondary_id"] = request.secondary_id(); - return dict; -} - -json FastPairProtoToJson( - const nearby::fastpair::proto::UserReadDevicesResponse& response) { - json dict = json::object(); - json fast_pair_info_list = json::array(); - for (const auto& fast_pair_info : response.fast_pair_info()) { - fast_pair_info_list.push_back(FastPairProtoToJson(fast_pair_info)); - } - dict["fast_pair_info"] = std::move(fast_pair_info_list); - return dict; -} - -// UserWriteDeviceRequest -json FastPairProtoToJson( - const nearby::fastpair::proto::UserWriteDeviceRequest& request) { - json dict = json::object(); - dict["fast_pair_info"] = FastPairProtoToJson(request.fast_pair_info()); - return dict; -} - -// UserDeleteDeviceRequest/Response -json FastPairProtoToJson( - const nearby::fastpair::proto::UserDeleteDeviceRequest& request) { - json dict = json::object(); - dict["hex_account_key"] = TruncateString(Encode(request.hex_account_key())); - return dict; -} - -json FastPairProtoToJson( - const nearby::fastpair::proto::UserDeleteDeviceResponse& response) { - json dict = json::object(); - dict["success"] = response.success(); - json error_messages = json::array(); - for (const auto& error_message : response.error_messages()) { - error_messages.push_back(error_message); - } - dict["error_messages"] = std::move(error_messages); - return dict; -} - -json FastPairProtoToJson( - const nearby::fastpair::proto::FastPairInfo& fast_pair_info) { - json dict = json::object(); - if (fast_pair_info.has_device()) { - dict["device"] = FastPairProtoToJson(fast_pair_info.device()); - } else if (fast_pair_info.has_opt_in_status()) { - dict["opt_in_status"] = fast_pair_info.opt_in_status(); - } - return dict; -} - -json FastPairProtoToJson( - const nearby::fastpair::proto::FastPairDevice& fast_pair_device) { - json dict = json::object(); - dict["account_key"] = TruncateString(Encode(fast_pair_device.account_key())); - return dict; -} - -json FastPairProtoToJson( - const nearby::fastpair::proto::ObservedDeviceStrings& strings) { - json dict = json::object(); - dict["locale"] = strings.locale(); - return dict; -} - -json FastPairProtoToJson(const nearby::fastpair::proto::Device& device) { - json dict = json::object(); - dict["id"] = device.id(); - dict["project_number"] = device.project_number(); - dict["notification_type"] = device.notification_type(); - dict["image_url"] = device.image_url(); - dict["name"] = device.name(); - dict["intent_uri"] = device.intent_uri(); - dict["ble_tx_power"] = device.ble_tx_power(); - dict["trigger_distance"] = device.trigger_distance(); - dict["device_type"] = device.device_type(); - dict["display_name"] = device.display_name(); - return dict; -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/proto/proto_to_json.h b/fastpair/proto/proto_to_json.h deleted file mode 100644 index 7aa9b33ad5..0000000000 --- a/fastpair/proto/proto_to_json.h +++ /dev/null @@ -1,62 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_TO_JSON_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_TO_JSON_H_ - -#include "nlohmann/json_fwd.hpp" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" - -namespace nearby { -namespace fastpair { -// Converts Fast Pair protos to readable, JSON-style dictionaries. - -// GetObservedDeviceRequest/Response -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::GetObservedDeviceRequest& request); -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::GetObservedDeviceResponse& response); - -// UserReadDevicesRequest/Response -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::UserReadDevicesRequest& request); -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::UserReadDevicesResponse& response); - -// UserWriteDeviceRequest -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::UserWriteDeviceRequest& request); - -// UserDeleteDeviceRequest/Response -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::UserDeleteDeviceRequest& request); -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::UserDeleteDeviceResponse& response); - -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::FastPairInfo& fast_pair_info); - -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::FastPairDevice& fast_pair_device); - -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::ObservedDeviceStrings& strings); - -nlohmann::json FastPairProtoToJson( - const nearby::fastpair::proto::Device& device); -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_TO_JSON_H_ diff --git a/fastpair/repository/BUILD b/fastpair/repository/BUILD deleted file mode 100644 index bc10943c88..0000000000 --- a/fastpair/repository/BUILD +++ /dev/null @@ -1,172 +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. - -licenses(["notice"]) - -cc_library( - name = "repository", - srcs = [ - "fast_pair_repository.cc", - ], - hdrs = [ - "fast_pair_repository.h", - ], - copts = [ - "-Ithird_party", - ], - visibility = ["//fastpair:__subpackages__"], - deps = [ - "//fastpair/common", - "//fastpair/proto:fastpair_cc_proto", - "//internal/base:bluetooth_address", - "//internal/crypto_cros", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - ], -) - -cc_library( - name = "repository_impl", - srcs = [ - "fast_pair_repository_impl.cc", - ], - hdrs = [ - "fast_pair_repository_impl.h", - ], - copts = [ - "-Ithird_party", - ], - visibility = ["//fastpair:__subpackages__"], - deps = [ - ":repository", - "//fastpair/common", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/proto:proto_builder", - "//fastpair/server_access", - "//internal/base", - "//internal/platform:types", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - ], -) - -cc_library( - name = "device_repository", - srcs = [ - "fast_pair_device_repository.cc", - ], - hdrs = [ - "fast_pair_device_repository.h", - ], - visibility = ["//fastpair:__subpackages__"], - deps = [ - "//fastpair/common", - "//internal/base", - "//internal/platform:types", - "@com_google_absl//absl/functional:any_invocable", - ], -) - -cc_library( - name = "test_support", - srcs = ["fake_fast_pair_repository.cc"], - hdrs = [ - "fake_fast_pair_repository.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":repository", - "//fastpair/common", - "//fastpair/proto:fastpair_cc_proto", - "//internal/base", - "//internal/platform:types", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - ], -) - -cc_library( - name = "mocks", - testonly = 1, - hdrs = [ - "mock_fast_pair_repository.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":repository", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_for_library_testonly", - ], -) - -cc_test( - name = "device_repository_test", - srcs = [ - "fast_pair_device_repository_test.cc", - ], - deps = [ - ":device_repository", - "//fastpair/common", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings:string_view", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_repository_test", - srcs = [ - "fast_pair_repository_test.cc", - ], - copts = [ - "-Ithird_party", - ], - deps = [ - ":repository", - "//fastpair/common", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_repository_impl_test", - srcs = [ - "fast_pair_repository_impl_test.cc", - ], - copts = [ - "-Ithird_party", - ], - deps = [ - ":repository_impl", - "//fastpair/common", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/proto:proto_builder", - "//fastpair/server_access:test_support", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/repository/fake_fast_pair_repository.cc b/fastpair/repository/fake_fast_pair_repository.cc deleted file mode 100644 index 713a615dc5..0000000000 --- a/fastpair/repository/fake_fast_pair_repository.cc +++ /dev/null @@ -1,146 +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. - -#include "fastpair/repository/fake_fast_pair_repository.h" - -#include -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/account_key_filter.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/enum.proto.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/repository/fast_pair_repository.h" - -namespace nearby { -namespace fastpair { -void FakeFastPairRepository::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void FakeFastPairRepository::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -void FakeFastPairRepository::SetFakeMetadata(absl::string_view hex_model_id, - proto::Device metadata) { - proto::GetObservedDeviceResponse response; - *response.mutable_device() = metadata; - data_[hex_model_id] = std::make_unique(response); -} - -void FakeFastPairRepository::ClearFakeMetadata(absl::string_view hex_model_id) { - data_.erase(hex_model_id); -} - -void FakeFastPairRepository::SetResultOfCheckIfAssociatedWithCurrentAccount( - std::optional account_key, - std::optional model_id) { - account_key_ = std::move(account_key); - model_id_ = std::move(model_id); -} - -void FakeFastPairRepository::SetResultOfWriteAccountAssociationToFootprints( - absl::Status status) { - write_account_association_to_footprints_ = status; -} - -void FakeFastPairRepository::SetResultOfDeleteAssociatedDeviceByAccountKey( - absl::Status status) { - deleted_associated_device_ = status; -} - -void FakeFastPairRepository::SetResultOfIsDeviceSavedToAccount( - absl::Status status) { - is_device_saved_to_account_ = status; -} - -void FakeFastPairRepository::GetDeviceMetadata( - absl::string_view hex_model_id, DeviceMetadataCallback callback) { - executor_.Execute([this, callback = std::move(callback), - hex_model_id = std::string(hex_model_id)]() mutable { - if (data_.contains(hex_model_id)) { - std::move(callback)(*data_[hex_model_id]); - } else { - std::move(callback)(std::nullopt); - } - }); -} - -void FakeFastPairRepository::GetUserSavedDevices() { - proto::OptInStatus opt_in_status = proto::OptInStatus::OPT_IN_STATUS_UNKNOWN; - std::vector saved_devices; - for (auto& observer : observers_.GetObservers()) { - observer->OnGetUserSavedDevices(opt_in_status, saved_devices); - } -} - -void FakeFastPairRepository::WriteAccountAssociationToFootprints( - FastPairDevice& device, OperationCallback callback) { - executor_.Execute([callback = std::move(callback), this]() mutable { - callback(write_account_association_to_footprints_); - }); -} - -void FakeFastPairRepository::DeleteAssociatedDeviceByAccountKey( - const AccountKey& account_key, OperationCallback callback) { - executor_.Execute([callback = std::move(callback), this]() mutable { - callback(deleted_associated_device_); - }); -} - -void FakeFastPairRepository::CheckIfAssociatedWithCurrentAccount( - AccountKeyFilter& account_key_filter, CheckAccountKeysCallback callback) { - executor_.Execute([this, callback = std::move(callback)]() mutable { - std::move(callback)(account_key_, model_id_); - }); -} - -void FakeFastPairRepository::IsDeviceSavedToAccount( - absl::string_view mac_address, OperationCallback callback) { - executor_.Execute([callback = std::move(callback), this]() mutable { - callback(is_device_saved_to_account_); - }); -} - -std::unique_ptr FakeFastPairRepository::Create( - absl::string_view model_id, absl::string_view public_anti_spoof_key) { - proto::Device metadata; - auto repository = std::make_unique(); - if (public_anti_spoof_key.empty()) { - // Missing ASK is fine for V1 devices. - } else if (public_anti_spoof_key.length() == kPublicKeyByteSize) { - metadata.mutable_anti_spoofing_key_pair()->set_public_key( - public_anti_spoof_key); - } else { - std::string decoded_key; - absl::Base64Unescape(public_anti_spoof_key, &decoded_key); - CHECK_EQ(decoded_key.length(), kPublicKeyByteSize); - metadata.mutable_anti_spoofing_key_pair()->set_public_key(decoded_key); - } - repository->SetFakeMetadata(model_id, metadata); - return repository; -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/repository/fake_fast_pair_repository.h b/fastpair/repository/fake_fast_pair_repository.h deleted file mode 100644 index ef1a7619a2..0000000000 --- a/fastpair/repository/fake_fast_pair_repository.h +++ /dev/null @@ -1,92 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAKE_FAST_PAIR_REPOSITORY_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAKE_FAST_PAIR_REPOSITORY_H_ - -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/base/observer_list.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { -class FakeFastPairRepository : public FastPairRepository { - public: - FakeFastPairRepository() = default; - FakeFastPairRepository(const FakeFastPairRepository&) = delete; - FakeFastPairRepository& operator=(const FakeFastPairRepository&) = delete; - ~FakeFastPairRepository() override = default; - - static std::unique_ptr Create( - absl::string_view model_id, absl::string_view public_anti_spoof_key); - - void SetFakeMetadata(absl::string_view hex_model_id, proto::Device metadata); - void ClearFakeMetadata(absl::string_view hex_model_id); - void SetResultOfWriteAccountAssociationToFootprints(absl::Status status); - void SetResultOfDeleteAssociatedDeviceByAccountKey(absl::Status status); - void SetResultOfCheckIfAssociatedWithCurrentAccount( - std::optional account_key, - std::optional model_id); - void SetResultOfIsDeviceSavedToAccount(absl::Status status); - - // FastPairRepository:: - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; - - void GetDeviceMetadata(absl::string_view hex_model_id, - DeviceMetadataCallback callback) override; - - void GetUserSavedDevices() override; - - void WriteAccountAssociationToFootprints(FastPairDevice& device, - OperationCallback callback) override; - - void DeleteAssociatedDeviceByAccountKey(const AccountKey& account_key, - OperationCallback callback) override; - - void CheckIfAssociatedWithCurrentAccount( - AccountKeyFilter& account_key_filter, - CheckAccountKeysCallback callback) override; - - void IsDeviceSavedToAccount(absl::string_view mac_address, - OperationCallback callback) override; - - private: - absl::flat_hash_map> data_; - - // Results of CheckIfAssociatedWithCurrentAccount - std::optional account_key_; - std::optional model_id_; - // Results of WriteAccountAssociationToFootprints - absl::Status write_account_association_to_footprints_; - // Results of DeleteAssociatedDeviceByAccountKey - absl::Status deleted_associated_device_; - // Results of IsDeviceSavedToAccount - absl::Status is_device_saved_to_account_; - ObserverList observers_; - SingleThreadExecutor executor_; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAKE_FAST_PAIR_REPOSITORY_H_ diff --git a/fastpair/repository/fast_pair_device_repository.cc b/fastpair/repository/fast_pair_device_repository.cc deleted file mode 100644 index e219a484d5..0000000000 --- a/fastpair/repository/fast_pair_device_repository.cc +++ /dev/null @@ -1,103 +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. - -#include "fastpair/repository/fast_pair_device_repository.h" - -#include -#include -#include -#include - -#include "fastpair/common/account_key.h" -#include "fastpair/common/fast_pair_device.h" -#include "internal/platform/logging.h" -#include "internal/platform/mutex_lock.h" - -namespace nearby { -namespace fastpair { - -FastPairDevice* FastPairDeviceRepository::AddDevice( - std::unique_ptr device) { - const auto& id = device->GetUniqueId(); - MutexLock lock(&mutex_); - for (auto& item : devices_) { - if (item->GetUniqueId() == id) { - // Overwrite the existing object. - *item = std::move(*device); - return item.get(); - } - } - FastPairDevice* ptr = device.get(); - devices_.push_back(std::move(device)); - return ptr; -} - -void FastPairDeviceRepository::RemoveDevice(const FastPairDevice* device) { - std::unique_ptr fast_pair_device = ExtractDevice(device); - if (fast_pair_device == nullptr) return; - // Tasks running in the background may still be referencing `device`. - // Deferring the destruction to the background thread should prevent - // use-after-free errors. - executor_->Execute([this, fast_pair_device = std::move(fast_pair_device)]() { - for (auto* callback : observers_.GetObservers()) { - (*callback)(*fast_pair_device); - } - NEARBY_LOGS(VERBOSE) << "Destroyed FP device: " << *fast_pair_device; - }); -} - -std::optional FastPairDeviceRepository::FindDevice( - absl::string_view mac_address) { - MutexLock lock(&mutex_); - auto it = std::find_if(devices_.begin(), devices_.end(), - [&](const std::unique_ptr& device) { - return device->GetBleAddress() == mac_address || - device->GetPublicAddress() == mac_address; - }); - if (it != devices_.end()) { - return it->get(); - } else { - return std::nullopt; - } -} - -std::optional FastPairDeviceRepository::FindDevice( - const AccountKey& account_key) { - MutexLock lock(&mutex_); - auto it = std::find_if(devices_.begin(), devices_.end(), - [&](const std::unique_ptr& device) { - return device->GetAccountKey() == account_key; - }); - if (it != devices_.end()) { - return it->get(); - } else { - return std::nullopt; - } -} - -std::unique_ptr FastPairDeviceRepository::ExtractDevice( - const FastPairDevice* device) { - MutexLock lock(&mutex_); - auto it = std::find_if(devices_.begin(), devices_.end(), - [&](const std::unique_ptr& item) { - return item.get() == device; - }); - if (it == devices_.end()) return nullptr; - std::unique_ptr fast_pair_device = std::move(*it); - devices_.erase(it); - return fast_pair_device; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/repository/fast_pair_device_repository.h b/fastpair/repository/fast_pair_device_repository.h deleted file mode 100644 index 5240122f49..0000000000 --- a/fastpair/repository/fast_pair_device_repository.h +++ /dev/null @@ -1,79 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_DEVICE_REPOSITORY_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_DEVICE_REPOSITORY_H_ - -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/fast_pair_device.h" -#include "internal/base/observer_list.h" -#include "internal/platform/mutex.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -// Owner of `FastPairDevice` instances. -class FastPairDeviceRepository { - public: - // Called on the background thread right before `device` is destroyed. - // The callbacks are not called when FastPairDeviceRepository is - // destructing. - using RemoveDeviceCallback = - absl::AnyInvocable; - - explicit FastPairDeviceRepository(SingleThreadExecutor* executor) - : executor_(executor) {} - - // Adds device to the repository and takes over ownership. - // If a device with the same MAC address is already in the repository, it is - // replaced. - // Returns a stable, non-null pointer to the inserted element. The pointer is - // valid until `RemoveDevice()`. - FastPairDevice* AddDevice(std::unique_ptr device); - - // Removes the device and frees resources. - void RemoveDevice(const FastPairDevice* device); - - // Finds a device matching the mac address. The mac address can be either BT - // or BLE. - std::optional FindDevice(absl::string_view mac_address); - - // Finds a device matching the account key. - std::optional FindDevice(const AccountKey& account_key); - - void AddObserver(RemoveDeviceCallback* observer) { - observers_.AddObserver(observer); - } - void RemoveObserver(RemoveDeviceCallback* observer) { - observers_.RemoveObserver(observer); - } - - private: - // Removes `device` from `devices_`. - std::unique_ptr ExtractDevice(const FastPairDevice* device); - Mutex mutex_; - SingleThreadExecutor* executor_; - std::vector> devices_ ABSL_GUARDED_BY(mutex_); - ObserverList observers_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_DEVICE_REPOSITORY_H_ diff --git a/fastpair/repository/fast_pair_device_repository_test.cc b/fastpair/repository/fast_pair_device_repository_test.cc deleted file mode 100644 index e476e1d064..0000000000 --- a/fastpair/repository/fast_pair_device_repository_test.cc +++ /dev/null @@ -1,144 +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. - -#include "fastpair/repository/fast_pair_device_repository.h" - -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/protocol.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { -namespace { - -constexpr absl::string_view kModelId = "123456"; -constexpr absl::string_view kBleAddress = "AA:BB:CC:DD:EE:FF"; -constexpr absl::string_view kBtAddress = "12:34:56:78:90:AB"; -constexpr absl::string_view kAccountKey = "04b85786180add47fb81a04a8ce6b0de"; - -TEST(FastPairDeviceRepositoryTest, AddDevice) { - SingleThreadExecutor executor; - FastPairDeviceRepository repo(&executor); - - FastPairDevice* device = repo.AddDevice(std::make_unique( - kModelId, kBleAddress, Protocol::kFastPairInitialPairing)); - - ASSERT_NE(device, nullptr); - EXPECT_EQ(device->GetModelId(), kModelId); - executor.Shutdown(); -} - -TEST(FastPairDeviceRepositoryTest, FindDeviceByBleAddress) { - SingleThreadExecutor executor; - FastPairDeviceRepository repo(&executor); - repo.AddDevice(std::make_unique( - kModelId, kBleAddress, Protocol::kFastPairInitialPairing)); - - auto opt_device = repo.FindDevice(kBleAddress); - - ASSERT_TRUE(opt_device.has_value()); - FastPairDevice* device = opt_device.value(); - ASSERT_NE(device, nullptr); - EXPECT_EQ(device->GetModelId(), kModelId); - executor.Shutdown(); -} - -TEST(FastPairDeviceRepositoryTest, FindDeviceByBtAddress) { - SingleThreadExecutor executor; - FastPairDeviceRepository repo(&executor); - auto fast_pair_device = - std::make_unique(Protocol::kFastPairInitialPairing); - fast_pair_device->SetPublicAddress(kBtAddress); - repo.AddDevice(std::move(fast_pair_device)); - - auto opt_device = repo.FindDevice(kBtAddress); - - ASSERT_TRUE(opt_device.has_value()); - FastPairDevice* device = opt_device.value(); - ASSERT_NE(device, nullptr); - EXPECT_EQ(device->GetPublicAddress(), kBtAddress); - executor.Shutdown(); -} - -TEST(FastPairDeviceRepositoryTest, FindDeviceByAccountKey) { - SingleThreadExecutor executor; - FastPairDeviceRepository repo(&executor); - auto fast_pair_device = - std::make_unique(Protocol::kFastPairInitialPairing); - fast_pair_device->SetPublicAddress(kBtAddress); - fast_pair_device->SetAccountKey(AccountKey(kAccountKey)); - repo.AddDevice(std::move(fast_pair_device)); - - auto opt_device = repo.FindDevice(AccountKey(kAccountKey)); - - ASSERT_TRUE(opt_device.has_value()); - FastPairDevice* device = opt_device.value(); - ASSERT_NE(device, nullptr); - EXPECT_EQ(device->GetAccountKey().GetAsBytes(), kAccountKey); - executor.Shutdown(); -} - -TEST(FastPairDeviceRepositoryTest, RemoveDevice) { - SingleThreadExecutor executor; - FastPairDeviceRepository repo(&executor); - FastPairDevice* device = repo.AddDevice(std::make_unique( - kModelId, kBleAddress, Protocol::kFastPairInitialPairing)); - - repo.RemoveDevice(device); - - EXPECT_FALSE(repo.FindDevice(kBleAddress).has_value()); - executor.Shutdown(); -} - -TEST(FastPairDeviceRepositoryTest, RemovingNonRegisteredDeviceIsSafe) { - SingleThreadExecutor executor; - FastPairDeviceRepository repo(&executor); - FastPairDevice* device = repo.AddDevice(std::make_unique( - kModelId, kBleAddress, Protocol::kFastPairInitialPairing)); - FastPairDevice other_device(Protocol::kFastPairInitialPairing); - repo.RemoveDevice(device); - - // `device` already removed. - repo.RemoveDevice(device); - // `other_device` was never added. - repo.RemoveDevice(&other_device); - - EXPECT_FALSE(repo.FindDevice(kBleAddress).has_value()); - executor.Shutdown(); -} - -TEST(FastPairDeviceRepositoryTest, RemovingDeviceCallsCallback) { - SingleThreadExecutor executor; - FastPairDeviceRepository repo(&executor); - FastPairDevice* device = repo.AddDevice(std::make_unique( - kModelId, kBleAddress, Protocol::kFastPairInitialPairing)); - FastPairDeviceRepository::RemoveDeviceCallback callback = - [&](const FastPairDevice& device) {}; - repo.AddObserver(&callback); - repo.RemoveDevice(device); - - EXPECT_FALSE(repo.FindDevice(kBleAddress).has_value()); - executor.Shutdown(); -} - -} // namespace - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/repository/fast_pair_repository.cc b/fastpair/repository/fast_pair_repository.cc deleted file mode 100644 index 183bd6e045..0000000000 --- a/fastpair/repository/fast_pair_repository.cc +++ /dev/null @@ -1,67 +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. - -#include "fastpair/repository/fast_pair_repository.h" - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/base/bluetooth_address.h" -#include "internal/crypto_cros/sha2.h" - -namespace nearby { -namespace fastpair { -namespace { -FastPairRepository* g_instance = nullptr; -constexpr int kBluetoothAddressSize = 6; -} - -FastPairRepository* FastPairRepository::Get() { - CHECK(g_instance); - return g_instance; -} - -void FastPairRepository::SetInstance(FastPairRepository* instance) { - DCHECK(!g_instance || !instance); - g_instance = instance; -} - -FastPairRepository::FastPairRepository() { SetInstance(this); } - -FastPairRepository::~FastPairRepository() { SetInstance(nullptr); } - -// static -std::string FastPairRepository::GenerateSha256OfAccountKeyAndMacAddress( - const AccountKey& account_key, absl::string_view public_address) { - std::string account_key_str = std::string(account_key.GetAsBytes()); - std::vector concat_bytes(account_key_str.begin(), - account_key_str.end()); - - std::vector public_address_bytes(kBluetoothAddressSize); - device::ParseBluetoothAddress( - public_address, - absl::MakeSpan(public_address_bytes.data(), kBluetoothAddressSize)); - - concat_bytes.insert(concat_bytes.end(), public_address_bytes.begin(), - public_address_bytes.end()); - std::array hashed = - crypto::SHA256Hash(concat_bytes); - - return std::string(hashed.begin(), hashed.end()); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/repository/fast_pair_repository.h b/fastpair/repository/fast_pair_repository.h deleted file mode 100644 index 1f1ea902f5..0000000000 --- a/fastpair/repository/fast_pair_repository.h +++ /dev/null @@ -1,98 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_REPOSITORY_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_REPOSITORY_H_ - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/account_key_filter.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/enum.proto.h" - -namespace nearby { -namespace fastpair { -using DeviceMetadataCallback = - absl::AnyInvocable device_metadata)>; -using CheckAccountKeysCallback = - absl::AnyInvocable account_key, - std::optional model_id)>; -using OperationCallback = absl::AnyInvocable; - -class FastPairRepository { - public: - class Observer { - public: - virtual ~Observer() = default; - - virtual void OnGetUserSavedDevices( - const proto::OptInStatus& opt_in_status, - const std::vector& devices) = 0; - }; - - static FastPairRepository* Get(); - - // Computes and returns the SHA256 of the concatenation of the given - // |account_key| and |public_address|. - static std::string GenerateSha256OfAccountKeyAndMacAddress( - const AccountKey& account_key, absl::string_view public_address); - - FastPairRepository(); - virtual ~FastPairRepository(); - - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; - - virtual void GetDeviceMetadata(absl::string_view hex_model_id, - DeviceMetadataCallback callback) = 0; - - // Gets a list of devices saved to the current user's account and the user's - // opt in status for saving future devices to their account. - virtual void GetUserSavedDevices() = 0; - - // Stores the given |account_key| for a |device| on the Footprints server. - virtual void WriteAccountAssociationToFootprints( - FastPairDevice& device, OperationCallback callback) = 0; - - // Deletes the associated data for a given |account_key|. - virtual void DeleteAssociatedDeviceByAccountKey( - const AccountKey& account_key, OperationCallback callback) = 0; - - // Checks all account keys associated with current user's account against the - // given filter. If a match is found, return the account key. - virtual void CheckIfAssociatedWithCurrentAccount( - AccountKeyFilter& account_key_filter, - CheckAccountKeysCallback callback) = 0; - - // Checks if a device with an address |mac_address| is already saved to - // the user's account by cross referencing the |mac_address| with any - // associated account keys. - virtual void IsDeviceSavedToAccount(absl::string_view mac_address, - OperationCallback callback) = 0; - - protected: - static void SetInstance(FastPairRepository* instance); -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_REPOSITORY_H_ diff --git a/fastpair/repository/fast_pair_repository_impl.cc b/fastpair/repository/fast_pair_repository_impl.cc deleted file mode 100644 index 8dea41cdb6..0000000000 --- a/fastpair/repository/fast_pair_repository_impl.cc +++ /dev/null @@ -1,281 +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. - -#include "fastpair/repository/fast_pair_repository_impl.h" - -#include -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/enum.proto.h" -#include "fastpair/proto/proto_builder.h" -#include "internal/platform/logging.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -namespace { -// This forget pattern is defined in the Android codebase as FORGET_PREFIX_BYTE -// and FORGET_PREFIX_LENGTH_IN_BYTES. Currently, those values evaluate to the -// string of bytes defined below, which is used as the prefix for the sha256 -// field of the device. -constexpr absl::string_view kForgetPattern = "\xf0\xf0\xf0\xf0"; - -// For all intents and purposes, a device that has the "Forget pattern" is no -// longer associated to the user's account, and should be treated as removed. -bool DoesDeviceHaveForgetPattern(const proto::FastPairDevice& device) { - // The device info is modified to have no account key upon removal from - // Fast Pair Saved Devices - if (device.account_key().empty() || - device.sha256_account_key_public_address().empty()) { - return true; - } - - // To match Android behavior, we check if the SHA256 of a device begins with - // the Forget pattern, defined in Android Fast Pair code. When a device is - // forgotten from Android Bluetooth Settings, the SHA256 hash is modified to - // contain this pattern. - return (device.sha256_account_key_public_address().compare( - 0, kForgetPattern.length(), kForgetPattern) == 0); -} - -// Checks if the mac address of a FastPairDevice is the same as the given -// |mac_address| by checking if the SHA256 from the given |device| equals to -// SHA256(concat(account_key of |device|, |mac_address|)). -bool IsDeviceSha256Matched(const proto::FastPairDevice& device, - absl::string_view mac_address) { - if (DoesDeviceHaveForgetPattern(device)) { - return false; - } - - return device.sha256_account_key_public_address() == - FastPairRepository::GenerateSha256OfAccountKeyAndMacAddress( - AccountKey(device.account_key()), mac_address); -} -} // namespace - -FastPairRepositoryImpl::FastPairRepositoryImpl(FastPairClient* fast_pair_client) - : fast_pair_client_(fast_pair_client) {} - -void FastPairRepositoryImpl::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void FastPairRepositoryImpl::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -void FastPairRepositoryImpl::GetDeviceMetadata( - absl::string_view hex_model_id, DeviceMetadataCallback callback) { - NEARBY_LOGS(INFO) << __func__ << " with model id= " << hex_model_id; - executor_.Execute( - "Get Device Metadata", [this, hex_model_id = std::string(hex_model_id), - callback = std::move(callback)]() mutable { - NEARBY_LOGS(INFO) << __func__ << ": Start to get devic metadata."; - proto::GetObservedDeviceRequest request; - int64_t device_id; - CHECK(absl::SimpleHexAtoi(hex_model_id, &device_id)); - request.set_device_id(device_id); - request.set_mode(proto::GetObservedDeviceRequest::MODE_RELEASE); - absl::StatusOr response = - fast_pair_client_->GetObservedDevice(request); - if (response.ok()) { - NEARBY_LOGS(WARNING) << "Got GetObservedDeviceResponse from backend."; - metadata_cache_[hex_model_id] = - std::make_unique(response.value()); - // TODO(b/289139378) : save device's metadata in local cache. - callback(*metadata_cache_[hex_model_id]); - } else { - NEARBY_LOGS(WARNING) - << "Failed to get GetObservedDeviceResponse from backend."; - callback(std::nullopt); - } - }); -} - -void FastPairRepositoryImpl::WriteAccountAssociationToFootprints( - FastPairDevice& device, OperationCallback callback) { - proto::UserWriteDeviceRequest request; - auto* fast_pair_info = request.mutable_fast_pair_info(); - BuildFastPairInfo(fast_pair_info, device); - executor_.Execute( - "Write associated device", [this, request = std::move(request), - callback = std::move(callback)]() mutable { - NEARBY_LOGS(INFO) - << __func__ - << ": Start to write account associated device to footprints."; - absl::StatusOr response = - fast_pair_client_->UserWriteDevice(request); - if (response.ok()) { - NEARBY_LOGS(INFO) - << __func__ << "Got GetWriteDeviceResponse from backend."; - std::move(callback)(absl::OkStatus()); - } else { - NEARBY_LOGS(WARNING) - << __func__ - << "Failed to get GetWriteDeviceResponse from backend."; - std::move(callback)(response.status()); - } - }); -} - -void FastPairRepositoryImpl::DeleteAssociatedDeviceByAccountKey( - const AccountKey& account_key, OperationCallback callback) { - std::string hex_string = absl::BytesToHexString(account_key.GetAsBytes()); - absl::AsciiStrToUpper(&hex_string); - executor_.Execute( - "Delete associated device", - [this, hex_account_key = std::move(hex_string), - callback = std::move(callback)]() mutable { - NEARBY_LOGS(INFO) - << __func__ - << ": Start to delete account associated device from footprints"; - proto::UserDeleteDeviceRequest request; - request.set_hex_account_key(hex_account_key); - absl::StatusOr response = - fast_pair_client_->UserDeleteDevice(request); - if (response.ok()) { - if (response->success()) { - NEARBY_LOGS(INFO) - << __func__ << "Successfully deleted associated device."; - std::move(callback)(absl::OkStatus()); - } else { - NEARBY_LOGS(WARNING) << __func__ << "Failed to delete device."; - std::move(callback)( - absl::InternalError("Failed to delete device.")); - } - } else { - NEARBY_LOGS(WARNING) - << __func__ - << "Failed to get UserDeleteDeviceResponse from backend."; - std::move(callback)(response.status()); - } - }); -} - -void FastPairRepositoryImpl::GetUserSavedDevices() { - executor_.Execute("Get associated devices", [this]() mutable { - NEARBY_LOGS(INFO) << __func__ - << ": Start to get all account associated devices."; - proto::UserReadDevicesRequest request; - absl::StatusOr response = - fast_pair_client_->UserReadDevices(request); - if (!response.ok()) { - NEARBY_LOGS(WARNING) - << __func__ << "Failed to get UserReadDevicesResponse from backend."; - return; - } - NEARBY_LOGS(INFO) << __func__ - << "Got UserReadDevicesResponse from backend."; - proto::OptInStatus opt_in_status = - proto::OptInStatus::OPT_IN_STATUS_UNKNOWN; - std::vector saved_devices; - for (const auto& info : response->fast_pair_info()) { - if (info.has_opt_in_status()) { - opt_in_status = info.opt_in_status(); - } - // We have to check that the devices in Footprints don't use the - // "forget pattern" which Android uses in some cases to mark a device - // as removed from the user's account. - if (!info.has_device() || DoesDeviceHaveForgetPattern(info.device())) { - continue; - } - saved_devices.push_back(info.device()); - } - NEARBY_LOGS(INFO) << __func__ << ": Got " << saved_devices.size() - << " saved devices."; - // TODO(b/289139378) : save device's in local cache. - for (auto& observer : observers_.GetObservers()) { - observer->OnGetUserSavedDevices(opt_in_status, saved_devices); - } - }); -} - -void FastPairRepositoryImpl::CheckIfAssociatedWithCurrentAccount( - AccountKeyFilter& account_key_filter, CheckAccountKeysCallback callback) { - executor_.Execute("Check if associated.", [this, - account_key_filter = - std::move(account_key_filter), - callback = std::move( - callback)]() mutable { - NEARBY_LOGS(INFO) << __func__ - << ": Start to check if associated with current account."; - proto::UserReadDevicesRequest request; - absl::StatusOr response = - fast_pair_client_->UserReadDevices(request); - if (response.ok()) { - for (const auto& info : response->fast_pair_info()) { - if (!info.has_device()) { - continue; - } - AccountKey account_key(info.device().account_key()); - if (!account_key_filter.IsPossiblyInSet(account_key)) { - continue; - } - proto::StoredDiscoveryItem device; - if (device.ParseFromString(info.device().discovery_item_bytes())) { - NEARBY_LOGS(INFO) - << "Account key matched with a paired device: " << device.title(); - std::move(callback)(account_key, device.id()); - return; - } - } - } - NEARBY_LOGS(INFO) << "Account key does not match any paired devices."; - std::move(callback)(std::nullopt, std::nullopt); - }); -} - -void FastPairRepositoryImpl::IsDeviceSavedToAccount( - absl::string_view mac_address, OperationCallback callback) { - executor_.Execute( - "Check is device saved to account.", - [this, mac_address = std::string(mac_address), - callback = std::move(callback)]() mutable { - NEARBY_LOGS(INFO) << __func__ - << ": Start to check is device saved to account."; - proto::UserReadDevicesRequest request; - absl::StatusOr response = - fast_pair_client_->UserReadDevices(request); - if (!response.ok()) { - NEARBY_LOGS(WARNING) - << __func__ - << "Failed to get UserDeleteDeviceResponse from backend."; - std::move(callback)(response.status()); - return; - } - for (const auto& info : response->fast_pair_info()) { - if (info.has_device() && - IsDeviceSha256Matched(info.device(), mac_address)) { - NEARBY_LOGS(VERBOSE) - << __func__ << ": found a SHA256 match for device at address = " - << mac_address; - std::move(callback)(absl::OkStatus()); - return; - } - } - std::move(callback)(absl::NotFoundError("Device " + mac_address + - " is not saved to account.")); - }); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/repository/fast_pair_repository_impl.h b/fastpair/repository/fast_pair_repository_impl.h deleted file mode 100644 index 6e9327c5cc..0000000000 --- a/fastpair/repository/fast_pair_repository_impl.h +++ /dev/null @@ -1,71 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_REPOSITORY_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_REPOSITORY_IMPL_H_ - -#include -#include - -#include "absl/strings/string_view.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "fastpair/server_access/fast_pair_client.h" -#include "internal/base/observer_list.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -class FastPairRepositoryImpl : public FastPairRepository { - public: - explicit FastPairRepositoryImpl(FastPairClient* fast_pair_client); - - FastPairRepositoryImpl(const FastPairRepositoryImpl&) = delete; - FastPairRepositoryImpl& operator=(const FastPairRepositoryImpl&) = delete; - ~FastPairRepositoryImpl() override = default; - - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; - - void GetDeviceMetadata(absl::string_view hex_model_id, - DeviceMetadataCallback callback) override; - - void GetUserSavedDevices() override; - - void WriteAccountAssociationToFootprints(FastPairDevice& device, - OperationCallback callback) override; - - void DeleteAssociatedDeviceByAccountKey(const AccountKey& account_key, - OperationCallback callback) override; - - void CheckIfAssociatedWithCurrentAccount( - AccountKeyFilter& account_key_filter, - CheckAccountKeysCallback callback) override; - - void IsDeviceSavedToAccount(absl::string_view mac_address, - OperationCallback callback) override; - - private: - // A thread for running blocking tasks. - SingleThreadExecutor executor_; - FastPairClient* fast_pair_client_; - absl::flat_hash_map> - metadata_cache_; - ObserverList observers_; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_REPOSITORY_IMPL_H_ diff --git a/fastpair/repository/fast_pair_repository_impl_test.cc b/fastpair/repository/fast_pair_repository_impl_test.cc deleted file mode 100644 index a0374410a1..0000000000 --- a/fastpair/repository/fast_pair_repository_impl_test.cc +++ /dev/null @@ -1,548 +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. - -#include "fastpair/repository/fast_pair_repository_impl.h" - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/fast_pair_string.proto.h" -#include "fastpair/proto/proto_builder.h" -#include "fastpair/server_access/fake_fast_pair_client.h" -#include "internal/platform/count_down_latch.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr absl::string_view kHexModelId = "718C17"; -constexpr absl::string_view kBleAddress = "11:22:33:44:55:66"; -constexpr absl::string_view kPublicAddress = "20:64:DE:40:F8:93"; -constexpr absl::string_view kDisplayName = "Test Device"; -constexpr absl::string_view kAccountKey = "04b85786180add47fb81a04a8ce6b0de"; -constexpr absl::string_view kInitialPairingdescription = - "InitialPairingdescription"; -constexpr absl::string_view kExpectedSha256Hash = - "6353c0075a35b7d81bb30a6190ab246da4b8c55a6111d387400579133c090ed8"; -constexpr absl::Duration kWaitTimeout = absl::Milliseconds(200); - -// A gMock matcher to match proto values. Use this matcher like: -// request/response proto, expected_proto; -// EXPECT_THAT(proto, MatchesProto(expected_proto)); -MATCHER_P( - MatchesProto, expected_proto, - absl::StrCat(negation ? "does not match" : "matches", - testing::PrintToString(expected_proto.SerializeAsString()))) { - return arg.SerializeAsString() == expected_proto.SerializeAsString(); -} - -class FastPairRepositoryObserver : public FastPairRepository::Observer { - public: - explicit FastPairRepositoryObserver(CountDownLatch* latch) { - latch_ = latch; - opt_in_status_ = proto::OptInStatus::OPT_IN_STATUS_UNKNOWN; - devices_ = std::vector(); - } - - void OnGetUserSavedDevices( - const proto::OptInStatus& opt_in_status, - const std::vector& devices) override { - for (const auto& device : devices) { - devices_.push_back(device); - } - opt_in_status_ = opt_in_status; - latch_->CountDown(); - } - - CountDownLatch* latch_ = nullptr; - proto::OptInStatus opt_in_status_; - std::vector devices_; -}; - -TEST(FastPairRepositoryImplTest, MetadataDownloadSuccess) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up proto::GetObservedDeviceResponse - proto::GetObservedDeviceResponse response_proto; - auto* device = response_proto.mutable_device(); - int64_t device_id; - CHECK(absl::SimpleHexAtoi(kHexModelId, &device_id)); - device->set_id(device_id); - auto* observed_device_strings = response_proto.mutable_strings(); - observed_device_strings->set_initial_pairing_description( - kInitialPairingdescription); - fake_fast_pair_client.SetGetObservedDeviceResponse(response_proto); - - CountDownLatch latch(1); - fast_pair_repository->GetDeviceMetadata( - kHexModelId, [&](std::optional device_metadata) { - EXPECT_TRUE(device_metadata.has_value()); - // Verifies proto::GetObservedDeviceResponse is as expected - proto::GetObservedDeviceResponse response = - device_metadata->GetResponse(); - EXPECT_THAT(response, MatchesProto(response_proto)); - EXPECT_EQ(response.device().id(), device_id); - EXPECT_EQ(response.strings().initial_pairing_description(), - kInitialPairingdescription); - latch.CountDown(); - }); - latch.Await(); - - // Verifies proto::GetObservedDeviceRequest is as expected. - proto::GetObservedDeviceRequest expected_request = - fake_fast_pair_client.get_observer_device_request(); - EXPECT_EQ(expected_request.device_id(), device_id); - EXPECT_EQ(expected_request.mode(), - proto::GetObservedDeviceRequest::MODE_RELEASE); -} - -TEST(FastPairRepositoryImplTest, FailedToDownloadMetadata) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - fake_fast_pair_client.SetGetObservedDeviceResponse( - absl::InternalError("No response")); - - CountDownLatch latch(1); - fast_pair_repository->GetDeviceMetadata( - kHexModelId, [&](std::optional device_metadata) { - EXPECT_FALSE(device_metadata.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairRepositoryImplTest, GetUserSavedDevicesSuccess) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up two devices to proto::UserReadDevicesResponse. - // Adds device 1. - proto::UserReadDevicesResponse response_proto; - FastPairDevice device_1(kHexModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - device_1.SetAccountKey(account_key); - device_1.SetPublicAddress(kPublicAddress); - device_1.SetDisplayName(kDisplayName); - proto::GetObservedDeviceResponse get_observed_device_response_1; - auto* observed_device_strings_1 = - get_observed_device_response_1.mutable_strings(); - observed_device_strings_1->set_initial_pairing_description( - kInitialPairingdescription); - DeviceMetadata device_metadata_1(get_observed_device_response_1); - device_1.SetMetadata(device_metadata_1); - auto* fast_pair_info_1 = response_proto.add_fast_pair_info(); - BuildFastPairInfo(fast_pair_info_1, device_1); - // Adds device 2. - auto* fast_pair_info_2 = response_proto.add_fast_pair_info(); - fast_pair_info_2->set_opt_in_status( - proto::OptInStatus::OPT_IN_STATUS_OPTED_IN); - fake_fast_pair_client.SetUserReadDevicesResponse(response_proto); - - // Adds FastPairRepository observer. - CountDownLatch latch(1); - FastPairRepositoryObserver observer(&latch); - EXPECT_EQ(observer.devices_.size(), 0); - EXPECT_EQ(observer.opt_in_status_, proto::OptInStatus::OPT_IN_STATUS_UNKNOWN); - fast_pair_repository->AddObserver(&observer); - - // Get user's saved device from footprints. - fast_pair_repository->GetUserSavedDevices(); - latch.Await(); - - // Verifies user's saved devices are as expected. - EXPECT_EQ(observer.opt_in_status_, - proto::OptInStatus::OPT_IN_STATUS_OPTED_IN); - EXPECT_EQ(observer.devices_.size(), 1); - proto::FastPairDevice saved_device = observer.devices_.front(); - EXPECT_EQ(saved_device.account_key(), account_key.GetAsBytes()); - EXPECT_EQ( - absl::BytesToHexString(saved_device.sha256_account_key_public_address()), - kExpectedSha256Hash); - proto::StoredDiscoveryItem stored_discovery_item; - EXPECT_TRUE(stored_discovery_item.ParseFromString( - saved_device.discovery_item_bytes())); - EXPECT_EQ(stored_discovery_item.title(), kDisplayName); - proto::FastPairStrings fast_pair_strings = - stored_discovery_item.fast_pair_strings(); - EXPECT_EQ(fast_pair_strings.initial_pairing_description(), - kInitialPairingdescription); - fast_pair_repository->RemoveObserver(&observer); -} - -TEST(FastPairRepositoryImplTest, FailedToGetUserSavedDevices) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - fake_fast_pair_client.SetUserReadDevicesResponse( - absl::InternalError("No response")); - - // Adds FastPairRepository observer. - CountDownLatch latch(1); - FastPairRepositoryObserver observer(&latch); - fast_pair_repository->AddObserver(&observer); - - // Get user's saved device from footprints. - fast_pair_repository->GetUserSavedDevices(); - EXPECT_FALSE(latch.Await(kWaitTimeout).result()); -} - -TEST(FastPairRepositoryImplTest, WriteAccountAssociationToFootprintsSuccess) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up proto::UserWriteDeviceResponse. - proto::UserWriteDeviceResponse response_proto; - fake_fast_pair_client.SetUserWriteDeviceResponse(response_proto); - - // Sets up device info to be saved to footprints. - FastPairDevice fast_pair_device(kHexModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - fast_pair_device.SetAccountKey(account_key); - fast_pair_device.SetPublicAddress(kPublicAddress); - fast_pair_device.SetDisplayName(kDisplayName); - proto::GetObservedDeviceResponse get_observed_device_response; - auto* observed_device_strings = - get_observed_device_response.mutable_strings(); - observed_device_strings->set_initial_pairing_description( - kInitialPairingdescription); - DeviceMetadata device_metadata(get_observed_device_response); - fast_pair_device.SetMetadata(device_metadata); - - CountDownLatch latch(1); - fast_pair_repository->WriteAccountAssociationToFootprints( - fast_pair_device, [&](absl::Status status) { - // Verifies successfully write device to footprints. - EXPECT_OK(status); - latch.CountDown(); - }); - latch.Await(); - - // Verifies proto::UserWriteDeviceRequest is as expected. - proto::UserWriteDeviceRequest expected_request = - fake_fast_pair_client.write_device_request(); - EXPECT_TRUE(expected_request.has_fast_pair_info()); - auto fast_proto_info = expected_request.fast_pair_info(); - EXPECT_TRUE(fast_proto_info.has_device()); - auto device = fast_proto_info.device(); - EXPECT_EQ(device.account_key(), account_key.GetAsBytes()); - EXPECT_EQ(absl::BytesToHexString(device.sha256_account_key_public_address()), - kExpectedSha256Hash); - proto::StoredDiscoveryItem stored_discovery_item; - EXPECT_TRUE( - stored_discovery_item.ParseFromString(device.discovery_item_bytes())); - EXPECT_EQ(stored_discovery_item.title(), kDisplayName); - proto::FastPairStrings fast_pair_strings = - stored_discovery_item.fast_pair_strings(); - EXPECT_EQ(fast_pair_strings.initial_pairing_description(), - kInitialPairingdescription); -} - -TEST(FastPairRepositoryImplTest, FailedToWriteAccountAssociationToFootprints) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - fake_fast_pair_client.SetUserWriteDeviceResponse( - absl::InternalError("No response")); - - // Sets up device info to be saved to footprints. - FastPairDevice fast_pair_device(kHexModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - fast_pair_device.SetAccountKey(account_key); - fast_pair_device.SetPublicAddress(kPublicAddress); - fast_pair_device.SetDisplayName(kDisplayName); - proto::GetObservedDeviceResponse get_observed_device_response; - auto* observed_device_strings = - get_observed_device_response.mutable_strings(); - observed_device_strings->set_initial_pairing_description( - kInitialPairingdescription); - DeviceMetadata device_metadata(get_observed_device_response); - fast_pair_device.SetMetadata(device_metadata); - - CountDownLatch latch(1); - fast_pair_repository->WriteAccountAssociationToFootprints( - fast_pair_device, [&](absl::Status status) { - // Failed to write device to footprints. - EXPECT_FALSE(status.ok()); - EXPECT_EQ(status.message(), "No response"); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairRepositoryImplTest, DeleteAssociatedDeviceByAccountKeySuccess) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up proto::UserDeleteDeviceResponse - proto::UserDeleteDeviceResponse response_proto; - response_proto.set_success(true); - fake_fast_pair_client.SetUserDeleteDeviceResponse(response_proto); - - // AccountKey of the device that will be removed from the footprint. - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - - CountDownLatch latch(1); - fast_pair_repository->DeleteAssociatedDeviceByAccountKey( - account_key, [&](absl::Status status) { - // Verifies successfully delete device from the footprints. - EXPECT_OK(status); - latch.CountDown(); - }); - latch.Await(); - - // Verifies proto::UserDeleteDeviceRequest is as expected. - proto::UserDeleteDeviceRequest expected_request = - fake_fast_pair_client.delete_device_request(); - std::string hex_account_key = std::string(kAccountKey); - absl::AsciiStrToUpper(&hex_account_key); - EXPECT_EQ(expected_request.hex_account_key(), hex_account_key); -} - -TEST(FastPairRepositoryImplTest, FailedToDeleteAssociatedDeviceWithNoResponse) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - fake_fast_pair_client.SetUserDeleteDeviceResponse( - absl::InternalError("No response")); - - // AccountKey of the device that will be removed from the footprint. - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - - CountDownLatch latch(1); - fast_pair_repository->DeleteAssociatedDeviceByAccountKey( - account_key, [&](absl::Status status) { - // Failed to delete device from the footprints. - EXPECT_FALSE(status.ok()); - EXPECT_EQ(status.message(), "No response"); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairRepositoryImplTest, FailedToDeleteAssociatedDeviceWithError) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up proto::UserDeleteDeviceResponse - proto::UserDeleteDeviceResponse response_proto; - response_proto.set_success(false); - fake_fast_pair_client.SetUserDeleteDeviceResponse(response_proto); - - // AccountKey of the device that will be removed from the footprint. - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - - CountDownLatch latch(1); - fast_pair_repository->DeleteAssociatedDeviceByAccountKey( - account_key, [&](absl::Status status) { - // Failed to delete device from the footprints. - EXPECT_FALSE(status.ok()); - EXPECT_EQ(status.message(), "Failed to delete device."); - latch.CountDown(); - }); - latch.Await(); -} - -// Test data comes from: -// https://developers.google.com/nearby/fast-pair/specifications/appendix/testcases#test_cases -TEST(FastPairRepositoryImplTest, DeviceAssociatedWithCurrentAccountSuccess) { - const std::vector filter{0x02, 0x0C, 0x80, 0x2A}; - const std::vector salt{0xC7, 0xC8}; - const std::vector account_key_vec{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, - 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, - 0xCC, 0xDD, 0xEE, 0xFF}; - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up two devices to proto::UserReadDevicesResponse. - proto::UserReadDevicesResponse response_proto; - // Adds device 1. - auto* fast_pair_info_1 = response_proto.add_fast_pair_info(); - fast_pair_info_1->set_opt_in_status( - proto::OptInStatus::OPT_IN_STATUS_OPTED_IN); - - // Adds device 2. - FastPairDevice device_2(kHexModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key(account_key_vec); - device_2.SetAccountKey(account_key); - device_2.SetPublicAddress(kPublicAddress); - device_2.SetDisplayName(kDisplayName); - proto::GetObservedDeviceResponse get_observed_device_response_1; - auto* observed_device_strings_1 = - get_observed_device_response_1.mutable_strings(); - observed_device_strings_1->set_initial_pairing_description( - kInitialPairingdescription); - DeviceMetadata device_metadata_1(get_observed_device_response_1); - device_2.SetMetadata(device_metadata_1); - auto* fast_pair_info_2 = response_proto.add_fast_pair_info(); - BuildFastPairInfo(fast_pair_info_2, device_2); - - fake_fast_pair_client.SetUserReadDevicesResponse(response_proto); - - AccountKeyFilter account_key_filter(filter, salt); - - CountDownLatch latch(1); - // Get user's saved device from footprints. - fast_pair_repository->CheckIfAssociatedWithCurrentAccount( - account_key_filter, [&](std::optional cb_account_key, - std::optional cb_model_id) { - ASSERT_TRUE(cb_account_key.has_value()); - ASSERT_TRUE(cb_model_id.has_value()); - EXPECT_EQ(cb_account_key.value(), account_key); - EXPECT_EQ(cb_model_id.value(), kHexModelId); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairRepositoryImplTest, DeviceNotAssociatedWithCurrentAccount) { - const std::vector filter{0x02, 0x0C, 0x80, 0x2A}; - const std::vector salt{0xC7, 0xC8}; - const std::vector account_key_vec{0x11, 0x11, 0x22, 0x22, 0x33, 0x33, - 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, - 0x77, 0x77, 0x88, 0x88}; - - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up two devices to proto::UserReadDevicesResponse. - // Adds device 1. - proto::UserReadDevicesResponse response_proto; - FastPairDevice device(kHexModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key(account_key_vec); - device.SetAccountKey(account_key); - device.SetPublicAddress(kPublicAddress); - device.SetDisplayName(kDisplayName); - proto::GetObservedDeviceResponse get_observed_device_response; - DeviceMetadata device_metadata(get_observed_device_response); - device.SetMetadata(device_metadata); - auto* fast_pair_info = response_proto.add_fast_pair_info(); - BuildFastPairInfo(fast_pair_info, device); - fake_fast_pair_client.SetUserReadDevicesResponse(response_proto); - - AccountKeyFilter account_key_filter(filter, salt); - - CountDownLatch latch(1); - // Get user's saved device from footprints. - fast_pair_repository->CheckIfAssociatedWithCurrentAccount( - account_key_filter, [&](std::optional cb_account_key, - std::optional cb_model_id) { - EXPECT_FALSE(cb_account_key.has_value()); - EXPECT_FALSE(cb_model_id.has_value()); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairRepositoryImplTest, DeviceIsSavedToCurrentAccount) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up two devices to proto::UserReadDevicesResponse. - proto::UserReadDevicesResponse response_proto; - // Device 1 - FastPairDevice device_1(kHexModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key_1(absl::HexStringToBytes(kAccountKey)); - device_1.SetAccountKey(account_key_1); - device_1.SetPublicAddress(kPublicAddress); - proto::GetObservedDeviceResponse get_observed_device_response; - DeviceMetadata device_metadata_1(get_observed_device_response); - device_1.SetMetadata(device_metadata_1); - auto* fast_pair_info_1 = response_proto.add_fast_pair_info(); - BuildFastPairInfo(fast_pair_info_1, device_1); - // Device 2 - auto* fast_pair_info_2 = response_proto.add_fast_pair_info(); - fast_pair_info_2->set_opt_in_status( - proto::OptInStatus::OPT_IN_STATUS_OPTED_IN); - fake_fast_pair_client.SetUserReadDevicesResponse(response_proto); - - CountDownLatch latch(1); - fast_pair_repository->IsDeviceSavedToAccount(kPublicAddress, - [&](absl::Status status) { - EXPECT_OK(status); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairRepositoryImplTest, DeviceIsNotSavedToCurrentAccount) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - // Sets up two devices to proto::UserReadDevicesResponse. - proto::UserReadDevicesResponse response_proto; - FastPairDevice device(kHexModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - device.SetAccountKey(account_key); - device.SetPublicAddress(kPublicAddress); - proto::GetObservedDeviceResponse get_observed_device_response; - DeviceMetadata device_metadata(get_observed_device_response); - device.SetMetadata(device_metadata); - auto* fast_pair_info = response_proto.add_fast_pair_info(); - BuildFastPairInfo(fast_pair_info, device); - fake_fast_pair_client.SetUserReadDevicesResponse(response_proto); - - CountDownLatch latch(1); - fast_pair_repository->IsDeviceSavedToAccount( - "11:22:33:44:55:66", [&](absl::Status status) { - EXPECT_EQ(status.code(), absl::StatusCode::kNotFound); - latch.CountDown(); - }); - latch.Await(); -} - -TEST(FastPairRepositoryImplTest, FailedToCheckDeviceIsSavedToCurrentAccount) { - FakeFastPairClient fake_fast_pair_client; - auto fast_pair_repository = - std::make_unique(&fake_fast_pair_client); - - CountDownLatch latch(1); - fast_pair_repository->IsDeviceSavedToAccount(kPublicAddress, - [&](absl::Status status) { - EXPECT_FALSE(status.ok()); - latch.CountDown(); - }); - latch.Await(); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/repository/fast_pair_repository_test.cc b/fastpair/repository/fast_pair_repository_test.cc deleted file mode 100644 index 2153fdc8f2..0000000000 --- a/fastpair/repository/fast_pair_repository_test.cc +++ /dev/null @@ -1,39 +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. - -#include "fastpair/repository/fast_pair_repository.h" - -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "fastpair/common/account_key.h" - -namespace nearby { -namespace fastpair { -namespace { -TEST(FastPairRepositoryTest, TestSHA256HashFunction) { - absl::string_view kTestClassicAddress("20:64:DE:40:F8:93"); - absl::string_view kExpectedSha256Hash( - "6353c0075a35b7d81bb30a6190ab246da4b8c55a6111d387400579133c090ed8"); - absl::string_view kAccountKey("04b85786180add47fb81a04a8ce6b0de"); - - EXPECT_EQ(absl::BytesToHexString( - FastPairRepository::GenerateSha256OfAccountKeyAndMacAddress( - AccountKey(absl::HexStringToBytes(kAccountKey)), - kTestClassicAddress)), - kExpectedSha256Hash); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/repository/mock_fast_pair_repository.h b/fastpair/repository/mock_fast_pair_repository.h deleted file mode 100644 index 8057b6a44d..0000000000 --- a/fastpair/repository/mock_fast_pair_repository.h +++ /dev/null @@ -1,36 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_MOCK_FAST_PAIR_REPOSITORY_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_MOCK_FAST_PAIR_REPOSITORY_H_ - -#include "gmock/gmock.h" -#include "absl/strings/string_view.h" -#include "fastpair/repository/fast_pair_repository.h" - -namespace nearby { -namespace fastpair { - -class MockFastPairRepository : public FastPairRepository { - public: - MOCK_METHOD(void, GetDeviceMetadata, - (absl::string_view hex_model_id, DeviceMetadataCallback callback), - (override)); -}; - -} // namespace fastpair -} // namespace nearby - - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_MOCK_FAST_PAIR_REPOSITORY_H_ diff --git a/fastpair/retroactive/BUILD b/fastpair/retroactive/BUILD deleted file mode 100644 index ccfc6b9a60..0000000000 --- a/fastpair/retroactive/BUILD +++ /dev/null @@ -1,76 +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. - -licenses(["notice"]) - -cc_library( - name = "retroactive", - srcs = [ - "retroactive.cc", - "retroactive_pairing_detector_impl.cc", - ], - hdrs = [ - "retroactive.h", - "retroactive_pairing_detector.h", - "retroactive_pairing_detector_impl.h", - ], - visibility = [ - "//:__subpackages__", - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair:fast_pair_controller", - "//fastpair/common", - "//fastpair/internal/mediums", - "//fastpair/message_stream", - "//fastpair/pairing", - "//fastpair/repository", - "//fastpair/repository:device_repository", - "//internal/base", - "//internal/platform:comm", - "//internal/platform:types", - "//internal/platform/implementation:account_manager", - "//internal/platform/implementation:types", - "//third_party/magic_enum", - "@com_google_absl//absl/container:flat_hash_set", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - ], -) - -cc_test( - name = "retroactive_test", - size = "small", - srcs = [ - "retroactive_test.cc", - ], - deps = [ - ":retroactive", - "//fastpair/common", - "//fastpair/message_stream:fake_gatt_callbacks", - "//fastpair/message_stream:fake_provider", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/repository:test_support", - "//internal/base:bluetooth_address", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/retroactive/retroactive.cc b/fastpair/retroactive/retroactive.cc deleted file mode 100644 index 4581723ab0..0000000000 --- a/fastpair/retroactive/retroactive.cc +++ /dev/null @@ -1,221 +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. - -#include "fastpair/retroactive/retroactive.h" - -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "third_party/magic_enum/magic_enum.hpp" -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/fast_pair_controller.h" -#include "fastpair/message_stream/message_stream.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/direct_executor.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr absl::string_view kSeekerAddress = "11:12:13:14:15:16"; -} -Retroactive::Retroactive(FastPairController* controller) noexcept - : controller_(controller) { - message_stream_connection_observer_ = { - .on_connected = - [this](const FastPairDevice& device) { - NEARBY_LOGS(INFO) << "Message stream connected"; - SetPairingStep(PairingStep::kWaitForModelIdAndBleAddress); - }, - .on_disconnected = - [this](const FastPairDevice& device, absl::Status status) { - NEARBY_LOGS(INFO) << "Message stream disconnected"; - if (pairing_step_ == PairingStep::kNewDevicePairedOrConnected) { - // New device is disconnected. Not an error. - SetPairingStep(PairingStep::kOpenMessageStream); - return; - } - pairing_result_.Set(status); - SetPairingStep(PairingStep::kFailed); - }}; - address_rotation_observer_ = { - .on_ble_address_rotated = [this](const FastPairDevice& device, - absl::string_view old_address) { - NEARBY_LOGS(INFO) << "Received ble address"; - if (pairing_step_ != PairingStep::kWaitForModelIdAndBleAddress) { - return; - } - if (!device.GetBleAddress().empty() && !device.GetModelId().empty()) { - SetPairingStep(PairingStep::kFetchAntiSpoofingKey); - } - }}; - model_id_observer_ = {.on_model_id = [this](const FastPairDevice& device) { - NEARBY_LOGS(INFO) << "Received model id"; - if (pairing_step_ != PairingStep::kWaitForModelIdAndBleAddress) { - return; - } - if (!device.GetBleAddress().empty() && !device.GetModelId().empty()) { - SetPairingStep(PairingStep::kFetchAntiSpoofingKey); - } - }}; -} - -Retroactive::~Retroactive() { - // TODO(jsobczak): Disable `data_encryptor_` listener. - SetPairingStep(PairingStep::kNone); -} - -Future Retroactive::Pair() { - SetPairingStep(PairingStep::kNewDevicePairedOrConnected); - return pairing_result_; -} - -void Retroactive::SetPairingStep(PairingStep step) { - if (pairing_step_ == step) return; - ExitPairingStep(pairing_step_); - NEARBY_LOGS(INFO) << "Enter pairing step " << magic_enum::enum_name(step); - pairing_step_ = step; - switch (step) { - case PairingStep::kNone: { - controller_->RemoveMessageStreamConnectionObserver( - &message_stream_connection_observer_); - break; - } - case PairingStep::kNewDevicePairedOrConnected: { - controller_->AddMessageStreamConnectionObserver( - &message_stream_connection_observer_); - break; - } - case PairingStep::kOpenMessageStream: { - absl::Status status = controller_->OpenMessageStream(); - if (!status.ok()) { - SetPairingStep(PairingStep::kFailed); - return; - } - break; - } - case PairingStep::kWaitForModelIdAndBleAddress: { - controller_->AddModelIdObserver(&model_id_observer_); - controller_->AddAddressRotationObserver(&address_rotation_observer_); - break; - } - case PairingStep::kFetchAntiSpoofingKey: { - // Fetch ASK and set up data encryptor. - data_encryptor_ = controller_->GetDataEncryptor(); - data_encryptor_.AddListener( - [this](ExceptionOr> result) { - if (result.ok() && result.result()) { - SetPairingStep(PairingStep::kSendKeyBasedPairingRequest); - } else { - SetPairingStep(PairingStep::kFailed); - } - }, - &executor_); - break; - } - case PairingStep::kSendKeyBasedPairingRequest: { - // Open GATT connection and send Key-based pairing request to provider. - gatt_client_ = controller_->GetGattClientRef(); - gatt_client_.AddListener( - [this](ExceptionOr gatt) { - if (!gatt.ok()) { - NEARBY_LOGS(INFO) << "Creating GATT client failed"; - return; - } - NEARBY_LOGS(INFO) << "Sending Key Based Pairing request to " - << controller_->GetDevice().GetBleAddress(); - auto decryptor = data_encryptor_.Get().result().get(); - (gatt.result()) - ->WriteRequestAsync( - kKeyBasedPairingType, kRetroactiveFlags, - controller_->GetDevice().GetBleAddress(), - controller_->GetSeekerMacAddress(), *decryptor, - [this](absl::string_view response, - std::optional failure) { - if (failure.has_value()) { - NEARBY_LOGS(WARNING) - << "Key-based pairing exchange failed"; - SetPairingStep(PairingStep::kFailed); - return; - } - NEARBY_LOGS(INFO) << "key based pairing reply " - << absl::BytesToHexString(response); - SetPairingStep(PairingStep::kSendAccountKeyToProvider); - }); - }, - &executor_); - break; - } - case PairingStep::kSendAccountKeyToProvider: { - auto decryptor = data_encryptor_.Get().result().get(); - gatt_client_.Get().result()->WriteAccountKey( - *decryptor, [this](std::optional account_key, - std::optional failure) { - if (failure.has_value()) { - NEARBY_LOGS(WARNING) - << "Account key write failed with: " << *failure; - SetPairingStep(PairingStep::kFailed); - return; - } - DCHECK(account_key.has_value()); - NEARBY_LOGS(INFO) - << "Sent account key: " - << absl::BytesToHexString(account_key->GetAsBytes()); - controller_->GetDevice().SetAccountKey(*account_key); - SetPairingStep(PairingStep::kAskForUserConfirmation); - }); - break; - } - case PairingStep::kAskForUserConfirmation: { - // TODO(jsobczak): Display UI to ask the user to confirm onboarding the - // device. - SetPairingStep(PairingStep::kUploadAccountKeyToCloud); - break; - } - case PairingStep::kUploadAccountKeyToCloud: { - // TODO(jsobczak): Upload the Account Key to the server. - SetPairingStep(PairingStep::kSuccess); - break; - } - case PairingStep::kSuccess: { - pairing_result_.Set(absl::OkStatus()); - break; - } - case PairingStep::kFailed: { - pairing_result_.Set(absl::InternalError("Pairing failed")); - break; - } - default: - break; - } -} - -void Retroactive::ExitPairingStep(PairingStep step) { - switch (step) { - case PairingStep::kWaitForModelIdAndBleAddress: { - controller_->RemoveModelIdObserver(&model_id_observer_); - controller_->RemoveAddressRotationObserver(&address_rotation_observer_); - break; - } - default: - break; - } -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/retroactive/retroactive.h b/fastpair/retroactive/retroactive.h deleted file mode 100644 index c46e62f67f..0000000000 --- a/fastpair/retroactive/retroactive.h +++ /dev/null @@ -1,76 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/fast_pair_controller.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/bluetooth_classic.h" - -namespace nearby { -namespace fastpair { - -class Retroactive { - public: - class PairingState { - public: - explicit PairingState(Retroactive* retro) : retro_(retro) {} - virtual void Enter() = 0; - virtual void Exit() = 0; - virtual ~PairingState() = default; - Retroactive* retro_; - }; - enum class PairingStep { - kNone, - kNewDevicePairedOrConnected, - kOpenMessageStream, - kWaitForModelIdAndBleAddress, - kFetchAntiSpoofingKey, - kOpenGattConnection, - kSendKeyBasedPairingRequest, - kSendAccountKeyToProvider, - kAskForUserConfirmation, - kUploadAccountKeyToCloud, - kSuccess, - kFailed - }; - - explicit Retroactive(FastPairController* controller) noexcept; - ~Retroactive(); - - Future Pair(); - - void SetPairingStep(PairingStep step); - void ExitPairingStep(PairingStep step); - FastPairController* controller_; - std::unique_ptr state_; - PairingStep pairing_step_ = PairingStep::kNone; - FastPairController::MessageStreamConnectionObserver - message_stream_connection_observer_; - FastPairController::BleAddressRotationObserver address_rotation_observer_; - FastPairController::ModelIdObserver model_id_observer_; - Future pairing_result_; - Future> data_encryptor_; - Future gatt_client_; - SingleThreadExecutor executor_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_H_ diff --git a/fastpair/retroactive/retroactive_pairing_detector.h b/fastpair/retroactive/retroactive_pairing_detector.h deleted file mode 100644 index ad8d248596..0000000000 --- a/fastpair/retroactive/retroactive_pairing_detector.h +++ /dev/null @@ -1,41 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_H_ - -#include "fastpair/common/fast_pair_device.h" -namespace nearby { -namespace fastpair { -// A RetroactivePairingDetector instance is responsible for detecting Fast Pair -// devices that can be paired retroactively, and notifying observers of this -// device. -class RetroactivePairingDetector { - public: - class Observer { - public: - virtual ~Observer() = default; - virtual void OnRetroactivePairFound(FastPairDevice& device) = 0; - }; - - virtual ~RetroactivePairingDetector() = default; - - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_H_ diff --git a/fastpair/retroactive/retroactive_pairing_detector_impl.cc b/fastpair/retroactive/retroactive_pairing_detector_impl.cc deleted file mode 100644 index 5bcffb7349..0000000000 --- a/fastpair/retroactive/retroactive_pairing_detector_impl.cc +++ /dev/null @@ -1,122 +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. - -#include "fastpair/retroactive/retroactive_pairing_detector_impl.h" - -#include -#include -#include -#include -#include - -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/platform/implementation/account_manager.h" - -namespace nearby { -namespace fastpair { - -RetroactivePairingDetectorImpl::RetroactivePairingDetectorImpl( - Mediums& mediums, FastPairDeviceRepository* repository, - AccountManager* account_manager, SingleThreadExecutor* executor) - : mediums_(mediums), - repository_(repository), - account_manager_(account_manager), - executor_(executor) { - mediums_.GetBluetoothClassic().AddObserver(this); - mediums_.GetBluetoothClassic().StartDiscovery(); -} - -RetroactivePairingDetectorImpl::~RetroactivePairingDetectorImpl() { - mediums_.GetBluetoothClassic().RemoveObserver(this); - mediums_.GetBluetoothClassic().StopDiscovery(); -} - -void RetroactivePairingDetectorImpl::AddObserver( - RetroactivePairingDetector::Observer* observer) { - observers_.AddObserver(observer); -} - -void RetroactivePairingDetectorImpl::RemoveObserver( - RetroactivePairingDetector::Observer* observer) { - observers_.RemoveObserver(observer); -} - -void RetroactivePairingDetectorImpl::DevicePairedChanged( - BluetoothDevice& device, bool new_paired_status) { - NEARBY_LOGS(INFO) << __func__ - << " Device paired changed, name = " << device.GetName() - << " address = " << device.GetMacAddress() - << " new_paired_status = " << std::boolalpha - << new_paired_status; - // This event fires whenever a device pairing has changed with - // the BluetoothClassicMedium. - // If the |new_paired_status| is false, it means a device was unpaired, - // so we early return since it would not be a device to retroactively pair to. - if (!new_paired_status) { - return; - } - - std::optional existing_device = - repository_->FindDevice(device.GetMacAddress()); - if (existing_device.has_value() && - existing_device.value()->HasStartedPairing()) { - // Both classic paired and Fast paired devices call this function, so we - // have to filter out pairing events for device that paired from Fast Pair. - NEARBY_LOGS(INFO) << __func__ << ": Ignoring Fast paired devices."; - return; - } - - // In order to confirm that this device is a retroactive pairing, we need to - // first check if it has already been saved to the user's account. If it has - // already been saved, we don't want to prompt the user to save a device - // again. - if (!account_manager_->GetCurrentAccount().has_value()) { - NEARBY_LOGS(INFO) << __func__ << ": Ignoring because no logged in user."; - return; - } - - FastPairRepository::Get()->IsDeviceSavedToAccount( - device.GetMacAddress(), - [this, mac_address = device.GetMacAddress()](absl::Status status) { - if (status.ok()) { - NEARBY_LOGS(VERBOSE) << __func__ - << ": Ignoring because device is already saved " - "to the current account."; - return; - } - NotifyRetroactiveDeviceFound(mac_address); - }); -} - -void RetroactivePairingDetectorImpl::NotifyRetroactiveDeviceFound( - absl::string_view mac_address) { - NEARBY_LOGS(VERBOSE) << __func__ << ": mac_address = " << mac_address; - auto fast_pair_device = - std::make_unique(Protocol::kFastPairRetroactivePairing); - fast_pair_device->SetPublicAddress(mac_address); - repository_->AddDevice(std::move(fast_pair_device)); - executor_->Execute("notify-retro-candidate", - [this, address = std::string(mac_address)]() { - std::optional fast_pair_device = - repository_->FindDevice(address); - if (!fast_pair_device) return; - for (auto observer : observers_.GetObservers()) { - observer->OnRetroactivePairFound(**fast_pair_device); - } - }); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/retroactive/retroactive_pairing_detector_impl.h b/fastpair/retroactive/retroactive_pairing_detector_impl.h deleted file mode 100644 index 796fb3476a..0000000000 --- a/fastpair/retroactive/retroactive_pairing_detector_impl.h +++ /dev/null @@ -1,64 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_IMPL_H_ - -#include "absl/strings/string_view.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/retroactive/retroactive_pairing_detector.h" -#include "internal/base/observer_list.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -class RetroactivePairingDetectorImpl - : public RetroactivePairingDetector, - public BluetoothClassicMedium ::Observer { - public: - RetroactivePairingDetectorImpl(Mediums& mediums, - FastPairDeviceRepository* repository, - AccountManager* account_manager, - SingleThreadExecutor* executor); - RetroactivePairingDetectorImpl(const RetroactivePairingDetectorImpl&) = - delete; - RetroactivePairingDetectorImpl& operator=( - const RetroactivePairingDetectorImpl&) = delete; - ~RetroactivePairingDetectorImpl() override; - - // RetroactivePairingDetector: - void AddObserver(RetroactivePairingDetector::Observer* observer) override; - void RemoveObserver(RetroactivePairingDetector::Observer* observer) override; - - // BluetoothClassicMedium::Observer - void DevicePairedChanged(BluetoothDevice& device, - bool new_paired_status) override; - - private: - void NotifyRetroactiveDeviceFound(absl::string_view mac_address); - Mediums& mediums_; - ObserverList observers_; - FastPairDeviceRepository* repository_; - AccountManager* account_manager_; - SingleThreadExecutor* executor_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_IMPL_H_ diff --git a/fastpair/retroactive/retroactive_test.cc b/fastpair/retroactive/retroactive_test.cc deleted file mode 100644 index 0172f6b500..0000000000 --- a/fastpair/retroactive/retroactive_test.cc +++ /dev/null @@ -1,163 +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. - -#include "fastpair/retroactive/retroactive.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "fastpair/common/constant.h" -#include "fastpair/message_stream/fake_gatt_callbacks.h" -#include "fastpair/message_stream/fake_provider.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/repository/fake_fast_pair_repository.h" -#include "internal/base/bluetooth_address.h" -#include "internal/platform/bluetooth_classic.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -namespace nearby { -namespace fastpair { -namespace { - -constexpr char kModelId[] = "abcdef"; -constexpr absl::string_view kBobPrivateKey = - "02B437B0EDD6BBD429064A4E529FCBF1C48D0D624924D592274B7ED81193D763"; -constexpr absl::string_view kBobPublicKey = - "F7D496A62ECA416351540AA343BC690A6109F551500666B83B1251FB84FA2860795EBD63D3" - "B8836F44A9A3E28BB34017E015F5979305D849FDF8DE10123B61D2"; - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class RetroactiveTest : public testing::Test { - protected: - void SetUp() override { - BluetoothClassicMedium& seeker_medium = - mediums_.GetBluetoothClassic().GetMedium(); - - provider_.DiscoverProvider(seeker_medium); - remote_device_ = seeker_medium.GetRemoteDevice(provider_.GetMacAddress()); - provider_.StartGattServer(&gatt_callbacks_); - provider_.InsertCorrectGattCharacteristics(); - ASSERT_TRUE(remote_device_.IsValid()); - fast_pair_device_ = - std::make_unique(Protocol::kFastPairRetroactivePairing); - fast_pair_device_->SetPublicAddress(remote_device_.GetMacAddress()); - } - - void TearDown() override { - executor_.Shutdown(); - provider_.DisableProviderRfcomm(); - provider_.Shutdown(); - MediumEnvironment::Instance().Stop(); - } - - void SetUpFastPairRepository(absl::string_view model_id, - absl::string_view public_key) { - proto::Device metadata; - metadata.mutable_anti_spoofing_key_pair()->set_public_key(public_key); - repository_.SetFakeMetadata(model_id, metadata); - } - - // The medium environment must be initialized (started) before adding - // adapters. - MediumEnvironmentStarter env_; - SingleThreadExecutor executor_; - Mediums mediums_; - FakeProvider provider_; - BluetoothDevice remote_device_; - FakeFastPairRepository repository_; - FakeGattCallbacks gatt_callbacks_; - std::unique_ptr fast_pair_device_; -}; - -TEST_F(RetroactiveTest, Constructor) { - FastPairController controller(&mediums_, &*fast_pair_device_, &executor_); - Retroactive retro(&controller); -} - -TEST_F(RetroactiveTest, Pair) { - SetUpFastPairRepository(kModelId, absl::HexStringToBytes(kBobPublicKey)); - FastPairController controller(&mediums_, &*fast_pair_device_, &executor_); - provider_.EnableProviderRfcomm(); - provider_.LoadAntiSpoofingKey(absl::HexStringToBytes(kBobPrivateKey), - absl::HexStringToBytes(kBobPublicKey)); - std::string provider_ble_address = provider_.GetMacAddressAsBytes(); - std::string seeker_address = - std::string(BluetoothUtils::FromString(controller.GetSeekerMacAddress())); - gatt_callbacks_.characteristics_[*provider_.key_based_characteristic_] - .write_callback = [&](absl::string_view request) { - // https://developers.google.com/nearby/fast-pair/specifications/characteristics#table1.1 - // Example valid KBP request: "0010aabbccddeeff111213141516" - // Byte 0, 0x00 = Key-based Pairing Request - // Byte 1, 0x10 (Bit 3 set) = retroactive pairing - // Bytes 2 - 7, aabbccddeeff, provider's address - // Bytes 8 - 13, 111213141516, seeker's address - // Bytes 14 - 15, (not included), random salt - std::string expected_kbp_request = - absl::HexStringToBytes("0010") + provider_ble_address + seeker_address; - - // https://developers.google.com/nearby/fast-pair/specifications/characteristics#table1.2.2 - // Byte 0, 0x01 = Key-based Pairing Response - // Bytes 1 - 6, c1c2c3c4c5c6, provider's public address - // Bytes 7 - 15, random salt - std::string kbp_response = - absl::HexStringToBytes("01c1c2c3c4c5c601234567890abcdef0"); - - NEARBY_LOGS(INFO) << "KBP request " << absl::BytesToHexString(request); - std::string decrypted_request = provider_.DecryptKbpRequest(request); - EXPECT_EQ(decrypted_request.size(), kEncryptedDataByteSize); - NEARBY_LOGS(INFO) << "KBP decrypted request " - << absl::BytesToHexString(decrypted_request); - // The last bytes in decrypted request are random, so we ignore them. - EXPECT_EQ(decrypted_request.substr(0, expected_kbp_request.size()), - expected_kbp_request); - - ByteArray response(provider_.Encrypt(kbp_response)); - EXPECT_OK(provider_.NotifyKeyBasedPairing(response)); - return absl::OkStatus(); - }; - - Retroactive retro(&controller); - - Future result = retro.Pair(); - - // Provider sends their ModelId. - provider_.WriteProviderBytes(absl::HexStringToBytes("03010003ABCDEF")); - // Provider sends their BLE address. - EXPECT_EQ(provider_ble_address.size(), 6); - provider_.WriteProviderBytes(absl::HexStringToBytes("03020006") + - provider_ble_address); - - EXPECT_TRUE(result.Get(absl::Minutes(5)).ok()); - EXPECT_EQ( - gatt_callbacks_.characteristics_[*provider_.accountkey_characteristic_] - .write_value.Get() - .result() - .size(), - kAccountKeySize); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/rust/.gitignore b/fastpair/rust/.gitignore deleted file mode 100644 index c1bf028bbc..0000000000 --- a/fastpair/rust/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Build files -target diff --git a/fastpair/rust/bluetooth/Cargo.toml b/fastpair/rust/bluetooth/Cargo.toml deleted file mode 100644 index 0c66621900..0000000000 --- a/fastpair/rust/bluetooth/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -# 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. -# 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. - -[package] -name = "bluetooth" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -futures = { version = "0.3" } -tracing = "0.1.37" -cfg-if = "1.0.0" -async-trait = "0.1" -thiserror = "1.0.43" - -[dev-dependencies] -futures = { version = "0.3", features = ["executor"] } - -[target.'cfg(windows)'.dependencies] -windows = { version = "0.48", features = [ - "Devices_Bluetooth", - "Devices_Enumeration", - "Devices_Bluetooth_Advertisement", - "Foundation", - "Foundation_Collections", - "Storage_Streams", -] } diff --git a/fastpair/rust/bluetooth/examples/fastpair_ui.rs b/fastpair/rust/bluetooth/examples/fastpair_ui.rs deleted file mode 100644 index 920ace4cc5..0000000000 --- a/fastpair/rust/bluetooth/examples/fastpair_ui.rs +++ /dev/null @@ -1,118 +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::{ - collections::HashSet, - error::Error, - io::{self, Write}, - sync::Arc, - thread, -}; - -use futures::{ - executor::{self, block_on}, - lock::Mutex, -}; - -extern crate bluetooth; - -use bluetooth::{ - api::{BleAdapter, BleDevice, ClassicDevice}, - BleDataTypeId, ClassicAddress, Platform, -}; - -async fn get_user_input( - device_vec: Arc>>, -) -> Result<(), Box> { - let mut buffer = String::new(); - loop { - io::stdout().flush()?; - buffer.clear(); - io::stdin().read_line(&mut buffer)?; - - let val = match buffer.trim().parse::() { - Ok(val) => val, - Err(_) => { - println!("Please enter a valid digit."); - continue; - } - }; - - let index_to_device = device_vec.lock().await; - match index_to_device.get(val) { - Some(device) => { - let addr = device.address(); - let classic_addr = ClassicAddress::try_from(addr)?; - - let classic_device = - Platform::new_classic_device(classic_addr).await?; - - match classic_device.pair().await { - Ok(_) => { - println!("Pairing success!"); - } - Err(err) => println!("Error {}", err), - } - break Ok(()); - } - None => println!("Please enter a valid digit."), - } - } -} - -fn main() -> Result<(), Box> { - let run = async { - let mut adapter = Platform::default_adapter().await?; - adapter.start_scan()?; - - let mut addr_set = HashSet::new(); - let device_vec = Arc::new(Mutex::new(Vec::new())); - - { - // Process user input in a separate thread. - let device_vec = device_vec.clone(); - thread::spawn(|| block_on(get_user_input(device_vec)).unwrap()); - } - - let mut counter: u32 = 0; - let datatype_selector = vec![BleDataTypeId::ServiceData16BitUuid]; - // Retrieve incoming device advertisements. - while let Ok(advertisement) = - adapter.next_advertisement(Some(&datatype_selector)).await - { - for service_data in advertisement.service_data_16bit_uuid()? { - let uuid = service_data.uuid(); - - // This is a Fast Pair device. - if uuid == 0x2cfe { - let addr = advertisement.address(); - let ble_device = Platform::new_ble_device(addr).await?; - let name = ble_device.name()?; - - if addr_set.insert(addr) { - // New FP device discovered. - println!("{}: {}", counter, name); - device_vec.lock().await.push(ble_device); - counter += 1; - } - break; - } - } - } - println!("Done scanning"); - Ok(()) - }; - - executor::block_on(run) -} diff --git a/fastpair/rust/bluetooth/rustfmt.toml b/fastpair/rust/bluetooth/rustfmt.toml deleted file mode 100644 index 5c8d9318b3..0000000000 --- a/fastpair/rust/bluetooth/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -max_width = 80 \ No newline at end of file diff --git a/fastpair/rust/bluetooth/src/api/adapter.rs b/fastpair/rust/bluetooth/src/api/adapter.rs deleted file mode 100644 index de9bc43ffc..0000000000 --- a/fastpair/rust/bluetooth/src/api/adapter.rs +++ /dev/null @@ -1,37 +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 crate::common::{BleAdvertisement, BleDataTypeId, BluetoothError}; - -/// Concrete types implementing this trait are Bluetooth Central devices. -/// They provide methods for retrieving nearby connections and device info. -#[async_trait] -pub trait BleAdapter: Sized { - /// Retrieve the system-default Bluetooth adapter. - async fn default() -> Result; - - /// Begin scanning for nearby advertisements. - fn start_scan(&mut self) -> Result<(), BluetoothError>; - - /// Stop scanning for nearby advertisements. - fn stop_scan(&mut self) -> Result<(), BluetoothError>; - - /// Poll next discovered device. - async fn next_advertisement( - &mut self, - data_selector: Option<&Vec>, - ) -> Result; -} diff --git a/fastpair/rust/bluetooth/src/api/device.rs b/fastpair/rust/bluetooth/src/api/device.rs deleted file mode 100644 index df43ec7267..0000000000 --- a/fastpair/rust/bluetooth/src/api/device.rs +++ /dev/null @@ -1,56 +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 crate::common::{ - BleAddress, BluetoothError, ClassicAddress, PairingResult, -}; - -/// Concrete types implementing this trait represent BLE Peripheral devices. -/// They provide methods for retrieving device info and running device actions, -/// such as pairing. -#[async_trait] -pub trait BleDevice: Sized { - /// Create a new `BleDevice` instance from a `BleAddress`, typically - /// enabled through locally cached data retrieved from a Bluetooth adapter's - /// scanning functionality. - async fn new(addr: BleAddress) -> Result; - - /// Retrieve the name advertised by this device. - fn name(&self) -> Result; - - /// Retrieve this device's Bluetooth address information. - fn address(&self) -> BleAddress; -} - -/// Concrete types implementing this trait represent BT Classic Peripheral -/// devices. They provide methods for retrieving device info and running device -/// actions, such as pairing. -#[async_trait] -pub trait ClassicDevice: Sized { - /// Create a new `ClassicDevice` instance from a `ClassicAddress`, typically - /// enabled through locally cached data retrieved from a Bluetooth adapter's - /// scanning functionality. - async fn new(addr: ClassicAddress) -> Result; - - /// Retrieve the name advertised by this device. - fn name(&self) -> Result; - - /// Retrieve this device's Bluetooth address information. - fn address(&self) -> ClassicAddress; - - /// Attempt pairing with the peripheral device. - async fn pair(&self) -> Result; -} diff --git a/fastpair/rust/bluetooth/src/api/mod.rs b/fastpair/rust/bluetooth/src/api/mod.rs deleted file mode 100644 index 64c382d043..0000000000 --- a/fastpair/rust/bluetooth/src/api/mod.rs +++ /dev/null @@ -1,19 +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. - -mod adapter; -mod device; - -pub use adapter::*; -pub use device::*; diff --git a/fastpair/rust/bluetooth/src/common/address.rs b/fastpair/rust/bluetooth/src/common/address.rs deleted file mode 100644 index 85f81f04f7..0000000000 --- a/fastpair/rust/bluetooth/src/common/address.rs +++ /dev/null @@ -1,179 +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 super::BluetoothError; - -/// BLE Addresses can either be the peripheral's public MAC address, or various -/// types of random addresses. -#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] -pub enum BleAddressKind { - Public, - Random, -} - -/// Struct representing a 48-bit BLE Address and its type. -#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] -pub struct BleAddress { - val: [u8; 6], - kind: BleAddressKind, -} - -/// Struct representing a 48-bit BT Classic address. -#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] -pub struct ClassicAddress([u8; 6]); - -impl BleAddress { - /// `BleAddress` constructor. - pub fn new(addr: u64, kind: BleAddressKind) -> Self { - let addr = u64_to_6lsb(addr); - - BleAddress { val: addr, kind } - } - - /// Retrieve the type of BLE Address (public or random). - pub fn get_kind(&self) -> BleAddressKind { - self.kind - } -} - -/// Function for converting the six LSB of a u64 into a 6-byte array. -#[inline] -fn u64_to_6lsb(num: u64) -> [u8; 6] { - num.to_le_bytes()[..6] - .try_into() - .expect("Sanity check, slice length matches array length") -} - -impl From for ClassicAddress { - fn from(addr: u64) -> Self { - let addr = u64_to_6lsb(addr); - - ClassicAddress(addr) - } -} - -impl TryFrom for ClassicAddress { - type Error = BluetoothError; - - fn try_from(addr: BleAddress) -> Result { - match addr.kind { - BleAddressKind::Public => Ok(ClassicAddress(addr.val)), - BleAddressKind::Random => Err(BluetoothError::BadTypeConversion(String::from( - "can't convert BLE Random address to Bluetooth Classic address." - ))), - } - } -} - -impl From for u64 { - fn from(addr: BleAddress) -> Self { - let mut bytes = [0u8; 8]; - bytes[..6].copy_from_slice(&addr.val); - - u64::from_le_bytes(bytes) - } -} - -impl From for u64 { - fn from(addr: ClassicAddress) -> Self { - let mut bytes = [0u8; 8]; - bytes[..6].copy_from_slice(&addr.0); - - u64::from_le_bytes(bytes) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn ble_address_new() { - let addr = BleAddress::new(0x112233445566, BleAddressKind::Public); - assert_eq!(addr.val, [0x66, 0x55, 0x44, 0x33, 0x22, 0x11]); - assert_eq!(addr.kind, BleAddressKind::Public); - } - - #[test] - fn ble_address_get_kind() { - let addr_public = - BleAddress::new(0x112233445566, BleAddressKind::Public); - assert_eq!(addr_public.get_kind(), BleAddressKind::Public); - - let addr_random = - BleAddress::new(0xAABBCCDDEEFF, BleAddressKind::Random); - assert_eq!(addr_random.get_kind(), BleAddressKind::Random); - } - - #[test] - fn ble_address_into_u64() { - let ble_addr = BleAddress::new(0x112233445566, BleAddressKind::Public); - let u64_addr: u64 = ble_addr.into(); - assert_eq!(u64_addr, 0x112233445566); - } - - #[test] - fn classic_address_from_u64() { - let u64_addr = 0x112233445566; - let classic_addr: ClassicAddress = u64_addr.into(); - assert_eq!(classic_addr.0, [0x66, 0x55, 0x44, 0x33, 0x22, 0x11]); - } - - #[test] - fn try_from_ble_address_to_classic() { - let ble_addr = BleAddress::new(0x112233445566, BleAddressKind::Public); - let result: Result = - ble_addr.try_into(); - assert!(result.is_ok()); - assert_eq!(result.unwrap().0, [0x66, 0x55, 0x44, 0x33, 0x22, 0x11]); - - let ble_addr_random = - BleAddress::new(0xAABBCCDDEEFF, BleAddressKind::Random); - let result: Result = - TryFrom::try_from(ble_addr_random); - assert!(result.is_err()); - assert!(matches!( - result.unwrap_err(), - BluetoothError::BadTypeConversion(_), - )); - } - - #[test] - fn test_u64_to_6lsb() { - // Test a case where the input number is smaller than 6 bytes - let num = 0x123456; - let expected_result = [0x56, 0x34, 0x12, 0, 0, 0]; - let result = u64_to_6lsb(num); - assert_eq!(result, expected_result); - - // Test a case where the input number is exactly 6 bytes - let num = 0xAABBCCDDEEFF; - let expected_result = [0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA]; - let result = u64_to_6lsb(num); - assert_eq!(result, expected_result); - - // Test a case where the number is too large so the two most significant - // bytes get dropped. - let num = 0x1122334455667788; - let expected_result = [0x88, 0x77, 0x66, 0x55, 0x44, 0x33]; - let result = u64_to_6lsb(num); - assert_eq!(result, expected_result); - - // Test a case where the input number is 0 - let num = 0; - let expected_result = [0, 0, 0, 0, 0, 0]; - let result = u64_to_6lsb(num); - assert_eq!(result, expected_result); - } -} diff --git a/fastpair/rust/bluetooth/src/common/advertisement.rs b/fastpair/rust/bluetooth/src/common/advertisement.rs deleted file mode 100644 index 00ce6bb3d6..0000000000 --- a/fastpair/rust/bluetooth/src/common/advertisement.rs +++ /dev/null @@ -1,172 +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 super::{BleAddress, BluetoothError}; - -/// Holds data related to an incoming BLE Advertisement. This includes -/// information about the advertisement (e.g. address of sender) as well as -/// data sections extracted from the advertisement. Platform-specific methods -/// should be written to load in data sections from incoming advertisements. -#[derive(Clone, Debug)] -pub struct BleAdvertisement { - address: BleAddress, - rssi: Option, - tx_power: Option, - service_data_16bit_uuid: Option>>, -} - -/// Decibel-milliwatt or dBm is a dimensionless absolute unit expressing the -/// power of a signal relative to one milliwatt (mW). The unit is in log10, i.e. -/// 1 mW is 0 dBm and a 10 dBm increase represents a ten-fold increase in power. -type DecibelMilliwatts = i16; - -impl BleAdvertisement { - /// Construct a new `BleAdvertisement` instance. - pub fn new( - address: BleAddress, - rssi: Option, - tx_power: Option, - ) -> Self { - BleAdvertisement { - address, - rssi, - tx_power, - service_data_16bit_uuid: None, - } - } - - /// Retrieve the `BleAddress` that emitted this advertisement. - pub fn address(&self) -> BleAddress { - self.address - } - - /// Retrieve the Received Signal Strength Indicator (RSSI) value for this - /// advertisement, expressed in dBm. The RSSI might be the raw value or the - /// filtered RSSI, depending on the configured signal strength filter. - pub fn rssi(&self) -> Option { - self.rssi - } - - /// Retrieve the transmit power advertised by this device, if any. - /// For BLE communication, values will range from -127 dBm to 20 dBm. - pub fn tx_power(&self) -> Option { - self.tx_power - } - - /// Setter for `ServiceData` field with 16bit UUID. - pub(crate) fn set_service_data_16bit_uuid( - &mut self, - data_sections: Vec>, - ) { - self.service_data_16bit_uuid = Some(data_sections); - } - - /// Getter for `ServiceData` field with 16bit UUID. - pub fn service_data_16bit_uuid( - &self, - ) -> Result<&Vec>, BluetoothError> { - match &self.service_data_16bit_uuid { - Some(service_data) => Ok(&service_data), - None => Err(BluetoothError::FailedPrecondition(String::from( - "No service data has been loaded into this advertisement.", - ))), - } - } -} - -/// Enum denoting the assigned number of Bluetooth common data types. Used for -/// fetching specific data sections from a Bluetooth advertisement. -/// Bluetooth Assigned Numbers, Section 2.3 -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub enum BleDataTypeId { - ServiceData16BitUuid = 0x16, -} - -/// Struct representing the Bluetooth Service Data common data type. `U` should -/// be one of the valid uuid sizes, specified in: -/// Bluetooth Supplement to the Core Specification, Part A, Section 1.11. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct ServiceData { - uuid: U, - data: Vec, -} - -impl ServiceData { - pub fn new(uuid: U, data: Vec) -> Self { - ServiceData { uuid, data } - } - - pub fn uuid(&self) -> U { - self.uuid - } - - pub fn data(&self) -> &Vec { - &self.data - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::common::BleAddressKind; - - #[test] - fn ble_advertisement_new() { - let address = BleAddress::new(0x112233445566, BleAddressKind::Public); - let ad = BleAdvertisement::new(address, Some(-60), Some(10)); - assert_eq!(ad.address(), address); - assert_eq!(ad.rssi(), Some(-60)); - assert_eq!(ad.tx_power(), Some(10)); - assert!(ad.service_data_16bit_uuid.is_none()); - } - - #[test] - fn ble_advertisement_set_and_get_service_data() { - let address = BleAddress::new(0x112233445566, BleAddressKind::Public); - let mut ad = BleAdvertisement::new(address, Some(-60), Some(10)); - - let service_data = vec![ - ServiceData::new(0x1234, vec![0x01, 0x02, 0x03]), - ServiceData::new(0x5678, vec![0x04, 0x05]), - ]; - - ad.set_service_data_16bit_uuid(service_data.clone()); - - let retrieved_service_data = ad.service_data_16bit_uuid().unwrap(); - assert_eq!(*retrieved_service_data, service_data); - } - - #[test] - fn ble_advertisement_missing_service_data() { - let address = BleAddress::new(0x112233445566, BleAddressKind::Public); - let ad = BleAdvertisement::new(address, Some(-60), Some(10)); - - let result = ad.service_data_16bit_uuid(); - assert!(result.is_err()); - assert!(matches!( - result.unwrap_err(), - BluetoothError::FailedPrecondition(_) - )); - } - - #[test] - fn service_data_new() { - let uuid = 0x1234; - let data = vec![0x01, 0x02, 0x03]; - - let service_data = ServiceData::new(uuid, data.clone()); - assert_eq!(service_data.uuid(), uuid); - assert_eq!(*service_data.data(), data); - } -} diff --git a/fastpair/rust/bluetooth/src/common/error.rs b/fastpair/rust/bluetooth/src/common/error.rs deleted file mode 100644 index d0d43208ae..0000000000 --- a/fastpair/rust/bluetooth/src/common/error.rs +++ /dev/null @@ -1,60 +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 thiserror::Error; - -/// Library error type. -#[non_exhaustive] -#[derive(Error, Debug, PartialEq)] -pub enum BluetoothError { - /// Reported when the user attempts a bad type conversion, e.g. converting - /// a BLE random address to a BT Classic address. - #[error("bad type conversion: {0}")] - BadTypeConversion(String), - /// Reported when Bluetooth device pairing fails. - #[error("pairing error: {0}")] - PairingFailed(String), - /// Indicates that the operation was rejected because the system is not in - /// a state required for the operation's execution. - /// E.g. The user calls `stop_scan()` or polls the advertisement stream - #[error("failed precondition: {0}")] - FailedPrecondition(String), - /// Reported when the user calls an operation that is supported by their - /// Operating System, but is not supported by their device. - /// E.g. a Windows machine with an old BT Classic adapter that - /// doesn't support BLE). - #[error("bluetooth operation not supported by system: {0}")] - NotSupported(String), - /// Wrapper around OS-level errors, e.g. `windows::core::Error` for Windows. - /// These typically mean something is very wrong with the system (e.g. OOM). - #[error("bluetooth system-level error: {0}")] - System(String), - /// Reported when a bug occurs inside the library. Whenever a seemingly - /// impossible error condition arises where you could call `expect()`, - /// return this error instead. - #[error("internal error: {0}")] - Internal(String), -} - -/// Abstraction around platform-specific pairing status enums. -/// `PairingResult::Failure` should eventually be converted to -/// `BluetoothError::PairingFailed`. -#[non_exhaustive] -#[derive(Debug)] -pub enum PairingResult { - Success, - AlreadyPaired, - AlreadyInProgress, - Failure(String), -} diff --git a/fastpair/rust/bluetooth/src/common/mod.rs b/fastpair/rust/bluetooth/src/common/mod.rs deleted file mode 100644 index 1ddd9b30eb..0000000000 --- a/fastpair/rust/bluetooth/src/common/mod.rs +++ /dev/null @@ -1,22 +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. - -/// Module for shared functionality between all Bluetooth platforms. -mod address; -mod advertisement; -mod error; - -pub use address::*; -pub use advertisement::*; -pub use error::*; diff --git a/fastpair/rust/bluetooth/src/lib.rs b/fastpair/rust/bluetooth/src/lib.rs deleted file mode 100644 index 99da63627e..0000000000 --- a/fastpair/rust/bluetooth/src/lib.rs +++ /dev/null @@ -1,53 +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. - -pub mod api; -mod common; - -use api::{BleAdapter, BleDevice, ClassicDevice}; -pub use common::{ - BleAddress, BleAddressKind, BleAdvertisement, BleDataTypeId, - BluetoothError, ClassicAddress, PairingResult, ServiceData, -}; - -cfg_if::cfg_if! { - if #[cfg(windows)] { - mod windows; - use self::windows as platform; - } else { - mod unsupported; - use unsupported as platform; - } -} - -pub struct Platform; - -impl Platform { - pub async fn default_adapter( - ) -> Result { - platform::BleAdapter::default().await - } - - pub async fn new_ble_device( - addr: BleAddress, - ) -> Result { - platform::BleDevice::new(addr).await - } - - pub async fn new_classic_device( - addr: ClassicAddress, - ) -> Result { - platform::ClassicDevice::new(addr).await - } -} diff --git a/fastpair/rust/bluetooth/src/message_stream.rs b/fastpair/rust/bluetooth/src/message_stream.rs deleted file mode 100644 index 5e535f446e..0000000000 --- a/fastpair/rust/bluetooth/src/message_stream.rs +++ /dev/null @@ -1,54 +0,0 @@ -// 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. -// 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. - -// Specification: https://developers.google.com/nearby/fast-pair/specifications/extensions/messagestream -// This file should be in sync with fastpair/message_stream/message_stream.h. - -use crate::types::packets::{MessageGroup, MessageStreamPacket}; - -struct BatteryInfo { - is_charging: bool, -} - -pub struct MessageStream { - battery_info: BatteryInfo, -} - -impl MessageStream { - pub fn on_received(&mut self, packet: MessageStreamPacket) { - match packet.group { - MessageGroup::Bluetooth(b) => println!("It's Bluetooth {:?}", b), - MessageGroup::CompanionAppEvent(c) => println!("It's CompanionAppEvent :{:?}", c), - _ => println!("whatever else"), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::types::packets::{BluetoothCode, MessageGroup, MessageStreamPacket}; - - #[test] - fn test_on_received() { - let packet = MessageStreamPacket { - group: MessageGroup::Bluetooth(BluetoothCode::DisableSilenceMode), - additional_data: vec![0, 1, 2], - }; - let mut message = MessageStream { - battery_info: BatteryInfo { is_charging: false } - }; - message.on_received(packet); - } -} diff --git a/fastpair/rust/bluetooth/src/types.rs b/fastpair/rust/bluetooth/src/types.rs deleted file mode 100644 index b0a402b91f..0000000000 --- a/fastpair/rust/bluetooth/src/types.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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. -// 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. - -pub mod packets; \ No newline at end of file diff --git a/fastpair/rust/bluetooth/src/types/packets.rs b/fastpair/rust/bluetooth/src/types/packets.rs deleted file mode 100644 index d62a30155f..0000000000 --- a/fastpair/rust/bluetooth/src/types/packets.rs +++ /dev/null @@ -1,89 +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 -// -// http://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. - -// Specification: https://developers.google.com/nearby/fast-pair/specifications/extensions/messagestream -// This file should be in sync with fastpair/message_stream/message.h. - - -#[derive(Debug)] -pub enum BluetoothCode { - EnableSilenceMode = 0x01, - DisableSilenceMode = 0x02, -} - -#[derive(Debug)] -pub enum CompanionAppEventCode { - LogBufferFull = 0x01, -} - -#[derive(Debug)] -pub enum DeviceInformationEventCode { - ModelId = 0x01, - BleAddressUpdated = 0x02, - BatteryUpdated = 0x03, - RemainingBattery = 0x04, - ActiveComponentsRequest = 0x05, - ActiveComponentsResponse = 0x06, - Capabilities = 0x07, - PlatformType = 0x08, - SessionNonce = 0x0A, -} - -#[derive(Debug)] -pub enum SassCode { - Acknowledgement = 0xFF, - SassGetCapability = 0x10, - SassNotifyCapability = 0x11, - SassSetMultipointState = 0x12, - SassSetSwitchingPreference = 0x20, - SassGetSwitchingPreference = 0x21, - SassNotifySwitchingPreference = 0x22, - SassSwitchActiveSourceCode = 0x30, - SassSwitchBackAudioSource = 0x31, - SassNotifyMultipointSwitchEvent = 0x32, - SassGetConnectionStatus = 0x33, - SassNotifyConnectionStatus = 0x34, - SassNotifySassInitiatedConnection = 0x40, - SassInUseAccountKey = 0x41, - SassSendCustomData = 0x42, - SassSetDropConnectionTarget = 0x43, -} - -#[derive(Debug)] -pub enum DeviceActionEventCode { - Ring = 1, -} - -#[derive(Debug)] -pub enum AcknowledgementCode { - Ack = 1, - Nack = 2, -} - -#[derive(Debug)] -pub enum MessageGroup { - Bluetooth(BluetoothCode), - CompanionAppEvent(CompanionAppEventCode), - DeviceInformationEvent(DeviceInformationEventCode), - DeviceActionEvent(DeviceActionEventCode), - Sass(SassCode), - Acknowledgement(AcknowledgementCode), -} - - -/// A packet that is sent over the RFCOMM Message Stream. -pub struct MessageStreamPacket { - pub group: MessageGroup, - pub additional_data: Vec, -} \ No newline at end of file diff --git a/fastpair/rust/bluetooth/src/unsupported/adapter.rs b/fastpair/rust/bluetooth/src/unsupported/adapter.rs deleted file mode 100644 index 7ae210e1c4..0000000000 --- a/fastpair/rust/bluetooth/src/unsupported/adapter.rs +++ /dev/null @@ -1,50 +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::{api, common::BluetoothError, BleAdvertisement, BleDataTypeId}; - -/// Concrete type implementing `Adapter`, used for unsupported devices. -/// Every method should panic. -pub struct BleAdapter; - -#[async_trait] -impl api::BleAdapter for BleAdapter { - async fn default() -> Result { - panic!("Unsupported target platform."); - } - - fn start_scan(&mut self) -> Result<(), BluetoothError> { - panic!("Unsupported target platform."); - } - - fn stop_scan(&mut self) -> Result<(), BluetoothError> { - panic!("Unsupported target platform."); - } - - async fn next_advertisement( - &mut self, - datatype_selector: Option<&Vec>, - ) -> Result { - panic!("Unsupported target platform"); - } -} - -mod tests { - use super::*; - - // TODO b/288592509 unit tests -} diff --git a/fastpair/rust/bluetooth/src/unsupported/device.rs b/fastpair/rust/bluetooth/src/unsupported/device.rs deleted file mode 100644 index 244ea06c9e..0000000000 --- a/fastpair/rust/bluetooth/src/unsupported/device.rs +++ /dev/null @@ -1,68 +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 crate::{ - api, - common::{BleAddress, BluetoothError, ClassicAddress, PairingResult}, -}; - -/// Concrete type implementing `api::BleDevice` for unsupported platforms. -/// Every method should panic. -pub struct BleDevice; - -#[async_trait] -impl api::BleDevice for BleDevice { - async fn new(addr: BleAddress) -> Result { - panic!("Unsupported target platform."); - } - - fn name(&self) -> Result { - panic!("Unsupported target platform."); - } - - fn address(&self) -> BleAddress { - panic!("Unsupported target platform."); - } -} - -/// Concrete type implementing `api::ClassicDevice` for unsupported platforms. -/// Every method should panic. -pub struct ClassicDevice; - -#[async_trait] -impl api::ClassicDevice for ClassicDevice { - async fn new(addr: ClassicAddress) -> Result { - panic!("Unsupported target platform."); - } - - fn name(&self) -> Result { - panic!("Unsupported target platform."); - } - - fn address(&self) -> ClassicAddress { - panic!("Unsupported target platform."); - } - - async fn pair(&self) -> Result { - panic!("Unsupported target platform."); - } -} - -mod tests { - use super::*; - - // TODO b/288592509 unit tests -} diff --git a/fastpair/rust/bluetooth/src/unsupported/mod.rs b/fastpair/rust/bluetooth/src/unsupported/mod.rs deleted file mode 100644 index a1af0e2d31..0000000000 --- a/fastpair/rust/bluetooth/src/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/bluetooth/src/windows/adapter.rs b/fastpair/rust/bluetooth/src/windows/adapter.rs deleted file mode 100644 index 81613411a3..0000000000 --- a/fastpair/rust/bluetooth/src/windows/adapter.rs +++ /dev/null @@ -1,223 +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::sync::Arc; - -use async_trait::async_trait; -use futures::{channel::mpsc::Receiver, StreamExt}; -use tracing::{error, info, 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 crate::{ - api, - common::{BleAdvertisement, BleDataTypeId, BluetoothError}, -}; - -/// Struct holding the necessary fields for listening to and handling incoming -/// BLE advertisements. -struct AdvListener { - /// Holds callback for sending received advertisement events to `receiver`. - watcher: BluetoothLEAdvertisementWatcher, - /// Can be polled to consume incoming advertisement events. - receiver: Receiver, -} - -/// Concrete type implementing `api::BleAdapter`, used for Windows BLE. -pub struct BleAdapter { - inner: BluetoothAdapter, - listener: Option, -} - -#[async_trait] -impl api::BleAdapter for BleAdapter { - async fn default() -> Result { - let inner = BluetoothAdapter::GetDefaultAsync()?.await?; - - if !inner.IsLowEnergySupported()? { - return Err(BluetoothError::NotSupported(String::from( - "LE transport type", - ))); - } - if !inner.IsCentralRoleSupported()? { - return Err(BluetoothError::NotSupported(String::from( - "central role", - ))); - } - - Ok(BleAdapter { - inner, - listener: None, - }) - } - - fn start_scan(&mut self) -> Result<(), BluetoothError> { - 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(); - info!("Watcher stopped receiving BLE advertisements."); - Ok(()) - }, - ); - - watcher.Received(&received_handler)?; - watcher.Stopped(&stopped_handler)?; - watcher.Start()?; - - self.listener = Some(AdvListener { watcher, receiver }); - - Ok(()) - } - - fn stop_scan(&mut self) -> Result<(), BluetoothError> { - if let Some(listener) = self.listener.take() { - listener.watcher.Stop()?; - Ok(()) - } else { - Err(BluetoothError::FailedPrecondition(String::from( - "device scanning hasn't started, please call `start_scan()`", - ))) - } - } - - async fn next_advertisement( - &mut self, - datatype_selector: Option<&Vec>, - ) -> Result { - if let Some(listener) = &mut self.listener { - let stream = &mut listener.receiver; - // We don't want the end-user to receive empty devices, so this is a - // loop to catch and skip trivial errors from advertisements that - // can't be turned into devices. - loop { - let event_args = - stream.next().await.ok_or(BluetoothError::Internal( - String::from("Event returned from stream is None."), - ))?; - - match event_args.AdvertisementType()? { - BluetoothLEAdvertisementType::NonConnectableUndirected => { - () - } - _ => { - let mut advertisement = - BleAdvertisement::try_from(&event_args)?; - - if let Some(datatype_selector) = datatype_selector { - advertisement - .load_data(&event_args, datatype_selector)?; - } - - break Ok(advertisement); - } - } - } - } else { - Err(BluetoothError::FailedPrecondition(String::from( - "device scanning hasn't started, please call `start_scan()`", - ))) - } - } -} - -mod tests { - // TODO b/288592509 unit tests -} diff --git a/fastpair/rust/bluetooth/src/windows/address.rs b/fastpair/rust/bluetooth/src/windows/address.rs deleted file mode 100644 index 5423c429fd..0000000000 --- a/fastpair/rust/bluetooth/src/windows/address.rs +++ /dev/null @@ -1,52 +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. - -// Whether the Bluetooth advertisement is Public, Random or Unspecified. -//https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothaddresstype?view=winrt-22621 -use windows::Devices::Bluetooth::BluetoothAddressType; - -use crate::common::{BleAddressKind, BluetoothError}; - -// Convenience for converting from Windows API to crate API. -impl TryFrom for BleAddressKind { - type Error = BluetoothError; - - fn try_from(kind: BluetoothAddressType) -> Result { - match kind { - BluetoothAddressType::Public => Ok(BleAddressKind::Public), - BluetoothAddressType::Random => Ok(BleAddressKind::Random), - BluetoothAddressType::Unspecified => { - Err(BluetoothError::BadTypeConversion(String::from( - "Attempting to construct `BleAddressKind` with device \ - advertising Unspecified address type.", - ))) - } - _ => Err(BluetoothError::BadTypeConversion(format!( - "Attempting to construct `BleAddressKind` with device \ - advertising invalid address type {}.", - kind.0, - ))), - } - } -} - -// Convenience for converting from crate API to Windows API. -impl From for BluetoothAddressType { - fn from(kind: BleAddressKind) -> Self { - match kind { - BleAddressKind::Public => BluetoothAddressType::Public, - BleAddressKind::Random => BluetoothAddressType::Random, - } - } -} diff --git a/fastpair/rust/bluetooth/src/windows/advertisement.rs b/fastpair/rust/bluetooth/src/windows/advertisement.rs deleted file mode 100644 index bf80b5a3fb..0000000000 --- a/fastpair/rust/bluetooth/src/windows/advertisement.rs +++ /dev/null @@ -1,115 +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 windows::{ - // Struct that receives Bluetooth Low Energy (LE) advertisements. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcher?view=winrt-22621 - Devices::Bluetooth::Advertisement::{ - BluetoothLEAdvertisementDataSection, - BluetoothLEAdvertisementReceivedEventArgs, - }, - - // Struct representing an immutable view into a vector. - // https://learn.microsoft.com/en-us/uwp/api/windows.foundation.collections.ivectorview-1?view=winrt-22621 - Foundation::Collections::IVectorView, - - // Struct for reading data from a Windows stream, like an IVectorView. - // https://learn.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-22621 - Storage::Streams::DataReader, -}; - -use crate::common::{ - BleAddress, BleAddressKind, BleAdvertisement, BleDataTypeId, - BluetoothError, ServiceData, -}; - -impl TryFrom<&BluetoothLEAdvertisementReceivedEventArgs> for BleAdvertisement { - type Error = BluetoothError; - - fn try_from( - adv: &BluetoothLEAdvertisementReceivedEventArgs, - ) -> Result { - let addr = adv.BluetoothAddress()?; - let kind = BleAddressKind::try_from(adv.BluetoothAddressType()?)?; - - let addr = BleAddress::new(addr, kind); - // `rssi` and tx_power` aren't always advertised, so convert to None if - // can't extract value. - let rssi = adv.RawSignalStrengthInDBm().ok(); - let tx_power = match adv.TransmitPowerLevelInDBm() { - Ok(val_ref) => val_ref.GetInt16().ok(), - Err(_) => None, - }; - - Ok(BleAdvertisement::new(addr, rssi, tx_power)) - } -} - -impl BleAdvertisement { - /// Load data of selected data types into self by parsing the raw Windows - /// advertisement. - /// See: Supplement to the Bluetooth Core Specification Part A, Section 1. - pub(crate) fn load_data( - &mut self, - adv: &BluetoothLEAdvertisementReceivedEventArgs, - datatype_ids: &[BleDataTypeId], - ) -> Result<(), BluetoothError> { - let adv = adv.Advertisement()?; - - for datatype_id in datatype_ids { - // Note `raw_data_sections` is `!Send` and `!Sync`. This means - // processing must occur in a synchronous environment. The compiler - // will complain if parsing is done in an async function. - let raw_data_sections = - adv.GetSectionsByType((*datatype_id) as u8)?; - match datatype_id { - BleDataTypeId::ServiceData16BitUuid => { - let service_data = - parse_service_data_16bit_uuid(raw_data_sections)?; - self.set_service_data_16bit_uuid(service_data) - } - }; - } - - Ok(()) - } -} - -/// Parse the advertisement's service data. -/// Further Reading: -/// * `BleMedium::AdvertisementReceivedHandler` under -/// github.com/google/nearby/internal/platform/implementation/windows_ble/ble_medium.cc. -/// * Bluetooth Supplement to the Core Specification, Part A, Section 1.11. -/// * go/fast_pair_windows_data_parse. -#[inline] -fn parse_service_data_16bit_uuid( - raw_data_sections: IVectorView, -) -> Result>, BluetoothError> { - let mut data_vec = Vec::new(); - - for raw_data in raw_data_sections { - let data_reader = DataReader::FromBuffer(&raw_data.Data()?)?; - let uuid = data_reader.ReadUInt16()?; - - let unconsumed_buffer_len = - data_reader.UnconsumedBufferLength()? as usize; - - let mut data = vec![0u8; unconsumed_buffer_len]; - data_reader.ReadBytes(&mut data)?; - - data_vec.push(ServiceData::new(uuid, data)); - } - - Ok(data_vec) -} diff --git a/fastpair/rust/bluetooth/src/windows/device.rs b/fastpair/rust/bluetooth/src/windows/device.rs deleted file mode 100644 index c0b96d8d39..0000000000 --- a/fastpair/rust/bluetooth/src/windows/device.rs +++ /dev/null @@ -1,161 +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 tracing::{info, warn}; -use windows::{ - Devices::{ - Bluetooth::{ - // Tuple struct 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 a discovered BT Classic device. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothdevice?view=winrt-22621 - BluetoothDevice, - - // Struct for interacting with a discovered BLE device. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothledevice?view=winrt-22621 - BluetoothLEDevice, - }, - Enumeration::{ - // Struct for custom pairing with a device. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationcustompairing?view=winrt-22621 - DeviceInformationCustomPairing, - - // Tuple struct to indicate the kinds of pairing supported by the application. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicepairingkinds?view=winrt-22621 - DevicePairingKinds, - - // Struct for retrieving data about a PairingRequested event. - // https://learn.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicepairingrequestedeventargs?view=winrt-22621 - DevicePairingRequestedEventArgs, - }, - }, - // Wraps a closure for handling events associated with a struct - // (e.g. PairingRequested event in `DeviceInformationCustomPairing`). - // https://learn.microsoft.com/en-us/uwp/api/windows.foundation.typedeventhandler-2?view=winrt-22621 - Foundation::TypedEventHandler, -}; - -use crate::{api, common::{BleAddress, ClassicAddress, BluetoothError, PairingResult}}; - -/// Concrete type implementing `Device`, used for Windows BLE. -pub struct BleDevice { - inner: BluetoothLEDevice, - addr: BleAddress, -} - -/// Concrete type implementing `Device`, used for Windows Bluetooth Classic. -pub struct ClassicDevice { - inner: BluetoothDevice, - addr: ClassicAddress, -} - -#[async_trait] -impl api::BleDevice for BleDevice { - async fn new(addr: BleAddress) -> Result { - let kind = BluetoothAddressType::from(addr.get_kind()); - let raw_addr = u64::from(addr); - - let inner = BluetoothLEDevice::FromBluetoothAddressWithBluetoothAddressTypeAsync( - raw_addr, kind, - )? - .await?; - - Ok(BleDevice { inner, addr }) - } - - fn name(&self) -> Result { - Ok(self.inner.Name()?.to_string()) - } - - fn address(&self) -> BleAddress { - self.addr - } -} - -#[async_trait] -impl api::ClassicDevice for ClassicDevice { - async fn new(addr: ClassicAddress) -> Result { - let raw_addr = u64::from(addr); - - let inner = BluetoothDevice::FromBluetoothAddressAsync( - raw_addr, - )? - .await?; - - Ok(ClassicDevice { inner, addr }) - } - - fn name(&self) -> Result { - Ok(self.inner.Name()?.to_string_lossy()) - } - - fn address(&self) -> ClassicAddress { - self.addr - } - - async fn pair(&self) -> Result { - let pair_info = self.inner.DeviceInformation()?.Pairing()?; - if pair_info.IsPaired()? { - info!("Device already paired"); - Ok(PairingResult::AlreadyPaired) - } else if !pair_info.CanPair()? { - info!("Device can't pair"); - Err(BluetoothError::PairingFailed(String::from("device can't pair"))) - } else { - let custom = pair_info.Custom()?; - custom.PairingRequested(&TypedEventHandler::new( - |_custom: &Option, - event_args: &Option, - | { - if let Some(event_args) = event_args { - match event_args.PairingKind()? { - DevicePairingKinds::ConfirmOnly => { - event_args.Accept() - } - _ => { - warn!("Unsupported pairing kind {:?}", event_args.PairingKind()); - Ok(()) - } - } - } else { - warn!("Empty pairing event arguments"); - Ok(()) - } - - }, - ))?; - let res = custom - .PairAsync( - DevicePairingKinds::ConfirmOnly - | DevicePairingKinds::ProvidePin - | DevicePairingKinds::ConfirmPinMatch - | DevicePairingKinds::DisplayPin, - )? - .await?; - let status = PairingResult::from(res.Status()?); - - match status { - PairingResult::Failure(msg) => Err(BluetoothError::PairingFailed(msg)), - _ => Ok(status), - } - } - } -} - -mod tests { - // TODO b/288592509 unit tests -} diff --git a/fastpair/rust/bluetooth/src/windows/error.rs b/fastpair/rust/bluetooth/src/windows/error.rs deleted file mode 100644 index 9a7f6d4c47..0000000000 --- a/fastpair/rust/bluetooth/src/windows/error.rs +++ /dev/null @@ -1,57 +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 windows::Devices::Enumeration::DevicePairingResultStatus; - -use crate::common::{BluetoothError, PairingResult}; - -impl From for BluetoothError { - fn from(err: windows::core::Error) -> Self { - BluetoothError::System(err.to_string()) - } -} - -// https://learn.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicepairingresultstatus?view=winrt-22621 -impl From for PairingResult { - fn from(status: DevicePairingResultStatus) -> Self { - match status { - DevicePairingResultStatus::Paired => PairingResult::Success, - DevicePairingResultStatus::AlreadyPaired => { - PairingResult::AlreadyPaired - } - DevicePairingResultStatus::OperationAlreadyInProgress => { - PairingResult::AlreadyInProgress - } - DevicePairingResultStatus::NotReadyToPair => PairingResult::Failure( - String::from("the device object is not in a state where it can be paired"), - ), - DevicePairingResultStatus::NotPaired => PairingResult::Failure(String::from("the device object is not currently paired.")), - DevicePairingResultStatus::ConnectionRejected => PairingResult::Failure(String::from("the device object rejected the connection.")), - DevicePairingResultStatus::TooManyConnections => PairingResult::Failure(String::from("the device object indicated it cannot accept any more incoming connections.")), - DevicePairingResultStatus::HardwareFailure => PairingResult::Failure(String::from("the device object indicated there was a hardware failure.")), - DevicePairingResultStatus::AuthenticationTimeout => PairingResult::Failure(String::from("the authentication process timed out before it could complete.")), - DevicePairingResultStatus::AuthenticationNotAllowed => PairingResult::Failure(String::from("the authentication protocol is not supported, so the device is not paired.")), - DevicePairingResultStatus::AuthenticationFailure => PairingResult::Failure(String::from("authentication failed, so the device is not paired. Either the device object or the application rejected the authentication.")), - DevicePairingResultStatus::NoSupportedProfiles => PairingResult::Failure(String::from("there are no network profiles for this device object to use.")), - DevicePairingResultStatus::ProtectionLevelCouldNotBeMet => PairingResult::Failure(String::from("the minimum level of protection is not supported by the device object or the application.")), - DevicePairingResultStatus::AccessDenied => PairingResult::Failure(String::from("your application does not have the appropriate permissions level to pair the device object.")), - DevicePairingResultStatus::InvalidCeremonyData => PairingResult::Failure(String::from("the ceremony data was incorrect.")), - DevicePairingResultStatus::PairingCanceled => PairingResult::Failure(String::from("the pairing action was canceled before completion.")), - DevicePairingResultStatus::RequiredHandlerNotRegistered => PairingResult::Failure(String::from("either the event handler wasn't registered or a required DevicePairingKinds was not supported.",)), - DevicePairingResultStatus::RejectedByHandler => PairingResult::Failure(String::from("the application handler rejected the pairing.")), - DevicePairingResultStatus::RemoteDeviceHasAssociation => PairingResult::Failure(String::from("the remote device already has an association.")), - DevicePairingResultStatus::Failed | _ => PairingResult::Failure(String::from("an unknown failure occurred.")), - } - } -} diff --git a/fastpair/rust/bluetooth/src/windows/mod.rs b/fastpair/rust/bluetooth/src/windows/mod.rs deleted file mode 100644 index 8003fe00a1..0000000000 --- a/fastpair/rust/bluetooth/src/windows/mod.rs +++ /dev/null @@ -1,25 +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 address; -mod advertisement; -mod device; -mod error; - -pub use adapter::*; -pub use address::*; -pub use advertisement::*; -pub use device::*; diff --git a/fastpair/rust/demo/.gitignore b/fastpair/rust/demo/.gitignore deleted file mode 100644 index 24476c5d1e..0000000000 --- a/fastpair/rust/demo/.gitignore +++ /dev/null @@ -1,44 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ -migrate_working_dir/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -/build/ - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release diff --git a/fastpair/rust/demo/.metadata b/fastpair/rust/demo/.metadata deleted file mode 100644 index de745e4a0a..0000000000 --- a/fastpair/rust/demo/.metadata +++ /dev/null @@ -1,45 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled. - -version: - revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - channel: stable - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - - platform: android - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - - platform: ios - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - - platform: linux - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - - platform: macos - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - - platform: web - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - - platform: windows - create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/fastpair/rust/demo/README.md b/fastpair/rust/demo/README.md deleted file mode 100644 index dbd403a001..0000000000 --- a/fastpair/rust/demo/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# demo - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) - -For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/fastpair/rust/demo/analysis_options.yaml b/fastpair/rust/demo/analysis_options.yaml deleted file mode 100644 index 6c5d26c526..0000000000 --- a/fastpair/rust/demo/analysis_options.yaml +++ /dev/null @@ -1,43 +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. - -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. -include: package:flutter_lints/flutter.yaml - -linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at - # https://dart-lang.github.io/linter/lints/index.html. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. - rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options diff --git a/fastpair/rust/demo/bindgen.script b/fastpair/rust/demo/bindgen.script deleted file mode 100644 index 4533096afa..0000000000 --- a/fastpair/rust/demo/bindgen.script +++ /dev/null @@ -1,4 +0,0 @@ -flutter_rust_bridge_codegen --rust-input rust/src/api.rs --dart-output lib/bridge_generated.dart --dart-decl-output lib/bridge_definitions.dart - -# github.com/google/addlicense -addlicense . \ No newline at end of file diff --git a/fastpair/rust/demo/lib/bridge_definitions.dart b/fastpair/rust/demo/lib/bridge_definitions.dart deleted file mode 100644 index b66ccf6b95..0000000000 --- a/fastpair/rust/demo/lib/bridge_definitions.dart +++ /dev/null @@ -1,42 +0,0 @@ -// AUTO GENERATED FILE, DO NOT EDIT. -// Generated by `flutter_rust_bridge`@ 1.79.0. -// ignore_for_file: non_constant_identifier_names, unused_element, duplicate_ignore, directives_ordering, curly_braces_in_flow_control_structures, unnecessary_lambdas, slash_for_doc_comments, prefer_const_literals_to_create_immutables, implicit_dynamic_list_literal, duplicate_import, unused_import, unnecessary_import, prefer_single_quotes, prefer_const_constructors, use_super_parameters, always_use_package_imports, annotate_overrides, invalid_use_of_protected_member, constant_identifier_names, invalid_use_of_internal_member, prefer_is_empty, unnecessary_const - -import 'dart:convert'; -import 'dart:async'; -import 'package:meta/meta.dart'; -import 'package:flutter_rust_bridge/flutter_rust_bridge.dart'; -import 'package:uuid/uuid.dart'; - -import 'package:collection/collection.dart'; - -abstract class Rust { - /// Sets up initial constructs and infinitely polls for advertisements. - Future init({dynamic hint}); - - FlutterRustBridgeTaskConstMeta get kInitConstMeta; - - /// Sets up `StreamSink` for Dart-Rust FFI. - Stream eventStream({dynamic hint}); - - FlutterRustBridgeTaskConstMeta get kEventStreamConstMeta; - - /// Attempt classic pairing with currently displayed device. - Future pair({dynamic hint}); - - FlutterRustBridgeTaskConstMeta get kPairConstMeta; - - /// Remove this device from display and add it to the TTL cache blacklist. - Future dismiss({dynamic hint}); - - FlutterRustBridgeTaskConstMeta get kDismissConstMeta; -} - -class StringArray2 extends NonGrowableListView { - static const arraySize = 2; - StringArray2(List inner) - : assert(inner.length == arraySize), - super(inner); - StringArray2.unchecked(List inner) : super(inner); - StringArray2.init(String fill) : super(List.filled(arraySize, fill)); -} diff --git a/fastpair/rust/demo/lib/bridge_generated.dart b/fastpair/rust/demo/lib/bridge_generated.dart deleted file mode 100644 index 9fc5d9db89..0000000000 --- a/fastpair/rust/demo/lib/bridge_generated.dart +++ /dev/null @@ -1,305 +0,0 @@ -// AUTO GENERATED FILE, DO NOT EDIT. -// Generated by `flutter_rust_bridge`@ 1.79.0. -// ignore_for_file: non_constant_identifier_names, unused_element, duplicate_ignore, directives_ordering, curly_braces_in_flow_control_structures, unnecessary_lambdas, slash_for_doc_comments, prefer_const_literals_to_create_immutables, implicit_dynamic_list_literal, duplicate_import, unused_import, unnecessary_import, prefer_single_quotes, prefer_const_constructors, use_super_parameters, always_use_package_imports, annotate_overrides, invalid_use_of_protected_member, constant_identifier_names, invalid_use_of_internal_member, prefer_is_empty, unnecessary_const - -import "bridge_definitions.dart"; -import 'dart:convert'; -import 'dart:async'; -import 'package:meta/meta.dart'; -import 'package:flutter_rust_bridge/flutter_rust_bridge.dart'; -import 'package:uuid/uuid.dart'; - -import 'dart:convert'; -import 'dart:async'; -import 'package:meta/meta.dart'; -import 'package:flutter_rust_bridge/flutter_rust_bridge.dart'; -import 'package:uuid/uuid.dart'; - -import 'dart:ffi' as ffi; - -class RustImpl implements Rust { - final RustPlatform _platform; - factory RustImpl(ExternalLibrary dylib) => RustImpl.raw(RustPlatform(dylib)); - - /// Only valid on web/WASM platforms. - factory RustImpl.wasm(FutureOr module) => - RustImpl(module as ExternalLibrary); - RustImpl.raw(this._platform); - Future init({dynamic hint}) { - return _platform.executeNormal(FlutterRustBridgeTask( - callFfi: (port_) => _platform.inner.wire_init(port_), - parseSuccessData: _wire2api_unit, - constMeta: kInitConstMeta, - argValues: [], - hint: hint, - )); - } - - FlutterRustBridgeTaskConstMeta get kInitConstMeta => - const FlutterRustBridgeTaskConstMeta( - debugName: "init", - argNames: [], - ); - - Stream eventStream({dynamic hint}) { - return _platform.executeStream(FlutterRustBridgeTask( - callFfi: (port_) => _platform.inner.wire_event_stream(port_), - parseSuccessData: _wire2api_opt_String_array_2, - constMeta: kEventStreamConstMeta, - argValues: [], - hint: hint, - )); - } - - FlutterRustBridgeTaskConstMeta get kEventStreamConstMeta => - const FlutterRustBridgeTaskConstMeta( - debugName: "event_stream", - argNames: [], - ); - - Future pair({dynamic hint}) { - return _platform.executeNormal(FlutterRustBridgeTask( - callFfi: (port_) => _platform.inner.wire_pair(port_), - parseSuccessData: _wire2api_String, - constMeta: kPairConstMeta, - argValues: [], - hint: hint, - )); - } - - FlutterRustBridgeTaskConstMeta get kPairConstMeta => - const FlutterRustBridgeTaskConstMeta( - debugName: "pair", - argNames: [], - ); - - Future dismiss({dynamic hint}) { - return _platform.executeNormal(FlutterRustBridgeTask( - callFfi: (port_) => _platform.inner.wire_dismiss(port_), - parseSuccessData: _wire2api_unit, - constMeta: kDismissConstMeta, - argValues: [], - hint: hint, - )); - } - - FlutterRustBridgeTaskConstMeta get kDismissConstMeta => - const FlutterRustBridgeTaskConstMeta( - debugName: "dismiss", - argNames: [], - ); - - void dispose() { - _platform.dispose(); - } -// Section: wire2api - - String _wire2api_String(dynamic raw) { - return raw as String; - } - - StringArray2 _wire2api_String_array_2(dynamic raw) { - return StringArray2((raw as List).map(_wire2api_String).toList()); - } - - List _wire2api_list_String(dynamic raw) { - return (raw as List).map(_wire2api_String).toList(); - } - - StringArray2? _wire2api_opt_String_array_2(dynamic raw) { - return raw == null ? null : _wire2api_String_array_2(raw); - } - - int _wire2api_u8(dynamic raw) { - return raw as int; - } - - Uint8List _wire2api_uint_8_list(dynamic raw) { - return raw as Uint8List; - } - - void _wire2api_unit(dynamic raw) { - return; - } -} - -// Section: api2wire - -// Section: finalizer - -class RustPlatform extends FlutterRustBridgeBase { - RustPlatform(ffi.DynamicLibrary dylib) : super(RustWire(dylib)); - -// Section: api2wire - -// Section: finalizer - -// Section: api_fill_to_wire -} - -// ignore_for_file: camel_case_types, non_constant_identifier_names, avoid_positional_boolean_parameters, annotate_overrides, constant_identifier_names - -// AUTO GENERATED FILE, DO NOT EDIT. -// -// Generated by `package:ffigen`. -// ignore_for_file: type=lint - -/// generated by flutter_rust_bridge -class RustWire implements FlutterRustBridgeWireBase { - @internal - late final dartApi = DartApiDl(init_frb_dart_api_dl); - - /// Holds the symbol lookup function. - final ffi.Pointer Function(String symbolName) - _lookup; - - /// The symbols are looked up in [dynamicLibrary]. - RustWire(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup; - - /// The symbols are looked up with [lookup]. - RustWire.fromLookup( - ffi.Pointer Function(String symbolName) - lookup) - : _lookup = lookup; - - void store_dart_post_cobject( - DartPostCObjectFnType ptr, - ) { - return _store_dart_post_cobject( - ptr, - ); - } - - late final _store_dart_post_cobjectPtr = - _lookup>( - 'store_dart_post_cobject'); - late final _store_dart_post_cobject = _store_dart_post_cobjectPtr - .asFunction(); - - Object get_dart_object( - int ptr, - ) { - return _get_dart_object( - ptr, - ); - } - - late final _get_dart_objectPtr = - _lookup>( - 'get_dart_object'); - late final _get_dart_object = - _get_dart_objectPtr.asFunction(); - - void drop_dart_object( - int ptr, - ) { - return _drop_dart_object( - ptr, - ); - } - - late final _drop_dart_objectPtr = - _lookup>( - 'drop_dart_object'); - late final _drop_dart_object = - _drop_dart_objectPtr.asFunction(); - - int new_dart_opaque( - Object handle, - ) { - return _new_dart_opaque( - handle, - ); - } - - late final _new_dart_opaquePtr = - _lookup>( - 'new_dart_opaque'); - late final _new_dart_opaque = - _new_dart_opaquePtr.asFunction(); - - int init_frb_dart_api_dl( - ffi.Pointer obj, - ) { - return _init_frb_dart_api_dl( - obj, - ); - } - - late final _init_frb_dart_api_dlPtr = - _lookup)>>( - 'init_frb_dart_api_dl'); - late final _init_frb_dart_api_dl = _init_frb_dart_api_dlPtr - .asFunction)>(); - - void wire_init( - int port_, - ) { - return _wire_init( - port_, - ); - } - - late final _wire_initPtr = - _lookup>('wire_init'); - late final _wire_init = _wire_initPtr.asFunction(); - - void wire_event_stream( - int port_, - ) { - return _wire_event_stream( - port_, - ); - } - - late final _wire_event_streamPtr = - _lookup>( - 'wire_event_stream'); - late final _wire_event_stream = - _wire_event_streamPtr.asFunction(); - - void wire_pair( - int port_, - ) { - return _wire_pair( - port_, - ); - } - - late final _wire_pairPtr = - _lookup>('wire_pair'); - late final _wire_pair = _wire_pairPtr.asFunction(); - - void wire_dismiss( - int port_, - ) { - return _wire_dismiss( - port_, - ); - } - - late final _wire_dismissPtr = - _lookup>('wire_dismiss'); - late final _wire_dismiss = _wire_dismissPtr.asFunction(); - - void free_WireSyncReturn( - WireSyncReturn ptr, - ) { - return _free_WireSyncReturn( - ptr, - ); - } - - late final _free_WireSyncReturnPtr = - _lookup>( - 'free_WireSyncReturn'); - late final _free_WireSyncReturn = - _free_WireSyncReturnPtr.asFunction(); -} - -final class _Dart_Handle extends ffi.Opaque {} - -typedef DartPostCObjectFnType = ffi.Pointer< - ffi.NativeFunction< - ffi.Bool Function(DartPort port_id, ffi.Pointer message)>>; -typedef DartPort = ffi.Int64; diff --git a/fastpair/rust/demo/lib/main.dart b/fastpair/rust/demo/lib/main.dart deleted file mode 100644 index a9995d7136..0000000000 --- a/fastpair/rust/demo/lib/main.dart +++ /dev/null @@ -1,130 +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. - -import 'package:flutter/material.dart'; -import 'package:demo/rust.dart'; - -void main() { - api.init(); - runApp(const FastPairApp()); -} - -class FastPairApp extends StatelessWidget { - const FastPairApp({super.key}); - @override - Widget build(BuildContext context) => MaterialApp( - title: 'Fast Pair', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: const HomePage(), - ); -} - -class HomePage extends StatelessWidget { - const HomePage({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: const Text("Fast Pair"), - ), - body: Center( - child: StreamBuilder( - // Retrieve device info stream from Rust side. - stream: api.eventStream(), - builder: (context, deviceInfo) { - var deviceName = deviceInfo.data?[0]; - var deviceImageUrl = deviceInfo.data?[1]; - - if (deviceInfo.hasData && - deviceName != null && - deviceImageUrl != null) { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Image.network(deviceImageUrl, - fit: BoxFit.contain)), - Text(deviceName), - // Spacing between device name text and buttons. - const SizedBox(height: 20), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - // Spacing between left edge of screen and first button. - const SizedBox(width: 20), - OutlinedButton( - // Invoke pairing dialog. - onPressed: () => pairing(context), - child: const Text('Pair'), - ), - // Spacing between buttons. - const SizedBox(width: 20), - OutlinedButton( - onPressed: () => api.dismiss(), - child: const Text('Dismiss')) - ], - ), - // Spacing between buttons and bottom of screen. - const SizedBox(height: 20), - ]); - } - return const Center( - child: CircularProgressIndicator(), - ); - }, - ), - ), - ); -} - -// Displays pairing dialog box. -Future pairing(BuildContext context) => showDialog( - context: context, - // Rust functions are invoked as futures. - builder: (context) => FutureBuilder( - future: api.pair(), - builder: (context, pairResult) { - var pairResultValue = pairResult.data; - - return pairResult.hasData && pairResultValue != null - ? AlertDialog( - title: const Text('Pairing result'), - content: Text(pairResultValue), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context, 'OK'), - child: const Text('OK'), - ) - ], - ) - : const AlertDialog( - title: Text('Pairing...'), - // Ensures the progress indicator has sensible dimensions, - // otherwise it follows the height/width of the alert dialog. - content: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 50, - height: 50, - child: CircularProgressIndicator(), - ), - ], - ), - ); - })); diff --git a/fastpair/rust/demo/lib/rust.dart b/fastpair/rust/demo/lib/rust.dart deleted file mode 100644 index a525483bc3..0000000000 --- a/fastpair/rust/demo/lib/rust.dart +++ /dev/null @@ -1,32 +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. - -// This file initializes the dynamic library and connects it with the stub -// generated by flutter_rust_bridge_codegen. - -import 'dart:ffi'; - -import 'dart:io' as io; - -import 'package:demo/bridge_generated.dart'; - -const _base = 'rust'; - -// On MacOS, the dynamic library is not bundled with the binary, -// but rather directly **linked** against the binary. -final _dylib = io.Platform.isWindows ? '$_base.dll' : 'lib$_base.so'; - -final api = RustImpl(io.Platform.isIOS || io.Platform.isMacOS - ? DynamicLibrary.executable() - : DynamicLibrary.open(_dylib)); diff --git a/fastpair/rust/demo/local/525296.json b/fastpair/rust/demo/local/525296.json deleted file mode 100644 index 0404cf7e06..0000000000 --- a/fastpair/rust/demo/local/525296.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "device": { - "id": "525296", - "notificationType": "FAST_PAIR_ONE", - "imageUrl": "https://lh3.googleusercontent.com/M67kfg-lVtqeP0-CLuvR68J4MlY9wixO0Za3urah_5axGRUyi20KSEQiqjvhqxCWTxpsicU1w-TCL3BX", - "name": "LG HBS-1125", - "intentUri": "intent:#Intent;action=com.google.android.gms.nearby.discovery%3AACTION_MAGIC_PAIR;package=com.google.android.gms;component=com.google.android.gms/.nearby.discovery.service.DiscoveryService;S.com.google.android.gms.nearby.discovery%3AEXTRA_COMPANION_APP=com.lge.tonentalkplus.tonentalkfree;end", - "triggerDistance": 0.6, - "antiSpoofingKeyPair": {}, - "status": { - "statusType": "PUBLISHED" - }, - "lastUpdateTimestamp": "2021-12-02T07:11:36.110Z", - "deviceType": "HEADPHONES", - "trueWirelessImages": {}, - "companyName": "LG", - "interactionType": "NOTIFICATION", - "companionDetail": {} - }, - "image": "iVBORw0KGgoAAAANSUhEUgAAAIwAAACMCAYAAACuwEE+AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABcRAAAXEQHKJvM/AAAAB3RJTUUH4gQEDBoz611DFwAAIABJREFUeNrtfWeYVFW29rv3SXUqdXWszt00SUCCkTuDIzKXa1ZAjAQFESQqwSFIK1EJYkbFgAqIaZwZHFHHa2B0RsfBhOSWaHfTTUOH6q58ztl7fz9OdcO933O/7w7SAa33eeppuqiu2qfWe9Zea+0VgCSSSCKJJJJIIokkOjyEEB36/To6yC+YOGT5ihVZgYbawlg8nsEsnhaLxR2yTNySpDiEEBIhiAIQjBuGJElNDoe7gUDUpKX5j8ybN6eGEMJ/ad/bz4owF11yDv7+1+9afl++fDndu3evommqRiXSPRoNXxKPsd8YRqx/LBbJMi0DhmHBNBg45wAEOBfgnINSgFIJhBBwLiBJFIqqQlVVKIoMSil0h+OYrMhfqor+aXp62t9MM/pDMByKdevS3Zw3r7SFTIMGDcQnn/wVhJAkYdobn376KQYOHPhfnps85Y7+DfXhgY2NjecbhtHTMIxuhhFVLEvANC0IYYFzASEECAEoJQAoKEXieYBzBkplABwASbyGgHOAEAFCCAghkGUFsixDUSTousPUNMcPDoe2V9cd33lTvFtWP7nmi+Z15ebmYv369Rg8eHCSMG2JFStWYM6cOQCAOXN+R1xOD21obOhbVfnjzIbG4PXBYJMWj5ngnNkXSSgEOIQAKCEQQoBS+70kKoNIBBC05TlCJAjB7J+w7K9JAJzb78EYgxAi8f4UQtgkEsL+HRBwOp1wuVxwe9yGy+n9Q35+3iOyLH/bvXt3fttttwEAtm7digsvvDBJmLbC0KFDrohEwyM444ODoXC2ZRotRmiz+re1iK0hJEmBqiYemgJNU6EqDkiSIiSJhCilIUKoKcDigsuCUkDAUgiIxjl3W4y5LZNRwzAQi8UQNwzEY3GYpgXGTAAcjInE59qfL0sSVE2D06mDc35YUZQ3s7Iy39y48bVvkhqmDfD73/+evvrqq+NqamqWB4ONaeFwBG53CnRdS9zlIqFBKGRZhizLcDqd8Hjc8Kb4uNfj2aVpjs8cTvUbn8+3M8XjO9i//6+aFiwstQry8wFIEDAhhAyJSgAsAAJ19XWYNnWGtHPn9ymhcKCgtraubzRqXBCPGxc1Bpp6NTQ0yA0NDYhGo2CMgzGe0EA2YS2LIxyOQksQNTU1dXtRUeGUl15a93cAWLJkCe67774kYX4iOXDDDTcAAMaNG9v1wIGDY6LR2LjGxkZ/LBYDpYCmaXA6nVBVDQIcsiTB4/EixeczXU73tx6P95uUFO9XWVnZ30yePHHX/+TZmKYJRVH+x7UYhgFVVf/H/3/22TU9q44eOjdQH7ogEAheEAqFz28INCihYCNMk8GyDAhBWohEKKA7dHi9KV+7XO5nx48fv3HYsGHRJGFOESUlJTh48CAee+wJ9+bNm9YeO3ZseDxuSjZRKFJTU+FwKGCMA6BQVRXZ2X7k5+fvSEtLXa7r+p/jcTN2zTXXsD59+rRZsKS+/jhWr35GTk1N1RsCdVfX1TbMPXRof5/q6qMwTdZiaDPGYBgmJEmCoijC5XJFcnNzZ7311lvPAsDSpUtRWlqaJMz/FpMmT8zbvWvP1FAoODsYbKSGYUKRFXi8HnjcbjDBITiB2+0WTqfz74WFhR/079//jREjRuxvfo8DBw6gc+fObb72gwcPoqSkpOX3t9/+Y/aWLZ+OKC+vuLaxsXFgINDQYmsZhgnLskCIrS293pS9Ho9nyebNm98ghLCrr74amzdvThLmv2PDhpcxevQYAMC11147//CPB0tNgzkikTAIocjKzILuVCFJMgzDhMftRWFR4dMpPs9Sl9Nbu2DB/Wbzex06dAidOnVq92vatWsXevXq1fL7ypUr5cbGpqz6+prFZWX7xwUaAyAJA900LYQjEWiqBl1XhdudcvD8888fumrVqp3331+KxYuXJgkDAOvWrUOzm3nV1Vf1r6ure6yhof7fLNOCZTGkpHiQmZkBQgk443A49CNZWRlvTpg0Zumv+w+uB4ANG1/C6JFjO7zB+Nprr+GWW24BAHz48Xt569dtXHDkSNWNoWAoxQ4aApFIBJZlQdNUOJ0upKWlruzX75xly5YtCyxfvgxz585LahgAGDx48KPVR49OMo24FolEoTt15OflQdM0OwpLgE6dimZJVH7h6afXNAHAnRPH4Nk1L59xrunwG67BH37/DgDgnntmZQQCgUV79pRNtqwIhJAghEAgEICiqHC5dGiadqR79+7D1q596avJkyfj6aefbre10/b4UCEELr3UjnbecsvNXQYMGLCtvLx8ejQS1qKRKPz+LHTv1hVOpw5CiOX2uN6aMeMu/7NrXniksKioqcUzOQPJAqCFLB999BFWrXq49oUX1k4ZMmTor1JT07+VZRlUosjIyIAQQFNTCNFoNK+s7Ietw4cPnzRs2DAJAFavXv3L0zC33Tb6mm3btr0ajcbc8bgddOvcuQTeFDeYxSHL8lG/P+eKNWvWbCOEYMrUO/HU6mfxc8XGja+rW7Z8NHbfvrI1pmkCIIhGIwgGQ/B6PXA4nPD5fH967733rgOAJ598AtOm3dWma5Ta8sOWLXsQH3/8MQDgyisvn7h3796NsVhMjcViUBQNPXqcBa/XC8tikGTy/rS7J/3b3dNmHhFC4NNPP8VXW7/BzxmmGWOvv/76N2PHjnmjsvLIZUKIdE1ToaoKgsEgCKEwTaNH3779rhk69Jo3S0vvj82ePQuff/6Pn7eGufzyy56srKyYGo8bCIcjSEtPRefOJVAVBYZpwOtJueepFesf9eZK/OTg3S8BS5cuRmnp/ZgzZ463rKzs8bq642Motb2ouroG6LodqHS7XXvHjRt73k03jYrMnv07rFz50M/Hhmk20oQQ5NJLL3uooqJ8ajweRzQaRVq6D926doGmOmBZpuV1e2du2LDx4ZVPL+AAflFkAYDS0vshhMAPP/zQtGnTprE+n+9JQig0TYPfn4F4PA7DMBAOR8566aX1FTNnzvKvXPkQ5s+/9+enYa666qpHy8vLp8diMUQiIWRmZqJzl2JoqhuGEY+l+FKGrn3hxQ+QxH/BdcOHjgk0NLwEUDDGUVNTA4/HA4fDAZfLeeiKK6485+67725cunQRSksXnNkaZsCAXyVslivnV1RUTG++Q3wpPnTu0hmq6kA8HjNTUnzXrX3hxQ/eeOO1JENO1jj3zcMf/7DpZV13TgcgFEVGbm4OgsEgACAajXT68MMPytasWe0uLV2At99++8zVMOPGjcPatWtxyy233FRWVvZaOBwmsVgMsqyg3zlnw+HQYFmW4XKlXP7i2he3JOnx/9E01w0Z29QUfJFKEmLRGI4dq0GW3w9KCLxe9+eTp4+6+NEV68QHH3wgzjgNs2LFCqxduxZTpky5YN++fa9HImHSnHjU75ye0HUHAECRHdNeXPvilueeey7JiP8H5s6djT/+8e2XNIe2DODQHQ5kZPhRX9cATdMQDkcHrH/hnedbkyytpmHsnFiK2bPneL744oud9fV1haZpIhgM4uyzeyEnNxOMMSiKOm/dyxuXJ+nwr+Hqq69+yTDiYwCK+vrjAIDs7CzETQNZGZn3b9z4xpLnn38B48ffcWZoGJrIddy1a8fvGxsbChljiEajyMvLgd/vB4ECStQ3Dx+uWT5n7j1JBvwLGDlyJDZv3jxWUaR/UMqRmZmJSCSKpqYgFElDIBAsnThxQq/x4+/AzBnTOz5hvv/+ewDA0KFDZldXV19mWQYYt+B0OtCtW3dIkgTO2dHios4TP/3rR1ixfFWSBf8CNm7cCABIS8u4DaAWIQR5eXmoq62HQ5dAqFCPHT/2wb5duxyPPPpYxybMww+vRN++fTFy5C2Fx4/XzIvFYgAo4rE4unTpDk3TIQRD9+7d+i99YHHDyy+/nGTAKeCe303Hhg2v7MvJyb9OCAFNU+D1eVFZcRRpqemwLDOvdPHSDQBw332nNz7TKjbMFVdc/pcjRyovY4wjEonA5/OhT9/eidIMLHjpxfWLFy68DwsXLklK/5RjWtfi3Xf/jCFDrn2FMTZSwMT+fYfQ6+we0B1uRKKReLY/61fPPPPcd6FQCG63u2NuSbfeOmr08ePHLhPCLgTjnKHX2WdBkSmEYHUjbx65HECSLD8Rmzfb8RavN3UBgLgsq8jNzcWhgz/C6XJBVVQtHI6+COC0keW0Emb+/PmYN2+eq7y8/H7TNCHLMuJxA0VFxVAVDVwAHnfKDYMvvcxIivs0bA2JMpoNG9YdcDj0VYIDLpcLnAsYRgwerxPRWKTflCmTbu2wW9KNN9502eHDB/9imjFIkoKammMYMODXcLvdIETZ9Pzzzw5Lirp1MHTY1RVCiPxAIIjGQAOuuPJyVB05hngs9kPffv3OvfTS34TPO++ijrUlBYOBh0wrDkWVEQyFkJ2dBY/HA0ookxX6RFKspx+BQAAAoCjORRLVhNfjRSwWR9WRo/B4nZAUqeuhgwd/fTrIcloJM2nSpMsaGhp7y7ICRXYgGomiS5fudr0yxMFnnn5my/r165ISPs3w+XwYMGAAcrNz/2SxWBOVBLKy/di9ew+cTiccDolYIn4fACxb9sBP/rzTlkCVmZmxLhwOFsqK/Za6riM3Nw+UStB1x+h//nPr/j/9aVNSwq2AiooK/POfX0Z79+mbJwS7UJZkNNQ3oGu3rpCojHAoWnTddcNeLy29v67dNczjjz+KW28d3SUYDPeWZRm67kAoFEZmZgZ0XQel0v4nnlj9flKsrY/rhg6bC1ComgqHrqOyvAq+VA8cuoaKivIHO8SWdPfdMxCJhH/NuelVFAWqqiEYDCE1LQUgHLJEn02KsvXxyCOPYMTIkWFVUd6CEHC7Pdi9Zye8Xh9cLicsSwy8d/68rFdffbX9CPPkk08CAOLx+B1CEKiaA8GmINxuF9xuD4RAhHHxYVKcrY+ZM2cCAGRF2UCoDJdLRygUwvFjtfB4PNA0KbUx0NhvxIgR7UeYadOm4bvvvneFw5HfqKoKh+ZAbW0dCgryQAjAGa8dNOg/diXF2Tb405/+BFmm3wGoByFIS0vFjh274HKmwOFwUYBcDQBbtmxpH8LYNswj44x4HJqmQpIpTMtCaloqZEmBJMnv3HjjdVZSlG2DYcOGYf26VyuIoD9KkgS324uqqipIsoCuO8C5uBEABg0a1H6Eqa+vG0klu+cJAeBLSYGiqOAccDqda5NibHvoTv2PBBQOhwrGOCyTwenUAWL5V616qKTdtqSVK5enhkKhElWlcDgciMUMOBwKPB4nCEFs1apV3yXF1/YoLi5+lRACRdVgWRaiMbv0WFNVlJdX3txuhNm2bVsnzoXLbsnlRiDQAK/XC84BSZK3AL+8PrYdAUuXLj0oSYjKkgRdd+BYTS1cuhMOhxumaQxvN8IYhtlJkmRdVXXouo6mpiB03QlCKKjE/w7gZ9Fq9EzCn//8BwCAJMn/4FzA6dRRUVEBh+6GrjsBsOLHH3/I3S6EIYT0oVSCw6FAUWTEojHoTicIBChRtiXF1/a49trhCcLQLwUYVFXDkSOV0BwUmqaAEEk7fLii8FQ1/08ijGma58kyhUPTEItFICDgcrnBBeKGZVQnxdd+UFVlG6UyFFVGY2MQjAkoCoWmaQ7DNPJPVfP/JMJwLnprmg5V1RCJRGzXmsqgRIo6VGdjUmztB8NglRBESFSBZVkINDRCVmSoqiZRqpxye66fRBiLxQtlBVBUGeFwFKqmgVABLnjU5XI2JcXWPkhUPwYBHieUgRCBhoY6KIoGWZYhUbQ9YdavX5fBGaDIDiiSA9FoDA7NYffIJTDcXmckKbr2wZAhQyDLUoRSGqOw+wKGQjFQIkOWJQjRDoTZu7esC+cCsiyBygKxWDTR51YAhFjnX/BvyVTMdkQ8bpmmyS0BAUmSEY2GEx3RJYCIojYnzPHjx0oIBRSFgBAKzk3IMoXggGWy2KCLByWPBNoRTrfDIoQxISxIMmCaFgAGSSKQKM1uc8IYplkoSxIIVSBRCZwn2AsLgGUmRda+SHF7GeOCcy4gOAVjFgTsqlTGWVabEyYWjfmpJEOiMjiHPTJGcAghQVGcSe3SzjAtBgjSMiQDoODMHu8DIfQ2J4yqqumUNP+5bcsIDnDBYFoxJSmy9nar4xLnjHLOIEkSKBVgLA5CKQglEEIobUoYyzJVQgB71gOHJMkQgkMIAs5E8jygncE5qGlZxDDiEMICpQpMywKEALFTuWmbEoZzLlFKIQAwZkGSJFiWBWZZYEw4hBA0Kbb2QzQWUikhiiRJEEKCQ1fAmAUu7B4969atlduYMMJhTyqj4IJBUSQIkbBluHA888xTelJs7YOvvvoKlsmdAHGYJgPnzO72ZVrgnIBAghBS22oYVVVDAAeIgGkg0eLdgmHGwWFo1UerXEnRtQ8uuOACECJSGLMcQjBIEoVEtQRZAEEsjBkzxmhrDdNkz1E0wbg9fMqyGDgT4IzrjYFGX1J07QfGWL5pGgREQNUUCBiwmAHLsiA4QAiJtylhGLNCRMjgTILgBJJEwbkdIBKcO03TSE+KrR3datM8TwgBZgEeVwpMQ4BZPDHgSzrlrLZTJozb7TrKhQnGTXBuQQhAkgi4MGBZpkwJSpJia3u8/fYfE4RhA0zTAoiAy+O05SQYGLNAJBEATi0b8pQJo6jKYS4AJMbxCiGgKDKYJWAxgZhhnZcUX9tjyJDrAADxeLQ/pYBpxqHriRFCwi5jFoxXAaeWDXnKhMnLyzvAOANjPOEdESiKBtMywZgBy7T+HQBeeOGFpBTbGPPmze0TjcZlRVFhGhYUWUkcDxi2hiGoOtX3lk/1D3v17Hn466++ghACpmUCYKCUIhKJwONxIRoP9xFCyISQ5DFBG2PPnt03M2ZCUXRwzqGoKriIgQsJnFOAkIo2t2GGD7+hXpJkYU91tc8oJInAMCxQKIjH4pgxfcZVSfG1PYKhpmsIoTAME4qigRIZQkgtI5CF4IfblDBHjx61/5hKhznnEBwtw8UNIwaTxQBB0RCoGZMUX9ti9OiRxUbczAOxZ3Hrug4BkQioApbFQQg51KaEyc620ykIRRnjDIzbZ0iESOBcIBqJgxAgFIr8+snVD7uTYmw7NDU19WaM+XSHjng8DpfbCaA5BE/BObM4Z1UfbfnPtt2SAEBVtB2MMXDGAQgQCCiqjFAomDhbEinffrOzd1KMbRl/MW40DIO43R5QKiWS8gkYtxKZBPG415tSPXjQpW1PGMbYDiE4BBKEoRQylREKR+D2uGCapmZZ5n8kxdg2EEJIwWBohKY5YDETsiJBkggEOAgoLGZAcMS7de1V2eZGLwAI8B85F6bgAgIcdv4oBYSAYZhQVQ3xePx2AFiwYEFSoq2M4cOvmx6JRKnfn4lwOAgpkftCCYWABcsyIctyzejRo4PtQpiM9Iwqy7CiggOCU1BCAUJACMGxmmPIzc1FUzBUNPOeKZcsWrQoKdFWQm1tLaqrj8r19bXTVU2GJCkIh+zBqxJVQIgMwRVwRuFwOP/2Uz7rJxHmjjvGVxJKo7bRK0CIgEQlEEJQV9cAQEDTVFRWVCUnULQiMjIyMHHinb+JxeN+TdUQDodACIEk2bIQQkAIDs450tLS3m43wpx77rkxXdd3WZYdmyNEAoiAJFNYzMKxY9Vwu3SEQrGzJ02a2HPAr36TlO5pxuzZswEAsVjsNtNgit+fg/r6RqiqBkppIvxPwDmHJEm49957P2o3wgBASkrKZsuKgws7K50QCoBAliRUVlYhy+9HPBbTGurrb/r8H39LSvg0Y+XKlXj55ZfTg8HgbW6PC4CA4CYkGSCU2ym0xALjJhSVfksIMdqVMJdccvFGSpVE/ZqARGXIkgJKCMKRMAwjhrR0HyLR8JRk2mbr4M0333zOMGIoKspDbV0NCKWgoJCobItYUAhO4HC41v/Uz/rJAhw9+rZjbrdzG+ccAEmMuCEg1D4ZLSs7gN5nn4NIJJ4+duzYe5PiPX2Yf+88jBo1uncgELjK4/GBMYH6ugbIsgIq2WQhRIALDofuMLJzUre2O2FsoyvtTdu4AkAEqGQXTFFCUV1VhUCgDpmZaTh2rHr+ipUrfXPnzk1K+ydiypQpeODBZaitrZlgGjHNn52GiopyyLLSYvBKkn3TUkrRqbgg4HZ693UIwqiq9tecnByLWRYIJBCi2F2oqARJovhu2zYUFxchGo05vv3m6wnLly9PtjL7Cfj+++/x1FNPYfHiJTnBYGiq2+ODpuoIBSO2dqEUmmZ3agCA3JxcgNAdEydOq+0QhEnxpe5XNa02PT3dJoIQoNQ2gAmRUV/XCCEkZGRkIhQKzX788ccdhBD84Q9vJKV/Cujbty8A4PPPP9tkmgZ69uyB8vJyEAmg1C5Z1jQNqqpCVlToThWKSk/LnOfTQphFCxcf58zclp6eBru4zX5elgkoFQAsbNv2DS7sfz5M00z/8ssvngOA4TfclJT+KWLI0GuGNwUbL/T7/QgEGtDQ0ABZkkEpRUqKJ3HDCkiUQlMdbOb0OW92GMIAQHp6zlOWZdn1SRCgdjkm7BleFOUVlThSWYWSkhLU1taNvnPiHf3Bk4L/V7B9+3YAwIoVy+VQMLTINBny8wtQVrYXsmwfMjbbLYwxRKIh+LMzoSjyywCwc+fOjkOYpUsXb5ZlOeBL9SUGnUvQNB2KooJSCaqi4YsvvkRBQSEYE6g5WrMUAGbNujvJhP8lJk2aBADYuvWrxY2NwV49evRCbW0t7PmaFIRK0BxqS6BOVR1IT0/nAFkHAGeffXbHIEyzAauq2hPZ/kwQIqAoCtxuDzweT0uI2jAMlJXtxoAB/RGOhAZPmXLnVQ8//HiSCf/L7/jzzz/HhAkT+lVXV89LS0uDLyUFBw4cBCEUkkxBKYEiK4kbVkFBfiGYxY94PO5dp8vJOC2Eac4+p5J4yzSteGFhIRizYFmGfXp90ut27doNSabwZ2Vj794f3hw69Nq+STr8/3HttXa26+HDhx42TQPFxYX4/vvvwbkJQgQgAFW1qwMMMwZCBNweHbIsfTRhwuT609Uv+bRGXs8759f7YjFrX3paOgiREYvF0BRshCyTFlJZloUtn3yKs3p0Q/XRamfN0ZrnJky4Q3E41CQr/h945533cOuto24OBht/W1CQh3A4gqamJlAqJ7YjAlWTYZomIChcbh2SRFFQkLf0dK7jtBLmlhE3xrxe70bTjCPF64YQgEPVIQRFoqoXlEpobArix8PluPTSwYhEIxcCom8sZuCBBx5IMuN/wF133dWlvLxyo8PhQlFRCfbt2w/Q5rM7QNNUO+9F2JkDRUUlUFXnX0eMGHPw+uv/vWMSBgBWrXpkBWMS8vILwbkA4/YkDU1X7WYPwk7l/P77HcjyZ6BHz56or2/8CLBnXyfxf2PBggVyWVnZE7FYjHbq1Am7du1ALBYFBUm4zwS6wwXLNEGohJycHKiqDIdDXQQAb731ccckzPPPPw9CiPD5fI8qioT09DSYpgnO7bxfAoBQCiEI4oaBz7Z8hh7duyIYbEy59bYRTwkh8NxzyYl/zbj77mkAgIMH990cDAWvyMrKhGHGcPRodaKrFAGlMjRNB0DAmF25kZ+fC8syDjl07dtEz97ThlbpFPW7383sHGwK7pQU4vju2x1gjNmlmon4QLPalCQJ/fr1g8vtxt49e3D++Rf0ffDBZdvtZKxkEysAeOihlUXvvvfOYUoJevbogW++2Y54PJ44L7I9I5/PB9OymzFkpGei+1nd4NS9j82dO3fG6V7Pad+S9uzZg4GDfvujAP8Swp6rTAhNuN4nXDtKKTjn2L17N1J9KUhNTcWevbvfSVRL/uKJMnXqVNx33730k08+fsmImyguKsb+A4cQiYSBxFZk2y72EUBzfVhRcSEoldC//4WtkhN72gnTo0cPXH3l1Zbfn7sqGjWRl5sDLizQxBUSAlAqJY4QCOLxOD777O/o0aMXopFo4c0337Dm5NjOLxGPPfYYVq9ejcrK6luagsFB/qxMRCIRHK2uSXhFdgSdSoDu0BAMhiEEkOX3w+nU4Xa5Hx406LeBM4IwzVi8eMm7TqerTHc6kZmZYZc6ENKSkXfyRzc1NeHgof3o2q0EgUDj6PHjx51LCMGSJUt+kYSZPn06Zs2a1bW8vPwVTZORk+fH4UPliRtOAKAgCQ8pFI6BcwZFUdGpUxE45xFNUx9rrbW1CmFeeeUVAIDH6xwbj8dQWFgIWbLbyv+X7SmhZQgBfij7AW5XCrKz89Ta2roPAOC+++77xZFlydIFWLDgfm3nzp0bYrEYSjp1xe7dZYgbpm3kSgClApQQ+0FtOyYjIw2EUMiy9NepU6cfef/9d84cwowaNQrPrHkSkiRt45zvpFRBZmYWAAlCsMT21BybsROvGGP48ssvkZeXA9M0M26++ab1vzTSXHzxQNxXughlZXsmRCKh/n5/FgKN9WioD9hbOLU1MyEyKJVBiAwkNHdBfjEgBHJyshcTQsQVV1zTKmtsdety5oy77w40Nj6mOXR88/VXiZIH2z6xU2fsk+3m9M6ioiIUFxfg++3beUlJl4ufXfPc56+88gpGjRr1iyDNrFmzzv3mm6++cblcyMnJwfbtO2BXZYhEFYAMSglkmSZOpgW6dOkKf3YWPG73X+699/4rWnN9rZ6U/cijjz8uy1KQgKO4uBgCwi5HAQBib002f+xIcOWRSnBOUFTYidYer9382msb3b8EsvTu3ROlpXNcu3fvfF0IIDs7B/v3H4BhGCDUPv23Dd4TwToAcLnd8PtzQInEsrPzprb2OluVMI899ggAICsre0I8biE9Ix0et+eEchPNFy4gBLO1Dge2bv0nMjJTYRhx36ZN72wSQpAXXlrzsyXLzJn3YMeO3ThwoLy0qampa3aOHzU1NQgGQ/ZJP6QTB7yUJrYj+6bLzcmDEAxra1UjAAAQCElEQVSyQt/PzMw49Ic/vNWqa231Lenhhx9GZWWlGg6HtgO8e1MwhP37TuQin3CfSYvrLUkUWVlZ6Na9C3bt2IucfP+NL76w7vczZt6FRx954mdJmsmTpw4sK9v1V01TkeXPxq6dO1u27xMhCZoI1lFQqsDt1tGvXz9wzlHSpeSSO8dP+rS119lmEbJ77pk5rbau5gldd2H3rj2IRCItX0hzdV5znAagkCSCvn37gBAJR49WmZf8dlDB9Ltm1vzciDJt2lRwzjIOHjz4XTgczu/WrZvtFcUjLW40oXbvHUqayWLbL3379oamaUhPz8DcufPbRJZtVliWl1f4umVKMA2B7t3Pwsk1TCeWQRIE4uAc2LZtBzweN6gklK3//Md/fv3tNnn06JE/K8I8+eRqHDt+fGE4HMrPzslGRWUFDDOa8IZIIpGeJoKdUsKWkZCVlQ1Nc8E0BXy+tE1ttd42I8yMGdOPu93O2lgsCkIocnJyT9IsiQ5JCXDerIIJtm/fgeLiYtTV1vVZ88zjEzds2Ijly5f9bAhzxx23j66vq5vi9fqgyArq6wIQvJkoJKFxT7b37Edubi4sy4IkScHa2roJAPDDDz/8PAjz2Wef2QZabu7I5lTNLH8mqHSiWByEQMBCc7WeEAKcczQ2NqG+rgFdu3ZDXW3Dk8uWPZg7d+68M5oke/fuTRi70/OPHKl6SgDIyEzD/v0HT4pT2eF/Qu2tqNnoFUKgpKSkJdmbEPLyDTfcUAsA3bp1+3kQ5uKLL8add96JYdcN+VBzaJ9Yln3a2rlz15ZTbIAkAnmAEBwAAxf2LKa9ZfvAhAlZIdixY9eHLzy/xrFw0Zkb0JsxYzoAoLKy6olQKOzJyvSjovwIGLe7YAiwxEDPhIY5KSKemupDaloKBDgYt2L9+p6zoHv37m128NZmW9Kzzz6L3mf3FZkZmQ9wLmJG3ITucCAjI+O/pTKIhDEMENhaRgiOst37kZdbhIaG4z2/+PKfkxcuWILzzjvzmo2/9957eP/9v+DOO8ePra+vG5aamgrGLASDwZYbxtYoooUkEqWJQ1t7K2KWgFN3ff34Y0+4Ro0e2fDii2vbbP1SW35ZZ53VFZs2vX3okksG/plz8wbGLafL7URtbS1OpD6QFk9JNO/bVIBxDkqA/Pwi1NfVXTps2HV/euONN844r6m+PoDLLr+kS2Vl5WbLMpX09HQcPnwInNshfgHbI7If9g1EiQQhBPLy8pCWlg5Kgcws/4QBAwb88Mc/voURI9ousNmm7Tf27rXjL4MHX7bD5fKuYoxBUWTk5uaAMYbmcyWbLKxF8xBhD/IqLy+HacYhywo5fPjwJ6+//qrzTCPM+++/i+PHGh4OBsN6Wno6yit+tEfSJGw2W8tYLRqFEgkAgcvtgt+fDcY4fL70T353z+/eBYDrrru+TdffLv1ahgy5FrfeNulxTdOqjLiBjMwMeFNSAPBEYpDd9fFEcM9uG0qIhB9+2I+MjAwEg8H0jz/5aAkAlJaeOV1Ebr/99rsDjcFrPV434rEoYtF4S3jBslji3EhKbM0k0TOQIy83D0IATqezoX///kMB4O9//7jN198uhPnoo7/ivHN7xHqe1fsKQikY48jNyYYkqYmRxiRxMita+rMh8dM0TVRXV6OwsBB1tfUz77+/tM/SpQ92aJK89tpriSDdXb2PHTv6kBAGvF43qqqqE3En+/ReUVQoitKyFdn1RgK+1FS43E5QSoXH41l0+eWXBwHgoov+/ZdBmMGDL8HKlSswY+bM7S6X+xnLNOFw6MjISAcXLOFW85babNGiaQDOOaqqqhAMNsHh0HHw4MGPH330iQ49/e3JJ58EABw9WrUqHAkrvpRU/PhjZUuJSHO02zZ0RYvBKwSBrjtRWFAEAPB4PPvnz5//9KZNm9rtWtqthdjs2XMAAGf36r2QUiViGCay/BnwetwgVCRa0SeSrQRaCCRgAuA4fPgwPF4XGpsCGbt3bV86bNh1LYlbHQnzS+fhiy++wIQJE6YEAo2XpnhTEY8biMejAHhLIE6A21l0FBDCrqyglCI3LxsQDLrDgT59ev+WEGIOHTr0l0eYZkyePPVYYWHhOEIkQEjIyysCBMWJYwJykgclwJmAAGBZBqqrjqIgvwiBxsCUbt26XTRq1Cjcv6Bj2TMPLF2GaXdN7VddXbWaUgJFVVBTcyzx1ZMWLUNgXz8EbbFpUlNT4XI5QSWKFK9n8U033Vy5YcO6dr0eqSN8qZ999tnOiy4a0DkaifRVVDuVMxQKtajpRESz5Qtu/ncsFoHL5QQIEI4Eb547d9Yzd02bFesoZJk7bzbqjsbg9KhvBAL1Rb5UH6qrjsBiVss90JwMj5acZ5s+uu5AcXERQAS8Hl/N8OFDb/j2u63W6tXtW7fVIbpazpgxHbk5maVUJk2WFYc/2w+329lyvGSPb+EtRjDnomUK3I8/lsPtcqGpKeTc8snfHgWAhQtL2/2acot1LF+2Er8eeM6MYDBwscvlRiQcscfP2LGCluuxDVzS8lOSCPLzc0Ephe50oFv34iv7ndM/unXr9na/rg5BmEWLHkHpfYvKSzp1nghIsEyO/PxCyLKS2JbQskWdODYwIQSDZTFUVdXA789BfcPx2xYuKh2wcOFSPNvOFZRVh6O4e/rEC4/WVDzMmYDD4UR9fcOJFFVBWzINT1RS2IZueno6XC4vqCTBl5I6f9ztU74dNfL6DqE1OwRhvF6K0aNHYeHCRa+lpqb+nnMORZGRmZma+HJPPjpIbE3CHnvMOUdDQx3CoSbouguHDh7+8OmnHku9c8Kd7XY9+fn5eGXDRunIkeOP6Q4nyS8oQHV1ZUvV5wmPiLTkMzcTx+FwIDc3HwIWXE7n/vMv6PPEiy+9gFc2vpUkzMlYs8bWCMXFxdMVRQ6YpoWMjHSkpPjAuUgcUtrL5VyAJ1S5AAeIQGVlJTIzM5CZmaZ//fXXTz3//Gr63HPPtfl1zJs3D5WVlfj753+bEY/Ff9W7T1+kp/lgGAZA+EkpqUBzq9rmbUmSgKKiIjBmwqnr6NWr1+VXX3lj6Paxd3QYI77DEMblcgEAZs2aVVVQkDeZUgLDNJGdkw1ZaR6ycMKOIYSA88SUMUbton/G0atnL8iqektZ2aELJ0yY0BIDaSssW7YM8+fPL6murnooPz8XbpcTwWAEWf6cxDaUCBnQ5tJhO+4iwOFLTYeqSVBUCZmZ2feNGTP2wLqXX+xQXl+HbOW+ZMmDr2VlZf0FApCojGx/HjhP9EIhAoQCzZ3HBQRMM478/HwQAtTW1aNbt+4IBALv2NHVaW2+/srKinsJJehU0gmHD/8IzjlysnPg8/lOeHyCJpxUO+bicnqQm5OT8JCcTS63tgEAbhtze5Iw/xuoGlkiKxJjzITP50Zaeqo9EZUTCJ7wnQSDEAw+nw8ZGRlgnKKi8hBcLie8Xk/GAw88eEVbr3v16tUaCHqd3asnGgONMAyzZdvJL8iFJEuJ7UiAUJ7YiiiKi4rAuYDD4YLL6Vl+9133/NgR5dIhCfPSS2uxfNkjX6R409bbvWTi8PszoGlqSwDvZBQX282LBDcgOHDkyBF06tQZAqxPW6/dEo00NdWt67oHgcZAwpszQSULkiTjrLN6glI7JABBAQH4/VmQZHsrcrkcLy1evKTD5qB2SMKMHTuu+W69PSUlZTuBBME5cnIygZOPDCDQ6+yekCTb/bYsEwIETU0BxIwQGDO7tfXamxqj3DRZuL6uHpbFbG1CqZ2nLACJKijqVAhC7G3V5dGR5c8ApUBqatrHyx5cMW7RooVIEuZf9prswrXf/nbwr1xu/SuLMTgcbvizM2CaBjhnKC4uASUUjJtg3AQXJNG8CKg7XofGQGPm7j2727TZjNuVxpiFqGGGW7whO9yPhIHL4fV40amkCAWFuSguLgKzOHy+tLrLL7tqKCFELFiQJMy/jIkTJwIAbrrphsi11141RNNUWMxEii8F3bp1R8+efeDxpIAxAsEFBOfgzPaYmMVhGIBhGKzHWT3aLN+1oaEBM6bPsAgVxyyLA4JAogoAAkoUe3QRLAguw6V74fOlg0CBrju435952cCBvwk1J8wnCXOqburyxRhy7Q3VuTl5QyghsEwLiipDkgg4NwDBwAWDAIUQJjhMcFgwrTgoUb5qy25WF1/8GwKAxKKxYosZCReaQSDx4AwEMkAsgHJwbjdayszMeW7WrNnfrF+/DhdffHGHlscZ0Rvs7c2bcO1VQ8j48be/GQgErydUQFHkE/OAiAIpUbIiSTIoBUwrDlXRNrmcKTeuevghs63WevXVVz7tcrkm6boLqiYDgttBRsEhINtVWEKAMTv+4vdn/7h8+fJinCE4I0bqDbl6KAghYvz4abd5PK5Ky7RgmhaYZR8bcMHAmJWY/m4gbkTg9/tx/Hjd0MamwD0AsGLFylZf59TJk0c1NjVNisVi+PWA/ojHYonqIprwijgYM8GYBS7icLm1YH6+fzAAtGdS1M+OMABw8OBB9O9/bqSoOP8STVMtZnFwZsJipp2+2ZIHbHfnLCgowv79+xEOhx58//3/TJ0zZ3arrW3r1q146OEVesWRH2c6HAp279mD7779FpRKMGIWeKIzhX3KLsA5gyzLyM7OXjF16oz9ANCeSVE/S8KUlJTgxZeew8IFDxxITU1fwTmDYVngjIMLbntHwkQoFMPx4/V4+qln0LVrN8TjMbz77qYZrbm2Cy+8EAf278syLbMnpRRdOpfgL3/5ENu370SgMQDLssAYBxe2FgQRyMrK/LB0/qIzrvX5GTXl9faxEwAAzzyzpjQtLW23ZVl2pr3JACEhEGjCtu++xY7tO5CV5Uc8HgfnQCQSO7e116Y7nB7BhcY5RyQaRVZWJqLRMD797FPs3bMXXJiJllsEbrenJjMj6wYAWLv2hSRhWhNvvfV7AMDZvXsO0lStnjG7P15TUxPK9u4D5wJpaWmIx6OIx2MwTQOEiEBrr6uxKVAvgHA8biIeM2CaFiRZQUF+AaLROIw4tjOLQFFUZGdnz541a05jRUUFxo27I0mY1sT119+AFSsewMwZs48VFhYtJ5RDlqVqj8dToygyNE2DZVkwDRPxuJ2tmZdX8ExrrkkIgSeeeLBalumHRjwGwzTs4jTOIcsyios7fZiZmXF+dk7O8IKCohH337doPQAUFBQgiTbGlo8/05v/feml/7H+3PPOEX379hHnnXeuuOSSgebt48bMB4Dhw4e3+lqEENLAgRe92rdf30jPnj3Fueee03TppYPXv735ef3k153J/YfP2En17777LgBg0L9fHG1+LjM9b0z37l3PzsjMWJmdnbPkrLN6dLrqsuEPAMCECRNadT0T7rwDhBA2YMCAUbk5Ofk9e/bsm5OTW3T99dePGXL1+OidE8e0vPaX2H+4Q2LaXZP+r+fmzWvbXjJLly5NCiKJJJJIIokkkkiig+H/ABIDiXN1ApuQAAAAAElFTkSuQmCC", - "strings": { - "initialNotificationDescription": "Tap to pair with this device", - "openCompanionAppDescription": "Tap to finish setup", - "updateCompanionAppDescription": "Tap to update device settings and finish setup", - "downloadCompanionAppDescription": "Tap to download device app on Google Play and see all features", - "unableToConnectTitle": "Unable to connect", - "unableToConnectDescription": "Try manually pairing to the device", - "initialPairingDescription": "%s will appear on devices linked with %s", - "connectSuccessCompanionAppInstalled": "Your device is ready to be set up", - "connectSuccessCompanionAppNotInstalled": "Download the device app on Google Play to see all available features", - "subsequentPairingDescription": "Connect %s to this phone", - "retroactivePairingDescription": "Save device to %s to connect more quickly to your other devices", - "waitLaunchCompanionAppDescription": "This will take a few moments", - "failConnectGoToSettingsDescription": "Try manually pairing to the device by going to Settings", - "assistantSetupHalfSheet": "Get hands-free help on the go from Google Assistant", - "assistantSetupNotification": "Tap to set up your Google Assistant", - "fastPairTvConnectDeviceNoAccountDescription": "Connect your %s with this device", - "subsequentPairingDescriptionOnTv": "Connect %s to TV" - } -} diff --git a/fastpair/rust/demo/local/706908.json b/fastpair/rust/demo/local/706908.json deleted file mode 100644 index 3a77259ceb..0000000000 --- a/fastpair/rust/demo/local/706908.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "device": { - "id": "706908", - "notificationType": "FAST_PAIR_ONE", - "imageUrl": "https://lh3.googleusercontent.com/9lYIq9GW5_tZ1WaTYsrU7NMc5MP8AgOcsHB5K75MlfeqhwIgm4jL_ilMtP9aLYEZR_6jx4rLI2-2-uYDjg", - "name": "Sony WH-1000XM3", - "intentUri": "intent:#Intent;action=com.google.android.gms.nearby.discovery%3AACTION_MAGIC_PAIR;package=com.google.android.gms;component=com.google.android.gms/.nearby.discovery.service.DiscoveryService;end", - "triggerDistance": 0.6, - "antiSpoofingKeyPair": {}, - "status": { - "statusType": "PUBLISHED" - }, - "lastUpdateTimestamp": "2020-05-19T17:58:19.881Z", - "deviceType": "HEADPHONES", - "trueWirelessImages": {}, - "companyName": "Sony", - "interactionType": "NOTIFICATION", - "companionDetail": {} - }, - "image": "iVBORw0KGgoAAAANSUhEUgAAAKAAAACgCAYAAACLz2ctAAAABGdBTUEAALGPC/xhBQAAM1xJREFUeAHtnQmQbVd1nvft27fn8U39RumNPEkPDQ4gxBBsSgzGxhRIFqkQpZxEGFJFnAomGMrBFckVQJghYEDBJgQsT2WJqRDEDjbWYM1CehoAlSae0Jvnnrtvd9/u/N9ae597+r5ux1U4Cbf77O5z9rT2Pufs9d+11h7OPiEUrmiBogWKFihaoGiBogWKFihaoGiBogWKFihaoGiB1dICpdXyoP8Yz3nNNdeUfzw93d47Ntam+lqnpqbK1NvZ2VmTNzfW2zuzs6OjeuuttxIv3D+gBQoALtNIl19++Y6FUuubagu17WF+fltYKA3Nh/nBsBB6wsJC50IIFRVticXn5c+WSmEqlErjCp8tlUrHS6F0sFwuPV9aWPjLBx988ECkLbxcC7TmwkUw1wJT1dl3t5YXPlCbrwlvC3YIfOYUy1HWg/5r1pl/oZFjfr4lzNZqHxPVB+uURSi1QAHA1BIN/uzMTM9867wDL+bV1UUKJSCWBMkUDovKtAiEtbm5nobqi2hsgQKAy0BB6ratUmoJ8p0CfLlw8wCpAhfS0YILCZRGZmmWgxRUXZZQnM5pgQKA5zRJTFgoVVChLZh5AE9hOyzbwZakHhhsaXEw5tU1+ZSR/Yi9WLglWqAA4BKNQlJHe3u5vbNd2HPgtbS0OJiUlw8DzqR95+ddZQPCfFhALNqZRl3CFQ2zRKOQ1NPTUyq3tpqK7enpNr8mgM3NzhoQW5W3yEnSzVRnQltbxQCK+p2emrZyrZVWG65ZRF9ErAUaWrFolXoLlCrlsuNmbm5OoEMZt4T29g4jMdWaiIU21G1HR4cBbn5eMUlByuPPzdWKdk5t1eAXDdPQICna0dFe7uzsCrNzs6ZO52u1MC8w5W28RGt+zk6k51uSyq5UKgFJqVghARc1Vj1SALDeFotCwyMjrdWZmbAgtSvxZ2rXuh50KuTyYWxAJCAOgKY44RZJzqnp6aKdrXXOPRUNc26bWEq5tSwTUDag1Cloy3rAEYBLFkNCkmEY5KResCRhy2xLIQGXbDDNZy6TvuqT1dMVBlvDfMt8HXwoUxd9S7RPHXwg0FS1qFDHZbrNhVuyBQoALtks+mWWW1uQgPMLAqCJQARhVL+LQGgyzyUfdWXSDwEoFazxQaTpMpdZ9ckFAJeBQLmlJB1cDqV5YIcOjgD0IDp5cckEPKVmdqAB0HrPhQRc3FpZrABg1hQNAalNBNe8OhFm/xneHH1pCCZB0GRgPOGZ+hX4kIYll4AFABuaN0ULAKaWaPArrZVyq4ZRluoFJwBmRXLgE/pMHScQYv6Vy0UnJGurhkABwIYGSVEBp6WCDahhGJeASD9Xx43aN5Ux0CniKtg7IvSCpcuTsEykhR9boADgMlDQ7FkpSUCTeIDPAKgCybeyYKveA3YQxl4wNqBo1ZkpVPAy7VwAcJmGURe4zExGJgFTR0SAwjWKNNfCdkYLRztwXr3gsoZhil7wMs1cjAMu2zBSm3kVDORcEp4LvlQHwEvSMG8DMpxTuKVboGiZpduFsTtbDVOqYQOide0UJR9gPLdgAh05KYzwU12FCj63uSylAOAyDaOVLBqGUSekVMvAhz1n8g8sZuUI5WxAwvSE40EHmLq8oHWQs5JFoJiKWw4DGoUWACsCYC2NAyap5+hzACYYJgDm/AhAtwE1mFi4JVugkIBLNot+mS3qBTMMU/JhGESeqWHRG+wadbAbgJJ8Lg/zElAdmmWuUiQXLbM0BkrSv7agFLAtsv9ywMuAiLRL9Zjkq4MQFawZFatGJBlZIl/tfgHAZRAg4Kj/4GsIAGAGNtHnw1nxHAiRfohCfMw/VZRswIy8CHgLFABcGglaga85DM1iACIDYJR8i9SwyiLSAKSJNkBHfdF3AJZ5R8QwS1bhFrdAAcDF7ZFigpuWw+QBSE5OEiZEGeDIIj8HPAMl4FUdpQVDbyoCZeFiCxQAXAYK6oP4auY4F2zgSwBMZfJxwEc8+gmM9n6ImYCpUOHnW6AAYL41cmF0sKleJFgCWs7PkWYq2KSeaAAfjjNlZQUW0s9a5NxTAcBz24QUaU6DoEm1c1QvIGtwKQUf4HFYzwMAZyPYDYWKaDEXvBwGSjLfAJ6BT34GsCXAZ3Uo3eSeTnkSyuWKL3e5VZtejNAvzXrUr+HIgBdVKikGsqXLuNgTRUYTkUg/WkUShpcrvSrTCwAuw3ZhTkJQmIrgg8zCufi5RevDMJYnWupQx6QA37mNZSkFAJduGADDIKA8l3qNQHRweuFGoJJqaVaak80FFyCkYRpc0QlpaJAYtVfZHEQuCm0oD0CiTfFj2F9cj2mxsJWLNIQjAIsfe2yfvFcAMN8a9XCL9G8rLyTZIdDlx/cyUQbIcPJjqB6PaSXGERdse7YCgN46i84FABc1R4ysWaNJ4FIrajepXgAGCJGACWwAMYWtJPkpLQKQJf1ytHPxcjot0eAKADY0CNGtXV2t2mKywn6ABiDrxDqh941joQg4U8skRdBZbi4sEFf6tm5tHT10KBYsvNQCBQBTS+R8vYxUATTaXNy2ZCMrU7sRjOdIv1z5TGoCQgPiQmWt6hzN0RRBb4ECgEsgobu7u02bTFbmtCdgtjsWdDlJuEQxS0rgQzcTZnMj6mpRncuVWc3pBQCX4H5bW2+7VG9lVtvxolYBns2FRDGYSUOTi3Ur0EIAz9Fn9mGpxrdC5isdbW3tS1xq1ScVAFwCAu3toVM7olbYDxpQAbjcvIgJQk93RWzAox7AKuqodmM8hJrq0qbnnZAUbnELFABc3B4W0wLS7tm5udYZ7ZCKA3wGwJz9Zxm5k4HQAAjufFjG1LEyZEtqb4SW7hx5EYwtUABwCSgslMt99H5n2BFf+Ql8WTiVAZAu9Ax0lpwDnwFRcUlAsnpTscKvt0ABwHpbZKGW+VI/9h8gBHzs8wzW8kC0hFRCIHSZF6UfIOSwYRwAOMcuqf2JvPDrLVAAsN4WWUhDx4MAkM8z8F6IrWoWAm15vWQiYMTWM/EooOE4u8pVzzeBTz4gti3eagtrjLA4LWqBAoCLmsMjCwvza5P9x3shAC8DoYtCw14qahCMUtAlnwOP7X0BIOisLSysTfSFX2+BAoD1tshCAtE6H4IRcHxFs6thraxHDbsAtLOXQeIpZOAz6YcUdMnHbApOduA6CxSnRS1QAHBRc3hEUmsI9YtrWZD00zd/GVCWbYghKABG9evkJuEMgkhBABglH19M4nvDEZ0bEnnh11ugAGC9LbKQZkA6pqenLM7eLmYHIv0y4CH9kHkJcPg245GBr6ZdteYFPrMBBcrqTLUYB7QWW3wqALi4PcK+ffva2tsqu1hDaj1g7D/UMJLPBJ9LwXwxl3raircFOYj9p7VcZQFQwEsAlCG5O+wO7eHZUM2XXe3hYo1aAwLWr1/fJz27eV4SjHlgDgNRCpuNp7zoe57HDXAm+bzzYd+X0xgg44Cq77ztc9sHGy636qMFABsgIElHb7UfSYaadR8iV7lZSAA0J89CnCwN9YzDT4cWA7aU+lo7OzdbVnHKWqAAYNYUHpiem9uqcbt2V6sNmTGaIGbAU8TihjWPZLaiZaiQgKmhnHJ7pbJ36RpXb2oBwAbeC3x7DFKGriA7TqtZFK7Zi22shlbcDpqOPNLy4VLQnqomDL2MS0gfvml5ecPlVn206IQ0QEC22qVspmEdDr0Ysq13imk02yHh1HRn6GufCb0VTdNpeOb4VEdY114Nk3PlMKOdVHsrMwbUttJsODHZGtZ1VMPzwxUNxSAE+W5cy5V0cn74wx/6KoeGa6/GaCEBc1y/5ppryhpNeYkNIiudXf129U+Foa5qGOqshjUdM2Fv/3g4PNETKsrbo3Bf21z4uXXDYXvfhMBZC6OzlXBeXzVctHYyVPWh9Hm9CsJcMk77DV40Xyr9vEWKk7VAAcAcEI4fP75T43n7kFZx1C+cqVbs6KnUQhvDLFLHXa210F6uhdn5sqnkHw0PhvUds6FSXgjjtfZwZKIrdFcWwolqd+BTD3z0ECnKB2u0LvV9umSyDnNXX53B4k2tHN83bdl2rYZS3gI62B2VTywIdlK/reFktSucmukOY3MdYW3nXJiabw9Hp3vUuSgr3BYOTfWFyRq0gLIlDM+0q6wsHBs/ZAxRtQq82nd117bt5z176ODBJ3KXXrXB4pcYWf+ud72rsv/RJ+7RuN7L2FGXz3TxpaRymcNnQ+xzH5JkbJoAntj2jw4J3ZC6YwxQ6fRclMs4IeOAdmh6j/dMBMaTF+3b99svueySb7773e8+VS+7+kIFACPPX/0LV755amL8W4rqC0kCX5sD0FWo1KhA2LgyxqQb5ZFysR5UtI0dKoAqZzHCIgDO1WyZ18DgQNi790UvDAz039zf2/uH73nPew7GKlaVl9ptVT1048P+xm/8RvuDDz9yx+zM7BV8I7hSaQttbW0mAQEin2sg3eaF2XQ8p1ZNtRoA1ZS51gR8GIz2brG6wSxK1TJ/Ax8LHXjfpL1D6nzN2rBu3dpjG4aGfn/DujWfu+6668Ya728lxwsbUNzt6u3/d9Wp6XeiVlG9bQKdHw7ENtQxgMykokCptHSgqpGUrZKcfNwGwHrcgWudECSoSVHvFTO/XJM0HBsbC4ePHOmZGJ+4UpD9xbf96tXPfvev/urASgZd/tlyv9l88uoJv+Utb7nk2PHTd87VZgfakHztbaFdYGtv75CEag+kJVChgpGCSD02vsf3wxcrmARE8mEVsjpG4XNsQEk/FrvOziINZ009QzcxMWEA3b1798z27ds/+qY3vv7DL33pS/Ve6Mp2qxqAH/jABy6+7/6H/nR8fPxipFS73sfk6BD4Ojp1KGySz4ZSZAcKfHRQbIW0wFgHoDcjZ+CH+uVgQUOy/+akgk31CoAsdp0FhFElQwNQASZA3LZtW7jggr1ff+k/+bl3XXXVVadXMgRX7UzIJz/5ybfc/8BDfygVOKRv0pjKtM4HKjhKQcBn6hd1G0HoawMj+EAGUjAiJA8+3gOxnJhJx8RAqXSAXMOmVJj6oGXdNHZmV1dXeOGFF1DNV01NTW36k6997e3XXn31oXiJFeetyoHoj9x447sfffwHtzz77HNDcBTGl82Gk+2GPQfgIugS8Mr6cuZi8AleqGQAiDQknDuQjiAT/BFMHRenR4XX6U2SOqWdkcKnT58ODz/8yCseuPPub952221bVhzy4gOtOgn44Y9+7H2PPfb47z35oyfBgqlYwOVA47tu3nEAIA4iIASI6qBBkrHUvjYb1/pJgpGGxMM2tG8Eo6512DScyjIuaDUpbHXFBa+xcvPyYe5jZGQkPLL/kZco/ZbHH3/8zZdccsnZOuHKCK0qAN748Y//5oMPPPSJp556yiRSWb1WgJbG+AwwUseILAOUfIAJGGbVYRgeGTZQjAyfDSOjo2FS9tr09LTZdthwAAt6JFhXd3fo6+0LAwMDob+/31QrQzvUzUJV0Ag9h7noEXagIjU1ozI8HPY/uv+VX/5K+Yu6p3eIfkUtZFg1APyvn/nMO++95/6PP/nkk8bvVvVuDXxIKcb2kHiSXkKeSa6uzk5LO3PmTDh65Eg4cuRwOHXqZFCHxQBHJQm8lOMvvYzkHQ+sugXZlpXQ09Mb1m3YELZs2RI2bdxk4LRpPnVCALo5eclOTEkGUp1OnjwpED569W9/6EMfFO3veoGVcc797lbGAy31FF/84pd/6fY7b//a/v37OwCHDTLHMTvCHEiu7q7uMLhm0MInjh8Pzz33bDh06KB6puOSksqXVOvp7ZXfEzo7Oq2zQjl7f0QXliJmHxjr5U5Xp8PU5KT1asfHxyzM8v5+ScTzz98RduzcGfr7+sKUJOiopCk9Y+5tTsMzSNvUYyY+MzujIZ1a2LVzd/XK1/78L77//e+/Y6nnbMa0FQ/Ab37zmxfd9u3/+bf3P/jAUFXMZpbDOhkCjvd65QuA69auDX19/eHEyRPhyR/9QMA7ZBKtv38gDCpvoH8w9AiAgJUOC9IPZ5Iv9nCJI9HsENiwEwEWanpMIByW6j575nSYHJ8wlbxz956wZ8+LTGUPnz0bJgVY5ooz8AnMAHpOA9Yzs1W7z30XXvTEdf/xN1/9S1dcsSL2u1zRMyHPnH6m78+/cuvXHnzowb1jY6MCnMBDj5cOgnxUZ2dnl6lGhkIefvj74eHvP2RgWb9hKGzfvits3XaewLnOpCPANeDJbkNNctC5SGFTpwbA+NKSAElPhx51d2e3bMEB2YSDobO7yyTfwRd+Yqq9TTbjBl0PZayhFx+cjh0bbEt7OUp51ZnpUK3ODB17/iczjz/26B1Kanq3YgEoMLR84sOf/vgDDz7wthMnjpm0K7dIcsnes0UFYt0azcNu3rI5AIS7775LttbxoDlZAW9n2ChbrUeqlg6IdRYSqwUoJYT+7pYw2FsOa/vKYaCnJXR3qEcti3pmDskHcQKmS0QWuYJUU/WqFzAy2D2qnu6BAz824G3atDl0aH6YwWjUcfZWHmXNzYeJqQk6MZf9ypt/+WsPPfTQmZjRtN6KBWBPf/+b77nn3k/8+MCzLa22pMrBZztdSfJt2bxZABwM35fEe+yxR00lbt+xMwwNbZJUVAfEgFbvqRoIJTnna9Vw6dBEeMPFnWHHYC1s7qmGrb2zYefaWrh4W2sYaNMy/JPaW1prAemU4DK1jHQ0iZk6Ot2ht68XqIbDsjVPSv0P6QdAz9k6O5o9SfRWh+g0ZagZk7kOScLO5w/8+LamRV688RVpA952++3r/ui/feE+jaHtZneCSmu7qdzUa92xfYckUTnce+/d4ezZM2HTlq1h/boNNgVnuJN9B+2ig3E7qe2OMB56Zw+Gv9l/3F5IEp5s3IQOtCjCL1y6PtS6t4az010Cnksx2yFB4LP3hKVSUauskkngYpruzNlT4YjsTnbyfdnlL7ee80HNiFQ1PQf4vIxsQlbVyK7U/U5uWLfx5d/97nd+0MwgXHHDMGJW6Z3v+rcfevqZp3djuLdX2k2FwiQ6DDvV+2QRwJ3f+1vrJOzctUe90QFTzahJwU5UdZeFFSgpf3qhM7R2nBfe8NrzVa9oIwE4xB6cnJ4PY9V2SVDFeWPOvjhXrw86DneunpGuawbX6UdRCYcPvhDuv+/ecPnLr5B5sCX85PnnJfVQ35SIJVX36NhIl3ri71XidV5Xc55XnAquzs+/ZP/DD3/+yNHDFXq52H0OlFLYvWuXDWncdecdtsKF4ZCe7l4HKAATELJDCCJsU2ek80dcUnB2oSNMzrbpbbi2MCHfj0qYmKmEmfmKKB1mrHJBehG1F51iPEk+VG/KV8CkX6fmgrELjx49YnYoQzXDikOb6qC+alW94kpl989ddvmtzz33VNPagitqLnjhllvKTzz62A2HjxzutMFhAQa5B8O3n3++DXH83V13mvG/bdt2GfydBgCYy787Ah6hdJZsmaRYjQIjOcx+MMUWD4X5xpcS6+UUdZARUBEAaS7Fidgd2H12qbe8RT1vhmIeeeT7ZjpouxBTwV6ByP02wvjEWO/IxPCvWXVNelpREvC59u7XPfPc0zeMjo6UUGf0duH3Vtl4PT3d4a677tDgcXvYunWbrfMznomZmdTLh1UW51LQ7UGWbNlC07RQQT1ketVIRwORLpaXesDK/qS6UzpgzB+AEprkk8dwDytyTqlTMjU1Hbbv2CF/MjC4bfXRkdEfy7c62to3v+H1r/sfmituyrWDK8YGvEXS7zOf+/wHz5w5LS2pMT5BAsN97Zo1Yf2G9eHOO/7Wxv02b96qoZWKASKz9kCpSbSoPBXFMehMj5gB6A75LE6VXreVLwDGcUfPlBmMWeswMI43rQMVWdOQTF3iWZUGNEujPNl2ckAZhRVZMNOAscijRw+HNRoIZ4hGEs+GZ6AD9Dzf+MT47hcOH36Nkv7SyjfZacVIwMnJmSsPHTn4O5IU6qz6qmUWBVyw94Kwf/8jQcDUQs/zDVTwCMkGgFxLw079KY7k7O3tCeuk9jas3xB4eQgQMlCNxJmUJGKIZEIHYGMqjTE7bEUWsjJ22KehFcpwDZvJUD5gyUs+wgDRcEgYZ/EIRoVZlQ2QmYPetGmL2a0MqEOR7EFmW9o7OiePHj7UlEMyCIqmd2Jm6eWvfNVthw698Ms8DKoSt+/CF8ugH9VY3wPhPHU4mMPFuVoFcJKBsbOB2uuTwY/EZCULYGAIBJABAlYwo0bNGVDALxIT+0+dE6lsgM+7JEhLFjNQJ6ueWdEyogN16ptW+rAKIMqAKbWaQJXvpKB2Dx38iUnACy/cF55+5indD/UwlOPLwYY2bHzuJZdddukf//EfT/gNNs95RUjARx554mVHjhz8iMAiDPBi+IKk11AYHFwT7rv/nrBWU2nM8yrZwAJgTNzh6Y9FCBu0WoX5YIA0NjqmcbmztkiA+WPmYt2pZuoAtPrjOjh+xQzBAAiTkprTRUoCXurr7unRQHe3yjqooTNpp+JWhwHaInaPnsq1NHOiXjw+UpDnQLKe1bIwrkk6y/41tTjQUmq77fnnnzvM/TSTWxG94BOnj/362MR4BWDgUKPnn7c9PPHEY5JKrVqBMmjMgtnZnwDDrIjey5V02SQQdtkav2NaBcO6PyRe5lStlQNvhGMnQInmogeRE4gItTwhIJ7QUqoTx09o8HhGttwa/TDW27smkFJn/I9+ujvLdIBJSvZKMvMuyqHDBzVm2W+vCQA+u57uZ7pabRmdGn0VV2821/QAvPbaazeNDI+8DQYjlZAuW9XRUE/YxtKY5Gdw2ZjlXDfGMhOyVoBYt269OhFz4ZSWwI/rFUlelXTnYAZxMNsOqyRmAwDFHQgKG3m8AOmJTGBlNcxprSvUfdq7wOtlWwJ4XI7SS8QqLF1h6mfxRK8Wt56WFMTmHBxYYyqYAjzzzEw16LXSptz6rekBeOCFQ2+ZmBxf5yoxmOE+NLQx/OiHPzC1y9SW2VbGarezGEqhZ4nNR6cCO9E+TAjzBSSwZIBD0hnQYHVMj9IvAcxhqjMgFU06Er1VRrpstonJCU39+ar6tbp+j1Qzzq5lAcr7HxXFkOVjl2L3HTt2RKbFoNmx6d6QtrJT911//fVN90nYpgbg9dcvtIyNDv8zOgmoX+Zat6i3yAs9vE+RVC/MNICIgaxGgYHYfahI1uAB0MwBpAx0FIwOQMQooHOQkhYhE69h17J8l5x5IPEjYYEp0hnQDMo0YJErLtXj96q4F7SLkocKpnNz4sQJsytZRpbuE19ScOsDDzzedJ+CaGoAPvjYVbvHxsevMAAJACwsXa/OxDPqKWI3JQMeZtKD5aVybCg6BFP6DMNMtW7nKduYbjgCEPZn2DAQ1FMMGspNLkk/T3Hg6CxQW52corPVMSJHko3HJVe8L8LqaqvQaP3Ki+/Hh3DogNADZgX1gMpZDzreiRYo9I1Mnt6WrtUsflMD8OyJE28QQzqRLDBjvey5yYlJG/LAZkrAREJAg8rjYIk7K0ocLGJVwkgOLDAQKefA01k01GGp0OswqCgjKw65nGWnROLQxLotTJruF/VPjZgCbPvhsyVOTy1eDvA5ANmhgbno06dP6TnYzF+l43Vkx5amJ6sFANWe/0+cmFMaHR//RYDEuB7HRtl+LC5FVdH7dWY7I9lmo0cDzGk5U2Kcc9C5aGeAQgDPgONhHgqo2V8OUIagVMaJKJhRW0Ux3ZItTL7XPz1dlVlQth8GnY38j4ZrZVdVYX4AbBvCfjKUYVaGe+QebKlXbW6zVdxEp6aVgO94xzvW6qWfl8EwmMCOAu3qcPBOB2+hMVSCQzIyNsgMBXPDJvkiEihXn6ONi0dVxiSOMZ8avB6YbMyOUQOHypMWkyCW8xhnAGOX8ohyFIj0KZ/7Y5+YTq2E7tQKaavB6vXrJeln11E6ZgY9fhYrdHZ0OWBViPWFGoNcbxU00alpAXjw6NHL1PnYgAqDiQynjGDcaxiGF48SsOAFNhYSEKbBeNxiMCXYkGHZdgI8RBPzSXS4ORH5yXl9MdcKeTnPV0KktTK5fEoglblflmKxhMx+VLZZh3LjTaR74MdEB4bOEz86+6GpPtqADZbS/TSL37QAnBibeAWvL2IHoX7XaNYD6cf8b2I6TKHX29nln2kj7ohKQFrMJmN2SsqjizQDgqMoy8qkoiPKSYBU41+8nhWPdaQboWodjD9yr7wnwvO45JN011/6MXF/5CGNAaB1Xrg3OQNobcG71J7UFOemBeDs3MzLkBxwj1UrrO1jyRIT+JIpYogGlLXCBUCSj41kAKGAHOrRHFHPiFFY7qAwQCrPVXIkIw5FLBNrsbL5k6WnimKG10wOGfEcadz2W7AFDYxTNqpeAxjXlKM3z7My18xjpPuZnZ9TQnO5pgTg9ddfzyDYRWnSnkUGqCW4wXgZzIKhGPUAcBHLxUMHQuR8FlNqBJXhgzDMjUw3tlJRdE5KGWioE98lrIHF6LiS15vq9pRUSfQprX/mk5GC2Hla3uCqOF7A6lSYP+aXGftEHbOgwosrBwnfZK4pAfj0889v0XzvZpgBSFBLzzzztBYAjNmAdAIAc8Ks4UsqLOMNjITn5iuQc9Tpf0pcnGVUDiS/LvnQOgJSyHur6R6yOrgglH5hvzalrROljBzY7eV3gct+YHE2xu4p3i8bILGqhkIsA7Mrc0sLC/6RYy7UJK4pF6ROjE3u1BSbjf+xoIA321if16ttM2A4TEYyoKJYsWyMJAP7yQjgDnHnknmKWjwChYhDKtJGjyog1UW8uCJ8xStWRY6DykIxHQLS9UcolbfElM4LTOSoXlQww0h2D7GXn6S9Pxtz3i7tzCa0CiVBS6WpVGez+E0JwLGRkT2oXFQQH5bW5uImBdmBwCSPmMiQC5tL2lCIs9yYC2PMyCcQwRb5Jw6SGUFTR4qVtgXTQCQHpoxY9UQ4Uik1Z4C0GNdRfXZvlnvuiTyjURbPhSrmPt02jGXtOgZTs2m5lj8LV0dpl0bOrflnO6UpAThTnd7BChNsP9bcwTyYZtIOJulIC0St+R0FDpIIhDxbwJoK6USm/ZNAqnkmOBX3FD9TxlIiaDN6K+TlyLe6icbqvFxK8NxUMxewzpEu6DsyuPSmSmjsL9LwfNRp1XJiKVopNN12vk0JQC0Q3ZYGYs/TMntUMJLQGCWu8GefVFAnxCSLs8nYiL4k31jvyPKxNEswdloezHV41MFjKSTaNexyOikhogAvKxOz/fpWSJm6NhWLKp1j0UhNVS7V7AclUBG3f65JWf4JSwX7rUCh57Uaysezipok0HSdEDV+SYPNQzABNcxsAEvV2VIj2UkwCQnBChljlpihJDuyc2SkCBw1kbkQQYvDX3QYDezOpzsAsjIK1MMe8hJKV/mU4uDhKnJEOKKDzlZdxx6uDUxTNndg41JXGttEFbeVWw+lOprFbzoJeIdMpFptflC8kPPhFl4GMluIRDECXtoL5S4jIsaM5SrhUsWpqMOBgZ8oIkpIimkW9JNdV5ROnPkJWlYmJ2XjbVpHxW6E61tZy/GkhuuQzfNw4PhheSCCWM+JjUgPmt4w19Ye1dX29nKxJN9b6v/e+dYbbujQZo1aySmm6B8WMf3GYc6RCQcVjbAwUg8bs5wSburfD6uOsvq3AxryEm30nUTpNjyimQp8qFI5grEePOowh697MmqFLSvWmYobLXmQ2h/VEs8divOs2IhIP94Jobw6XSe1sdHRVGWz+E0nAasHD7bJ/ukwJtPKYir2oA9EO8OSdDNGijkw0XuxUaIYNoEA5d2z+hyznhDPlLPyilsJThyxnEHKMrzAOVUYrU743BCe/vweFY9Srp5H1YnOiA2AVi6Wr2nxQqWPN+60pMweUhK/XD7w13/916NJakLfDK7pADg5WarUFuYrCYBJVcFUYyzqz9AGc2GBfP5j2ADi/HX+5MJ5kCbmUScuI7N6Uq7SDQC6pnxA5eo1lsiBy7CzqGys2TLq9aWQ1as8/Po9cBe+9pFFtYwEkI+9W2ktP6G2yG4z1fOz7jddJ6RcnmaOSvettqa58cSEiC9rb0WlnhLzIgsy2hxLSGtwzmwqVQYVRd+AkOq0dPIiNXFz6Zr4ZJPPX84pkv0IUkYqT5wy8inb2PlI94LPUn4WJOCYcixXKt+3SJOdmk4C0r55ttr8qzW6ixd4qCkpN84FGLidh0BivvlemUgUMzqrPJOWxvB4taTWDR2QRemWr8euQzo3kVxD2GiUliWnAKiLjjrNvsPGi/PLZBmF6Bii4Uub7KSKkwSc7W7raEoANp0E1PQa8501QUwM8Y0eUcM2MGssEovFJGxCmJiBL/IXz0BT57fRmLRKICDPwhZQBEdNXlsq6lJKMfuPeSqX/cUOShYHTFaTeY4ouwQVeD1Wl8J0NKyHm6sDGtJYN4hj7JNn1wzQcxs3bnwm1tpUXtNJQDGdXaBmYD4chCEwAakA81ySwUB1TJSnj24ZIM3YVxlI3MVuQJbgAacAorhYISFDbT3Nr+9xK5mhul7WSmcFSdfhl6GgOa5nRWMsefUvaXovl3QvWrK36ViOReeL59aCi/vvuOOOaSvbZKemk4CDg5dUxchJ44Y4AtCAEt97M/DAJR3sWMXye1sJA1MMsFH6GQngdeIEy1jU6iGNOJVZKAI+SzEwK0dERkE8hj3FiqbS0YcmdyjV64PWClsctWvfCtF6x2wM0Ah9E8tB7V/D7g1cl09GtHe2Ne02vU0HwE996r1VzRKM0Pg43qewcTEWZyYnkcICVN5+M0kFb7PDAWAJqgOAUpX+/WSBepjslJ/qcOJIIy9zCDgRcSDVMhfrSHG/dyVahZ7ql/Vz+thN2qXBilOvSGe1CwI/HF4/QPJrwcXJge6+m1PdzeY3HQDV6POa5TjpoMDW0/sUAhsvJKWOAj5ShC0r6kyss5h8Y2rGLQeNs1iJxuxEQarCVjyGLcXDdoY+HlRpJa1ITE/0Wb1+YUU9h0Asx7VnJLn58SDFPcPzeU6k+rHjR/ROsxakqvfb1t7xPX0B6qQTNt+56QBIE6vDcchtOqlgk3Sz9iJSvSMiIvGMt8dgZHKAxV3yY8yRYBEDFCGRGKicxIGSwjl6S6K6hiP1zqljUR4FrG68ep7TuVnAy+fc+6IVzhKpPCvSkeEXLkdnRHvM3EKVzeqaEoCyew6g4mAaPd2qJB1r/5gfTTyFIRjp7ICQDWXAtch842CKQ2wJeE5wDhBTunwvFiuyOCk491NZA5WlphKUMUI72TMowWskqWS233RVaxwl6XKkZgvOaicHdnPgU19sbqRdHg6sX7Pmb+o1Nl+oKQGo7348hf0Dg/ljDz9WENsLSQAF1sX86elJ3pc1zji156cwfnJeX8RIrCbLV5wks+1SXkyjfKKzeu0eIm2s3G9LufGeM7pYF8Anj94t73tgOti1svI+/sePjI2UAKh20L/lnnvuGYskTek1JQA7ezoFwJY4FKPvq0nKwTw2HIKxeQejtHuWScHEUJFGlNUprVRKj5E6SCxBZVLtHreYggYq5XmHJs3KxHj9EnZnXsYKWY5dw3K0zZrU7qQ+xcUPJl0JIqQ8H0vcvWdvWL9xYxhcxz6DG6Z2bn/RzbnqmzLYlAC8cNeun2j86zCMx6GCOZiewjB3DAoIUQoiVWzeVLQGFmMvICAhphm4vD4SU4j6nczTvLyXSSoUGsKpc5OXfQmc+Rq9PuqgpDvMhElt38Z9YjqkDhXlkHqbN2+x78hhWyLpB/oH/vKWW/7kyVS+Wf2mBODnP//5Cc2IPG5cFxPpHWq3ePWEO7JvfySGAELG1Nhh3hnrOXXwRBREVMBwS4nJqR7zE42GQQCMfW4rosizdOZfecQXOSfwpHymwoAN4CGpk7lgzyZqxgGRfrxeeubsaZOGXZ1d8+s2rP+cni1f06LLNUukKQFIwwtsf8cbcUkijY+P2iriPu2KlZc2MMIZPGWvbZqaVJpxTifDTyMbc5mZBMuAtqCPWg+EIX36Ya0+dshmQdBYRakc9Sstf3AfBu54QcvjLvRLQPWO6f7ZkJwxTX40SYryZh/bjrA7PlNvvHilfQ9v/7Vrr72LOpvdNSUAafT+3u47tQZuDkbCLl5O4mAzcvZXcYRF9kRVjIRhl1JzBoQYdGgoIohI4vCH87MFY9yv1auP3rAz1aA+4dCuD8p4mQiwJcpRONVJpfl6GVrRd9+s88HmlUn18kz8WNiYnHebz+i9F+ro6eqe37h+6Pfe/va3x0FCam9e17QAvPjiq57QJkRPJUmC5BgZHbZtOPp6+10qRb6YPBEIYfaYmA0IAYFBDSB6xDwrEpNSet533Grumd6obDWcgStXT6rDfCfwINehMvPlCeyjkmz8MOgs8Usy6Sef5+JTD+vXbjCA2hfT9cHtwTVrv/utb32jqYdevDH83LQA/Oxn/31VW5p9h8FnGIrkYOtbbCg+z8AkvfEZ9OHkQ2sSR3RsDpmA4AQ6WwFHBwDwBI9D41JswbYAHtaG46Nj46pn2js7WT4Bg3ZWPAHUy4My79mOjo/INh2195qpP4EvhTcObTZbc3jkrD2fzIvq5qEtN4jOl9VA2OSuaQFIu/f2939VkmjOBpoVR4oMD5+1XaP4IrnPRuQQKBq9vGN21qikJR0TB4WDy6VpAlqGH6Op0wXZaxO6zoi+3XFm0Ta/3BN0CbIeVoz/lCgaZjOYy8Wu46V6AAn40h/3geplp4fTZ07Zj4aer77wfvPXvv4XD3CdleKaGoD/4T3veUS7YokhzO2Kw2LiWUkLhmTWrVkv20lbtUXOGwxhtDjHG3OMrWH4o7b5TEPKz9CTOAxwFh0+vANg2KNFnudDn0CW0euuuD40dgEfMuIekXxIY6QynamUDz2fkN24YZMBlKEZaLQC5sS+C/feoGrSVbhi07um/lLSrbfeunD+9l3zU9OTb7V5U4AlpgJGhi7YT9k2LFI6gAEthgP5gBCnbd5MbZPPm2aAKjkDjyJeyvnOOdbiZFaPwd/qTvmkQJckG2DD9sQG1YdlBCPl27V0vfgj4Xr0erdtOc9U76nTJ7JnuWDP3j//oz/6yp+me1spflNLQJhw4Yt2fV1S8FkHi0unEa2VG9NOWRqs1ZeQ/CtJeYYliJkUk/Rh8SeS8OzIGZ87lnTEJTrqBlgOQfzcX8yDPuUTNsDLd+CNh7PDZ2Qz6gtMMhMAP1LNAAqxHDWStmkjHyWs6MM5J0xK06PfsX3HwUsu3ve7Trmyzk0tAWHFE088Ud2xcydjZG9CrcJ4gMCKkl7tFc1+0ZOaD2b+1KSeUJVJMNGahDIpBljmwvTMtElEr0sgSTSL4LIYBADVD4cUNilA47qo2glbvey2HluGQJt3AJzrbNq42b6IdOLkcZkRWuCstO3n76y9aO+F/+ZjH/3IirL90vM3PQB5kDe98Y1PHjt+4q2axF8P0/QvqaZv+ApQ/X0DNjuC+vPl+0gedzA9uQQ0MpFa9vkrgZhBYjoNpGn+w226JBHlA1RmRBiSgZZpP67F0EpVA8es6eMyma2XLhh9JB+w3bBho0nrU6f1OS7VQdqQPrh4wQV7P/3FL9z0mYZiKyZa50CTP9IVr3rN248dO/QXrCSxfVXEQBy9ScbSmOQ/euyogTLZf3kApscnzdW51CJAi2CjtgRSKyc60hINQHRaV8TkJjqr2+pRHv+xXiQldOvWrjeb9dSZk9YzJ43vnLz4ohd/7+qr3vorGnRuun3/Unv+n/ymtwHTA953951f7e8f/CYDxOaEDgDAh6rpdXZ1dpuKw8gHAMu5LI/y6iQgudhrEB/H7ATSEKmI1CMM+HAM8dg7ulKz0BtgyUjXy12W67CEjLE+howy8Ome2e96z649z+zeddG/Xsngo2lWDADF7PmtO7a/T3bfMSSI4OD/YuipUyesE8DMwhYZ+R16pzYDGq2wlAMsHFQVHYBKHQhTqRGYWVj5jS6HOctC5QJixvW4FxaWntT9TWgxBcMxvFqwe9fuk7v27vnnH/7whw421rfS4ivCBkxMeebJJ89e8uJLX9D6wKs1vCIB5r8vgGMzHyKkU5I2NcfOw5H/j+GWBHWUfo5nh2NfT7+2k9tolzyuDgcroLkHxi23bT3v6V17dv3aZz/1qfv+Me7pZ72OFQVAGvvAgR//6IKLLmrTSzuvQUUm1UkeC1d514KFq7361hoftGGOFTX604DQYJXULBeKLkk/gMkfn47FHuV7v3RUkMz0vLk2km/Tps0/vOiCF735CzfdtD/VsdL9FQdAGHbzV75y1733P7hdILw0MRgmczBLQi8TW5FhGqQhKpthk8yWE91P60ziAUod2J0DAt0GgY9thE9peo2pQECJiu9o7wR8j+x98b63/eFNNx34aa/dTOV/+pb+GX3a9773U533PvDVm0+dOvWrSL1MwvHE8F0gY8qLDgDLnVi0yuA1tpi9kRYlWlZumedsVLsu7Xy6D4nHN+pQ+ziWXdm3grVyJ61lRBqrI/K9Sy/Z9y8//elPN93+fss0yz84eUVKQJ7+/vv/19yvX3fdd44eO3b+zMzsJahjA1OUhNAgDRmvI49vcyAROeikMC2HdDJAoUIjIClnCrUhjbptmwyBrk/qfXBwrc3E8MkFgH1aQyz+OqUPOiN1Wbu4dcu2L/3TV73iX914441nqHu1uRUrARMjb7/99tbf+c83/BcN8P6WVK89b6NUA1zYimz129XVo69WdmYABJxIRHwO1LSvqgZIPkSDOgdo2JTUAw3jkYAbdZ+3MQEv4JZKHtPMx3/69re+8Xndz4pZXpXa/R/qr3gApoa48g1v+BcnTp78xMT42MY8IFI+fpJySDLAxHsYdA6w4RizQ2qlQW6n9SEV27FA4LTZE0lVpgG5BjSNYOcDg2vWrLt3y3lb33vrn/3Zg/nrr8bwqgEgzL366nfseeHwj28cHRm5immzBLilGJ/PA0RprA+pp6jZkUhC1hyaVLTBaBmX6O0GR12AWCu1hzUz87FXv/KK37/++ut9d8kG2tUWPbe1VngLCAwtr33dG68aPnv6gxoKeQkrYRYvXP37GyAPTLCGVMy7fD5hvlfX19enud6hOzdu3vRbN3/pS6te6uXba3Hr5XNWeJhe8vf3f+dqDYe8W3baK7VwoQVV+tO4BD4kJp0a9X7ntDD29s2bNt305S//928r3V8i+WkussLKrloAJj4KNOXXv/5Nrzg7NnxNdWryjXqnZI9Wt7SgVl0yJspGH3WLMzFowyrYiXqJfKS7s3v/xk2bHtm8ccstf/AHn3tIwFu1nQxvo+XPqx6A+aZ5l75D/PTdd18yOT71Cg3RXF6rzV6g5VSbJRn7BNQOM/ysgDVbTXbhpEB3WjvUP9/a1vZYd2fnfWsGBh74xmXfeKF0fQG6fNsuFy4AuFzLKJ0hnJtuumlwbGxsjYZVBmYXFjolHFsqpdJspVIab2vrO7Nx48CZL33pS+OSckkk/j01FllFCxQtULRA0QJFCxQtULRA0QJFCxQtULRA0QJFCxQtULRA0QJFC/x/aYH/DcZeQn52ItB2AAAAAElFTkSuQmCC", - "strings": { - "initialNotificationDescription": "Tap to pair with this device", - "openCompanionAppDescription": "Tap to finish setup", - "updateCompanionAppDescription": "Tap to update device settings and finish setup", - "downloadCompanionAppDescription": "Tap to download device app on Google Play and see all features", - "unableToConnectTitle": "Unable to connect", - "unableToConnectDescription": "Try manually pairing to the device", - "initialPairingDescription": "%s will appear on devices linked with %s", - "connectSuccessCompanionAppInstalled": "Your device is ready to be set up", - "connectSuccessCompanionAppNotInstalled": "Download the device app on Google Play to see all available features", - "subsequentPairingDescription": "Connect %s to this phone", - "retroactivePairingDescription": "Save device to %s to connect more quickly to your other devices", - "waitLaunchCompanionAppDescription": "This will take a few moments", - "failConnectGoToSettingsDescription": "Try manually pairing to the device by going to Settings", - "assistantSetupHalfSheet": "Get hands-free help on the go from Google Assistant", - "assistantSetupNotification": "Tap to set up your Google Assistant", - "fastPairTvConnectDeviceNoAccountDescription": "Connect your %s with this device", - "subsequentPairingDescriptionOnTv": "Connect %s to TV" - } -} diff --git a/fastpair/rust/demo/pubspec.lock b/fastpair/rust/demo/pubspec.lock deleted file mode 100644 index b475ef499e..0000000000 --- a/fastpair/rust/demo/pubspec.lock +++ /dev/null @@ -1,652 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a - url: "https://pub.dev" - source: hosted - version: "61.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 - url: "https://pub.dev" - source: hosted - version: "5.13.0" - archive: - dependency: transitive - description: - name: archive - sha256: "49b1fad315e57ab0bbc15bcbb874e83116a1d78f77ebd500a4af6c9407d6b28e" - url: "https://pub.dev" - source: hosted - version: "3.3.8" - args: - dependency: transitive - description: - name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 - url: "https://pub.dev" - source: hosted - version: "2.4.2" - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - build: - dependency: transitive - description: - name: build - sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - build_cli_annotations: - dependency: transitive - description: - name: build_cli_annotations - sha256: b59d2769769efd6c9ff6d4c4cede0be115a566afc591705c2040b707534b1172 - url: "https://pub.dev" - source: hosted - version: "2.1.0" - build_config: - dependency: transitive - description: - name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.dev" - source: hosted - version: "1.1.1" - build_daemon: - dependency: transitive - description: - name: build_daemon - sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" - url: "https://pub.dev" - source: hosted - version: "4.0.0" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: "6c4dd11d05d056e76320b828a1db0fc01ccd376922526f8e9d6c796a5adbac20" - url: "https://pub.dev" - source: hosted - version: "2.2.1" - build_runner: - dependency: "direct dev" - description: - name: build_runner - sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" - url: "https://pub.dev" - source: hosted - version: "2.4.6" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41" - url: "https://pub.dev" - source: hosted - version: "7.2.10" - built_collection: - dependency: transitive - description: - name: built_collection - sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" - url: "https://pub.dev" - source: hosted - version: "5.1.1" - built_value: - dependency: transitive - description: - name: built_value - sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166" - url: "https://pub.dev" - source: hosted - version: "8.6.1" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff - url: "https://pub.dev" - source: hosted - version: "2.0.3" - cli_util: - dependency: transitive - description: - name: cli_util - sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 - url: "https://pub.dev" - source: hosted - version: "0.4.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - code_builder: - dependency: transitive - description: - name: code_builder - sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189" - url: "https://pub.dev" - source: hosted - version: "4.5.0" - collection: - dependency: transitive - description: - name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 - url: "https://pub.dev" - source: hosted - version: "1.17.2" - convert: - dependency: transitive - description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - crypto: - dependency: transitive - description: - name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab - url: "https://pub.dev" - source: hosted - version: "3.0.3" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be - url: "https://pub.dev" - source: hosted - version: "1.0.5" - dart_style: - dependency: transitive - description: - name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - ffi: - dependency: "direct main" - description: - name: ffi - sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 - url: "https://pub.dev" - source: hosted - version: "2.0.2" - ffigen: - dependency: "direct dev" - description: - name: ffigen - sha256: d3e76c2ad48a4e7f93a29a162006f00eba46ce7c08194a77bb5c5e97d1b5ff0a - url: "https://pub.dev" - source: hosted - version: "8.0.2" - file: - dependency: transitive - description: - name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - flutter_rust_bridge: - dependency: "direct main" - description: - name: flutter_rust_bridge - sha256: dcb436ba4b466e19da1656ef14622b5ac2ed90efc8fcb0946942c6cd185578d1 - url: "https://pub.dev" - source: hosted - version: "1.79.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - freezed: - dependency: "direct dev" - description: - name: freezed - sha256: "2df89855fe181baae3b6d714dc3c4317acf4fccd495a6f36e5e00f24144c6c3b" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - freezed_annotation: - dependency: "direct main" - description: - name: freezed_annotation - sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d - url: "https://pub.dev" - source: hosted - version: "2.4.1" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" - url: "https://pub.dev" - source: hosted - version: "3.2.0" - glob: - dependency: transitive - description: - name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - graphs: - dependency: transitive - description: - name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 - url: "https://pub.dev" - source: hosted - version: "2.3.1" - http: - dependency: transitive - description: - name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - io: - dependency: transitive - description: - name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - js: - dependency: transitive - description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" - source: hosted - version: "0.6.7" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 - url: "https://pub.dev" - source: hosted - version: "4.8.1" - lints: - dependency: transitive - description: - name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - logging: - dependency: transitive - description: - name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" - url: "https://pub.dev" - source: hosted - version: "0.12.16" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" - url: "https://pub.dev" - source: hosted - version: "0.5.0" - meta: - dependency: transitive - description: - name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - mime: - dependency: transitive - description: - name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e - url: "https://pub.dev" - source: hosted - version: "1.0.4" - package_config: - dependency: transitive - description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - path: - dependency: transitive - description: - name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" - url: "https://pub.dev" - source: hosted - version: "1.8.3" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 - url: "https://pub.dev" - source: hosted - version: "5.4.0" - pointycastle: - dependency: transitive - description: - name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" - url: "https://pub.dev" - source: hosted - version: "3.7.3" - pool: - dependency: transitive - description: - name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" - url: "https://pub.dev" - source: hosted - version: "1.5.1" - pub_semver: - dependency: transitive - description: - name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - pubspec_parse: - dependency: transitive - description: - name: pubspec_parse - sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 - url: "https://pub.dev" - source: hosted - version: "1.2.3" - puppeteer: - dependency: transitive - description: - name: puppeteer - sha256: f00b54703dc22af04eaace8f23a33c56008870f990684c2ad8c4115ac51b0a38 - url: "https://pub.dev" - source: hosted - version: "3.1.1" - quiver: - dependency: transitive - description: - name: quiver - sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 - url: "https://pub.dev" - source: hosted - version: "3.2.1" - shelf: - dependency: transitive - description: - name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 - url: "https://pub.dev" - source: hosted - version: "1.4.1" - shelf_static: - dependency: transitive - description: - name: shelf_static - sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e - url: "https://pub.dev" - source: hosted - version: "1.1.2" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_gen: - dependency: transitive - description: - name: source_gen - sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - source_span: - dependency: transitive - description: - name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" - url: "https://pub.dev" - source: hosted - version: "0.6.0" - timing: - dependency: transitive - description: - name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - tuple: - dependency: transitive - description: - name: tuple - sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 - url: "https://pub.dev" - source: hosted - version: "2.0.2" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c - url: "https://pub.dev" - source: hosted - version: "1.3.2" - uuid: - dependency: transitive - description: - name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" - url: "https://pub.dev" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - watcher: - dependency: transitive - description: - name: watcher - sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - web: - dependency: transitive - description: - name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 - url: "https://pub.dev" - source: hosted - version: "0.1.4-beta" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b - url: "https://pub.dev" - source: hosted - version: "2.4.0" - yaml: - dependency: transitive - description: - name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" - url: "https://pub.dev" - source: hosted - version: "3.1.2" - yaml_edit: - dependency: transitive - description: - name: yaml_edit - sha256: "1579d4a0340a83cf9e4d580ea51a16329c916973bffd5bd4b45e911b25d46bfd" - url: "https://pub.dev" - source: hosted - version: "2.1.1" -sdks: - dart: ">=3.0.6 <4.0.0" diff --git a/fastpair/rust/demo/pubspec.yaml b/fastpair/rust/demo/pubspec.yaml deleted file mode 100644 index 1264ee3ce0..0000000000 --- a/fastpair/rust/demo/pubspec.yaml +++ /dev/null @@ -1,110 +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. - -name: demo -description: FLutter UI demo for Fast Pair Windows written in Rust. -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 - -environment: - sdk: '>=3.0.6 <4.0.0' - -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. -dependencies: - flutter: - sdk: flutter - - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.2 - ffi: ^2.0.2 - flutter_rust_bridge: ^1.79.0 - freezed_annotation: ^2.4.1 - -dev_dependencies: - flutter_test: - sdk: flutter - - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. - flutter_lints: ^2.0.0 - ffigen: ^8.0.2 - build_runner: ^2.4.6 - freezed: ^2.4.1 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/fastpair/rust/demo/rust/Cargo.toml b/fastpair/rust/demo/rust/Cargo.toml deleted file mode 100644 index e976983415..0000000000 --- a/fastpair/rust/demo/rust/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "rust" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["lib", "cdylib", "staticlib"] - -[dependencies] -bluetooth = { version = "0.1", path = "../../bluetooth" } -flutter_rust_bridge = "=1.80.1" -futures = { version = "0.3", features = ["executor"] } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -tracing = "0.1.37" -ttl_cache = "0.5.1" -thiserror = "1.0.43" diff --git a/fastpair/rust/demo/rust/src/advertisement.rs b/fastpair/rust/demo/rust/src/advertisement.rs deleted file mode 100644 index da59517b7c..0000000000 --- a/fastpair/rust/demo/rust/src/advertisement.rs +++ /dev/null @@ -1,230 +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 bluetooth::{BleAddress, BleAdvertisement, ServiceData}; - -use crate::{decoder::FpDecoder, error::FpError, fetcher::FpFetcher}; - -/// Represents a FP device model ID. -pub(crate) type ModelId = String; - -/// Holds information required to make decisions about an incoming Fast Pair -/// advertisement. -#[derive(Clone, Debug)] -pub(crate) struct FpPairingAdvertisement { - inner: BleAdvertisement, - /// Estimated distance in meters of device from BLE adapter. - distance: f64, - model_id: ModelId, - device_name: String, - image_url: String, -} - -impl FpPairingAdvertisement { - /// Create a new Fast Pair advertisement instance. - pub(crate) fn new( - adv: BleAdvertisement, - service_data: &ServiceData, - fetcher: &Box, - ) -> Result { - let rssi = adv.rssi().ok_or(FpError::ContractViolation(String::from( - "Windows advertisements should contain RSSI information.", - )))?; - let tx_power = adv - .tx_power() - .ok_or(FpError::ContractViolation(String::from( - "Windows advertisements should contain RSSI information.", - )))?; - - let distance = distance_from_rssi_and_tx_power(rssi, tx_power); - - // Extract model ID from service data. We don't need to store service - // data in the `FpPairingAdvertisement` since it's easily accessible from - // `FpPairingAdvertisement.inner`, but it's convenient to save the parsed - // model ID. - let mut model_id = FpDecoder::get_model_id_from_service_data(service_data)?; - - if model_id.len() != 3 { - // In this demo of Fast Pair Rust, only model ID's - // of length 3 bytes are supported. Therefore, if a - // larger model ID makes it this far, log an error. - // TODO b/294453912 - return Err(FpError::Internal(String::from( - "creating `model_id` should have already failed", - ))); - } - - // Pad with 0 at the beginning to successfully call `from_be_bytes`. - // Assumes `model_id.len() == 3` before the call to `insert`, otherwise - // this will panic. - model_id.insert(0, 0); - let model_id = format!("{}", u32::from_be_bytes(model_id.try_into().unwrap())); - - // Retrieve device info of the device corresponding to this model ID. - let device_info = fetcher.get_device_info_from_model_id(&model_id)?; - - Ok(FpPairingAdvertisement { - inner: adv, - distance, - model_id, - device_name: device_info.name().to_string(), - image_url: device_info.image_url().to_string(), - }) - } - - /// Retrieve estimated distance the BLE advertisement travelled between - /// the sending device and this receiver. - pub(crate) fn distance(&self) -> f64 { - self.distance - } - - /// Retrieve the BLE Address of the advertising device. - pub(crate) fn address(&self) -> BleAddress { - self.inner.address() - } - - /// Retrieve the Model ID advertised by this device, parsed from the - /// 16-bit UUID service data. - pub(crate) fn model_id(&self) -> &ModelId { - &self.model_id - } - - pub(crate) fn device_name(&self) -> &String { - &self.device_name - } - - pub(crate) fn image_url(&self) -> &String { - &self.image_url - } -} - -/// Convert RSSI and transmit power to distance using log-distance path loss -/// model, with reference path loss of 1m at 41dB in free space. -/// See: https://en.wikipedia.org/wiki/Log-distance_path_loss_model. -#[inline] -pub(crate) fn distance_from_rssi_and_tx_power(rssi: i16, tx_power: i16) -> f64 { - // Source: Android Nearby implementation, `RangingUtils.java`. - // - // PL = total path loss in db - // txPower = TxPower in dbm - // rssi = Received signal strength in dbm - // PL_0 = Path loss at reference distance d_0 {@link RSSI_DROP_OFF_AT_1_M} dbm - // d = length of path - // d_0 = reference distance (1 m) - // gamma = path loss exponent (2 in free space) - // - // Log-distance path loss (LDPL) formula: - // - // PL = txPower - rssi = PL_0 + 10 * gamma * log_10(d / d_0) - // txPower - rssi = RSSI_DROP_OFF_AT_1_M + 10 * gamma * log_10(d / d_0) - // txPower - rssi - RSSI_DROP_OFF_AT_1_M = 10 * 2 * log_10(distanceInMeters / 1) - // txPower - rssi - RSSI_DROP_OFF_AT_1_M = 20 * log_10(distanceInMeters / 1) - // (txPower - rssi - RSSI_DROP_OFF_AT_1_M) / 20 = log_10(distanceInMeters) - // 10 ^ ((txPower - rssi - RSSI_DROP_OFF_AT_1_M) / 20) = distanceInMeters - - const RSSI_DROPOFF_AT_1_M: i16 = 41; - const PATH_LOSS_EXPONENT: i16 = 2; - - f64::from(10.0).powf( - (f64::from(tx_power - rssi - RSSI_DROPOFF_AT_1_M)) / f64::from(10 * PATH_LOSS_EXPONENT), - ) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::fetcher::{mock::FpFetcherMock, DeviceInfo}; - - use bluetooth::BleAddressKind; - - #[test] - fn test_new_fp_pairing_advertisement() { - let addr = BleAddress::new(0x112233, BleAddressKind::Public); - let ble_adv = BleAdvertisement::new(addr, Some(-60), Some(10)); - - let raw_data = vec![3, 2, 1]; - let expected_model_id = "197121"; // (3 << 16) + (2 << 8) + 1. - let service_data = ServiceData::new(0x123 as u16, raw_data); - - let image_url = String::from("image_url"); - let device_name = String::from("name"); - let device_info = Ok(DeviceInfo::new(image_url.clone(), device_name.clone())); - let fetcher: Box = Box::new(FpFetcherMock::new(device_info)); - - let fp_adv = FpPairingAdvertisement::new(ble_adv, &service_data, &fetcher); - - assert!(fp_adv.is_ok()); - let fp_adv = fp_adv.unwrap(); - assert_eq!(fp_adv.address(), addr); - assert_eq!(fp_adv.image_url(), &image_url); - assert_eq!(fp_adv.device_name(), &device_name); - assert_eq!(fp_adv.model_id(), &expected_model_id); - } - - #[test] - fn test_new_fp_pairing_advertisement_bad_rssi() { - let addr = BleAddress::new(0x112233, BleAddressKind::Public); - let ble_adv = BleAdvertisement::new(addr, None, Some(10)); - - let raw_data = vec![3, 2, 1]; - let service_data = ServiceData::new(0x123 as u16, raw_data); - - let device_info = Ok(DeviceInfo::new( - String::from("image_url"), - String::from("name"), - )); - let fetcher: Box = Box::new(FpFetcherMock::new(device_info)); - - let fp_adv = FpPairingAdvertisement::new(ble_adv, &service_data, &fetcher); - - assert!(fp_adv.is_err()); - assert!(matches!(fp_adv.unwrap_err(), FpError::ContractViolation(_))); - } - - #[test] - fn test_new_fp_pairing_advertisement_bad_tx_power() { - let addr = BleAddress::new(0x112233, BleAddressKind::Public); - let ble_adv = BleAdvertisement::new(addr, Some(-60), None); - - let raw_data = vec![3, 2, 1]; - let service_data = ServiceData::new(0x123 as u16, raw_data); - - let device_info = Ok(DeviceInfo::new( - String::from("image_url"), - String::from("name"), - )); - let fetcher: Box = Box::new(FpFetcherMock::new(device_info)); - - let fp_adv = FpPairingAdvertisement::new(ble_adv, &service_data, &fetcher); - - assert!(fp_adv.is_err()); - assert!(matches!(fp_adv.unwrap_err(), FpError::ContractViolation(_))); - } - - #[test] - fn test_new_fp_pairing_advertisement_bad_fetcher() { - let addr = BleAddress::new(0x112233, BleAddressKind::Public); - let ble_adv = BleAdvertisement::new(addr, Some(-60), Some(10)); - - let raw_data = vec![3, 2, 1]; - let service_data = ServiceData::new(0x123 as u16, raw_data); - - let fetcher: Box = Box::new(FpFetcherMock::new(Err(FpError::Test))); - - let fp_adv = FpPairingAdvertisement::new(ble_adv, &service_data, &fetcher); - - assert!(fp_adv.is_err()); - assert!(matches!(fp_adv.unwrap_err(), FpError::Test)); - } -} diff --git a/fastpair/rust/demo/rust/src/api.rs b/fastpair/rust/demo/rust/src/api.rs deleted file mode 100644 index 40d69038f7..0000000000 --- a/fastpair/rust/demo/rust/src/api.rs +++ /dev/null @@ -1,249 +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::{collections::HashMap, sync::RwLock, time::Duration}; - -use bluetooth::{ - api::{BleAdapter, ClassicDevice}, - BleAdvertisement, BleDataTypeId, ClassicAddress, PairingResult, Platform, ServiceData, -}; -use flutter_rust_bridge::StreamSink; -use futures::executor; -use tracing::{info, warn}; -use ttl_cache::TtlCache; - -use crate::{ - advertisement::{FpPairingAdvertisement, ModelId}, - fetcher::{FpFetcher, FpFetcherFs}, -}; - -// Sends a device name to Flutter via `StreamSink` FFI layer. -static DEVICE_STREAM: RwLock>>> = RwLock::new(None); - -// Saves the currently displayed device's advertisement, to be used for pairing. -static CURR_DEVICE_ADV: RwLock> = RwLock::new(None); - -// Temporarily restricts which model IDs can be displayed. -static MODEL_ID_BLACKLIST: RwLock>> = RwLock::new(None); - -// Specifies how long entries should blacklisted for. -const TTL_BLACKLIST: Duration = Duration::from_secs(10); - -/// Updates the device name as displayed by Flutter. -#[inline] -async fn update_best_device(best_adv: FpPairingAdvertisement) { - match DEVICE_STREAM.read().unwrap().as_ref() { - Some(stream) => { - stream.add(Some([ - best_adv.device_name().to_string(), - best_adv.image_url().to_string(), - ])); - } - None => info!("Name stream is None"), - } - let mut curr_adv = CURR_DEVICE_ADV.write().unwrap(); - *curr_adv = Some(best_adv); -} - -/// Determines whether the device advertised by the provided service data is the -/// closest Fast Pair device. -/// If this device has been seen previously but has now moved further away, -/// decide which other seen device is now closer. -#[inline] -fn new_best_fp_advertisement( - advertisement: BleAdvertisement, - service_data: &ServiceData, - fetcher: &Box, - latest_advertisement_map: &mut HashMap, -) -> Option { - // Analyze service data sections. - let uuid = service_data.uuid(); - - // This is not a Fast Pair device. - if uuid != 0x2cfe { - return None; - } - - let fp_adv = match FpPairingAdvertisement::new(advertisement, service_data, fetcher) { - Ok(fp_adv) => fp_adv, - Err(err) => { - // If error during construction (e.g. non-discoverable - // Fast Pair device not advertising tx_power or - // with service data that isn't model ID) ignore - // this advertisement section. - warn!("Error creating FP Advertisement: {}", err); - return None; - } - }; - - // If blacklisted in TTL cache, skip this advertisement. - let blacklisted = match MODEL_ID_BLACKLIST.read().unwrap().as_ref() { - Some(cache) => cache.get(fp_adv.model_id()).is_some(), - None => false, - }; - if blacklisted { - latest_advertisement_map.remove(fp_adv.model_id()); - return None; - } - - // Else, this advertisement is now the most recent advertisement by the - // device with model ID `fp_adv.model_id()`. - latest_advertisement_map.insert(fp_adv.model_id().to_owned(), fp_adv.clone()); - - if let Some(best_adv) = CURR_DEVICE_ADV.read().unwrap().as_ref() { - if best_adv.distance() >= fp_adv.distance() { - // New advertised distance is closer. - Some(fp_adv) - } else if best_adv.model_id() == fp_adv.model_id() { - // New advertised distance by the previous best device has - // increased, so select new closest device. - let next_best_adv_ref = - latest_advertisement_map - .values() - .into_iter() - .min_by(|adv1, adv2| { - // We should never get NaN, so it's okay to unwrap. - adv1.distance().partial_cmp(&adv2.distance()).unwrap() - }); - - // If next closest device exists, it's now the closest! - if let Some(next_best_adv) = next_best_adv_ref { - Some(next_best_adv.to_owned()) - } else { - None - } - } else { - None - } - } else { - // First discovered device, must be closest. - Some(fp_adv) - } -} - -/// Sets up necessary constructs to maintain a TTL blacklist of model IDs. -#[inline] -fn init_cache() { - let mut cache = MODEL_ID_BLACKLIST.write().unwrap(); - *cache = Some(TtlCache::new(16)); -} - -/// Sets up initial constructs and infinitely polls for advertisements. -pub fn init() { - const JSON_PATH: &str = "./local"; - - let run = async { - info!("start making adapter"); - - let mut adapter = Platform::default_adapter().await.unwrap(); - adapter.start_scan().unwrap(); - - init_cache(); - - let mut latest_advertisement_map = HashMap::new(); - let datatype_selector = vec![BleDataTypeId::ServiceData16BitUuid]; - let fetcher: Box = Box::new(FpFetcherFs::new(String::from(JSON_PATH))); - - loop { - // Retrieve the next received advertisement. - let advertisement = adapter - .next_advertisement(Some(&datatype_selector)) - .await - .unwrap(); - - for service_data in advertisement.service_data_16bit_uuid().unwrap() { - if let Some(best_adv) = new_best_fp_advertisement( - advertisement.clone(), - service_data, - &fetcher, - &mut latest_advertisement_map, - ) { - update_best_device(best_adv).await; - } - } - } - }; - - executor::block_on(run) -} - -/// Sets up `StreamSink` for Dart-Rust FFI. -pub fn event_stream(s: StreamSink>) { - let mut stream = DEVICE_STREAM.write().unwrap(); - *stream = Some(s); -} - -/// Attempt classic pairing with currently displayed device. -pub fn pair() -> String { - let result = match CURR_DEVICE_ADV.read().unwrap().as_ref() { - Some(adv) => { - let run = async { - let classic_addr = ClassicAddress::try_from(adv.address()).unwrap(); - let classic_device = Platform::new_classic_device(classic_addr).await.unwrap(); - - match classic_device.pair().await { - Ok(result) => match result { - PairingResult::Success => String::from("Pairing success!"), - PairingResult::AlreadyPaired => { - String::from("This device is already paired.") - } - PairingResult::AlreadyInProgress => { - String::from("Pairing already in progress.") - } - _ => String::from("Unknown result."), - }, - Err(err) => { - format!("Error {}", err) - } - } - }; - - executor::block_on(run) - } - None => String::from("No device available to pair."), - }; - info!(result); - result -} - -/// Remove this device from display and add it to the TTL cache blacklist. -pub fn dismiss() { - let run = async { - let mut adv = CURR_DEVICE_ADV.write().unwrap(); - match MODEL_ID_BLACKLIST.write().unwrap().as_mut() { - Some(cache) => { - // Get rid of the best (i.e. currently displayed) device. - let adv = adv.take(); - match adv { - Some(adv) => { - // Add device to TTL blacklist. - cache.insert(adv.model_id().to_string(), (), TTL_BLACKLIST); - } - None => (), - } - - // Ensure the currently-displayed device is no longer displayed. - match DEVICE_STREAM.read().unwrap().as_ref() { - Some(stream) => { - stream.add(None); - } - None => (), - } - } - None => (), - } - }; - - executor::block_on(run); -} diff --git a/fastpair/rust/demo/rust/src/bridge_generated.io.rs b/fastpair/rust/demo/rust/src/bridge_generated.io.rs deleted file mode 100644 index cb0a62f40f..0000000000 --- a/fastpair/rust/demo/rust/src/bridge_generated.io.rs +++ /dev/null @@ -1,65 +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 super::*; -// Section: wire functions - -#[no_mangle] -pub extern "C" fn wire_init(port_: i64) { - wire_init_impl(port_) -} - -#[no_mangle] -pub extern "C" fn wire_event_stream(port_: i64) { - wire_event_stream_impl(port_) -} - -#[no_mangle] -pub extern "C" fn wire_pair(port_: i64) { - wire_pair_impl(port_) -} - -#[no_mangle] -pub extern "C" fn wire_dismiss(port_: i64) { - wire_dismiss_impl(port_) -} - -// Section: allocate functions - -// Section: related functions - -// Section: impl Wire2Api - -// Section: wire structs - -// Section: impl NewWithNullPtr - -pub trait NewWithNullPtr { - fn new_with_null_ptr() -> Self; -} - -impl NewWithNullPtr for *mut T { - fn new_with_null_ptr() -> Self { - std::ptr::null_mut() - } -} - -// Section: sync execution mode utility - -#[no_mangle] -pub extern "C" fn free_WireSyncReturn(ptr: support::WireSyncReturn) { - unsafe { - let _ = support::box_from_leak_ptr(ptr); - }; -} diff --git a/fastpair/rust/demo/rust/src/bridge_generated.rs b/fastpair/rust/demo/rust/src/bridge_generated.rs deleted file mode 100644 index bf1f040fc5..0000000000 --- a/fastpair/rust/demo/rust/src/bridge_generated.rs +++ /dev/null @@ -1,119 +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. - -#![allow( - non_camel_case_types, - unused, - clippy::redundant_closure, - clippy::useless_conversion, - clippy::unit_arg, - clippy::double_parens, - non_snake_case, - clippy::too_many_arguments -)] -// AUTO GENERATED FILE, DO NOT EDIT. -// Generated by `flutter_rust_bridge`@ 1.79.0. - -use crate::api::*; -use core::panic::UnwindSafe; -use flutter_rust_bridge::rust2dart::IntoIntoDart; -use flutter_rust_bridge::*; -use std::ffi::c_void; -use std::sync::Arc; - -// Section: imports - -// Section: wire functions - -fn wire_init_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( - WrapInfo { - debug_name: "init", - port: Some(port_), - mode: FfiCallMode::Normal, - }, - move || move |task_callback| Ok(init()), - ) -} -fn wire_event_stream_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( - WrapInfo { - debug_name: "event_stream", - port: Some(port_), - mode: FfiCallMode::Stream, - }, - move || { - move |task_callback| { - Ok(event_stream( - task_callback.stream_sink::<_, Option<[String; 2]>>(), - )) - } - }, - ) -} -fn wire_pair_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, String>( - WrapInfo { - debug_name: "pair", - port: Some(port_), - mode: FfiCallMode::Normal, - }, - move || move |task_callback| Ok(pair()), - ) -} -fn wire_dismiss_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( - WrapInfo { - debug_name: "dismiss", - port: Some(port_), - mode: FfiCallMode::Normal, - }, - move || move |task_callback| Ok(dismiss()), - ) -} -// Section: wrapper structs - -// Section: static checks - -// Section: allocate functions - -// Section: related functions - -// Section: impl Wire2Api - -pub trait Wire2Api { - fn wire2api(self) -> T; -} - -impl Wire2Api> for *mut S -where - *mut S: Wire2Api, -{ - fn wire2api(self) -> Option { - (!self.is_null()).then(|| self.wire2api()) - } -} -// Section: impl IntoDart - -// Section: executor - -support::lazy_static! { - pub static ref FLUTTER_RUST_BRIDGE_HANDLER: support::DefaultHandler = Default::default(); -} - -#[cfg(not(target_family = "wasm"))] -#[path = "bridge_generated.io.rs"] -mod io; -#[cfg(not(target_family = "wasm"))] -pub use io::*; diff --git a/fastpair/rust/demo/rust/src/decoder.rs b/fastpair/rust/demo/rust/src/decoder.rs deleted file mode 100644 index fd190557f1..0000000000 --- a/fastpair/rust/demo/rust/src/decoder.rs +++ /dev/null @@ -1,90 +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 bluetooth::ServiceData; - -use crate::error::FpError; - -/// Unit struct providing parsing operations for Fast Pair advertisements. -pub(crate) struct FpDecoder; - -impl FpDecoder { - /// Retrieve the Fast Pair device model ID from a service data payload. - /// https://developers.google.com/nearby/fast-pair/specifications/service/provider. - /// * Length < 3: invalid payload - /// * Length == 3: entire payload is the model ID - /// * Length > 3: first byte specifies the length of the model ID, in bytes. - /// Currently unavailable in Fast Pair devices and not supported. - pub(crate) fn get_model_id_from_service_data( - service_data: &ServiceData, - ) -> Result, FpError> { - const MIN_MODEL_ID_LENGTH: usize = 3; - let data = service_data.data(); - - if data.len() < MIN_MODEL_ID_LENGTH { - // If service data too small, invalid payload. - Err(FpError::ContractViolation(format!( - "Invalid model ID for Fast Pair advertisement of length {}.", - data.len() - ))) - } else if data.len() == MIN_MODEL_ID_LENGTH { - // Else if service data length is exactly 3, all bytes are the ID. - Ok(data.clone()) - } else { - // Else, this Fast Pair advertisement is currently unsupported. - // b/294453912 - Err(FpError::NotImplemented(String::from( - "This Fast Pair device is currently unsupported.", - ))) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_get_model_id_valid() { - // Valid scenario: Length == 3 - let uuid: u16 = 0x1234; - let data = vec![0xAA, 0xBB, 0xCC]; - let service_data = ServiceData::new(uuid, data.clone()); - let result = FpDecoder::get_model_id_from_service_data(&service_data); - assert!(result.is_ok()); - assert_eq!(result.unwrap(), data); - } - - #[test] - fn test_get_model_id_invalid() { - // Invalid scenario: Length < 3 - let uuid: u16 = 0x1234; - let data = vec![0xAA, 0xBB]; - let service_data = ServiceData::new(uuid, data); - let result = FpDecoder::get_model_id_from_service_data(&service_data); - assert!(result.is_err()); - assert!(matches!(result.unwrap_err(), FpError::ContractViolation(_))); - } - - #[test] - fn test_get_model_id_unsupported() { - // Unsupported scenario: Length > 3 - let uuid: u16 = 0x1234; - let data = vec![0xAA, 0xBB, 0xCC, 0xDD]; - let service_data = ServiceData::new(uuid, data); - let result = FpDecoder::get_model_id_from_service_data(&service_data); - assert!(result.is_err()); - assert!(matches!(result.unwrap_err(), FpError::NotImplemented(_))); - } -} diff --git a/fastpair/rust/demo/rust/src/error.rs b/fastpair/rust/demo/rust/src/error.rs deleted file mode 100644 index 81ecb40080..0000000000 --- a/fastpair/rust/demo/rust/src/error.rs +++ /dev/null @@ -1,43 +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 thiserror::Error; - -/// Library error type. -#[non_exhaustive] -#[derive(Error, Debug, PartialEq, Clone)] -pub enum FpError { - /// Reported when a requested resource could not be accessed, either because - /// it's missing or because the user lacks access permissions. - #[error("not found: {0}")] - AccessDenied(String), - /// Reported when Fast Pair functionality does not behave according to the - /// specification. For example, advertisement packets with invalid lengths, - /// JSON data with bad formatting, etc. - #[error("contract violation: {0}")] - ContractViolation(String), - /// Reported when trying to invoke Fast Pair functionality that is currently - /// not implemented. - #[error("feature not implemented: {0}")] - NotImplemented(String), - /// Reported when a bug occurs inside the library. Whenever a seemingly - /// impossible error condition arises where you could call `expect()`, - /// return this error instead. - #[error("internal error: {0}")] - Internal(String), - /// Reported when an error was intentionally raised by test code. - #[error("intentional error")] - #[cfg(test)] - Test, -} diff --git a/fastpair/rust/demo/rust/src/fetcher/common.rs b/fastpair/rust/demo/rust/src/fetcher/common.rs deleted file mode 100644 index d2bc13f4ef..0000000000 --- a/fastpair/rust/demo/rust/src/fetcher/common.rs +++ /dev/null @@ -1,63 +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 serde::Deserialize; - -use crate::{advertisement::ModelId, error::FpError}; - -/// Types that can fetch Fast Pair data from external storage (e.g. filesystem, -/// remote server). -pub(crate) trait FpFetcher { - fn get_device_info_from_model_id(&self, model_id: &ModelId) -> Result; -} - -/// Holds Fast Pair device information parsed from JSON. -#[derive(Clone, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct DeviceInfo { - image_url: String, - name: String, -} - -/// Holds top-level Fast Pair information parsed from JSON. See `local` -/// directory for format. -#[derive(Deserialize)] -pub(super) struct JsonData { - device: DeviceInfo, -} - -impl DeviceInfo { - // `new()` is conceivably only used in tests, since this struct should be - // constructed by serde_json. Therefore, adding cfg to disable dead code - // warnings. Can be removed in the future. - #[cfg(test)] - pub(crate) fn new(image_url: String, name: String) -> Self { - DeviceInfo { image_url, name } - } - - pub(crate) fn name(&self) -> &String { - &self.name - } - - pub(crate) fn image_url(&self) -> &String { - &self.image_url - } -} - -impl JsonData { - // Returns the `DeviceInfo` associated with parsed self, consuming self. - pub(super) fn device(self) -> DeviceInfo { - self.device - } -} diff --git a/fastpair/rust/demo/rust/src/fetcher/fs.rs b/fastpair/rust/demo/rust/src/fetcher/fs.rs deleted file mode 100644 index df2db49519..0000000000 --- a/fastpair/rust/demo/rust/src/fetcher/fs.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 std::fs; - -use crate::{ - advertisement::ModelId, - error::FpError, - fetcher::{DeviceInfo, FpFetcher, JsonData}, -}; - -/// A struct for retrieving Fast Pair information from the local filesystem. -pub(crate) struct FpFetcherFs { - path: String, -} - -impl FpFetcherFs { - pub(crate) fn new(path: String) -> Self { - FpFetcherFs { path } - } -} - -impl FpFetcher for FpFetcherFs { - /// Retrieve device information for the provided Model ID. Currently, - /// this information is saved locally. In the future, this should instead - /// be retrieved from a remote server and cached. - /// b/294456411 - fn get_device_info_from_model_id(&self, model_id: &ModelId) -> Result { - let file_path = format!("{}/{}.json", self.path, model_id); - let contents = fs::read_to_string(file_path) - .or_else(|err| Err(FpError::AccessDenied(err.to_string())))?; - - let model_info: JsonData = serde_json::from_str(&contents) - .or_else(|err| Err(FpError::ContractViolation(err.to_string())))?; - - Ok(model_info.device()) - } -} diff --git a/fastpair/rust/demo/rust/src/fetcher/mock.rs b/fastpair/rust/demo/rust/src/fetcher/mock.rs deleted file mode 100644 index 1d82efb50f..0000000000 --- a/fastpair/rust/demo/rust/src/fetcher/mock.rs +++ /dev/null @@ -1,38 +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::{ - advertisement::ModelId, - error::FpError, - fetcher::{DeviceInfo, FpFetcher}, -}; - -/// A struct for mocking retrieval of Fast Pair data. -pub(crate) struct FpFetcherMock { - device_info_from_model_id: Result, -} - -impl FpFetcherMock { - pub(crate) fn new(device_info_from_model_id: Result) -> Self { - FpFetcherMock { - device_info_from_model_id, - } - } -} - -impl FpFetcher for FpFetcherMock { - fn get_device_info_from_model_id(&self, _model_id: &ModelId) -> Result { - self.device_info_from_model_id.clone() - } -} diff --git a/fastpair/rust/demo/rust/src/fetcher/mod.rs b/fastpair/rust/demo/rust/src/fetcher/mod.rs deleted file mode 100644 index 98772f6e9d..0000000000 --- a/fastpair/rust/demo/rust/src/fetcher/mod.rs +++ /dev/null @@ -1,22 +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. - -pub(crate) mod common; -pub(crate) mod fs; - -#[cfg(test)] -pub(crate) mod mock; - -pub(crate) use common::*; -pub(crate) use fs::*; diff --git a/fastpair/rust/demo/rust/src/lib.rs b/fastpair/rust/demo/rust/src/lib.rs deleted file mode 100644 index 3d3f5bfb72..0000000000 --- a/fastpair/rust/demo/rust/src/lib.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. - -mod advertisement; -mod api; -mod bridge_generated; /* AUTO INJECTED BY flutter_rust_bridge. This line may not be accurate, and you can change it according to your needs. */ -mod decoder; -mod error; -mod fetcher; diff --git a/fastpair/rust/demo/windows/.gitignore b/fastpair/rust/demo/windows/.gitignore deleted file mode 100644 index d492d0d98c..0000000000 --- a/fastpair/rust/demo/windows/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -flutter/ephemeral/ - -# Visual Studio user-specific files. -*.suo -*.user -*.userosscache -*.sln.docstates - -# Visual Studio build-related files. -x64/ -x86/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ diff --git a/fastpair/rust/demo/windows/CMakeLists.txt b/fastpair/rust/demo/windows/CMakeLists.txt deleted file mode 100644 index c08df44aef..0000000000 --- a/fastpair/rust/demo/windows/CMakeLists.txt +++ /dev/null @@ -1,117 +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. - -# Project-level configuration. -cmake_minimum_required(VERSION 3.14) -project(demo LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "demo") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(SET CMP0063 NEW) - -# Define build configuration option. -get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(IS_MULTICONFIG) - set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" - CACHE STRING "" FORCE) -else() - if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") - endif() -endif() -# Define settings for the Profile build mode. -set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") -set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") -set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") -set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") - -# Use Unicode for all projects. -add_definitions(-DUNICODE -D_UNICODE) - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_17) - target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") - target_compile_options(${TARGET} PRIVATE /EHsc) - target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") - target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# Application build; see runner/CMakeLists.txt. -add_subdirectory("runner") - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) -include(./rust.cmake) - - -# === Installation === -# Support files are copied into place next to the executable, so that it can -# run in place. This is done instead of making a separate bundle (as on Linux) -# so that building and running from within Visual Studio will work. -set(BUILD_BUNDLE_DIR "$") -# Make the "install" step default, as it's required to run. -set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - CONFIGURATIONS Profile;Release - COMPONENT Runtime) diff --git a/fastpair/rust/demo/windows/flutter/CMakeLists.txt b/fastpair/rust/demo/windows/flutter/CMakeLists.txt deleted file mode 100644 index 1230e03ea6..0000000000 --- a/fastpair/rust/demo/windows/flutter/CMakeLists.txt +++ /dev/null @@ -1,118 +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. - -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.14) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. -set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") - -# === Flutter Library === -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "flutter_export.h" - "flutter_windows.h" - "flutter_messenger.h" - "flutter_plugin_registrar.h" - "flutter_texture_registrar.h" -) -list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") -add_dependencies(flutter flutter_assemble) - -# === Wrapper === -list(APPEND CPP_WRAPPER_SOURCES_CORE - "core_implementations.cc" - "standard_codec.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_PLUGIN - "plugin_registrar.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_APP - "flutter_engine.cc" - "flutter_view_controller.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") - -# Wrapper sources needed for a plugin. -add_library(flutter_wrapper_plugin STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} -) -apply_standard_settings(flutter_wrapper_plugin) -set_target_properties(flutter_wrapper_plugin PROPERTIES - POSITION_INDEPENDENT_CODE ON) -set_target_properties(flutter_wrapper_plugin PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) -target_include_directories(flutter_wrapper_plugin PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_plugin flutter_assemble) - -# Wrapper sources needed for the runner. -add_library(flutter_wrapper_app STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_APP} -) -apply_standard_settings(flutter_wrapper_app) -target_link_libraries(flutter_wrapper_app PUBLIC flutter) -target_include_directories(flutter_wrapper_app PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_app flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") -set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} - ${PHONY_OUTPUT} - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - windows-x64 $ - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} -) diff --git a/fastpair/rust/demo/windows/flutter/generated_plugin_registrant.cc b/fastpair/rust/demo/windows/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 5da9cfa42e..0000000000 --- a/fastpair/rust/demo/windows/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,25 +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. - -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "./generated_plugin_registrant.h" - - -void RegisterPlugins(flutter::PluginRegistry* registry) { -} diff --git a/fastpair/rust/demo/windows/flutter/generated_plugin_registrant.h b/fastpair/rust/demo/windows/flutter/generated_plugin_registrant.h deleted file mode 100644 index 7e32ef7b87..0000000000 --- a/fastpair/rust/demo/windows/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,29 +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. - -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/fastpair/rust/demo/windows/flutter/generated_plugins.cmake b/fastpair/rust/demo/windows/flutter/generated_plugins.cmake deleted file mode 100644 index b93c4c30c1..0000000000 --- a/fastpair/rust/demo/windows/flutter/generated_plugins.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/fastpair/rust/demo/windows/runner/CMakeLists.txt b/fastpair/rust/demo/windows/runner/CMakeLists.txt deleted file mode 100644 index f498e23e05..0000000000 --- a/fastpair/rust/demo/windows/runner/CMakeLists.txt +++ /dev/null @@ -1,54 +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. - -cmake_minimum_required(VERSION 3.14) -project(runner LANGUAGES CXX) - -# Define the application target. To change its name, change BINARY_NAME in the -# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer -# work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} WIN32 - "flutter_window.cpp" - "main.cpp" - "utils.cpp" - "win32_window.cpp" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" - "Runner.rc" - "runner.exe.manifest" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add preprocessor definitions for the build version. -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") - -# Disable Windows macros that collide with C++ standard library functions. -target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") - -# Add dependency libraries and include directories. Add any application-specific -# dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) -target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") -target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/fastpair/rust/demo/windows/runner/Runner.rc b/fastpair/rust/demo/windows/runner/Runner.rc deleted file mode 100644 index 3c7cdc73aa..0000000000 --- a/fastpair/rust/demo/windows/runner/Runner.rc +++ /dev/null @@ -1,121 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APP_ICON ICON "resources\\app_icon.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) -#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD -#else -#define VERSION_AS_NUMBER 1,0,0,0 -#endif - -#if defined(FLUTTER_VERSION) -#define VERSION_AS_STRING FLUTTER_VERSION -#else -#define VERSION_AS_STRING "1.0.0" -#endif - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VERSION_AS_NUMBER - PRODUCTVERSION VERSION_AS_NUMBER - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", "com.example" "\0" - VALUE "FileDescription", "demo" "\0" - VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "demo" "\0" - VALUE "LegalCopyright", "Copyright (C) 2023 com.example. All rights reserved." "\0" - VALUE "OriginalFilename", "demo.exe" "\0" - VALUE "ProductName", "demo" "\0" - VALUE "ProductVersion", VERSION_AS_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/fastpair/rust/demo/windows/runner/flutter_window.cpp b/fastpair/rust/demo/windows/runner/flutter_window.cpp deleted file mode 100644 index 0f6bf6e464..0000000000 --- a/fastpair/rust/demo/windows/runner/flutter_window.cpp +++ /dev/null @@ -1,80 +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. - -#include "./flutter_window.h" - -#include - -#include "flutter/generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow(const flutter::DartProject& project) - : project_(project) {} - -FlutterWindow::~FlutterWindow() {} - -bool FlutterWindow::OnCreate() { - if (!Win32Window::OnCreate()) { - return false; - } - - RECT frame = GetClientArea(); - - // The size here must match the window dimensions to avoid unnecessary surface - // creation / destruction in the startup path. - flutter_controller_ = std::make_unique( - frame.right - frame.left, frame.bottom - frame.top, project_); - // Ensure that basic setup of the controller was successful. - if (!flutter_controller_->engine() || !flutter_controller_->view()) { - return false; - } - RegisterPlugins(flutter_controller_->engine()); - SetChildContent(flutter_controller_->view()->GetNativeWindow()); - - flutter_controller_->engine()->SetNextFrameCallback([&]() { - this->Show(); - }); - - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_controller_) { - flutter_controller_ = nullptr; - } - - Win32Window::OnDestroy(); -} - -LRESULT -FlutterWindow::MessageHandler(HWND hwnd, UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - // Give Flutter, including plugins, an opportunity to handle window messages. - if (flutter_controller_) { - std::optional result = - flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, - lparam); - if (result) { - return *result; - } - } - - switch (message) { - case WM_FONTCHANGE: - flutter_controller_->engine()->ReloadSystemFonts(); - break; - } - - return Win32Window::MessageHandler(hwnd, message, wparam, lparam); -} diff --git a/fastpair/rust/demo/windows/runner/flutter_window.h b/fastpair/rust/demo/windows/runner/flutter_window.h deleted file mode 100644 index adb318a08c..0000000000 --- a/fastpair/rust/demo/windows/runner/flutter_window.h +++ /dev/null @@ -1,47 +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. - -#ifndef RUNNER_FLUTTER_WINDOW_H_ -#define RUNNER_FLUTTER_WINDOW_H_ - -#include -#include - -#include - -#include "./win32_window.h" - -// A window that does nothing but host a Flutter view. -class FlutterWindow : public Win32Window { - public: - // Creates a new FlutterWindow hosting a Flutter view running |project|. - explicit FlutterWindow(const flutter::DartProject& project); - virtual ~FlutterWindow(); - - protected: - // Win32Window: - bool OnCreate() override; - void OnDestroy() override; - LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, - LPARAM const lparam) noexcept override; - - private: - // The project to run. - flutter::DartProject project_; - - // The Flutter instance hosted by this window. - std::unique_ptr flutter_controller_; -}; - -#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/fastpair/rust/demo/windows/runner/main.cpp b/fastpair/rust/demo/windows/runner/main.cpp deleted file mode 100644 index 2827bb3a65..0000000000 --- a/fastpair/rust/demo/windows/runner/main.cpp +++ /dev/null @@ -1,57 +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. - -#include -#include -#include - -#include "./flutter_window.h" -#include "./utils.h" - -int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, - _In_ wchar_t *command_line, _In_ int show_command) { - // Attach to console when present (e.g., 'flutter run') or create a - // new console when running with a debugger. - if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { - CreateAndAttachConsole(); - } - - // Initialize COM, so that it is available for use in the library and/or - // plugins. - ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - - flutter::DartProject project(L"data"); - - std::vector command_line_arguments = - GetCommandLineArguments(); - - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - FlutterWindow window(project); - Win32Window::Point origin(10, 10); - Win32Window::Size size(1280, 720); - if (!window.Create(L"demo", origin, size)) { - return EXIT_FAILURE; - } - window.SetQuitOnClose(true); - - ::MSG msg; - while (::GetMessage(&msg, nullptr, 0, 0)) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - ::CoUninitialize(); - return EXIT_SUCCESS; -} diff --git a/fastpair/rust/demo/windows/runner/resource.h b/fastpair/rust/demo/windows/runner/resource.h deleted file mode 100644 index 85a4c6ebcf..0000000000 --- a/fastpair/rust/demo/windows/runner/resource.h +++ /dev/null @@ -1,33 +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. - -// {{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Runner.rc -// -#ifndef RUNNER_RESOURCE_H_ -#define RUNNER_RESOURCE_H_ -#define IDI_APP_ICON 101 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif -#endif // RUNNER_RESOURCE_H_ diff --git a/fastpair/rust/demo/windows/runner/resources/app_icon.ico b/fastpair/rust/demo/windows/runner/resources/app_icon.ico deleted file mode 100644 index c04e20caf6370ebb9253ad831cc31de4a9c965f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33772 zcmeHQc|26z|35SKE&G-*mXah&B~fFkXr)DEO&hIfqby^T&>|8^_Ub8Vp#`BLl3lbZ zvPO!8k!2X>cg~Elr=IVxo~J*a`+9wR=A83c-k-DFd(XM&UI1VKCqM@V;DDtJ09WB} zRaHKiW(GT00brH|0EeTeKVbpbGZg?nK6-j827q-+NFM34gXjqWxJ*a#{b_apGN<-L_m3#8Z26atkEn& ze87Bvv^6vVmM+p+cQ~{u%=NJF>#(d;8{7Q{^rWKWNtf14H}>#&y7$lqmY6xmZryI& z($uy?c5-+cPnt2%)R&(KIWEXww>Cnz{OUpT>W$CbO$h1= z#4BPMkFG1Y)x}Ui+WXr?Z!w!t_hjRq8qTaWpu}FH{MsHlU{>;08goVLm{V<&`itk~ zE_Ys=D(hjiy+5=?=$HGii=Y5)jMe9|wWoD_K07(}edAxh`~LBorOJ!Cf@f{_gNCC| z%{*04ViE!#>@hc1t5bb+NO>ncf@@Dv01K!NxH$3Eg1%)|wLyMDF8^d44lV!_Sr}iEWefOaL z8f?ud3Q%Sen39u|%00W<#!E=-RpGa+H8}{ulxVl4mwpjaU+%2pzmi{3HM)%8vb*~-M9rPUAfGCSos8GUXp02|o~0BTV2l#`>>aFV&_P$ejS;nGwSVP8 zMbOaG7<7eKD>c12VdGH;?2@q7535sa7MN*L@&!m?L`ASG%boY7(&L5imY#EQ$KrBB z4@_tfP5m50(T--qv1BJcD&aiH#b-QC>8#7Fx@3yXlonJI#aEIi=8&ChiVpc#N=5le zM*?rDIdcpawoc5kizv$GEjnveyrp3sY>+5_R5;>`>erS%JolimF=A^EIsAK zsPoVyyUHCgf0aYr&alx`<)eb6Be$m&`JYSuBu=p8j%QlNNp$-5C{b4#RubPb|CAIS zGE=9OFLP7?Hgc{?k45)84biT0k&-C6C%Q}aI~q<(7BL`C#<6HyxaR%!dFx7*o^laG z=!GBF^cwK$IA(sn9y6>60Rw{mYRYkp%$jH z*xQM~+bp)G$_RhtFPYx2HTsWk80+p(uqv9@I9)y{b$7NK53rYL$ezbmRjdXS?V}fj zWxX_feWoLFNm3MG7pMUuFPs$qrQWO9!l2B(SIuy2}S|lHNbHzoE+M2|Zxhjq9+Ws8c{*}x^VAib7SbxJ*Q3EnY5lgI9 z=U^f3IW6T=TWaVj+2N%K3<%Un;CF(wUp`TC&Y|ZjyFu6co^uqDDB#EP?DV5v_dw~E zIRK*BoY9y-G_ToU2V_XCX4nJ32~`czdjT!zwme zGgJ0nOk3U4@IE5JwtM}pwimLjk{ln^*4HMU%Fl4~n(cnsLB}Ja-jUM>xIB%aY;Nq8 z)Fp8dv1tkqKanv<68o@cN|%thj$+f;zGSO7H#b+eMAV8xH$hLggtt?O?;oYEgbq@= zV(u9bbd12^%;?nyk6&$GPI%|+<_mEpJGNfl*`!KV;VfmZWw{n{rnZ51?}FDh8we_L z8OI9nE31skDqJ5Oa_ybn7|5@ui>aC`s34p4ZEu6-s!%{uU45$Zd1=p$^^dZBh zu<*pDDPLW+c>iWO$&Z_*{VSQKg7=YEpS3PssPn1U!lSm6eZIho*{@&20e4Y_lRklKDTUCKI%o4Pc<|G^Xgu$J^Q|B87U;`c1zGwf^-zH*VQ^x+i^OUWE0yd z;{FJq)2w!%`x7yg@>uGFFf-XJl4H`YtUG%0slGKOlXV`q?RP>AEWg#x!b{0RicxGhS!3$p7 zij;{gm!_u@D4$Ox%>>bPtLJ> zwKtYz?T_DR1jN>DkkfGU^<#6sGz|~p*I{y`aZ>^Di#TC|Z!7j_O1=Wo8thuit?WxR zh9_S>kw^{V^|g}HRUF=dcq>?q(pHxw!8rx4dC6vbQVmIhmICF#zU!HkHpQ>9S%Uo( zMw{eC+`&pb=GZRou|3;Po1}m46H6NGd$t<2mQh}kaK-WFfmj_66_17BX0|j-E2fe3Jat}ijpc53 zJV$$;PC<5aW`{*^Z6e5##^`Ed#a0nwJDT#Qq~^e8^JTA=z^Kl>La|(UQ!bI@#ge{Dzz@61p-I)kc2?ZxFt^QQ}f%ldLjO*GPj(5)V9IyuUakJX=~GnTgZ4$5!3E=V#t`yOG4U z(gphZB6u2zsj=qNFLYShhg$}lNpO`P9xOSnO*$@@UdMYES*{jJVj|9z-}F^riksLK zbsU+4-{281P9e2UjY6tse^&a)WM1MFw;p#_dHhWI7p&U*9TR0zKdVuQed%6{otTsq z$f~S!;wg#Bd9kez=Br{m|66Wv z#g1xMup<0)H;c2ZO6su_ii&m8j&+jJz4iKnGZ&wxoQX|5a>v&_e#6WA!MB_4asTxLRGQCC5cI(em z%$ZfeqP>!*q5kU>a+BO&ln=4Jm>Ef(QE8o&RgLkk%2}4Tf}U%IFP&uS7}&|Q-)`5< z+e>;s#4cJ-z%&-^&!xsYx777Wt(wZY9(3(avmr|gRe4cD+a8&!LY`1^T?7x{E<=kdY9NYw>A;FtTvQ=Y&1M%lyZPl$ss1oY^Sl8we}n}Aob#6 zl4jERwnt9BlSoWb@3HxYgga(752Vu6Y)k4yk9u~Kw>cA5&LHcrvn1Y-HoIuFWg~}4 zEw4bR`mXZQIyOAzo)FYqg?$5W<;^+XX%Uz61{-L6@eP|lLH%|w?g=rFc;OvEW;^qh z&iYXGhVt(G-q<+_j}CTbPS_=K>RKN0&;dubh0NxJyDOHFF;<1k!{k#7b{|Qok9hac z;gHz}6>H6C6RnB`Tt#oaSrX0p-j-oRJ;_WvS-qS--P*8}V943RT6kou-G=A+7QPGQ z!ze^UGxtW3FC0$|(lY9^L!Lx^?Q8cny(rR`es5U;-xBhphF%_WNu|aO<+e9%6LuZq zt(0PoagJG<%hyuf;te}n+qIl_Ej;czWdc{LX^pS>77s9t*2b4s5dvP_!L^3cwlc)E!(!kGrg~FescVT zZCLeua3f4;d;Tk4iXzt}g}O@nlK3?_o91_~@UMIl?@77Qc$IAlLE95#Z=TES>2E%z zxUKpK{_HvGF;5%Q7n&vA?`{%8ohlYT_?(3A$cZSi)MvIJygXD}TS-3UwyUxGLGiJP znblO~G|*uA^|ac8E-w#}uBtg|s_~s&t>-g0X%zIZ@;o_wNMr_;{KDg^O=rg`fhDZu zFp(VKd1Edj%F zWHPl+)FGj%J1BO3bOHVfH^3d1F{)*PL&sRX`~(-Zy3&9UQX)Z;c51tvaI2E*E7!)q zcz|{vpK7bjxix(k&6=OEIBJC!9lTkUbgg?4-yE{9+pFS)$Ar@vrIf`D0Bnsed(Cf? zObt2CJ>BKOl>q8PyFO6w)+6Iz`LW%T5^R`U_NIW0r1dWv6OY=TVF?N=EfA(k(~7VBW(S;Tu5m4Lg8emDG-(mOSSs=M9Q&N8jc^Y4&9RqIsk(yO_P(mcCr}rCs%1MW1VBrn=0-oQN(Xj!k%iKV zb%ricBF3G4S1;+8lzg5PbZ|$Se$)I=PwiK=cDpHYdov2QO1_a-*dL4KUi|g&oh>(* zq$<`dQ^fat`+VW?m)?_KLn&mp^-@d=&7yGDt<=XwZZC=1scwxO2^RRI7n@g-1o8ps z)&+et_~)vr8aIF1VY1Qrq~Xe``KJrQSnAZ{CSq3yP;V*JC;mmCT6oRLSs7=GA?@6g zUooM}@tKtx(^|aKK8vbaHlUQqwE0}>j&~YlN3H#vKGm@u)xxS?n9XrOWUfCRa< z`20Fld2f&;gg7zpo{Adh+mqNntMc-D$N^yWZAZRI+u1T1zWHPxk{+?vcS1D>08>@6 zLhE@`gt1Y9mAK6Z4p|u(5I%EkfU7rKFSM=E4?VG9tI;a*@?6!ey{lzN5=Y-!$WFSe z&2dtO>^0@V4WRc#L&P%R(?@KfSblMS+N+?xUN$u3K4Ys%OmEh+tq}fnU}i>6YHM?< zlnL2gl~sF!j!Y4E;j3eIU-lfa`RsOL*Tt<%EFC0gPzoHfNWAfKFIKZN8}w~(Yi~=q z>=VNLO2|CjkxP}RkutxjV#4fWYR1KNrPYq5ha9Wl+u>ipsk*I(HS@iLnmGH9MFlTU zaFZ*KSR0px>o+pL7BbhB2EC1%PJ{67_ z#kY&#O4@P=OV#-79y_W>Gv2dxL*@G7%LksNSqgId9v;2xJ zrh8uR!F-eU$NMx@S*+sk=C~Dxr9Qn7TfWnTupuHKuQ$;gGiBcU>GF5sWx(~4IP3`f zWE;YFO*?jGwYh%C3X<>RKHC-DZ!*r;cIr}GLOno^3U4tFSSoJp%oHPiSa%nh=Zgn% z14+8v@ygy0>UgEN1bczD6wK45%M>psM)y^)IfG*>3ItX|TzV*0i%@>L(VN!zdKb8S?Qf7BhjNpziA zR}?={-eu>9JDcl*R=OP9B8N$IcCETXah9SUDhr{yrld{G;PnCWRsPD7!eOOFBTWUQ=LrA_~)mFf&!zJX!Oc-_=kT<}m|K52 z)M=G#;p;Rdb@~h5D{q^K;^fX-m5V}L%!wVC2iZ1uu401Ll}#rocTeK|7FAeBRhNdQ zCc2d^aQnQp=MpOmak60N$OgS}a;p(l9CL`o4r(e-nN}mQ?M&isv-P&d$!8|1D1I(3-z!wi zTgoo)*Mv`gC?~bm?S|@}I|m-E2yqPEvYybiD5azInexpK8?9q*$9Yy9-t%5jU8~ym zgZDx>!@ujQ=|HJnwp^wv-FdD{RtzO9SnyfB{mH_(c!jHL*$>0o-(h(eqe*ZwF6Lvu z{7rkk%PEqaA>o+f{H02tzZ@TWy&su?VNw43! z-X+rN`6llvpUms3ZiSt)JMeztB~>9{J8SPmYs&qohxdYFi!ra8KR$35Zp9oR)eFC4 zE;P31#3V)n`w$fZ|4X-|%MX`xZDM~gJyl2W;O$H25*=+1S#%|53>|LyH za@yh+;325%Gq3;J&a)?%7X%t@WXcWL*BaaR*7UEZad4I8iDt7^R_Fd`XeUo256;sAo2F!HcIQKk;h})QxEsPE5BcKc7WyerTchgKmrfRX z!x#H_%cL#B9TWAqkA4I$R^8{%do3Y*&(;WFmJ zU7Dih{t1<{($VtJRl9|&EB?|cJ)xse!;}>6mSO$o5XIx@V|AA8ZcoD88ZM?C*;{|f zZVmf94_l1OmaICt`2sTyG!$^UeTHx9YuUP!omj(r|7zpm5475|yXI=rR>>fteLI+| z)MoiGho0oEt=*J(;?VY0QzwCqw@cVm?d7Y!z0A@u#H?sCJ*ecvyhj& z-F77lO;SH^dmf?L>3i>?Z*U}Em4ZYV_CjgfvzYsRZ+1B!Uo6H6mbS<-FFL`ytqvb& zE7+)2ahv-~dz(Hs+f})z{*4|{)b=2!RZK;PWwOnO=hG7xG`JU5>bAvUbdYd_CjvtHBHgtGdlO+s^9ca^Bv3`t@VRX2_AD$Ckg36OcQRF zXD6QtGfHdw*hx~V(MV-;;ZZF#dJ-piEF+s27z4X1qi5$!o~xBnvf=uopcn7ftfsZc zy@(PuOk`4GL_n(H9(E2)VUjqRCk9kR?w)v@xO6Jm_Mx})&WGEl=GS0#)0FAq^J*o! zAClhvoTsNP*-b~rN{8Yym3g{01}Ep^^Omf=SKqvN?{Q*C4HNNAcrowIa^mf+3PRy! z*_G-|3i8a;+q;iP@~Of_$(vtFkB8yOyWt2*K)vAn9El>=D;A$CEx6b*XF@4y_6M+2 zpeW`RHoI_p(B{%(&jTHI->hmNmZjHUj<@;7w0mx3&koy!2$@cfX{sN19Y}euYJFn& z1?)+?HCkD0MRI$~uB2UWri})0bru_B;klFdwsLc!ne4YUE;t41JqfG# zZJq6%vbsdx!wYeE<~?>o4V`A3?lN%MnKQ`z=uUivQN^vzJ|C;sdQ37Qn?;lpzg})y z)_2~rUdH}zNwX;Tp0tJ78+&I=IwOQ-fl30R79O8@?Ub8IIA(6I`yHn%lARVL`%b8+ z4$8D-|MZZWxc_)vu6@VZN!HsI$*2NOV&uMxBNzIbRgy%ob_ zhwEH{J9r$!dEix9XM7n&c{S(h>nGm?el;gaX0@|QnzFD@bne`el^CO$yXC?BDJ|Qg z+y$GRoR`?ST1z^e*>;!IS@5Ovb7*RlN>BV_UC!7E_F;N#ky%1J{+iixp(dUJj93aK zzHNN>R-oN7>kykHClPnoPTIj7zc6KM(Pnlb(|s??)SMb)4!sMHU^-ntJwY5Big7xv zb1Ew`Xj;|D2kzGja*C$eS44(d&RMU~c_Y14V9_TLTz0J#uHlsx`S6{nhsA0dWZ#cG zJ?`fO50E>*X4TQLv#nl%3GOk*UkAgt=IY+u0LNXqeln3Z zv$~&Li`ZJOKkFuS)dJRA>)b_Da%Q~axwA_8zNK{BH{#}#m}zGcuckz}riDE-z_Ms> zR8-EqAMcfyGJCtvTpaUVQtajhUS%c@Yj}&6Zz;-M7MZzqv3kA7{SuW$oW#=0az2wQ zg-WG@Vb4|D`pl~Il54N7Hmsauc_ne-a!o5#j3WaBBh@Wuefb!QJIOn5;d)%A#s+5% zuD$H=VNux9bE-}1&bcYGZ+>1Fo;3Z@e&zX^n!?JK*adSbONm$XW9z;Q^L>9U!}Toj2WdafJ%oL#h|yWWwyAGxzfrAWdDTtaKl zK4`5tDpPg5>z$MNv=X0LZ0d6l%D{(D8oT@+w0?ce$DZ6pv>{1&Ok67Ix1 zH}3=IEhPJEhItCC8E=`T`N5(k?G=B4+xzZ?<4!~ ze~z6Wk9!CHTI(0rLJ4{JU?E-puc;xusR?>G?;4vt;q~iI9=kDL=z0Rr%O$vU`30X$ zDZRFyZ`(omOy@u|i6h;wtJlP;+}$|Ak|k2dea7n?U1*$T!sXqqOjq^NxLPMmk~&qI zYg0W?yK8T(6+Ea+$YyspKK?kP$+B`~t3^Pib_`!6xCs32!i@pqXfFV6PmBIR<-QW= zN8L{pt0Vap0x`Gzn#E@zh@H)0FfVfA_Iu4fjYZ+umO1LXIbVc$pY+E234u)ttcrl$ z>s92z4vT%n6cMb>=XT6;l0+9e(|CZG)$@C7t7Z7Ez@a)h)!hyuV&B5K%%)P5?Lk|C zZZSVzdXp{@OXSP0hoU-gF8s8Um(#xzjP2Vem zec#-^JqTa&Y#QJ>-FBxd7tf`XB6e^JPUgagB8iBSEps;92KG`!#mvVcPQ5yNC-GEG zTiHEDYfH+0O15}r^+ z#jxj=@x8iNHWALe!P3R67TwmhItn**0JwnzSV2O&KE8KcT+0hWH^OPD1pwiuyx=b@ zNf5Jh0{9X)8;~Es)$t@%(3!OnbY+`@?i{mGX7Yy}8T_*0a6g;kaFPq;*=px5EhO{Cp%1kI<0?*|h8v!6WnO3cCJRF2-CRrU3JiLJnj@6;L)!0kWYAc_}F{2P))3HmCrz zQ&N&gE70;`!6*eJ4^1IR{f6j4(-l&X!tjHxkbHA^Zhrnhr9g{exN|xrS`5Pq=#Xf& zG%P=#ra-TyVFfgW%cZo5OSIwFL9WtXAlFOa+ubmI5t*3=g#Y zF%;70p5;{ZeFL}&}yOY1N1*Q;*<(kTB!7vM$QokF)yr2FlIU@$Ph58$Bz z0J?xQG=MlS4L6jA22eS42g|9*9pX@$#*sUeM(z+t?hr@r5J&D1rx}2pW&m*_`VDCW zUYY@v-;bAO0HqoAgbbiGGC<=ryf96}3pouhy3XJrX+!!u*O_>Si38V{uJmQ&USptX zKp#l(?>%^7;2%h(q@YWS#9;a!JhKlkR#Vd)ERILlgu!Hr@jA@V;sk4BJ-H#p*4EqC zDGjC*tl=@3Oi6)Bn^QwFpul18fpkbpg0+peH$xyPBqb%`$OUhPKyWb32o7clB*9Z< zN=i~NLjavrLtwgJ01bufP+>p-jR2I95|TpmKpQL2!oV>g(4RvS2pK4*ou%m(h6r3A zX#s&`9LU1ZG&;{CkOK!4fLDTnBys`M!vuz>Q&9OZ0hGQl!~!jSDg|~s*w52opC{sB ze|Cf2luD(*G13LcOAGA!s2FjSK8&IE5#W%J25w!vM0^VyQM!t)inj&RTiJ!wXzFgz z3^IqzB7I0L$llljsGq})thBy9UOyjtFO_*hYM_sgcMk>44jeH0V1FDyELc{S1F-;A zS;T^k^~4biG&V*Irq}O;e}j$$+E_#G?HKIn05iP3j|87TkGK~SqG!-KBg5+mN(aLm z8ybhIM`%C19UX$H$KY6JgXbY$0AT%rEpHC;u`rQ$Y=rxUdsc5*Kvc8jaYaO$^)cI6){P6K0r)I6DY4Wr4&B zLQUBraey#0HV|&c4v7PVo3n$zHj99(TZO^3?Ly%C4nYvJTL9eLBLHsM3WKKD>5!B` zQ=BsR3aR6PD(Fa>327E2HAu5TM~Wusc!)>~(gM)+3~m;92Jd;FnSib=M5d6;;5{%R zb4V7DEJ0V!CP-F*oU?gkc>ksUtAYP&V4ND5J>J2^jt*vcFflQWCrB&fLdT%O59PVJ zhid#toR=FNgD!q3&r8#wEBr`!wzvQu5zX?Q>nlSJ4i@WC*CN*-xU66F^V5crWevQ9gsq$I@z1o(a=k7LL~ z7m_~`o;_Ozha1$8Q}{WBehvAlO4EL60y5}8GDrZ< zXh&F}71JbW2A~8KfEWj&UWV#4+Z4p`b{uAj4&WC zha`}X@3~+Iz^WRlOHU&KngK>#j}+_o@LdBC1H-`gT+krWX3-;!)6?{FBp~%20a}FL zFP9%Emqcwa#(`=G>BBZ0qZDQhmZKJg_g8<=bBFKWr!dyg(YkpE+|R*SGpDVU!+VlU zFC54^DLv}`qa%49T>nNiA9Q7Ips#!Xx90tCU2gvK`(F+GPcL=J^>No{)~we#o@&mUb6c$ zCc*<|NJBk-#+{j9xkQ&ujB zI~`#kN~7W!f*-}wkG~Ld!JqZ@tK}eeSnsS5J1fMFXm|`LJx&}5`@dK3W^7#Wnm+_P zBZkp&j1fa2Y=eIjJ0}gh85jt43kaIXXv?xmo@eHrka!Z|vQv12HN#+!I5E z`(fbuW>gFiJL|uXJ!vKt#z3e3HlVdboH7;e#i3(2<)Fg-I@BR!qY#eof3MFZ&*Y@l zI|KJf&ge@p2Dq09Vu$$Qxb7!}{m-iRk@!)%KL)txi3;~Z4Pb}u@GsW;ELiWeG9V51 znX#}B&4Y2E7-H=OpNE@q{%hFLxwIpBF2t{vPREa8_{linXT;#1vMRWjOzLOP$-hf( z>=?$0;~~PnkqY;~K{EM6Vo-T(0K{A0}VUGmu*hR z{tw3hvBN%N3G3Yw`X5Te+F{J`(3w1s3-+1EbnFQKcrgrX1Jqvs@ADGe%M0s$EbK$$ zK)=y=upBc6SjGYAACCcI=Y*6Fi8_jgwZlLxD26fnQfJmb8^gHRN5(TemhX@0e=vr> zg`W}6U>x6VhoA3DqsGGD9uL1DhB3!OXO=k}59TqD@(0Nb{)Ut_luTioK_>7wjc!5C zIr@w}b`Fez3)0wQfKl&bae7;PcTA7%?f2xucM0G)wt_KO!Ewx>F~;=BI0j=Fb4>pp zv}0R^xM4eti~+^+gE$6b81p(kwzuDti(-K9bc|?+pJEl@H+jSYuxZQV8rl8 zjp@M{#%qItIUFN~KcO9Hed*`$5A-2~pAo~K&<-Q+`9`$CK>rzqAI4w~$F%vs9s{~x zg4BP%Gy*@m?;D6=SRX?888Q6peF@_4Z->8wAH~Cn!R$|Hhq2cIzFYqT_+cDourHbY z0qroxJnrZ4Gh+Ay+F`_c%+KRT>y3qw{)89?=hJ@=KO=@ep)aBJ$c!JHfBMJpsP*3G za7|)VJJ8B;4?n{~ldJF7%jmb`-ftIvNd~ekoufG(`K(3=LNc;HBY& z(lp#q8XAD#cIf}k49zX_i`*fO+#!zKA&%T3j@%)R+#yag067CU%yUEe47>wzGU8^` z1EXFT^@I!{J!F8!X?S6ph8J=gUi5tl93*W>7}_uR<2N2~e}FaG?}KPyugQ=-OGEZs z!GBoyYY+H*ANn4?Z)X4l+7H%`17i5~zRlRIX?t)6_eu=g2Q`3WBhxSUeea+M-S?RL zX9oBGKn%a!H+*hx4d2(I!gsi+@SQK%<{X22M~2tMulJoa)0*+z9=-YO+;DFEm5eE1U9b^B(Z}2^9!Qk`!A$wUE z7$Ar5?NRg2&G!AZqnmE64eh^Anss3i!{}%6@Et+4rr!=}!SBF8eZ2*J3ujCWbl;3; z48H~goPSv(8X61fKKdpP!Z7$88NL^Z?j`!^*I?-P4X^pMxyWz~@$(UeAcTSDd(`vO z{~rc;9|GfMJcApU3k}22a!&)k4{CU!e_ny^Y3cO;tOvOMKEyWz!vG(Kp*;hB?d|R3`2X~=5a6#^o5@qn?J-bI8Ppip{-yG z!k|VcGsq!jF~}7DMr49Wap-s&>o=U^T0!Lcy}!(bhtYsPQy z4|EJe{12QL#=c(suQ89Mhw9<`bui%nx7Nep`C&*M3~vMEACmcRYYRGtANq$F%zh&V zc)cEVeHz*Z1N)L7k-(k3np#{GcDh2Q@ya0YHl*n7fl*ZPAsbU-a94MYYtA#&!c`xGIaV;yzsmrjfieTEtqB_WgZp2*NplHx=$O{M~2#i_vJ{ps-NgK zQsxKK_CBM2PP_je+Xft`(vYfXXgIUr{=PA=7a8`2EHk)Ym2QKIforz# tySWtj{oF3N9@_;i*Fv5S)9x^z=nlWP>jpp-9)52ZmLVA=i*%6g{{fxOO~wEK diff --git a/fastpair/rust/demo/windows/runner/runner.exe.manifest b/fastpair/rust/demo/windows/runner/runner.exe.manifest deleted file mode 100644 index a42ea7687c..0000000000 --- a/fastpair/rust/demo/windows/runner/runner.exe.manifest +++ /dev/null @@ -1,20 +0,0 @@ - - - - - PerMonitorV2 - - - - - - - - - - - - - - - diff --git a/fastpair/rust/demo/windows/runner/utils.cpp b/fastpair/rust/demo/windows/runner/utils.cpp deleted file mode 100644 index 070097ecc0..0000000000 --- a/fastpair/rust/demo/windows/runner/utils.cpp +++ /dev/null @@ -1,79 +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. - -#include "./utils.h" - -#include -#include -#include -#include - -#include - -void CreateAndAttachConsole() { - if (::AllocConsole()) { - FILE *unused; - if (freopen_s(&unused, "CONOUT$", "w", stdout)) { - _dup2(_fileno(stdout), 1); - } - if (freopen_s(&unused, "CONOUT$", "w", stderr)) { - _dup2(_fileno(stdout), 2); - } - std::ios::sync_with_stdio(); - FlutterDesktopResyncOutputStreams(); - } -} - -std::vector GetCommandLineArguments() { - // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. - int argc; - wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); - if (argv == nullptr) { - return std::vector(); - } - - std::vector command_line_arguments; - - // Skip the first argument as it's the binary name. - for (int i = 1; i < argc; i++) { - command_line_arguments.push_back(Utf8FromUtf16(argv[i])); - } - - ::LocalFree(argv); - - return command_line_arguments; -} - -std::string Utf8FromUtf16(const wchar_t* utf16_string) { - if (utf16_string == nullptr) { - return std::string(); - } - int target_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, nullptr, 0, nullptr, nullptr) - -1; // remove the trailing null character - int input_length = (int)wcslen(utf16_string); - std::string utf8_string; - if (target_length <= 0 || target_length > utf8_string.max_size()) { - return utf8_string; - } - utf8_string.resize(target_length); - int converted_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - input_length, utf8_string.data(), target_length, nullptr, nullptr); - if (converted_length == 0) { - return std::string(); - } - return utf8_string; -} diff --git a/fastpair/rust/demo/windows/runner/utils.h b/fastpair/rust/demo/windows/runner/utils.h deleted file mode 100644 index b089ab5fa5..0000000000 --- a/fastpair/rust/demo/windows/runner/utils.h +++ /dev/null @@ -1,33 +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. - -#ifndef RUNNER_UTILS_H_ -#define RUNNER_UTILS_H_ - -#include -#include - -// Creates a console for the process, and redirects stdout and stderr to -// it for both the runner and the Flutter library. -void CreateAndAttachConsole(); - -// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string -// encoded in UTF-8. Returns an empty std::string on failure. -std::string Utf8FromUtf16(const wchar_t* utf16_string); - -// Gets the command line arguments passed in as a std::vector, -// encoded in UTF-8. Returns an empty std::vector on failure. -std::vector GetCommandLineArguments(); - -#endif // RUNNER_UTILS_H_ diff --git a/fastpair/rust/demo/windows/runner/win32_window.cpp b/fastpair/rust/demo/windows/runner/win32_window.cpp deleted file mode 100644 index b3c2fa35b5..0000000000 --- a/fastpair/rust/demo/windows/runner/win32_window.cpp +++ /dev/null @@ -1,303 +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. - -#include "./win32_window.h" - -#include -#include - -#include "./resource.h" - -namespace { - -/// Window attribute that enables dark mode window decorations. -/// -/// Redefined in case the developer's machine has a Windows SDK older than -/// version 10.0.22000.0. -/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute -#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE -#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 -#endif - -constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; - -/// Registry key for app theme preference. -/// -/// A value of 0 indicates apps should use dark mode. A non-zero or missing -/// value indicates apps should use light mode. -constexpr const wchar_t kGetPreferredBrightnessRegKey[] = - L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; -constexpr const wchar_t kGetPreferredBrightnessRegValue[] = - L"AppsUseLightTheme"; - -// The number of Win32Window objects that currently exist. -static int g_active_window_count = 0; - -using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); - -// Scale helper to convert logical scaler values to physical using passed in -// scale factor -int Scale(int source, double scale_factor) { - return static_cast(source * scale_factor); -} - -// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. -// This API is only needed for PerMonitor V1 awareness mode. -void EnableFullDpiSupportIfAvailable(HWND hwnd) { - HMODULE user32_module = LoadLibraryA("User32.dll"); - if (!user32_module) { - return; - } - auto enable_non_client_dpi_scaling = - reinterpret_cast( - GetProcAddress(user32_module, "EnableNonClientDpiScaling")); - if (enable_non_client_dpi_scaling != nullptr) { - enable_non_client_dpi_scaling(hwnd); - } - FreeLibrary(user32_module); -} - -} // namespace - -// Manages the Win32Window's window class registration. -class WindowClassRegistrar { - public: - ~WindowClassRegistrar() = default; - - // Returns the singleton registrar instance. - static WindowClassRegistrar* GetInstance() { - if (!instance_) { - instance_ = new WindowClassRegistrar(); - } - return instance_; - } - - // Returns the name of the window class, registering the class if it hasn't - // previously been registered. - const wchar_t* GetWindowClass(); - - // Unregisters the window class. Should only be called if there are no - // instances of the window. - void UnregisterWindowClass(); - - private: - WindowClassRegistrar() = default; - - static WindowClassRegistrar* instance_; - - bool class_registered_ = false; -}; - -WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; - -const wchar_t* WindowClassRegistrar::GetWindowClass() { - if (!class_registered_) { - WNDCLASS window_class{}; - window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); - window_class.lpszClassName = kWindowClassName; - window_class.style = CS_HREDRAW | CS_VREDRAW; - window_class.cbClsExtra = 0; - window_class.cbWndExtra = 0; - window_class.hInstance = GetModuleHandle(nullptr); - window_class.hIcon = - LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); - window_class.hbrBackground = 0; - window_class.lpszMenuName = nullptr; - window_class.lpfnWndProc = Win32Window::WndProc; - RegisterClass(&window_class); - class_registered_ = true; - } - return kWindowClassName; -} - -void WindowClassRegistrar::UnregisterWindowClass() { - UnregisterClass(kWindowClassName, nullptr); - class_registered_ = false; -} - -Win32Window::Win32Window() { - ++g_active_window_count; -} - -Win32Window::~Win32Window() { - --g_active_window_count; - Destroy(); -} - -bool Win32Window::Create(const std::wstring& title, - const Point& origin, - const Size& size) { - Destroy(); - - const wchar_t* window_class = - WindowClassRegistrar::GetInstance()->GetWindowClass(); - - const POINT target_point = {static_cast(origin.x), - static_cast(origin.y)}; - HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); - UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); - double scale_factor = dpi / 96.0; - - HWND window = CreateWindow( - window_class, title.c_str(), WS_OVERLAPPEDWINDOW, - Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), - Scale(size.width, scale_factor), Scale(size.height, scale_factor), - nullptr, nullptr, GetModuleHandle(nullptr), this); - - if (!window) { - return false; - } - - UpdateTheme(window); - - return OnCreate(); -} - -bool Win32Window::Show() { - return ShowWindow(window_handle_, SW_SHOWNORMAL); -} - -// static -LRESULT CALLBACK Win32Window::WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - if (message == WM_NCCREATE) { - auto window_struct = reinterpret_cast(lparam); - SetWindowLongPtr(window, GWLP_USERDATA, - reinterpret_cast(window_struct->lpCreateParams)); - - auto that = static_cast(window_struct->lpCreateParams); - EnableFullDpiSupportIfAvailable(window); - that->window_handle_ = window; - } else if (Win32Window* that = GetThisFromHandle(window)) { - return that->MessageHandler(window, message, wparam, lparam); - } - - return DefWindowProc(window, message, wparam, lparam); -} - -LRESULT -Win32Window::MessageHandler(HWND hwnd, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - switch (message) { - case WM_DESTROY: - window_handle_ = nullptr; - Destroy(); - if (quit_on_close_) { - PostQuitMessage(0); - } - return 0; - - case WM_DPICHANGED: { - auto newRectSize = reinterpret_cast(lparam); - LONG newWidth = newRectSize->right - newRectSize->left; - LONG newHeight = newRectSize->bottom - newRectSize->top; - - SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, - newHeight, SWP_NOZORDER | SWP_NOACTIVATE); - - return 0; - } - case WM_SIZE: { - RECT rect = GetClientArea(); - if (child_content_ != nullptr) { - // Size and position the child window. - MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, TRUE); - } - return 0; - } - - case WM_ACTIVATE: - if (child_content_ != nullptr) { - SetFocus(child_content_); - } - return 0; - - case WM_DWMCOLORIZATIONCOLORCHANGED: - UpdateTheme(hwnd); - return 0; - } - - return DefWindowProc(window_handle_, message, wparam, lparam); -} - -void Win32Window::Destroy() { - OnDestroy(); - - if (window_handle_) { - DestroyWindow(window_handle_); - window_handle_ = nullptr; - } - if (g_active_window_count == 0) { - WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); - } -} - -Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { - return reinterpret_cast( - GetWindowLongPtr(window, GWLP_USERDATA)); -} - -void Win32Window::SetChildContent(HWND content) { - child_content_ = content; - SetParent(content, window_handle_); - RECT frame = GetClientArea(); - - MoveWindow(content, frame.left, frame.top, frame.right - frame.left, - frame.bottom - frame.top, true); - - SetFocus(child_content_); -} - -RECT Win32Window::GetClientArea() { - RECT frame; - GetClientRect(window_handle_, &frame); - return frame; -} - -HWND Win32Window::GetHandle() { - return window_handle_; -} - -void Win32Window::SetQuitOnClose(bool quit_on_close) { - quit_on_close_ = quit_on_close; -} - -bool Win32Window::OnCreate() { - // No-op; provided for subclasses. - return true; -} - -void Win32Window::OnDestroy() { - // No-op; provided for subclasses. -} - -void Win32Window::UpdateTheme(HWND const window) { - DWORD light_mode; - DWORD light_mode_size = sizeof(light_mode); - LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, - kGetPreferredBrightnessRegValue, - RRF_RT_REG_DWORD, nullptr, &light_mode, - &light_mode_size); - - if (result == ERROR_SUCCESS) { - BOOL enable_dark_mode = light_mode == 0; - DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, - &enable_dark_mode, sizeof(enable_dark_mode)); - } -} diff --git a/fastpair/rust/demo/windows/runner/win32_window.h b/fastpair/rust/demo/windows/runner/win32_window.h deleted file mode 100644 index 0597809cdf..0000000000 --- a/fastpair/rust/demo/windows/runner/win32_window.h +++ /dev/null @@ -1,116 +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. - -#ifndef RUNNER_WIN32_WINDOW_H_ -#define RUNNER_WIN32_WINDOW_H_ - -#include - -#include -#include -#include - -// A class abstraction for a high DPI-aware Win32 Window. Intended to be -// inherited from by classes that wish to specialize with custom -// rendering and input handling -class Win32Window { - public: - struct Point { - unsigned int x; - unsigned int y; - Point(unsigned int x, unsigned int y) : x(x), y(y) {} - }; - - struct Size { - unsigned int width; - unsigned int height; - Size(unsigned int width, unsigned int height) - : width(width), height(height) {} - }; - - Win32Window(); - virtual ~Win32Window(); - - // Creates a win32 window with |title| that is positioned and sized using - // |origin| and |size|. New windows are created on the default monitor. Window - // sizes are specified to the OS in physical pixels, hence to ensure a - // consistent size this function will scale the inputted width and height as - // as appropriate for the default monitor. The window is invisible until - // |Show| is called. Returns true if the window was created successfully. - bool Create(const std::wstring& title, const Point& origin, const Size& size); - - // Show the current window. Returns true if the window was successfully shown. - bool Show(); - - // Release OS resources associated with window. - void Destroy(); - - // Inserts |content| into the window tree. - void SetChildContent(HWND content); - - // Returns the backing Window handle to enable clients to set icon and other - // window properties. Returns nullptr if the window has been destroyed. - HWND GetHandle(); - - // If true, closing this window will quit the application. - void SetQuitOnClose(bool quit_on_close); - - // Return a RECT representing the bounds of the current client area. - RECT GetClientArea(); - - protected: - // Processes and route salient window messages for mouse handling, - // size change and DPI. Delegates handling of these to member overloads that - // inheriting classes can handle. - virtual LRESULT MessageHandler(HWND window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Called when CreateAndShow is called, allowing subclass window-related - // setup. Subclasses should return false if setup fails. - virtual bool OnCreate(); - - // Called when Destroy is called. - virtual void OnDestroy(); - - private: - friend class WindowClassRegistrar; - - // OS callback called by message pump. Handles the WM_NCCREATE message which - // is passed when the non-client area is being created and enables automatic - // non-client DPI scaling so that the non-client area automatically - // responds to changes in DPI. All other messages are handled by - // MessageHandler. - static LRESULT CALLBACK WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Retrieves a class instance pointer for |window| - static Win32Window* GetThisFromHandle(HWND const window) noexcept; - - // Update the window frame's theme to match the system theme. - static void UpdateTheme(HWND const window); - - bool quit_on_close_ = false; - - // window handle for top level window. - HWND window_handle_ = nullptr; - - // window handle for hosted content. - HWND child_content_ = nullptr; -}; - -#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/fastpair/rust/demo/windows/rust.cmake b/fastpair/rust/demo/windows/rust.cmake deleted file mode 100644 index 74a7bf9be0..0000000000 --- a/fastpair/rust/demo/windows/rust.cmake +++ /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. - -# We include Corrosion inline here, but ideally in a project with -# many dependencies we would need to install Corrosion on the system. -# See instructions on https://github.com/AndrewGaspar/corrosion#cmake-install -# Once done, uncomment this line: -# find_package(Corrosion REQUIRED) - -include(FetchContent) - -FetchContent_Declare( - Corrosion - GIT_REPOSITORY https://github.com/AndrewGaspar/corrosion.git - GIT_TAG origin/master # Optionally specify a version tag or branch here -) - -FetchContent_MakeAvailable(Corrosion) - -corrosion_import_crate(MANIFEST_PATH ../rust/Cargo.toml IMPORTED_CRATES imported_crates) -target_link_libraries(${BINARY_NAME} PRIVATE ${imported_crates}) -foreach(imported_crate ${imported_crates}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) -endforeach() \ No newline at end of file diff --git a/fastpair/scanning/BUILD b/fastpair/scanning/BUILD deleted file mode 100644 index c4b3588792..0000000000 --- a/fastpair/scanning/BUILD +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2022 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. - -licenses(["notice"]) - -cc_library( - name = "scanner", - srcs = [ - "scanner_broker_impl.cc", - ], - hdrs = [ - "scanner_broker.h", - "scanner_broker_impl.h", - ], - visibility = [ - "//:__subpackages__", - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//fastpair/internal/mediums", - "//fastpair/repository:device_repository", - "//fastpair/scanning/fastpair:scanning", - "//internal/base", - "//internal/platform:types", - "@com_google_absl//absl/functional:bind_front", - ], -) - -cc_library( - name = "mocks", - testonly = 1, - hdrs = [ - "mock_scanner_broker.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":scanner", - "//fastpair/common", - "//internal/base", - "@com_google_googletest//:gtest_for_library_testonly", - ], -) - -cc_test( - name = "scanner_broker_impl_test", - size = "small", - srcs = [ - "scanner_broker_impl_test.cc", - ], - shard_count = 16, - deps = [ - ":scanner", - "//fastpair/common", - "//fastpair/internal/mediums", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/repository:device_repository", - "//fastpair/repository:test_support", - "//fastpair/testing", - "//internal/platform:base", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/scanning/fastpair/BUILD b/fastpair/scanning/fastpair/BUILD deleted file mode 100644 index f70cd686ea..0000000000 --- a/fastpair/scanning/fastpair/BUILD +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright 2022 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. - -licenses(["notice"]) - -cc_library( - name = "scanning", - srcs = [ - "fast_pair_discoverable_scanner.cc", - "fast_pair_non_discoverable_scanner.cc", - "fast_pair_scanner_impl.cc", - ], - hdrs = [ - "fast_pair_discoverable_scanner.h", - "fast_pair_non_discoverable_scanner.h", - "fast_pair_scanner.h", - "fast_pair_scanner_impl.h", - ], - visibility = [ - "//:__subpackages__", - "//fastpair/scanning:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//fastpair/dataparser", - "//fastpair/internal/mediums", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/repository", - "//fastpair/repository:device_repository", - "//internal/base", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:types", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/functional:bind_front", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - ], -) - -cc_library( - name = "test_support", - srcs = [ - "fake_fast_pair_scanner.cc", - ], - hdrs = [ - "fake_fast_pair_scanner.h", - ], - visibility = [ - "//fastpair/scanning:__subpackages__", - ], - deps = [ - ":scanning", - "//fastpair/common", - "//internal/base", - "@com_google_absl//absl/functional:any_invocable", - ], -) - -cc_test( - name = "fast_pair_scanner_impl_test", - size = "small", - srcs = [ - "fast_pair_scanner_impl_test.cc", - ], - shard_count = 16, - deps = [ - ":scanning", - "//fastpair/common", - "//fastpair/internal/mediums", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_discoverable_scanner_test", - size = "small", - srcs = [ - "fast_pair_discoverable_scanner_test.cc", - ], - shard_count = 16, - deps = [ - ":scanning", - ":test_support", - "//fastpair/repository:device_repository", - "//fastpair/repository:test_support", - "//fastpair/testing", - "//internal/platform:comm", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/synchronization", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_non_discoverable_scanner_test", - size = "small", - srcs = [ - "fast_pair_non_discoverable_scanner_test.cc", - ], - shard_count = 16, - deps = [ - ":scanning", - ":test_support", - "//fastpair/common", - "//fastpair/repository:test_support", - "//fastpair/testing", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/scanning/fastpair/fake_fast_pair_scanner.cc b/fastpair/scanning/fastpair/fake_fast_pair_scanner.cc deleted file mode 100644 index 1c5eae58e1..0000000000 --- a/fastpair/scanning/fastpair/fake_fast_pair_scanner.cc +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/scanning/fastpair/fake_fast_pair_scanner.h" - -namespace nearby { -namespace fastpair { - -void FakeFastPairScanner::AddObserver(Observer* observer) { - observer_.AddObserver(observer); -} - -void FakeFastPairScanner::RemoveObserver(Observer* observer) { - observer_.RemoveObserver(observer); -} - -void FakeFastPairScanner::NotifyDeviceFound(const BlePeripheral& peripheral) { - for (auto& obs : observer_.GetObservers()) obs->OnDeviceFound(peripheral); -} - -void FakeFastPairScanner::NotifyDeviceLost(const BlePeripheral& peripheral) { - for (auto& obs : observer_.GetObservers()) obs->OnDeviceLost(peripheral); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/scanning/fastpair/fake_fast_pair_scanner.h b/fastpair/scanning/fastpair/fake_fast_pair_scanner.h deleted file mode 100644 index c6f5f666a0..0000000000 --- a/fastpair/scanning/fastpair/fake_fast_pair_scanner.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAKE_FAST_PAIR_SCANNER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAKE_FAST_PAIR_SCANNER_H_ - -#include - -#include "fastpair/scanning/fastpair/fast_pair_scanner.h" -#include "internal/base/observer_list.h" - -namespace nearby { -namespace fastpair { - -class FakeFastPairScanner final : public FastPairScanner { - public: - FakeFastPairScanner() = default; - FakeFastPairScanner(const FakeFastPairScanner&) = delete; - FakeFastPairScanner& operator=(const FakeFastPairScanner&) = delete; - ~FakeFastPairScanner() override = default; - - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; - void NotifyDeviceFound(const BlePeripheral& peripheral); - void NotifyDeviceLost(const BlePeripheral& peripheral); - std::unique_ptr StartScanning() override { - return std::make_unique(); - }; - - private: - ObserverList observer_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAKE_FAST_PAIR_SCANNER_H_ diff --git a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner.cc b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner.cc deleted file mode 100644 index 5206bf93d2..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner.cc +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "absl/functional/bind_front.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/protocol.h" -#include "fastpair/dataparser/fast_pair_data_parser.h" -#include "fastpair/proto/fastpair_rpcs.pb.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr char kNearbyShareModelId[] = "fc128e"; - -bool IsValidDeviceType(const proto::Device& device) { - return device.device_type() == proto::DeviceType::HEADPHONES || - device.device_type() == proto::DeviceType::SPEAKER || - device.device_type() == proto::DeviceType::TRUE_WIRELESS_HEADPHONES || - device.device_type() == proto::DeviceType::DEVICE_TYPE_UNSPECIFIED; -} - -bool IsSupportedNotificationType(const proto::Device& device) { - // We only allow-list notification types that should trigger a pairing - // notification, since we currently only support pairing. We include - // NOTIFICATION_TYPE_UNSPECIFIED to handle the case where a Provider is - // advertising incorrectly and conservatively allow it to show a notification, - // matching Android behavior. - return device.notification_type() == - proto::NotificationType::NOTIFICATION_TYPE_UNSPECIFIED || - device.notification_type() == proto::NotificationType::FAST_PAIR || - device.notification_type() == proto::NotificationType::FAST_PAIR_ONE; -} -} // namespace - -// FastPairScannerImpl::Factory -FastPairDiscoverableScanner::Factory* - FastPairDiscoverableScanner::Factory::g_test_factory_ = nullptr; - -std::unique_ptr -FastPairDiscoverableScanner::Factory::Create( - FastPairScanner& scanner, DiscoverableScannerCallback found_callback, - DiscoverableScannerCallback lost_callback, SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository) { - if (g_test_factory_) { - return g_test_factory_->CreateInstance(scanner, std::move(found_callback), - std::move(lost_callback), executor, - device_repository); - } - - return std::make_unique( - scanner, std::move(found_callback), std::move(lost_callback), executor, - device_repository); -} - -void FastPairDiscoverableScanner::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -FastPairDiscoverableScanner::Factory::~Factory() = default; - -// FastPairScannerImpl -FastPairDiscoverableScanner::FastPairDiscoverableScanner( - FastPairScanner& scanner, DiscoverableScannerCallback found_callback, - DiscoverableScannerCallback lost_callback, SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository) - : scanner_(scanner), - found_callback_(std::move(found_callback)), - lost_callback_(std::move(lost_callback)), - executor_(executor), - device_repository_(device_repository) { - scanner_.AddObserver(this); -} - -FastPairDiscoverableScanner::~FastPairDiscoverableScanner() { - scanner_.RemoveObserver(this); -} - -void FastPairDiscoverableScanner::OnDeviceFound( - const BlePeripheral& peripheral) { - std::string fast_pair_service_data = - peripheral.GetAdvertisementBytes(kServiceId).string_data(); - if (fast_pair_service_data.empty()) { - NEARBY_LOGS(WARNING) << __func__ - << ": Device doesn't have any Fast Pair Service Data."; - return; - } - executor_->Execute( - "device-found", - [this, fast_pair_service_data = std::move(fast_pair_service_data), - address = peripheral.GetName()]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NEARBY_LOGS(INFO) << __func__ << ": Attempting to get model ID"; - std::vector service_data; - std::move(std::begin(fast_pair_service_data), - std::end(fast_pair_service_data), - std::back_inserter(service_data)); - - // TODO(jsobczak): GetHexModelIdFromServiceData() callback is - // synchronous. It would be simpler if - // GetHexModelIdFromServiceData() used return value rather than a - // callback. - FastPairDataParser::GetHexModelIdFromServiceData( - service_data, {[&](std::optional model_id) { - OnModelIdRetrieved(address, model_id); - }}); - }); -} - -void FastPairDiscoverableScanner::OnModelIdRetrieved( - const std::string& address, - const std::optional model_id) { - if (!model_id.has_value()) { - NEARBY_LOGS(INFO) << __func__ - << ": Returning early because no model id was parsed."; - return; - } - - // The Nearby Share feature advertises under the Fast Pair Service Data UUID - // and uses a reserved model ID to enable their 'fast initiation' scenario. - // We must detect this instance and ignore these advertisements since they - // do not correspond to Fast Pair devices that are open to pairing. - if (model_id.value().compare(kNearbyShareModelId) == 0) { - NEARBY_LOGS(WARNING) << __func__ << ": Ignore Nearby Share Model ID."; - return; - } - - NEARBY_LOGS(INFO) << __func__ << ": Attempting to get device metadata."; - FastPairRepository::Get()->GetDeviceMetadata( - model_id.value(), - absl::bind_front(&FastPairDiscoverableScanner::OnDeviceMetadataRetrieved, - this, address, std::string(model_id.value()))); -} - -void FastPairDiscoverableScanner::OnDeviceMetadataRetrieved( - const std::string address, const std::string model_id, - std::optional device_metadata) { - if (!device_metadata.has_value()) { - NEARBY_LOGS(WARNING) << __func__ << ": Failed to get device metadata"; - return; - } - // Ignore advertisements that aren't for Fast Pair but leverage the service - // UUID. - if (!IsValidDeviceType(device_metadata->GetDetails())) { - NEARBY_LOGS(WARNING) - << __func__ - << ": Invalid device type for Fast Pair. Ignoring this advertisement"; - return; - } - - // Ignore advertisements for unsupported notification types, such as - // APP_LAUNCH which should launch a companion app instead of beginning Fast - // Pair. - if (!IsSupportedNotificationType(device_metadata->GetDetails())) { - NEARBY_LOGS(WARNING) << __func__ - << ": Unsupported notification type for Fast Pair. " - "Ignoring this advertisement"; - return; - } - auto fast_pair_device = std::make_unique( - model_id, address, Protocol::kFastPairInitialPairing); - fast_pair_device->SetMetadata(device_metadata.value()); - - executor_->Execute( - "add-device", - [this, fast_pair_device = std::move(fast_pair_device)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - FastPairDevice* device = - device_repository_->AddDevice(std::move(fast_pair_device)); - NotifyDeviceFound(*device); - }); -} - -void FastPairDiscoverableScanner::NotifyDeviceFound(FastPairDevice& device) { - NEARBY_LOGS(VERBOSE) << "Notify Device found:" - << "BluetoothAddress = " << device.GetBleAddress() - << ", Model id = " << device.GetModelId(); - { - MutexLock lock(&mutex_); - notified_devices_[device.GetBleAddress()] = &device; - } - found_callback_(device); -} - -void FastPairDiscoverableScanner::OnDeviceLost( - const BlePeripheral& peripheral) { - NEARBY_LOGS(INFO) << __func__ << ": Running lost callback"; - { - MutexLock lock(&mutex_); - auto node = notified_devices_.extract(peripheral.GetName()); - // Don't invoke callback if we didn't notify this device. - if (node.empty()) return; - } - executor_->Execute("device-lost", - [this, address = peripheral.GetName()]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - auto opt_device = - device_repository_->FindDevice(address); - if (!opt_device.has_value()) return; - FastPairDevice* device = opt_device.value(); - lost_callback_(*device); - device_repository_->RemoveDevice(device); - }); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h deleted file mode 100644 index 6960613699..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_H_ - -#include -#include -#include -#include - -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/scanning/fastpair/fast_pair_scanner.h" -#include "internal/base/observer_list.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/mutex.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { -using DiscoverableScannerCallback = - absl::AnyInvocable; -// This class detects Fast Pair 'discoverable' advertisements (see -// https://developers.google.com/nearby/fast-pair/spec#AdvertisingWhenDiscoverable) -// and invokes the |found_callback| when it finds a device within the -// appropriate range. |lost_callback| will be invoked when that device is lost -// to the bluetooth adapter. -class FastPairDiscoverableScanner : public FastPairScanner::Observer { - public: - class Factory { - public: - static std::unique_ptr Create( - FastPairScanner& scanner, DiscoverableScannerCallback found_callback, - DiscoverableScannerCallback lost_callback, - SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository); - - static void SetFactoryForTesting(Factory* g_test_factory); - - protected: - virtual ~Factory(); - virtual std::unique_ptr CreateInstance( - FastPairScanner& scanner, DiscoverableScannerCallback found_callback, - DiscoverableScannerCallback lost_callback, - SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository) = 0; - - private: - static Factory* g_test_factory_; - }; - - FastPairDiscoverableScanner(FastPairScanner& scanner, - DiscoverableScannerCallback found_callback, - DiscoverableScannerCallback lost_callback, - SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository); - FastPairDiscoverableScanner(const FastPairDiscoverableScanner&) = delete; - FastPairDiscoverableScanner& operator=(const FastPairDiscoverableScanner&) = - delete; - ~FastPairDiscoverableScanner(); - - // FastPairScanner::Observer - void OnDeviceFound(const BlePeripheral& peripheral) override; - void OnDeviceLost(const BlePeripheral& peripheral) override; - - private: - void OnModelIdRetrieved(const std::string& address, - std::optional model_id); - void OnDeviceMetadataRetrieved(std::string address, std::string model_id, - std::optional device_metadata); - void NotifyDeviceFound(FastPairDevice& device) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - - Mutex mutex_; - FastPairScanner& scanner_; - DiscoverableScannerCallback found_callback_ ABSL_GUARDED_BY(*executor_); - DiscoverableScannerCallback lost_callback_ ABSL_GUARDED_BY(*executor_); - SingleThreadExecutor* executor_; - absl::flat_hash_map notified_devices_ - ABSL_GUARDED_BY(mutex_); - FastPairDeviceRepository* device_repository_ ABSL_GUARDED_BY(*executor_); - ObserverList observer_list_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_H_ diff --git a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_test.cc b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_test.cc deleted file mode 100644 index f487e463fb..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_test.cc +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h" - -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/synchronization/notification.h" -#include "fastpair/repository/fake_fast_pair_repository.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/scanning/fastpair/fake_fast_pair_scanner.h" -#include "fastpair/testing/fast_pair_service_data_creator.h" -#include "internal/platform/bluetooth_adapter.h" - -namespace nearby { -namespace fastpair { -namespace { - -constexpr absl::Duration kWaitTimeout = absl::Milliseconds(200); -constexpr char kValidModelId[] = "718c17"; -constexpr char kInvalidModelId[] = "12345"; -constexpr char kNearbyShareModelId[] = "fc128e"; -constexpr char kTestBleDeviceAddress[] = "11:12:13:14:15:16"; - -class FakeBlePeripheral : public api::BlePeripheral { - public: - explicit FakeBlePeripheral(absl::string_view name, - absl::string_view model_id) { - name_ = std::string(name); - const std::vector service_data = - FastPairServiceDataCreator::Builder() - .SetModelId(model_id) - .Build() - ->CreateServiceData(); - ByteArray advertisement_bytes( - std::string(service_data.begin(), service_data.end())); - advertisement_data_ = advertisement_bytes; - } - - FakeBlePeripheral(const FakeBlePeripheral&) = default; - ~FakeBlePeripheral() override = default; - - std::string GetName() const override { return name_; } - - ByteArray GetAdvertisementBytes( - const std::string& service_id) const override { - return advertisement_data_; - } - - void SetName(const std::string& name) { name_ = name; } - - void SetAdvertisementBytes(ByteArray advertisement_bytes) { - advertisement_data_ = advertisement_bytes; - } - - private: - std::string name_; - ByteArray advertisement_data_; -}; - -class FastPairDiscoverableScannerTest : public ::testing::Test { - protected: - void TearDown() override { executor_.Shutdown(); } - - SingleThreadExecutor executor_; - FastPairDeviceRepository devices_{&executor_}; - std::unique_ptr scanner_; - std::unique_ptr discoverable_scanner_; -}; - -TEST_F(FastPairDiscoverableScannerTest, ValidModelId) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::TRUE_WIRELESS_HEADPHONES); - repository->SetFakeMetadata(kValidModelId, metadata); - absl::Notification found_notification; - absl::Notification lost_notification; - - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = - std::make_unique(kTestBleDeviceAddress, kValidModelId); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - found_notification.WaitForNotification(); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - lost_notification.WaitForNotification(); -} - -TEST_F(FastPairDiscoverableScannerTest, InvalidModelId) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::TRUE_WIRELESS_HEADPHONES); - repository->SetFakeMetadata(kValidModelId, metadata); - absl::Notification found_notification; - absl::Notification lost_notification; - - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = std::make_unique( - kTestBleDeviceAddress, kInvalidModelId); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(lost_notification.WaitForNotificationWithTimeout(kWaitTimeout)); -} - -TEST_F(FastPairDiscoverableScannerTest, NoServiceData) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::TRUE_WIRELESS_HEADPHONES); - repository->SetFakeMetadata(kValidModelId, metadata); - absl::Notification found_notification; - absl::Notification lost_notification; - - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = - std::make_unique(kTestBleDeviceAddress, ""); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(lost_notification.WaitForNotificationWithTimeout(kWaitTimeout)); -} - -TEST_F(FastPairDiscoverableScannerTest, UnsupportedDeviceType) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::AUTOMOTIVE); - repository->SetFakeMetadata(kValidModelId, metadata); - - absl::Notification found_notification; - absl::Notification lost_notification; - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = - std::make_unique(kTestBleDeviceAddress, kValidModelId); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(lost_notification.WaitForNotificationWithTimeout(kWaitTimeout)); -} - -TEST_F(FastPairDiscoverableScannerTest, UnsupportedNotifictionType) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::HEADPHONES); - metadata.set_notification_type(proto::NotificationType::APP_LAUNCH); - repository->SetFakeMetadata(kValidModelId, metadata); - - absl::Notification found_notification; - absl::Notification lost_notification; - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = - std::make_unique(kTestBleDeviceAddress, kValidModelId); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(lost_notification.WaitForNotificationWithTimeout(kWaitTimeout)); -} - -TEST_F(FastPairDiscoverableScannerTest, UnspecifiedNotificationType) { - scanner_ = std::make_unique(); - // Set metadata to mimic a device that doesn't specify the notification - // or device type. Since we aren't sure what this device is, we'll show - // the notification to be safe. - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::DEVICE_TYPE_UNSPECIFIED); - metadata.set_notification_type( - proto::NotificationType::NOTIFICATION_TYPE_UNSPECIFIED); - repository->SetFakeMetadata(kValidModelId, metadata); - - absl::Notification found_notification; - absl::Notification lost_notification; - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = - std::make_unique(kTestBleDeviceAddress, kValidModelId); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - found_notification.WaitForNotification(); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - lost_notification.WaitForNotification(); -} - -TEST_F(FastPairDiscoverableScannerTest, V1NotificationType) { - scanner_ = std::make_unique(); - // Set metadata to mimic a V1 device which advertises with no device - // type and a notification type of FAST_PAIR_ONE. - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::DEVICE_TYPE_UNSPECIFIED); - metadata.set_notification_type(proto::NotificationType::FAST_PAIR_ONE); - repository->SetFakeMetadata(kValidModelId, metadata); - - absl::Notification found_notification; - absl::Notification lost_notification; - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = - std::make_unique(kTestBleDeviceAddress, kValidModelId); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - found_notification.WaitForNotification(); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - lost_notification.WaitForNotification(); -} - -TEST_F(FastPairDiscoverableScannerTest, V2NotificationType) { - scanner_ = std::make_unique(); - // Set metadata to mimic a V2 device which advertises with a device - // type of TRUE_WIRELESS_HEADPHONES and a notification type of FAST_PAIR. - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::TRUE_WIRELESS_HEADPHONES); - metadata.set_notification_type(proto::NotificationType::FAST_PAIR); - repository->SetFakeMetadata(kValidModelId, metadata); - - absl::Notification found_notification; - absl::Notification lost_notification; - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = - std::make_unique(kTestBleDeviceAddress, kValidModelId); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - found_notification.WaitForNotification(); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - lost_notification.WaitForNotification(); -} - -TEST_F(FastPairDiscoverableScannerTest, NearbyShareModelId) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::TRUE_WIRELESS_HEADPHONES); - repository->SetFakeMetadata(kValidModelId, metadata); - absl::Notification found_notification; - absl::Notification lost_notification; - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = std::make_unique( - kTestBleDeviceAddress, kNearbyShareModelId); - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(lost_notification.WaitForNotificationWithTimeout(kWaitTimeout)); -} - -TEST_F(FastPairDiscoverableScannerTest, - DoesntInvokeLostCallbackIfDidntInvokeFound) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - metadata.set_device_type(proto::DeviceType::TRUE_WIRELESS_HEADPHONES); - repository->SetFakeMetadata(kValidModelId, metadata); - absl::Notification found_notification; - absl::Notification lost_notification; - discoverable_scanner_ = FastPairDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - auto ble_peripheral = - std::make_unique(kTestBleDeviceAddress, kValidModelId); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE(lost_notification.WaitForNotificationWithTimeout(kWaitTimeout)); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.cc b/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.cc deleted file mode 100644 index 009ab87ee0..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.cc +++ /dev/null @@ -1,201 +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. - -#include "fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.h" - -#include -#include -#include -#include -#include - -#include "fastpair/common/constant.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/non_discoverable_advertisement.h" -#include "fastpair/dataparser/fast_pair_data_parser.h" -#include "fastpair/repository/fast_pair_repository.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -// static -FastPairNonDiscoverableScanner::Factory* - FastPairNonDiscoverableScanner::Factory::g_test_factory_ = nullptr; - -// static -std::unique_ptr -FastPairNonDiscoverableScanner::Factory::Create( - FastPairScanner& scanner, NonDiscoverableScannerCallback found_callback, - NonDiscoverableScannerCallback lost_callback, - SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository) { - if (g_test_factory_) { - return g_test_factory_->CreateInstance(scanner, std::move(found_callback), - std::move(lost_callback), executor, - device_repository); - } - - return std::make_unique( - scanner, std::move(found_callback), std::move(lost_callback), executor, - device_repository); -} - -// static -void FastPairNonDiscoverableScanner::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -FastPairNonDiscoverableScanner::FastPairNonDiscoverableScanner( - FastPairScanner& scanner, NonDiscoverableScannerCallback found_callback, - NonDiscoverableScannerCallback lost_callback, - SingleThreadExecutor* executor, FastPairDeviceRepository* device_repository) - : scanner_(scanner), - found_callback_(std::move(found_callback)), - lost_callback_(std::move(lost_callback)), - executor_(executor), - device_repository_(device_repository) { - scanner_.AddObserver(this); -} - -FastPairNonDiscoverableScanner::~FastPairNonDiscoverableScanner() { - scanner_.RemoveObserver(this); -} - -void FastPairNonDiscoverableScanner::OnDeviceFound( - const BlePeripheral& peripheral) { - std::string fast_pair_service_data = - peripheral.GetAdvertisementBytes(kServiceId).string_data(); - if (fast_pair_service_data.empty()) { - NEARBY_LOGS(WARNING) << __func__ - << ": Device doesn't have any Fast Pair Service Data."; - return; - } - executor_->Execute( - "device-found", - [this, fast_pair_service_data = std::move(fast_pair_service_data), - address = - peripheral.GetName()]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NEARBY_LOGS(INFO) << __func__ << ": Attempting to parse advertisement."; - FastPairDataParser::ParseNotDiscoverableAdvertisement( - fast_pair_service_data, address, - [&](std::optional advertisement) { - OnAdvertisementParsed(address, advertisement); - }); - }); -} - -void FastPairNonDiscoverableScanner::OnAdvertisementParsed( - absl::string_view address, - std::optional advertisement) { - if (!advertisement.has_value()) { - NEARBY_LOGS(INFO) - << __func__ << ": Returning early because no advertisement was parsed."; - return; - } - NEARBY_LOGS(INFO) - << __func__ - << ": Attempting to check if device is associated with current account."; - AccountKeyFilter account_filter(advertisement.value()); - FastPairRepository::Get()->CheckIfAssociatedWithCurrentAccount( - account_filter, [&, address = std::string(address), - advertisement = std::move(advertisement)]( - std::optional account_key, - std::optional model_id) { - OnAccountKeyFilterCheckResult(address, advertisement, account_key, - model_id); - }); -} - -void FastPairNonDiscoverableScanner::OnAccountKeyFilterCheckResult( - absl::string_view address, - std::optional advertisement, - std::optional account_key, - std::optional model_id) { - if (!account_key.has_value() || !model_id.has_value()) { - return; - } - NEARBY_LOGS(INFO) << __func__ << ": Attempting to get device metadata."; - FastPairRepository::Get()->GetDeviceMetadata( - model_id.value(), - [&, address = std::string(address), - advertisement = std::move(advertisement), model_id = model_id.value(), - account_key = - account_key.value()](std::optional device_metadata) { - OnDeviceMetadataRetrieved(address, advertisement, model_id, account_key, - device_metadata); - }); -} - -void FastPairNonDiscoverableScanner::OnDeviceMetadataRetrieved( - absl::string_view address, - std::optional advertisement, - absl::string_view model_id, AccountKey account_key, - std::optional device_metadata) { - if (!device_metadata.has_value()) { - NEARBY_LOGS(WARNING) << __func__ << ": Failed to get device metadata"; - return; - } - - auto fast_pair_device = std::make_unique( - model_id, address, Protocol::kFastPairSubsequentPairing); - fast_pair_device->SetAccountKey(account_key); - fast_pair_device->SetMetadata(device_metadata.value()); - fast_pair_device->SetShowUiNotification( - advertisement->type == NonDiscoverableAdvertisement::Type::kShowUi); - executor_->Execute( - "add-device", - [this, fast_pair_device = std::move(fast_pair_device)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - FastPairDevice* device = - device_repository_->AddDevice(std::move(fast_pair_device)); - NotifyDeviceFound(*device); - }); -} - -void FastPairNonDiscoverableScanner::NotifyDeviceFound(FastPairDevice& device) { - NEARBY_LOGS(VERBOSE) << "Notify Device found:" - << "BluetoothAddress = " << device.GetBleAddress() - << ", Model id = " << device.GetModelId(); - { - MutexLock lock(&mutex_); - notified_devices_[device.GetBleAddress()] = &device; - } - found_callback_(device); -} - -void FastPairNonDiscoverableScanner::OnDeviceLost( - const BlePeripheral& peripheral) { - NEARBY_LOGS(INFO) << __func__ << ": Running lost callback"; - { - MutexLock lock(&mutex_); - auto node = notified_devices_.extract(peripheral.GetName()); - // Don't invoke callback if we didn't notify this device. - if (node.empty()) return; - } - executor_->Execute("device-lost", - [this, address = peripheral.GetName()]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - auto opt_device = - device_repository_->FindDevice(address); - if (!opt_device.has_value()) return; - FastPairDevice* device = opt_device.value(); - lost_callback_(*device); - device_repository_->RemoveDevice(device); - }); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.h b/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.h deleted file mode 100644 index 1db0c2ccd8..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.h +++ /dev/null @@ -1,108 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_NON_DISCOVERABLE_SCANNER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_NON_DISCOVERABLE_SCANNER_H_ - -#include -#include - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/non_discoverable_advertisement.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/scanning/fastpair/fast_pair_scanner.h" -#include "internal/base/observer_list.h" -#include "internal/platform/mutex.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { -using NonDiscoverableScannerCallback = - absl::AnyInvocable; -// This class detects Fast Pair 'not discoverable' advertisements (see -// https://developers.google.com/nearby/fast-pair/spec#AdvertisingWhenNotDiscoverable) -// and invokes the |found_callback| when it finds a device within the -// appropriate range. |lost_callback| will be invoked when that device is lost. -class FastPairNonDiscoverableScanner : public FastPairScanner::Observer { - public: - class Factory { - public: - static std::unique_ptr Create( - FastPairScanner& scanner, NonDiscoverableScannerCallback found_callback, - NonDiscoverableScannerCallback lost_callback, - SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository); - - static void SetFactoryForTesting(Factory* g_test_factory); - - protected: - virtual ~Factory() = default; - virtual std::unique_ptr CreateInstance( - FastPairScanner& scanner, NonDiscoverableScannerCallback found_callback, - NonDiscoverableScannerCallback lost_callback, - SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository) = 0; - - private: - static Factory* g_test_factory_; - }; - - FastPairNonDiscoverableScanner(FastPairScanner& scanner, - NonDiscoverableScannerCallback found_callback, - NonDiscoverableScannerCallback lost_callback, - SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository); - FastPairNonDiscoverableScanner(const FastPairNonDiscoverableScanner&) = - delete; - FastPairNonDiscoverableScanner& operator=( - const FastPairNonDiscoverableScanner&) = delete; - ~FastPairNonDiscoverableScanner(); - - // FastPairScanner::Observer - void OnDeviceFound(const BlePeripheral& peripheral) override; - void OnDeviceLost(const BlePeripheral& peripheral) override; - - private: - void OnAdvertisementParsed( - absl::string_view address, - std::optional advertisement); - void OnAccountKeyFilterCheckResult( - absl::string_view address, - std::optional advertisement, - std::optional account_key, - std::optional model_id); - void OnDeviceMetadataRetrieved( - absl::string_view address, - std::optional advertisement, - absl::string_view model_id, AccountKey account_key, - std::optional device_metadata); - void NotifyDeviceFound(FastPairDevice& device) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - - Mutex mutex_; - FastPairScanner& scanner_; - NonDiscoverableScannerCallback found_callback_ ABSL_GUARDED_BY(*executor_); - NonDiscoverableScannerCallback lost_callback_ ABSL_GUARDED_BY(*executor_); - SingleThreadExecutor* executor_; - absl::flat_hash_map notified_devices_ - ABSL_GUARDED_BY(mutex_); - FastPairDeviceRepository* device_repository_ ABSL_GUARDED_BY(*executor_); - ObserverList observer_list_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_NON_DISCOVERABLE_SCANNER_H_ diff --git a/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner_test.cc b/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner_test.cc deleted file mode 100644 index 8b5f93121c..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner_test.cc +++ /dev/null @@ -1,298 +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. - -#include "fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.h" - -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "fastpair/common/account_key.h" -#include "fastpair/repository/fake_fast_pair_repository.h" -#include "fastpair/scanning/fastpair/fake_fast_pair_scanner.h" -#include "fastpair/testing/fast_pair_service_data_creator.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr int kNotDiscoverableAdvHeader = 0b00000110; -constexpr int kAccountKeyFilterHeader = 0b01100000; -constexpr int kAccountKeyFilterNoNotificationHeader = 0b01100010; -constexpr int kSaltHeader = 0b00010001; -constexpr absl::string_view kModelId("aabbcc"); -constexpr absl::string_view kBleAddress("11:12:13:14:15:16"); -constexpr absl::string_view kAccountKeyFilter("112233445566"); -constexpr absl::string_view kSalt("01"); - -// Short timeout for operation that we expect to timeout. -constexpr absl::Duration kFailureTimeout = absl::Milliseconds(100); - -class FakeBlePeripheral : public api::BlePeripheral { - public: - explicit FakeBlePeripheral(absl::string_view name, - std::vector service_data) { - name_ = std::string(name); - ByteArray advertisement_bytes( - std::string(service_data.begin(), service_data.end())); - advertisement_data_ = advertisement_bytes; - } - - FakeBlePeripheral(const FakeBlePeripheral&) = default; - ~FakeBlePeripheral() override = default; - - std::string GetName() const override { return name_; } - - ByteArray GetAdvertisementBytes( - const std::string& service_id) const override { - return advertisement_data_; - } - - void SetName(const std::string& name) { name_ = name; } - - void SetAdvertisementBytes(ByteArray advertisement_bytes) { - advertisement_data_ = advertisement_bytes; - } - - private: - std::string name_; - ByteArray advertisement_data_; -}; - -class FastPairNonDiscoverableScannerTest : public ::testing::Test { - protected: - void TearDown() override { - executor_.Shutdown(); - } - - std::vector GetAdvServicedata() { - return FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - } - - std::vector GetAdvNoUiServicedata() { - return FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterNoNotificationHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - } - - std::vector GetAdvWrongServicedata() { - return FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader /*InvalidType*/ (0b01100001) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - } - - SingleThreadExecutor executor_; - FastPairDeviceRepository devices_{&executor_}; - std::unique_ptr scanner_; - std::unique_ptr non_discoverable_scanner_; -}; - -TEST_F(FastPairNonDiscoverableScannerTest, FoundAssociatedDevice) { - const std::vector account_key_vec{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, - 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, - 0xCC, 0xDD, 0xEE, 0xFF}; - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - repository->SetFakeMetadata(kModelId, metadata); - AccountKey account_key(account_key_vec); - repository->SetResultOfCheckIfAssociatedWithCurrentAccount(account_key, - kModelId); - - auto ble_peripheral = - std::make_unique(kBleAddress, GetAdvServicedata()); - - absl::Notification found_notification; - absl::Notification lost_notification; - non_discoverable_scanner_ = FastPairNonDiscoverableScanner::Factory::Create( - *scanner_, - [&](FastPairDevice& device) { - EXPECT_EQ(device.GetModelId(), kModelId); - EXPECT_EQ(device.GetBleAddress(), kBleAddress); - EXPECT_EQ(device.GetProtocol(), Protocol::kFastPairSubsequentPairing); - EXPECT_EQ(device.GetAccountKey(), account_key); - EXPECT_TRUE(device.ShouldShowUiNotification()); - found_notification.Notify(); - }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - found_notification.WaitForNotification(); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - lost_notification.WaitForNotification(); -} - -TEST_F(FastPairNonDiscoverableScannerTest, FoundNonAssociatedDevice) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - repository->SetFakeMetadata(kModelId, metadata); - repository->SetResultOfCheckIfAssociatedWithCurrentAccount(std::nullopt, - std::nullopt); - - auto ble_peripheral = - std::make_unique(kBleAddress, GetAdvServicedata()); - - absl::Notification found_notification; - absl::Notification lost_notification; - non_discoverable_scanner_ = FastPairNonDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE( - found_notification.WaitForNotificationWithTimeout(kFailureTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE( - lost_notification.WaitForNotificationWithTimeout(kFailureTimeout)); -} - -TEST_F(FastPairNonDiscoverableScannerTest, FoundNoUIDevice) { - const std::vector account_key_vec{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, - 0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB, - 0xCC, 0xDD, 0xEE, 0xFF}; - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - repository->SetFakeMetadata(kModelId, metadata); - AccountKey account_key(account_key_vec); - repository->SetResultOfCheckIfAssociatedWithCurrentAccount(account_key, - kModelId); - - auto ble_peripheral = - std::make_unique(kBleAddress, GetAdvNoUiServicedata()); - - absl::Notification found_notification; - absl::Notification lost_notification; - non_discoverable_scanner_ = FastPairNonDiscoverableScanner::Factory::Create( - *scanner_, - [&](FastPairDevice& device) { - EXPECT_EQ(device.GetModelId(), kModelId); - EXPECT_EQ(device.GetBleAddress(), kBleAddress); - EXPECT_EQ(device.GetProtocol(), Protocol::kFastPairSubsequentPairing); - EXPECT_EQ(device.GetAccountKey(), account_key); - EXPECT_FALSE(device.ShouldShowUiNotification().value()); - found_notification.Notify(); - }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - found_notification.WaitForNotification(); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - lost_notification.WaitForNotification(); -} - -TEST_F(FastPairNonDiscoverableScannerTest, FailedToGetDeviceMetadata) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - repository->SetResultOfCheckIfAssociatedWithCurrentAccount(AccountKey(), - kModelId); - - auto ble_peripheral = - std::make_unique(kBleAddress, GetAdvServicedata()); - - absl::Notification found_notification; - absl::Notification lost_notification; - non_discoverable_scanner_ = FastPairNonDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE( - found_notification.WaitForNotificationWithTimeout(kFailureTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE( - lost_notification.WaitForNotificationWithTimeout(kFailureTimeout)); -} - -TEST_F(FastPairNonDiscoverableScannerTest, NoServiceData) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - repository->SetFakeMetadata(kModelId, metadata); - repository->SetResultOfCheckIfAssociatedWithCurrentAccount(AccountKey(), - kModelId); - - auto ble_peripheral = - std::make_unique(kBleAddress, std::vector()); - - absl::Notification found_notification; - absl::Notification lost_notification; - non_discoverable_scanner_ = FastPairNonDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE( - found_notification.WaitForNotificationWithTimeout(kFailureTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE( - lost_notification.WaitForNotificationWithTimeout(kFailureTimeout)); -} - -TEST_F(FastPairNonDiscoverableScannerTest, FailedToParseNonDiscoverableAdv) { - scanner_ = std::make_unique(); - auto repository = std::make_unique(); - proto::Device metadata; - repository->SetFakeMetadata(kModelId, metadata); - repository->SetResultOfCheckIfAssociatedWithCurrentAccount(AccountKey(), - kModelId); - - auto ble_peripheral = std::make_unique( - kBleAddress, GetAdvWrongServicedata()); - - absl::Notification found_notification; - absl::Notification lost_notification; - non_discoverable_scanner_ = FastPairNonDiscoverableScanner::Factory::Create( - *scanner_, [&](FastPairDevice& device) { found_notification.Notify(); }, - [&](FastPairDevice& device) { lost_notification.Notify(); }, &executor_, - &devices_); - - scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE( - found_notification.WaitForNotificationWithTimeout(kFailureTimeout)); - scanner_->NotifyDeviceLost(BlePeripheral(ble_peripheral.get())); - EXPECT_FALSE( - lost_notification.WaitForNotificationWithTimeout(kFailureTimeout)); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/scanning/fastpair/fast_pair_scanner.h b/fastpair/scanning/fastpair/fast_pair_scanner.h deleted file mode 100644 index 5205d51829..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_scanner.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_SCANNER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_SCANNER_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "internal/platform/bluetooth_adapter.h" - -namespace nearby { -namespace fastpair { - -// This registers a BluetoothLowEnergy Scanner and exposes the Fast Pair -// devices found/lost events to its observers. -class FastPairScanner { - public: - class Observer { - public: - virtual ~Observer() = default; - - // The callbacks are called on platform thread. - virtual void OnDeviceFound(const BlePeripheral& peripheral) = 0; - virtual void OnDeviceLost(const BlePeripheral& peripheral) = 0; - }; - - // Represents scanning session. Must be destroyed before FastPairScanner. - class ScanningSession { - public: - virtual ~ScanningSession() = default; - }; - - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; - - virtual std::unique_ptr StartScanning() = 0; - - virtual ~FastPairScanner() = default; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_SCANNER_H_ diff --git a/fastpair/scanning/fastpair/fast_pair_scanner_impl.cc b/fastpair/scanning/fastpair/fast_pair_scanner_impl.cc deleted file mode 100644 index 825e9000f9..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_scanner_impl.cc +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/scanning/fastpair/fast_pair_scanner_impl.h" - -#include -#include -#include - -#include "absl/time/time.h" -#include "fastpair/common/constant.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -namespace { -constexpr absl::Duration kFastPairLowPowerActiveSeconds = absl::Seconds(2); -constexpr absl::Duration kFastPairLowPowerInactiveSeconds = absl::Seconds(3); -constexpr char kFastPairServiceUuid[] = "0000FE2C-0000-1000-8000-00805F9B34FB"; - -class ScanningSessionImpl : public FastPairScanner::ScanningSession { - public: - explicit ScanningSessionImpl(FastPairScannerImpl* scanner) - : scanner_(scanner) {} - ~ScanningSessionImpl() override { - NEARBY_LOGS(VERBOSE) << __func__; - scanner_->StopScanning(); - } - - private: - FastPairScannerImpl* scanner_; -}; - -} // namespace - -// FastPairScannerImpl -FastPairScannerImpl::FastPairScannerImpl(Mediums& mediums, - SingleThreadExecutor* executor) - : mediums_(mediums), executor_(executor) {} - -void FastPairScannerImpl::AddObserver(FastPairScanner::Observer* observer) { - observer_.AddObserver(observer); -} - -void FastPairScannerImpl::RemoveObserver(FastPairScanner::Observer* observer) { - observer_.RemoveObserver(observer); -} - -std::unique_ptr -FastPairScannerImpl::StartScanning() { - NEARBY_LOGS(VERBOSE) << __func__; - executor_->Execute("scanning", [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED( - *executor_) { StartScanningInternal(); }); - return std::make_unique(this); -} - -void FastPairScannerImpl::StartScanningInternal() { - NEARBY_LOGS(VERBOSE) << __func__; - if (mediums_.GetBluetoothRadio().Enable() && - mediums_.GetBle().IsAvailable() && - mediums_.GetBle().StartScanning( - kServiceId, kFastPairServiceUuid, - { - .peripheral_discovered_cb = - [this](BlePeripheral& peripheral, - const std::string& service_id, - const ByteArray& medium_advertisement_bytes, - bool fast_advertisement) { - if (service_id != kServiceId) { - NEARBY_LOGS(INFO) - << "Skipping non-fastpair advertisement"; - return; - } - OnDeviceFound(peripheral); - }, - .peripheral_lost_cb = - [this](BlePeripheral& peripheral, - const std::string& service_id) { - OnDeviceLost(peripheral); - }, - })) { - NEARBY_LOGS(INFO) - << "Started scanning for BLE advertisements for service_id = " - << kServiceId; - if (IsFastPairLowPowerEnabled()) { - StartTimer(kFastPairLowPowerActiveSeconds, - [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - PauseScanning(); - }); - } - } else { - NEARBY_LOGS(INFO) << "Couldn't start scanning on BLE for service_id = " - << kServiceId; - } -} - -void FastPairScannerImpl::StopScanning() { - NEARBY_LOGS(VERBOSE) << __func__; - executor_->Execute("stop-scan", - [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NEARBY_LOGS(VERBOSE) << __func__ << " in background"; - timer_.reset(); - mediums_.GetBle().StopScanning(kServiceId); - }); -} - -void FastPairScannerImpl::PauseScanning() { - DCHECK(IsFastPairLowPowerEnabled()); - mediums_.GetBle().StopScanning(kServiceId); - StartTimer(kFastPairLowPowerInactiveSeconds, - [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - StartScanningInternal(); - }); -} - -void FastPairScannerImpl::StartTimer(absl::Duration delay, - absl::AnyInvocable callback) { - timer_ = std::make_unique(); - timer_->Start(delay / absl::Milliseconds(1), 0, - [this, callback = std::move(callback)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - executor_->Execute(std::move(callback)); - }); -} - -void FastPairScannerImpl::OnDeviceFound(const BlePeripheral& peripheral) { - NEARBY_LOGS(INFO) << __func__ << "Found device with ble Address = " - << peripheral.GetName(); - std::string service_data = - peripheral.GetAdvertisementBytes(kServiceId).string_data(); - if (service_data.empty()) { - NEARBY_LOGS(WARNING) << "No Fast Pair service data found on device"; - return; - } - - device_address_advertisement_data_map_[peripheral.GetName()].insert( - service_data); - - NotifyDeviceFound(peripheral); -} - -void FastPairScannerImpl::OnDeviceLost(const BlePeripheral& peripheral) { - NEARBY_LOGS(INFO) << __func__ << "Lost device with ble Address = " - << peripheral.GetName(); - device_address_advertisement_data_map_.erase(peripheral.GetName()); - - for (auto& observer : observer_.GetObservers()) { - observer->OnDeviceLost(peripheral); - } -} - -void FastPairScannerImpl::NotifyDeviceFound(const BlePeripheral& peripheral) { - for (auto& observer : observer_.GetObservers()) { - observer->OnDeviceFound(peripheral); - } -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/scanning/fastpair/fast_pair_scanner_impl.h b/fastpair/scanning/fastpair/fast_pair_scanner_impl.h deleted file mode 100644 index 474f60e1a6..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_scanner_impl.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_SCANNER_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_SCANNER_IMPL_H_ - -#include -#include -#include - -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/scanning/fastpair/fast_pair_scanner.h" -#include "internal/base/observer_list.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/platform/timer_impl.h" - -namespace nearby { -namespace fastpair { - -class FastPairScannerImpl : public FastPairScanner { - public: - explicit FastPairScannerImpl(Mediums& mediums, - SingleThreadExecutor* executor); - FastPairScannerImpl(const FastPairScannerImpl&) = delete; - FastPairScannerImpl& operator=(const FastPairScannerImpl&) = delete; - ~FastPairScannerImpl() override = default; - - // FastPairScanner::Observer - void AddObserver(FastPairScanner::Observer* observer) override; - void RemoveObserver(FastPairScanner::Observer* observer) override; - - // Fast Pair discovered peripheral callback - void OnDeviceFound(const BlePeripheral& peripheral); - void OnDeviceLost(const BlePeripheral& peripheral); - - void NotifyDeviceFound(const BlePeripheral& peripheral); - // Todo(b/267348348): Support Flags to control feature ramp - bool IsFastPairLowPowerEnabled() const { return false; } - - std::unique_ptr StartScanning() override; - void StopScanning(); - - private: - void StartScanningInternal() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - // Pauses, and then restarts, scanning for a few seconds to safe power. - void PauseScanning() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void StartTimer(absl::Duration delay, absl::AnyInvocable callback) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - - Mediums& mediums_; - SingleThreadExecutor* executor_; - std::unique_ptr timer_ ABSL_GUARDED_BY(*executor_); - - // Map of a Bluetooth device address to a set of advertisement data we have - // seen. - absl::flat_hash_map> - device_address_advertisement_data_map_; - ObserverList observer_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_SCANNER_IMPL_H_ diff --git a/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc b/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc deleted file mode 100644 index 184bd3aa42..0000000000 --- a/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/scanning/fastpair/fast_pair_scanner_impl.h" - -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/scanning/fastpair/fast_pair_scanner.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { -namespace { - -constexpr absl::Duration kTaskWaitTimeout = absl::Milliseconds(1000); -constexpr absl::Duration kShortTimeout = absl::Milliseconds(100); -constexpr absl::string_view kServiceID{"Fast Pair"}; -constexpr absl::string_view kModelId{"718c17"}; -constexpr absl::string_view kFastPairServiceUuid{ - "0000FE2C-0000-1000-8000-00805F9B34FB"}; - -class FastPairScannerObserver : public FastPairScanner::Observer { - public: - explicit FastPairScannerObserver(FastPairScanner* scanner, - CountDownLatch* accept_latch, - CountDownLatch* lost_latch) { - accept_latch_ = accept_latch; - lost_latch_ = lost_latch; - scanner->AddObserver(this); - } - // FastPairScanner::Observer overrides - void OnDeviceFound(const BlePeripheral& peripheral) override { - accept_latch_->CountDown(); - } - - void OnDeviceLost(const BlePeripheral& peripheral) override { - lost_latch_->CountDown(); - } - - CountDownLatch* accept_latch_ = nullptr; - CountDownLatch* lost_latch_ = nullptr; -}; - -class FastPairScannerImplTest : public testing::Test { - public: - void SetUp() override { MediumEnvironment::Instance().Start(); } - void TearDown() override { MediumEnvironment::Instance().Stop(); } -}; - -TEST_F(FastPairScannerImplTest, StartScanning) { - // Create Fast Pair Scanner and add its observer - Mediums mediums_1; - SingleThreadExecutor executor; - auto scanner = std::make_unique(mediums_1, &executor); - CountDownLatch accept_latch(1); - CountDownLatch lost_latch(1); - FastPairScannerObserver observer(scanner.get(), &accept_latch, &lost_latch); - - // Create Advertiser and startAdvertising - Mediums mediums_2; - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_2.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - // Fast Pair scanner startScanning - auto scan_session = scanner->StartScanning(); - // Notify device found - EXPECT_TRUE(accept_latch.Await(kTaskWaitTimeout).result()); - - // Advertiser stopAdvertising - mediums_2.GetBle().GetMedium().StopAdvertising(service_id); - // Notify device lost - EXPECT_TRUE(lost_latch.Await(kTaskWaitTimeout).result()); - scan_session.reset(); - DestroyOnExecutor(std::move(scanner), &executor); -} - -TEST_F(FastPairScannerImplTest, StopScanning) { - // Create Fast Pair Scanner and add its observer - Mediums mediums_1; - SingleThreadExecutor executor; - auto scanner = std::make_unique(mediums_1, &executor); - CountDownLatch accept_latch(1); - CountDownLatch lost_latch(1); - FastPairScannerObserver observer(scanner.get(), &accept_latch, &lost_latch); - // Create Advertiser and startAdvertising - Mediums mediums_2; - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_2.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - auto scan_session = scanner->StartScanning(); - scan_session.reset(); - - mediums_2.GetBle().GetMedium().StopAdvertising(service_id); - // Device lost event should not be delivered when scan session has terminated. - EXPECT_FALSE(lost_latch.Await(kShortTimeout).result()); - DestroyOnExecutor(std::move(scanner), &executor); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/scanning/mock_scanner_broker.h b/fastpair/scanning/mock_scanner_broker.h deleted file mode 100644 index 5ce7252ea2..0000000000 --- a/fastpair/scanning/mock_scanner_broker.h +++ /dev/null @@ -1,57 +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. -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_MOCK_SCANNER_BROKER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_MOCK_SCANNER_BROKER_H_ - -#include "gmock/gmock.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/scanning/scanner_broker.h" -#include "internal/base/observer_list.h" - -namespace nearby { -namespace fastpair { - -class MockScannerBroker : public ScannerBroker { - public: - MOCK_METHOD(std::unique_ptr, StartScanning, (Protocol), - (override)); - - void AddObserver(Observer* observer) override { - observers_.AddObserver(observer); - } - - void RemoveObserver(Observer* observer) override { - observers_.RemoveObserver(observer); - } - - void NotifyDeviceFound(FastPairDevice& device) { - for (auto& observer : observers_.GetObservers()) { - observer->OnDeviceFound(device); - } - } - - void NotifyDeviceLost(FastPairDevice& device) { - for (auto& observer : observers_.GetObservers()) { - observer->OnDeviceLost(device); - } - } - - private: - ObserverList observers_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_MOCK_SCANNER_BROKER_H_ diff --git a/fastpair/scanning/scanner_broker.h b/fastpair/scanning/scanner_broker.h deleted file mode 100644 index b037a458e1..0000000000 --- a/fastpair/scanning/scanner_broker.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/protocol.h" - -namespace nearby { -namespace fastpair { - -// The ScannerBroker is the entry point for the Scanning component in the Fast -// Pair. It is responsible for brokering the start/stop scanning calls -// to the correct concrete Scanner implementation, and exposing an observer -// pattern for other components to become aware of device found/lost events. -class ScannerBroker { - public: - // Observes the activity of the scan broker. - class Observer { - public: - virtual ~Observer() = default; - - virtual void OnDeviceFound(FastPairDevice& device) = 0; - virtual void OnDeviceLost(FastPairDevice& device) = 0; - }; - - // Represents scanning session. Must be destroyed before ScannerBroker. - class ScanningSession { - public: - virtual ~ScanningSession() = default; - }; - - virtual ~ScannerBroker() = default; - - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; - - virtual std::unique_ptr StartScanning(Protocol protocol) = 0; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_H_ diff --git a/fastpair/scanning/scanner_broker_impl.cc b/fastpair/scanning/scanner_broker_impl.cc deleted file mode 100644 index 92f1a7b307..0000000000 --- a/fastpair/scanning/scanner_broker_impl.cc +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/scanning/scanner_broker_impl.h" - -#include -#include - -#include "absl/functional/bind_front.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h" -#include "fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.h" -#include "fastpair/scanning/fastpair/fast_pair_scanner_impl.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -namespace { - -class ScanningSessionImpl : public ScannerBroker::ScanningSession { - public: - ScanningSessionImpl(ScannerBrokerImpl* scanner, Protocol protocol) - : scanner_(scanner), protocol_(protocol) {} - ~ScanningSessionImpl() override { scanner_->StopScanning(protocol_); } - - private: - ScannerBrokerImpl* scanner_; - Protocol protocol_; -}; - -} // namespace - -ScannerBrokerImpl::ScannerBrokerImpl( - Mediums& mediums, SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository) - : mediums_(mediums), - executor_(executor), - device_repository_(device_repository) {} - -void ScannerBrokerImpl::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void ScannerBrokerImpl::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -std::unique_ptr -ScannerBrokerImpl::StartScanning(Protocol protocol) { - DCHECK(!fast_pair_discoverable_scanner_); - DCHECK(!fast_pair_non_discoverable_scanner_); - NEARBY_LOGS(VERBOSE) << "Starting Fast Pair Scanning."; - scanner_ = std::make_unique(mediums_, executor_); - fast_pair_discoverable_scanner_ = - FastPairDiscoverableScanner::Factory::Create( - *scanner_, - absl::bind_front(&ScannerBrokerImpl::NotifyDeviceFound, this), - absl::bind_front(&ScannerBrokerImpl::NotifyDeviceLost, this), - executor_, device_repository_); - - fast_pair_non_discoverable_scanner_ = - FastPairNonDiscoverableScanner::Factory::Create( - *scanner_, - absl::bind_front(&ScannerBrokerImpl::NotifyDeviceFound, this), - absl::bind_front(&ScannerBrokerImpl::NotifyDeviceLost, this), - executor_, device_repository_); - scanning_session_ = scanner_->StartScanning(); - return std::make_unique(this, protocol); -} - -void ScannerBrokerImpl::StopScanning(Protocol protocol) { - NEARBY_LOGS(VERBOSE) << __func__ << " Stopping Fast Pair Scanning."; - scanning_session_.reset(); - observers_.Clear(); - - DestroyOnExecutor(std::move(fast_pair_discoverable_scanner_), executor_); - DestroyOnExecutor(std::move(fast_pair_non_discoverable_scanner_), executor_); - DestroyOnExecutor(std::move(scanner_), executor_); -} - -void ScannerBrokerImpl::NotifyDeviceFound(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": Notifying device found, model id = " - << device.GetModelId(); - for (auto& observer : observers_.GetObservers()) { - observer->OnDeviceFound(device); - } -} - -void ScannerBrokerImpl::NotifyDeviceLost(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": Notifying device lost, model id = " - << device.GetModelId(); - for (auto& observer : observers_.GetObservers()) { - observer->OnDeviceLost(device); - } -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/scanning/scanner_broker_impl.h b/fastpair/scanning/scanner_broker_impl.h deleted file mode 100644 index 5ec9950fda..0000000000 --- a/fastpair/scanning/scanner_broker_impl.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_IMPL_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h" -#include "fastpair/scanning/fastpair/fast_pair_non_discoverable_scanner.h" -#include "fastpair/scanning/fastpair/fast_pair_scanner.h" -#include "fastpair/scanning/scanner_broker.h" -#include "internal/base/observer_list.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { - -class ScannerBrokerImpl : public ScannerBroker { - public: - ScannerBrokerImpl(Mediums& mediums, SingleThreadExecutor* executor, - FastPairDeviceRepository* device_repository); - ~ScannerBrokerImpl() override = default; - - // ScannerBroker: - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; - std::unique_ptr StartScanning(Protocol protocol) override; - void StopScanning(Protocol protocol); - - private: - void NotifyDeviceFound(FastPairDevice& device); - void NotifyDeviceLost(FastPairDevice& device); - - Mediums& mediums_; - SingleThreadExecutor* executor_; - std::unique_ptr scanner_; - std::unique_ptr fast_pair_discoverable_scanner_; - std::unique_ptr - fast_pair_non_discoverable_scanner_; - ObserverList observers_; - FastPairDeviceRepository* device_repository_; - std::unique_ptr scanning_session_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_IMPL_H_ diff --git a/fastpair/scanning/scanner_broker_impl_test.cc b/fastpair/scanning/scanner_broker_impl_test.cc deleted file mode 100644 index aed8f9168e..0000000000 --- a/fastpair/scanning/scanner_broker_impl_test.cc +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/scanning/scanner_broker_impl.h" - -#include -#include -#include - -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/protocol.h" -#include "fastpair/internal/mediums/mediums.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/repository/fake_fast_pair_repository.h" -#include "fastpair/repository/fast_pair_device_repository.h" -#include "fastpair/scanning/scanner_broker.h" -#include "fastpair/testing/fast_pair_service_data_creator.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" - -namespace nearby { -namespace fastpair { -namespace { -constexpr int kNotDiscoverableAdvHeader = 0b00000110; -constexpr int kAccountKeyFilterHeader = 0b01100000; -constexpr int kSaltHeader = 0b00010001; -constexpr absl::string_view kAccountKeyFilter("112233445566"); -constexpr absl::string_view kSalt("01"); -constexpr absl::string_view kServiceID{"Fast Pair"}; -constexpr absl::string_view kModelId{"718c17"}; -constexpr absl::string_view kFastPairServiceUuid{ - "0000FE2C-0000-1000-8000-00805F9B34FB"}; -constexpr absl::string_view kPublicAntiSpoof = - "Wuyr48lD3txnUhGiMF1IfzlTwRxxe+wMB1HLzP+" - "0wVcljfT3XPoiy1fntlneziyLD5knDVAJSE+RM/zlPRP/Jg=="; -class ScannerBrokerObserver : public ScannerBroker::Observer { - public: - explicit ScannerBrokerObserver(ScannerBroker* scanner_broker, - CountDownLatch* accept_latch, - CountDownLatch* lost_latch) { - accept_latch_ = accept_latch; - lost_latch_ = lost_latch; - scanner_broker->AddObserver(this); - } - - void OnDeviceFound(FastPairDevice& device) override { - accept_latch_->CountDown(); - } - - void OnDeviceLost(FastPairDevice& device) override { - lost_latch_->CountDown(); - } - - CountDownLatch* accept_latch_ = nullptr; - CountDownLatch* lost_latch_ = nullptr; -}; - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class ScannerBrokerImplTest : public testing::Test { - protected: - void SetUp() override { - MediumEnvironment::Instance().Start(); - advertiser_ble_address_ = - mediums_advertiser_.GetBle().GetMedium().GetAdapter().GetMacAddress(); - } - - void TearDown() override { MediumEnvironment::Instance().Stop(); } - - // The medium environment must be initialized (started) - // before registering medium. - MediumEnvironmentStarter env_; - Mediums mediums_scanner_; - Mediums mediums_advertiser_; - std::string advertiser_ble_address_; -}; - -TEST_F(ScannerBrokerImplTest, FoundDiscoverableAdvertisement) { - SingleThreadExecutor executor; - FastPairDeviceRepository devices{&executor}; - - // Setup FakeFastPairRepository - std::string decoded_key; - absl::Base64Unescape(kPublicAntiSpoof, &decoded_key); - proto::Device metadata; - auto repository_ = std::make_unique(); - metadata.mutable_anti_spoofing_key_pair()->set_public_key(decoded_key); - repository_->SetFakeMetadata(kModelId, metadata); - - // Create Scanner and ScannerBrokerObserver - auto scanner_broker = std::make_unique( - mediums_scanner_, &executor, &devices); - CountDownLatch accept_latch(1); - CountDownLatch lost_latch(1); - CountDownLatch device_removed(1); - FastPairDeviceRepository::RemoveDeviceCallback callback = - [&](const FastPairDevice& device) { - EXPECT_EQ(device.GetBleAddress(), advertiser_ble_address_); - device_removed.CountDown(); - }; - devices.AddObserver(&callback); - ScannerBrokerObserver observer(scanner_broker.get(), &accept_latch, - &lost_latch); - - // Create Advertiser and startAdvertising - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_advertiser_.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - // Fast Pair scanner startScanning - auto scanning_session = - scanner_broker->StartScanning(Protocol::kFastPairInitialPairing); - - // Notify device found - accept_latch.Await(); - - // Advertiser stopAdvertising - mediums_advertiser_.GetBle().GetMedium().StopAdvertising(service_id); - - // Notify device lost - lost_latch.Await(); - device_removed.Await(); - scanning_session.reset(); -} - -TEST_F(ScannerBrokerImplTest, DISABLED_FoundNonDiscoverableAdvertisement) { - SingleThreadExecutor executor; - FastPairDeviceRepository devices{&executor}; - - // Setup FakeFastPairRepository - auto repository = std::make_unique(); - proto::Device metadata; - repository->SetFakeMetadata(kModelId, metadata); - repository->SetResultOfCheckIfAssociatedWithCurrentAccount(AccountKey(), - kModelId); - - // Create Scanner and ScannerBrokerObserver - auto scanner_broker = std::make_unique( - mediums_scanner_, &executor, &devices); - CountDownLatch accept_latch(1); - CountDownLatch lost_latch(1); - CountDownLatch device_removed(1); - FastPairDeviceRepository::RemoveDeviceCallback callback = - [&](const FastPairDevice& device) { - EXPECT_EQ(device.GetBleAddress(), advertiser_ble_address_); - device_removed.CountDown(); - }; - devices.AddObserver(&callback); - ScannerBrokerObserver observer(scanner_broker.get(), &accept_latch, - &lost_latch); - - // Create Advertiser and startAdvertising - std::string service_id(kServiceID); - std::vector service_data = - FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - ByteArray advertisement_bytes( - std::string(service_data.begin(), service_data.end())); - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_advertiser_.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - // Fast Pair scanner startScanning - auto scanning_session = - scanner_broker->StartScanning(Protocol::kFastPairInitialPairing); - - // Notify device found - accept_latch.Await(); - - // Advertiser stopAdvertising - mediums_advertiser_.GetBle().GetMedium().StopAdvertising(service_id); - - // Notify device lost - lost_latch.Await(); - device_removed.Await(); - scanning_session.reset(); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/server_access/BUILD b/fastpair/server_access/BUILD deleted file mode 100644 index e4fa40f466..0000000000 --- a/fastpair/server_access/BUILD +++ /dev/null @@ -1,113 +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. - -licenses(["notice"]) - -cc_library( - name = "server_access", - srcs = [ - "fast_pair_client_impl.cc", - "fast_pair_http_notifier.cc", - ], - hdrs = [ - "fast_pair_client.h", - "fast_pair_client_impl.h", - "fast_pair_http_notifier.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/proto:proto_to_json", - "//internal/auth:credential", - "//internal/auth:types", - "//internal/base", - "//internal/network:types", - "//internal/network:url", - "//internal/platform:types", - "//internal/platform/implementation:account_manager", - "//internal/platform/implementation:types", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/strings:str_format", - "@com_google_absl//absl/synchronization", - "@nlohmann_json//:json", - ], -) - -cc_library( - name = "test_support", - hdrs = [ - "fake_fast_pair_client.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":server_access", - "//fastpair/proto:fastpair_cc_proto", - ], -) - -cc_test( - name = "fast_pair_http_notifier_test", - srcs = [ - "fast_pair_http_notifier_test.cc", - ], - copts = [ - "-Ithird_party", - ], - deps = [ - ":server_access", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_client_impl_test", - srcs = [ - "fast_pair_client_impl_test.cc", - ], - copts = [ - "-Ithird_party", - ], - deps = [ - ":server_access", - "//fastpair/common", - "//fastpair/proto:fastpair_cc_proto", - "//fastpair/proto:proto_builder", - "//internal/auth:credential", - "//internal/auth:types", - "//internal/network:types", - "//internal/network:url", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "//internal/test", - "//internal/test/google3_only:test", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/log:check", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/strings:string_view", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/server_access/fake_fast_pair_client.h b/fastpair/server_access/fake_fast_pair_client.h deleted file mode 100644 index 3ec9f275a1..0000000000 --- a/fastpair/server_access/fake_fast_pair_client.h +++ /dev/null @@ -1,123 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAKE_FAST_PAIR_CLIENT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAKE_FAST_PAIR_CLIENT_H_ - -#include - -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/server_access/fast_pair_client.h" - -namespace nearby { -namespace fastpair { - -// A fake implementation of the FastPairClient that stores all request -// data. Only use in unit tests. -class FakeFastPairClient : public FastPairClient { - public: - FakeFastPairClient() = default; - ~FakeFastPairClient() override = default; - proto::GetObservedDeviceRequest& get_observer_device_request() { - return get_observer_device_request_.value(); - } - - proto::GetObservedDeviceResponse& get_observer_device_response() { - return get_observer_device_response_.value(); - } - - proto::UserReadDevicesRequest& read_devices_request() { - return read_devices_request_.value(); - } - - proto::UserReadDevicesResponse& read_devices_response() { - return read_devices_response_.value(); - } - - proto::UserWriteDeviceRequest& write_device_request() { - return write_device_request_.value(); - } - - proto::UserDeleteDeviceRequest& delete_device_request() { - return delete_device_request_.value(); - } - - void SetGetObservedDeviceResponse( - absl::StatusOr response) { - get_observer_device_response_ = response; - } - - void SetUserReadDevicesResponse( - absl::StatusOr responses) { - read_devices_response_ = responses; - } - - void SetUserWriteDeviceResponse( - absl::StatusOr response) { - write_device_response_ = response; - } - - void SetUserDeleteDeviceResponse( - absl::StatusOr response) { - delete_device_response_ = response; - } - - private: - // Gets an observed device. - // Blocking function - absl::StatusOr GetObservedDevice( - const proto::GetObservedDeviceRequest& request) override { - get_observer_device_request_ = request; - return get_observer_device_response_; - } - - // Reads the user's devices. - // Blocking function - absl::StatusOr UserReadDevices( - const proto::UserReadDevicesRequest& request) override { - read_devices_request_ = request; - return read_devices_response_; - } - - // Writes a new device to a user's account. - // Blocking function - absl::StatusOr UserWriteDevice( - const proto::UserWriteDeviceRequest& request) override { - write_device_request_ = request; - return write_device_response_; - } - - // Deletes an existing device from a user's account. - // Blocking function - absl::StatusOr UserDeleteDevice( - const proto::UserDeleteDeviceRequest& request) override { - delete_device_request_ = request; - return delete_device_response_; - } - - // Requests/Responses - std::optional get_observer_device_request_; - absl::StatusOr - get_observer_device_response_; - std::optional read_devices_request_; - absl::StatusOr read_devices_response_; - std::optional write_device_request_; - absl::StatusOr write_device_response_; - std::optional delete_device_request_; - absl::StatusOr delete_device_response_; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAKE_FAST_PAIR_CLIENT_H_ diff --git a/fastpair/server_access/fast_pair_client.h b/fastpair/server_access/fast_pair_client.h deleted file mode 100644 index 32a2157a9e..0000000000 --- a/fastpair/server_access/fast_pair_client.h +++ /dev/null @@ -1,51 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_CLIENT_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_CLIENT_H_ - -#include "absl/status/statusor.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" - -namespace nearby { -namespace fastpair { - -// FastPairClient is used to access Fast Pair backend APIs. -class FastPairClient { - public: - virtual ~FastPairClient() = default; - // Gets an observed device. - // Blocking function - virtual absl::StatusOr GetObservedDevice( - const proto::GetObservedDeviceRequest& request) = 0; - - // Reads the user's devices. - // Blocking function - virtual absl::StatusOr UserReadDevices( - const proto::UserReadDevicesRequest& request) = 0; - - // Writes a new device to a user's account. - // Blocking function - virtual absl::StatusOr UserWriteDevice( - const proto::UserWriteDeviceRequest& request) = 0; - - // Deletes an existing device from a user's account. - // Blocking function - virtual absl::StatusOr UserDeleteDevice( - const proto::UserDeleteDeviceRequest& request) = 0; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_CLIENT_H_ diff --git a/fastpair/server_access/fast_pair_client_impl.cc b/fastpair/server_access/fast_pair_client_impl.cc deleted file mode 100644 index 515c65f161..0000000000 --- a/fastpair/server_access/fast_pair_client_impl.cc +++ /dev/null @@ -1,347 +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. - -#include "fastpair/server_access/fast_pair_client_impl.h" - -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/notification.h" -#include "fastpair/common/fast_pair_switches.h" -#include "fastpair/server_access/fast_pair_http_notifier.h" -#include "internal/auth/auth_status_util.h" -#include "internal/auth/authentication_manager.h" -#include "internal/network/http_client.h" -#include "internal/network/http_request.h" -#include "internal/network/http_response.h" -#include "internal/network/url.h" -#include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" -#include "internal/platform/implementation/device_info.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { -namespace { -using ::nearby::network::HttpRequest; -using ::nearby::network::HttpRequestMethod; -using ::nearby::network::HttpResponse; -using ::nearby::network::Url; -// ----------------- HTTP Constants --------------------------------- -constexpr absl::string_view kProtobufContentType = "application/x-protobuf"; -constexpr absl::string_view kKey = "key"; -constexpr absl::string_view kClientId = - "AIzaSyBv7ZrOlX5oIJLVQrZh-WkZFKm5L6FlStQ"; -constexpr absl::string_view kMode = "mode"; -constexpr absl::string_view kQueryParameterAlternateOutputKey = "alt"; -constexpr absl::string_view kQueryParameterAlternateOutputProto = "proto"; -constexpr absl::string_view kPlatformTypeHeaderName = - "X-FastPair-Platform-Type"; -constexpr absl::string_view kDefaultNearbyDevicesHttpHost = - "https://nearbydevices-pa.googleapis.com"; - -constexpr absl::string_view kNearbyV1Path = "v1/"; -constexpr absl::string_view kDevicesPath = "device/"; -constexpr absl::string_view kUserDevicesPath = "user/devices"; -constexpr absl::string_view kUserDeleteDevicePath = "user/device"; -const char* GetObservedDeviceMode[3] = {"MODE_UNKNOWN", "MODE_RELEASE", - "MODE_DEBUG"}; - -absl::string_view GetPlatformTypeString(api::DeviceInfo::OsType os_type) { - switch (os_type) { - case api::DeviceInfo::OsType::kAndroid: - return "OSType.ANDROID"; - case api::DeviceInfo::OsType::kChromeOs: - return "OSType.CHROME_OS"; - case api::DeviceInfo::OsType::kIos: - return "OSType.IOS"; - case api::DeviceInfo::OsType::kWindows: - return "OSType.WINDOWS"; - default: - return "OSType.UNKNOWN"; - } -} - -// Creates the full Nearby V1 URL with |request_path|. -Url CreateV1RequestUrl(absl::string_view request_path) { - std::string host = std::string(kDefaultNearbyDevicesHttpHost); - auto host_switch = switches::GetNearbyFastPairHttpHost(); - if (!host_switch.empty()) { - host = host_switch; - } - std::string path = - absl::StrFormat("%s/%s%s", host, kNearbyV1Path, request_path); - NEARBY_LOGS(INFO) << __func__ << "= " << path; - return Url::Create(path).value(); -} -} // namespace - -FastPairClientImpl::FastPairClientImpl( - auth::AuthenticationManager* authentication_manager, - AccountManager* account_manager, network::HttpClient* http_client, - FastPairHttpNotifier* notifier, DeviceInfo* device_info) - : authentication_manager_(authentication_manager), - account_manager_(account_manager), - http_client_(std::move(http_client)), - notifier_(notifier), - device_info_(device_info) {} - -// Gets an observed device. -absl::StatusOr -FastPairClientImpl::GetObservedDevice( - const proto::GetObservedDeviceRequest& request) { - NEARBY_LOGS(VERBOSE) << __func__ << ": Start API call to get observed device"; - notifier_->NotifyOfRequest(request); - - // Sets up request mode. - QueryParameters params; - params.push_back({std::string(kMode), GetObservedDeviceMode[request.mode()]}); - - HttpRequest http_request = CreateHttpRequest( - /*access token= */ std::nullopt, - /*Url=*/ - CreateV1RequestUrl(std::string(kDevicesPath) + - std::to_string(request.device_id())), - RequestType::kGet, - /*query parameters=*/params, - /*body=*/std::string()); - - absl::StatusOr http_response = - http_client_->GetResponse(http_request); - - if (!http_response.ok()) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to get response."; - return http_response.status(); - } - - proto::GetObservedDeviceResponse response; - if (!response.ParseFromString(http_response->GetBody().GetRawData())) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to parse server response."; - return absl::InvalidArgumentError("Parse proto error"); - } - - notifier_->NotifyOfResponse(response); - NEARBY_LOGS(INFO) - << __func__ << ": Complete API call to get observed device successfully"; - return response; -} - -// Reads the user's devices. -absl::StatusOr -FastPairClientImpl::UserReadDevices( - const proto::UserReadDevicesRequest& request) { - NEARBY_LOGS(VERBOSE) << __func__ << ": Start API call to read user's devices"; - notifier_->NotifyOfRequest(request); - - absl::StatusOr access_token = GetAccessToken(); - if (!access_token.ok()) { - NEARBY_LOGS(WARNING) << __func__ - << ": Skip API call to read user devices due to no " - "available access token."; - return absl::UnauthenticatedError("No user logged in."); - } - - HttpRequest http_request = CreateHttpRequest( - *access_token, - /*Url=*/CreateV1RequestUrl(kUserDevicesPath), RequestType::kGet, - /*query parameters=*/std::nullopt, - /*body=*/request.SerializeAsString()); - - absl::StatusOr http_response = - http_client_->GetResponse(http_request); - - if (!http_response.ok()) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to get response."; - return http_response.status(); - } - - proto::UserReadDevicesResponse response; - if (!response.ParseFromString(http_response->GetBody().GetRawData())) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to parse server response."; - return absl::InvalidArgumentError("Parse proto error"); - } - - notifier_->NotifyOfResponse(response); - NEARBY_LOGS(INFO) << __func__ - << ": Complete API call to read user devices successfully"; - return response; -} - -// Writes a new device to a user's account. -absl::StatusOr -FastPairClientImpl::UserWriteDevice( - const proto::UserWriteDeviceRequest& request) { - NEARBY_LOGS(VERBOSE) << __func__ << ": Start API call to write user device"; - notifier_->NotifyOfRequest(request); - - absl::StatusOr access_token = GetAccessToken(); - if (!access_token.ok()) { - NEARBY_LOGS(WARNING) << __func__ - << ": Skip API call to write user devices due to no " - "available access token."; - return absl::UnauthenticatedError("No user logged in."); - } - - HttpRequest http_request = CreateHttpRequest( - *access_token, - /*Url=*/CreateV1RequestUrl(kUserDevicesPath), RequestType::kPost, - /*query parameters=*/std::nullopt, - /*body=*/request.SerializeAsString()); - absl::StatusOr http_response = - http_client_->GetResponse(http_request); - - if (!http_response.ok()) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to get response."; - return http_response.status(); - } - - proto::UserWriteDeviceResponse response; - if (!response.ParseFromString(http_response->GetBody().GetRawData())) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to parse server response."; - return absl::InvalidArgumentError("Parse proto error"); - } - - notifier_->NotifyOfResponse(response); - NEARBY_LOGS(INFO) << __func__ - << ": Complete API call to write user devices successfully"; - return response; -} - -// Deletes an existing device from a user's account. -absl::StatusOr -FastPairClientImpl::UserDeleteDevice( - const proto::UserDeleteDeviceRequest& request) { - NEARBY_LOGS(VERBOSE) << __func__ << ": Start API call to delete user device"; - notifier_->NotifyOfRequest(request); - - absl::StatusOr access_token = GetAccessToken(); - if (!access_token.ok()) { - NEARBY_LOGS(WARNING) << __func__ - << ": Skip API call to delete user devices due to no " - "available access token."; - return absl::UnauthenticatedError("No user logged in."); - } - - HttpRequest http_request = - CreateHttpRequest(*access_token, - /*Url=*/ - CreateV1RequestUrl(std::string(kUserDeleteDevicePath) + - "/" + request.hex_account_key()), - RequestType::kDelete, - /*query parameters=*/std::nullopt, - /*body=*/std::string()); - - absl::StatusOr http_response = - http_client_->GetResponse(http_request); - - if (!http_response.ok()) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to get response."; - return http_response.status(); - } - - proto::UserDeleteDeviceResponse response; - if (!response.ParseFromString(http_response->GetBody().GetRawData())) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to parse server response."; - return absl::InvalidArgumentError("Parse proto error"); - } - - notifier_->NotifyOfResponse(response); - NEARBY_LOGS(INFO) - << __func__ << ": Complete API call to delete user devices successfully"; - return response; -} - -// Blocking function -absl::StatusOr FastPairClientImpl::GetAccessToken() { - NEARBY_LOGS(VERBOSE) << __func__; - std::optional account = - account_manager_->GetCurrentAccount(); - if (!account.has_value()) { - NEARBY_LOGS(WARNING) - << __func__ << ": Failed to get access token due to no login user."; - return absl::UnauthenticatedError("No user logged in."); - } - absl::StatusOr result; - absl::Notification notification; - authentication_manager_->FetchAccessToken( - account->id, - [&](auth::AuthStatus status, absl::string_view access_token) { - if (status == auth::AuthStatus::SUCCESS) { - result = std::string(access_token); - } else { - result = absl::UnknownError(absl::StrCat(static_cast(status))); - } - notification.Notify(); - }); - notification.WaitForNotification(); - return result; -} - -HttpRequest FastPairClientImpl::CreateHttpRequest( - std::optional access_token, Url url, - RequestType request_type, - std::optional request_as_query_parameters, - std::optional body) { - NEARBY_LOGS(VERBOSE) << __func__; - HttpRequest request{url}; - - // Handles query strings - request.AddQueryParameter(kQueryParameterAlternateOutputKey, - kQueryParameterAlternateOutputProto); - request.AddQueryParameter(kKey, kClientId); - if (request_as_query_parameters.has_value()) { - for (const auto& key_value_pair : *request_as_query_parameters) { - request.AddQueryParameter(key_value_pair.first, key_value_pair.second); - } - } - - // Handles request method - request.SetMethod(GetRequestMethod(request_type)); - // Handles headers - if (access_token.has_value()) { - NEARBY_LOGS(INFO) << __func__ << " : Authorization with access token"; - request.AddHeader("Authorization", - absl::StrCat("Bearer ", access_token.value())); - } - request.AddHeader(kPlatformTypeHeaderName, - GetPlatformTypeString(device_info_->GetOsType())); - request.AddHeader("Content-Type", - body ? kProtobufContentType : std::string()); - - // Handles request body - request.SetBody(body.value_or(std::string())); - return request; -} - -HttpRequestMethod FastPairClientImpl::GetRequestMethod( - RequestType request_type) const { - if (request_type == RequestType::kPost) { - NEARBY_LOGS(INFO) << __func__ << " : request_type= kPost"; - return HttpRequestMethod::kPost; - } else if (request_type == RequestType::kDelete) { - NEARBY_LOGS(INFO) << __func__ << ": request_type= kDelete"; - return HttpRequestMethod::kDelete; - } - NEARBY_LOGS(INFO) << __func__ << " : request_type= kGet"; - return HttpRequestMethod::kGet; -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/server_access/fast_pair_client_impl.h b/fastpair/server_access/fast_pair_client_impl.h deleted file mode 100644 index f24a965d4e..0000000000 --- a/fastpair/server_access/fast_pair_client_impl.h +++ /dev/null @@ -1,87 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_CLIENT_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_CLIENT_IMPL_H_ - -#include -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "fastpair/server_access/fast_pair_client.h" -#include "fastpair/server_access/fast_pair_http_notifier.h" -#include "internal/auth/authentication_manager.h" -#include "internal/network/http_client.h" -#include "internal/network/url.h" -#include "internal/platform/device_info.h" -#include "internal/platform/implementation/account_manager.h" - -namespace nearby { -namespace fastpair { -// An implementation of FastPairClient that fetches access tokens and makes -// HTTP request to FastPair backend. -class FastPairClientImpl : public FastPairClient { - public: - // Query strings of the request. - using QueryParameters = std::vector>; - - FastPairClientImpl(auth::AuthenticationManager* authentication_manager, - AccountManager* account_manager, - network::HttpClient* http_client, - FastPairHttpNotifier* notifier, DeviceInfo* device_info); - FastPairClientImpl(FastPairClientImpl&) = delete; - FastPairClientImpl& operator=(FastPairClientImpl&) = delete; - ~FastPairClientImpl() override = default; - - // Gets an observed device. - absl::StatusOr GetObservedDevice( - const proto::GetObservedDeviceRequest& request) override; - - // Reads the user's devices. - absl::StatusOr UserReadDevices( - const proto::UserReadDevicesRequest& request) override; - - // Writes a new device to a user's account. - absl::StatusOr UserWriteDevice( - const proto::UserWriteDeviceRequest& request) override; - - // Deletes an existing device from a user's account. - absl::StatusOr UserDeleteDevice( - const proto::UserDeleteDeviceRequest& request) override; - - private: - enum class RequestType { kGet, kPost, kDelete }; - network::HttpRequestMethod GetRequestMethod( - FastPairClientImpl::RequestType request_type) const; - // Fetches access token for a logged in user. - absl::StatusOr GetAccessToken(); - network::HttpRequest CreateHttpRequest( - std::optional access_token, network::Url url, - RequestType request_type, - std::optional request_as_query_parameters, - std::optional body); - - auth::AuthenticationManager* authentication_manager_ = nullptr; - AccountManager* account_manager_ = nullptr; - network::HttpClient* http_client_; - FastPairHttpNotifier* notifier_ = nullptr; - DeviceInfo* device_info_ = nullptr; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_CLIENT_IMPL_H_ diff --git a/fastpair/server_access/fast_pair_client_impl_test.cc b/fastpair/server_access/fast_pair_client_impl_test.cc deleted file mode 100644 index e8b86a601e..0000000000 --- a/fastpair/server_access/fast_pair_client_impl_test.cc +++ /dev/null @@ -1,677 +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. - -#include "fastpair/server_access/fast_pair_client_impl.h" - -#include - -#include -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/functional/any_invocable.h" -#include "absl/log/check.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/ascii.h" -#include "absl/strings/escaping.h" -#include "absl/strings/numbers.h" -#include "absl/strings/string_view.h" -#include "fastpair/common/account_key.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/fast_pair_switches.h" -#include "fastpair/common/protocol.h" -#include "fastpair/proto/data.proto.h" -#include "fastpair/proto/enum.proto.h" -#include "fastpair/proto/fast_pair_string.proto.h" -#include "fastpair/proto/proto_builder.h" -#include "fastpair/server_access/fast_pair_client.h" -#include "fastpair/server_access/fast_pair_http_notifier.h" -#include "internal/auth/auth_status_util.h" -#include "internal/auth/authentication_manager.h" -#include "internal/network/http_client.h" -#include "internal/network/http_request.h" -#include "internal/network/http_response.h" -#include "internal/network/http_status_code.h" -#include "internal/network/url.h" -#include "internal/platform/device_info.h" -#include "internal/test/fake_account_manager.h" -#include "internal/test/fake_device_info.h" -#include "internal/test/google3_only/fake_authentication_manager.h" - -namespace nearby { -namespace fastpair { -namespace { - -using ::nearby::network::HttpClient; -using ::nearby::network::HttpRequest; -using ::nearby::network::HttpRequestMethod; -using ::nearby::network::HttpResponse; -using ::nearby::network::HttpStatusCode; -using ::nearby::network::Url; - -constexpr absl::string_view kHexModelId = "718C17"; -constexpr absl::string_view kAccessToken = "access_token"; -constexpr absl::string_view kTestAccountId = "test_account_id"; -constexpr absl::string_view kFastPairPreferencesFilePath = - "Google/Nearby/FastPair"; -constexpr absl::string_view kDevicesPath = "device/"; -constexpr absl::string_view kUserDevicesPath = "user/devices"; -constexpr absl::string_view kUserDeleteDevicePath = "user/device"; -constexpr absl::string_view kKey = "key"; -constexpr absl::string_view kClientId = - "AIzaSyBv7ZrOlX5oIJLVQrZh-WkZFKm5L6FlStQ"; -constexpr absl::string_view kQueryParameterAlternateOutputKey = "alt"; -constexpr absl::string_view kQueryParameterAlternateOutputProto = "proto"; -constexpr absl::string_view kPlatformTypeHeaderName = - "X-FastPair-Platform-Type"; -constexpr absl::string_view kWindowsPlatformType = "OSType.WINDOWS"; -constexpr absl::string_view kMode = "mode"; -constexpr absl::string_view kReleaseMode = "MODE_RELEASE"; -constexpr absl::string_view kTestGoogleApisUrl = - "https://nearbydevices-pa.testgoogleapis.com"; -constexpr absl::string_view kBleAddress = "11::22::33::44::55::66"; -constexpr absl::string_view kPublicAddress = "20:64:DE:40:F8:93"; -constexpr absl::string_view kDisplayName = "Test Device"; -constexpr absl::string_view kInitialPairingdescription = - "InitialPairingdescription"; -constexpr absl::string_view kAccountKey = "04b85786180add47fb81a04a8ce6b0de"; -constexpr absl::string_view kExpectedSha256Hash = - "6353c0075a35b7d81bb30a6190ab246da4b8c55a6111d387400579133c090ed8"; - -class MockHttpClient : public HttpClient { - public: - MOCK_METHOD(void, StartRequest, - (const HttpRequest& request, - absl::AnyInvocable&)>), - (override)); - MOCK_METHOD(void, StartCancellableRequest, - (std::unique_ptr request, - absl::AnyInvocable&)>), - (override)); - MOCK_METHOD(absl::StatusOr, GetResponse, (const HttpRequest&), - (override)); -}; - -// Return the values associated with |key|, or fail the test if |key| isn't in -// |query_parameters| -std::vector ExpectQueryStringValues( - const std::vector>& query_parameters, - absl::string_view key) { - std::vector values; - for (const auto& pair : query_parameters) { - const auto& query_key = pair.first; - const auto& query_value = pair.second; - if (query_key == key) { - values.push_back(query_value); - } - } - EXPECT_GT(values.size(), 0); - return values; -} - -// A gMock matcher to match proto values. Use this matcher like: -// request/response proto, expected_proto; -// EXPECT_THAT(proto, MatchesProto(expected_proto)); -MATCHER_P( - MatchesProto, expected_proto, - absl::StrCat(negation ? "does not match" : "matches", - testing::PrintToString(expected_proto.SerializeAsString()))) { - return arg.has_value() && - arg->SerializeAsString() == expected_proto.SerializeAsString(); -} - -class FastPairClientImplTest : public ::testing::Test, - public FastPairHttpNotifier::Observer { - protected: - FastPairClientImplTest() { - authentication_manager_ = std::make_unique(); - AccountManager::Account account; - account.id = kTestAccountId; - account_manager_ = std::make_unique(); - account_manager_->SetAccount(account); - device_info_ = std::make_unique(); - } - - void SetUp() override { - GetAuthManager()->EnableSyncMode(); - mock_http_client_ = std::make_unique<::testing::NiceMock>(); - http_client_ = dynamic_cast<::testing::NiceMock*>( - mock_http_client_.get()); - switches::SetNearbyFastPairHttpHost(std::string(kTestGoogleApisUrl)); - fast_pair_client_ = std::make_unique( - authentication_manager_.get(), account_manager_.get(), - mock_http_client_.get(), ¬ifier_, device_info_.get()); - notifier_.AddObserver(this); - } - - void TearDown() override { notifier_.RemoveObserver(this); } - - nearby::FakeAuthenticationManager* GetAuthManager() { - return reinterpret_cast( - authentication_manager_.get()); - } - - // FastPairHttpNotifier::Observer: - // Called when HTTP RPC is made for GetObservedDeviceRequest/Response - void OnGetObservedDeviceRequest( - const proto::GetObservedDeviceRequest& request) override { - get_observer_device_request_ = request; - } - - void OnGetObservedDeviceResponse( - const proto::GetObservedDeviceResponse& response) override { - get_observer_device_response_ = response; - } - - // Called when HTTP RPC is made for UserReadDevicesRequest/Response - void OnUserReadDevicesRequest( - const proto::UserReadDevicesRequest& request) override { - read_devices_request_ = request; - } - void OnUserReadDevicesResponse( - const proto::UserReadDevicesResponse& response) override { - read_devices_response_ = response; - } - - // Called when HTTP RPC is made for UserWriteDeviceRequest/Response - void OnUserWriteDeviceRequest( - const proto::UserWriteDeviceRequest& request) override { - write_device_request_ = request; - } - void OnUserWriteDeviceResponse( - const proto::UserWriteDeviceResponse& response) override { - write_device_response_ = response; - } - - // Called when HTTP RPC is made for UserDeleteDeviceRequest/Response - void OnUserDeleteDeviceRequest( - const proto::UserDeleteDeviceRequest& request) override { - delete_device_request_ = request; - } - void OnUserDeleteDeviceResponse( - const proto::UserDeleteDeviceResponse& response) override { - delete_device_response_ = response; - } - - Url GetUrl(absl::string_view path) { - return Url::Create(absl::StrCat(kTestGoogleApisUrl, "/v1/", path)).value(); - } - - // Requests/Responses - std::optional get_observer_device_request_; - std::optional get_observer_device_response_; - std::optional read_devices_request_; - std::optional read_devices_response_; - std::optional write_device_request_; - std::optional write_device_response_; - std::optional delete_device_request_; - std::optional delete_device_response_; - - std::unique_ptr authentication_manager_; - std::unique_ptr account_manager_; - std::unique_ptr fast_pair_client_; - std::unique_ptr device_info_; - ::testing::NiceMock* http_client_; - std::unique_ptr mock_http_client_; - FastPairHttpNotifier notifier_; -}; - -TEST_F(FastPairClientImplTest, GetObservedDeviceSuccess) { - // Sets up proto::GetObservedDeviceRequest - proto::GetObservedDeviceRequest request_proto; - int64_t device_id; - CHECK(absl::SimpleHexAtoi(kHexModelId, &device_id)); - request_proto.set_device_id(device_id); - request_proto.set_mode(proto::GetObservedDeviceRequest::MODE_RELEASE); - - // Sets up proto::GetObservedDeviceResponse - proto::GetObservedDeviceResponse response_proto; - auto* device = response_proto.mutable_device(); - device->set_id(device_id); - auto* observed_device_strings = response_proto.mutable_strings(); - observed_device_strings->set_initial_pairing_description( - kInitialPairingdescription); - - // Sets up HttpResponse - HttpResponse http_response; - http_response.SetStatusCode(nearby::network::HttpStatusCode::kHttpOk); - http_response.SetBody(response_proto.SerializeAsString()); - - // Verifies HttpRequest is as expected - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kGet); - EXPECT_THAT(request.GetUrl().GetUrlPath(), - ::testing::HasSubstr(GetUrl(kDevicesPath).GetUrlPath())); - - EXPECT_EQ(request.GetAllHeaders().find(kPlatformTypeHeaderName)->second, - std::vector{std::string(kWindowsPlatformType)}); - EXPECT_EQ( - ExpectQueryStringValues(request.GetAllQueryParameters(), kKey), - std::vector{std::string(kClientId)}); - EXPECT_EQ(ExpectQueryStringValues(request.GetAllQueryParameters(), - kQueryParameterAlternateOutputKey), - std::vector{ - std::string(kQueryParameterAlternateOutputProto)}); - EXPECT_EQ( - ExpectQueryStringValues(request.GetAllQueryParameters(), kMode), - std::vector{std::string(kReleaseMode)}); - proto::GetObservedDeviceRequest expected_request; - EXPECT_TRUE(expected_request.ParseFromString( - request_proto.SerializeAsString())); - EXPECT_EQ(expected_request.device_id(), device_id); - EXPECT_EQ(expected_request.mode(), - proto::GetObservedDeviceRequest::MODE_RELEASE); - return http_response; - }); - - absl::StatusOr response = - fast_pair_client_->GetObservedDevice(request_proto); - - EXPECT_OK(response); - - // Verifies proto::GetObservedDeviceRequest is as expected - EXPECT_THAT(get_observer_device_request_, MatchesProto(request_proto)); - - // Verifies proto::GetObservedDeviceResponse is as expected - EXPECT_THAT(get_observer_device_response_, MatchesProto(response_proto)); - EXPECT_EQ(response->device().id(), device_id); - EXPECT_EQ(response->strings().initial_pairing_description(), - kInitialPairingdescription); -} - -TEST_F(FastPairClientImplTest, GetObservedDeviceFailureWhenNoRespsone) { - // Sets up proto::GetObservedDeviceRequest - proto::GetObservedDeviceRequest request_proto; - int64_t device_id; - CHECK(absl::SimpleHexAtoi(kHexModelId, &device_id)); - request_proto.set_device_id(device_id); - request_proto.set_mode(proto::GetObservedDeviceRequest::MODE_RELEASE); - - // Verifies HttpRequest is as expected - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kGet); - EXPECT_THAT(request.GetUrl().GetUrlPath(), - ::testing::HasSubstr(GetUrl(kDevicesPath).GetUrlPath())); - return absl::UnavailableError(""); - }); - - absl::StatusOr response = - fast_pair_client_->GetObservedDevice(request_proto); - - EXPECT_FALSE(response.ok()); - EXPECT_TRUE(absl::IsUnavailable(response.status())); -} - -TEST_F(FastPairClientImplTest, GetObservedDeviceFailureWhenParseResponse) { - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kGet); - HttpResponse http_response; - http_response.SetStatusCode(HttpStatusCode::kHttpOk); - http_response.SetBody("Not a valid serialized response message."); - return http_response; - }); - - absl::StatusOr response = - fast_pair_client_->GetObservedDevice(proto::GetObservedDeviceRequest()); - EXPECT_TRUE(absl::IsInvalidArgument(response.status())); -} - -TEST_F(FastPairClientImplTest, UserReadDevicesSuccess) { - // Sets up proto::UserReadDevicesRequest - proto::UserReadDevicesRequest request_proto; - - // Sets up proto::UserReadDevicesResponse - proto::UserReadDevicesResponse response_proto; - auto* fast_pair_info = response_proto.add_fast_pair_info(); - fast_pair_info->set_opt_in_status(proto::OptInStatus::OPT_IN_STATUS_OPTED_IN); - - // Sets up HttpResponse - HttpResponse http_response; - http_response.SetStatusCode(nearby::network::HttpStatusCode::kHttpOk); - http_response.SetBody(response_proto.SerializeAsString()); - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - - // Verifies HttpRequest is as expected - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kGet); - EXPECT_THAT( - request.GetUrl().GetUrlPath(), - ::testing::HasSubstr(GetUrl(kUserDevicesPath).GetUrlPath())); - return http_response; - }); - - absl::StatusOr response = - fast_pair_client_->UserReadDevices(request_proto); - - EXPECT_OK(response); - - // Verifies proto::UserReadDevicesRequest is as expected - EXPECT_THAT(read_devices_request_, MatchesProto(request_proto)); - - // Verifies proto::UserReadDevicesResponse is as expected - EXPECT_THAT(read_devices_response_, MatchesProto(response_proto)); - EXPECT_EQ(response->fast_pair_info().size(), 1); - EXPECT_EQ(response->fast_pair_info().Get(0).opt_in_status(), - proto::OptInStatus::OPT_IN_STATUS_OPTED_IN); -} - -TEST_F(FastPairClientImplTest, UserReadDevicesFailureWhenNoRespsone) { - // Sets up proto::UserReadDevicesRequest - proto::UserReadDevicesRequest request_proto; - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - - // Verifies HttpRequest is as expected - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kGet); - EXPECT_THAT( - request.GetUrl().GetUrlPath(), - ::testing::HasSubstr(GetUrl(kUserDevicesPath).GetUrlPath())); - return absl::UnavailableError(""); - }); - - absl::StatusOr response = - fast_pair_client_->UserReadDevices(request_proto); - - EXPECT_FALSE(response.ok()); - EXPECT_TRUE(absl::IsUnavailable(response.status())); -} - -TEST_F(FastPairClientImplTest, UserReadDevicesFailureWhenNoLoginUser) { - account_manager_->SetAccount(std::nullopt); - - EXPECT_CALL(*http_client_, GetResponse).Times(0); - absl::StatusOr response = - fast_pair_client_->UserReadDevices(proto::UserReadDevicesRequest()); - EXPECT_FALSE(response.ok()); -} - -TEST_F(FastPairClientImplTest, UserReadDevicesFailureWhenParseResponse) { - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kGet); - HttpResponse http_response; - http_response.SetStatusCode(HttpStatusCode::kHttpOk); - http_response.SetBody("Not a valid serialized response message."); - return http_response; - }); - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - absl::StatusOr response = - fast_pair_client_->UserReadDevices(proto::UserReadDevicesRequest()); - EXPECT_TRUE(absl::IsInvalidArgument(response.status())); -} - -TEST_F(FastPairClientImplTest, UserWriteDeviceSuccess) { - // Sets up proto::UserWriteDeviceRequest - proto::UserWriteDeviceRequest request_proto; - FastPairDevice device(kHexModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - AccountKey account_key(absl::HexStringToBytes(kAccountKey)); - device.SetAccountKey(account_key); - device.SetPublicAddress(kPublicAddress); - device.SetDisplayName(kDisplayName); - proto::GetObservedDeviceResponse get_observed_device_response; - auto* observed_device_strings = - get_observed_device_response.mutable_strings(); - observed_device_strings->set_initial_pairing_description( - kInitialPairingdescription); - DeviceMetadata device_metadata(get_observed_device_response); - device.SetMetadata(device_metadata); - auto* fast_pair_info = request_proto.mutable_fast_pair_info(); - BuildFastPairInfo(fast_pair_info, device); - - // Sets up proto::UserWriteDeviceResponse - proto::UserWriteDeviceResponse response_proto; - - // Sets up HttpResponse - HttpResponse http_response; - http_response.SetStatusCode(nearby::network::HttpStatusCode::kHttpOk); - http_response.SetBody(response_proto.SerializeAsString()); - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - - // Verifies HttpRequest is as expected - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kPost); - EXPECT_THAT( - request.GetUrl().GetUrlPath(), - ::testing::HasSubstr(GetUrl(kUserDevicesPath).GetUrlPath())); - proto::UserWriteDeviceRequest expected_request; - EXPECT_TRUE(expected_request.ParseFromString( - request_proto.SerializeAsString())); - EXPECT_TRUE(expected_request.has_fast_pair_info()); - auto fast_proto_info = expected_request.fast_pair_info(); - EXPECT_TRUE(fast_proto_info.has_device()); - auto device = fast_proto_info.device(); - EXPECT_EQ(device.account_key(), account_key.GetAsBytes()); - EXPECT_EQ( - absl::BytesToHexString(device.sha256_account_key_public_address()), - kExpectedSha256Hash); - proto::StoredDiscoveryItem stored_discovery_item; - EXPECT_TRUE(stored_discovery_item.ParseFromString( - device.discovery_item_bytes())); - EXPECT_EQ(stored_discovery_item.title(), kDisplayName); - proto::FastPairStrings fast_pair_strings = - stored_discovery_item.fast_pair_strings(); - EXPECT_EQ(fast_pair_strings.initial_pairing_description(), - kInitialPairingdescription); - return http_response; - }); - - absl::StatusOr response = - fast_pair_client_->UserWriteDevice(request_proto); - - EXPECT_OK(response); - - // Verifies proto::UserWriteDeviceRequest is as expected - EXPECT_THAT(write_device_request_, MatchesProto(request_proto)); - - // Verifies proto::UserWriteDeviceResponse is as expected - EXPECT_THAT(write_device_response_, MatchesProto(response_proto)); -} - -TEST_F(FastPairClientImplTest, UserWriteDeviceFailureWhenNoRespsone) { - // Sets up proto::UserWriteDeviceRequest - proto::UserWriteDeviceRequest request_proto; - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - - // Verifies HttpRequest is as expected - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kPost); - EXPECT_THAT( - request.GetUrl().GetUrlPath(), - ::testing::HasSubstr(GetUrl(kUserDevicesPath).GetUrlPath())); - return absl::UnavailableError(""); - }); - - absl::StatusOr response = - fast_pair_client_->UserWriteDevice(request_proto); - - EXPECT_FALSE(response.ok()); - EXPECT_TRUE(absl::IsUnavailable(response.status())); -} - -TEST_F(FastPairClientImplTest, UserWriteDeviceFailureWhenNoLoginUser) { - account_manager_->SetAccount(std::nullopt); - - EXPECT_CALL(*http_client_, GetResponse).Times(0); - absl::StatusOr response = - fast_pair_client_->UserWriteDevice(proto::UserWriteDeviceRequest()); - EXPECT_FALSE(response.ok()); -} - -TEST_F(FastPairClientImplTest, UserWriteDeviceFailureWhenParseResponse) { - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kPost); - HttpResponse http_response; - http_response.SetStatusCode(HttpStatusCode::kHttpOk); - http_response.SetBody("Not a valid serialized response message."); - return http_response; - }); - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - absl::StatusOr response = - fast_pair_client_->UserWriteDevice(proto::UserWriteDeviceRequest()); - EXPECT_TRUE(absl::IsInvalidArgument(response.status())); -} - -TEST_F(FastPairClientImplTest, UserDeleteDeviceSuccess) { - // Sets up proto::UserDeleteDeviceRequest - std::string hex_account_key = std::string(kAccountKey); - absl::AsciiStrToUpper(&hex_account_key); - proto::UserDeleteDeviceRequest request_proto; - request_proto.set_hex_account_key(hex_account_key); - - // Sets up proto::UserDeleteDeviceResponse - proto::UserDeleteDeviceResponse response_proto; - - // Sets up HttpResponse - HttpResponse http_response; - http_response.SetStatusCode(nearby::network::HttpStatusCode::kHttpOk); - http_response.SetBody(response_proto.SerializeAsString()); - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - - // Verifies HttpRequest is as expected - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kDelete); - EXPECT_THAT( - request.GetUrl().GetUrlPath(), - ::testing::HasSubstr(GetUrl(kUserDeleteDevicePath).GetUrlPath())); - proto::UserDeleteDeviceRequest expected_request; - EXPECT_TRUE(expected_request.ParseFromString( - request_proto.SerializeAsString())); - EXPECT_EQ(expected_request.hex_account_key(), hex_account_key); - return http_response; - }); - - absl::StatusOr response = - fast_pair_client_->UserDeleteDevice(request_proto); - - EXPECT_OK(response); - - // Verifies proto::UserDeleteDeviceRequest is as expected - EXPECT_THAT(delete_device_request_, MatchesProto(request_proto)); - - // Verifies proto::UserDeleteDeviceResponse is as expected - EXPECT_THAT(delete_device_response_, MatchesProto(response_proto)); -} - -TEST_F(FastPairClientImplTest, UserDeleteDeviceFailureWhenNoRespsone) { - // Sets up proto::UserDeleteDeviceRequest - proto::UserDeleteDeviceRequest request_proto; - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - - // Verifies HttpRequest is as expected - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kDelete); - EXPECT_THAT( - request.GetUrl().GetUrlPath(), - ::testing::HasSubstr(GetUrl(kUserDeleteDevicePath).GetUrlPath())); - return absl::UnavailableError(""); - }); - - absl::StatusOr response = - fast_pair_client_->UserDeleteDevice(request_proto); - - EXPECT_FALSE(response.ok()); - EXPECT_TRUE(absl::IsUnavailable(response.status())); -} - -TEST_F(FastPairClientImplTest, UserDeleteDeviceFailureWhenNoLoginUser) { - account_manager_->SetAccount(std::nullopt); - - EXPECT_CALL(*http_client_, GetResponse).Times(0); - absl::StatusOr response = - fast_pair_client_->UserDeleteDevice(proto::UserDeleteDeviceRequest()); - EXPECT_FALSE(response.ok()); -} - -TEST_F(FastPairClientImplTest, UserDeleteDeviceFailureWhenParseResponse) { - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kDelete); - HttpResponse http_response; - http_response.SetStatusCode(HttpStatusCode::kHttpOk); - http_response.SetBody("Not a valid serialized response message."); - return http_response; - }); - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - absl::StatusOr response = - fast_pair_client_->UserDeleteDevice(proto::UserDeleteDeviceRequest()); - EXPECT_TRUE(absl::IsInvalidArgument(response.status())); -} - -TEST_F(FastPairClientImplTest, FetchAccessTokenFailure) { - EXPECT_CALL(*http_client_, GetResponse).Times(0); - - GetAuthManager()->SetFetchAccessTokenResult( - auth::AuthStatus::PERMISSION_DENIED, std::nullopt); - absl::StatusOr response = - fast_pair_client_->UserReadDevices(proto::UserReadDevicesRequest()); - - EXPECT_TRUE(absl::IsUnauthenticated(response.status())); -} - -TEST_F(FastPairClientImplTest, ParseResponseProtoFailure) { - EXPECT_CALL(*http_client_, GetResponse) - .WillOnce([&](const HttpRequest& request) { - EXPECT_EQ(request.GetMethod(), HttpRequestMethod::kGet); - HttpResponse http_response; - http_response.SetStatusCode(HttpStatusCode::kHttpOk); - http_response.SetBody("Not a valid serialized response message."); - return http_response; - }); - - GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - std::string(kAccessToken)); - absl::StatusOr response = - fast_pair_client_->UserReadDevices(proto::UserReadDevicesRequest()); - EXPECT_TRUE(absl::IsInvalidArgument(response.status())); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/server_access/fast_pair_http_notifier.cc b/fastpair/server_access/fast_pair_http_notifier.cc deleted file mode 100644 index 24f7acd05d..0000000000 --- a/fastpair/server_access/fast_pair_http_notifier.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/server_access/fast_pair_http_notifier.h" - -#include "nlohmann/json.hpp" -#include "fastpair/proto/proto_to_json.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -void FastPairHttpNotifier::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void FastPairHttpNotifier::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -// Notifies all observers of GetObservedDeviceRequest/Response -void FastPairHttpNotifier::NotifyOfRequest( - const proto::GetObservedDeviceRequest& request) { - NEARBY_LOGS(VERBOSE) << ": GetObservedDeviceRequest=" - << FastPairProtoToJson(request).dump(); - for (auto& observer : observers_.GetObservers()) - observer->OnGetObservedDeviceRequest(request); -} - -void FastPairHttpNotifier::NotifyOfResponse( - const proto::GetObservedDeviceResponse& response) { - NEARBY_LOGS(VERBOSE) << ": GetObservedDeviceResponse=" - << FastPairProtoToJson(response).dump(); - for (auto& observer : observers_.GetObservers()) - observer->OnGetObservedDeviceResponse(response); -} - -// Notifies all observers of UserReadDevicesRequest/Response -void FastPairHttpNotifier::NotifyOfRequest( - const proto::UserReadDevicesRequest& request) { - NEARBY_LOGS(VERBOSE) << ": UserReadDevicesRequest=" - << FastPairProtoToJson(request).dump(); - for (auto& observer : observers_.GetObservers()) - observer->OnUserReadDevicesRequest(request); -} - -void FastPairHttpNotifier::NotifyOfResponse( - const proto::UserReadDevicesResponse& response) { - NEARBY_LOGS(VERBOSE) << ": UserReadDevicesResponse=" - << FastPairProtoToJson(response).dump(); - for (auto& observer : observers_.GetObservers()) - observer->OnUserReadDevicesResponse(response); -} - -// Notifies all observers of UserWriteDeviceRequest/Response -void FastPairHttpNotifier::NotifyOfRequest( - const proto::UserWriteDeviceRequest& request) { - NEARBY_LOGS(VERBOSE) << ": UserWriteDeviceRequest=" - << FastPairProtoToJson(request).dump(); - for (auto& observer : observers_.GetObservers()) - observer->OnUserWriteDeviceRequest(request); -} - -void FastPairHttpNotifier::NotifyOfResponse( - const proto::UserWriteDeviceResponse& response) { - for (auto& observer : observers_.GetObservers()) - observer->OnUserWriteDeviceResponse(response); -} - -// Notifies all observers of UserDeleteDeviceRequest/Response -void FastPairHttpNotifier::NotifyOfRequest( - const proto::UserDeleteDeviceRequest& request) { - NEARBY_LOGS(VERBOSE) << ": UserDeleteDeviceRequest=" - << FastPairProtoToJson(request).dump(); - for (auto& observer : observers_.GetObservers()) - observer->OnUserDeleteDeviceRequest(request); -} -void FastPairHttpNotifier::NotifyOfResponse( - const proto::UserDeleteDeviceResponse& response) { - NEARBY_LOGS(VERBOSE) << ": UserDeleteDeviceResponse=" - << FastPairProtoToJson(response).dump(); - for (auto& observer : observers_.GetObservers()) - observer->OnUserDeleteDeviceResponse(response); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/server_access/fast_pair_http_notifier.h b/fastpair/server_access/fast_pair_http_notifier.h deleted file mode 100644 index 7e43292eb6..0000000000 --- a/fastpair/server_access/fast_pair_http_notifier.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_HTTP_NOTIFIER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_HTTP_NOTIFIER_H_ - -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "internal/base/observer_list.h" - -namespace nearby { -namespace fastpair { - -// Interface for passing HTTP Responses/Requests to observers, by passing -// instances of this class to each HTTP Client. -class FastPairHttpNotifier { - public: - class Observer { - public: - virtual ~Observer() = default; - - // Called when HTTP RPC is made for GetObservedDeviceRequest/Response - virtual void OnGetObservedDeviceRequest( - const proto::GetObservedDeviceRequest& request) = 0; - virtual void OnGetObservedDeviceResponse( - const proto::GetObservedDeviceResponse& response) = 0; - - // Called when HTTP RPC is made for UserReadDevicesRequest/Response - virtual void OnUserReadDevicesRequest( - const proto::UserReadDevicesRequest& request) = 0; - virtual void OnUserReadDevicesResponse( - const proto::UserReadDevicesResponse& response) = 0; - - // Called when HTTP RPC is made for UserWriteDeviceRequest/Response - virtual void OnUserWriteDeviceRequest( - const proto::UserWriteDeviceRequest& request) = 0; - virtual void OnUserWriteDeviceResponse( - const proto::UserWriteDeviceResponse& response) = 0; - - // Called when HTTP RPC is made for UserDeleteDeviceRequest/Response - virtual void OnUserDeleteDeviceRequest( - const proto::UserDeleteDeviceRequest& request) = 0; - virtual void OnUserDeleteDeviceResponse( - const proto::UserDeleteDeviceResponse& response) = 0; - }; - - FastPairHttpNotifier() = default; - FastPairHttpNotifier(const FastPairHttpNotifier&) = delete; - FastPairHttpNotifier& operator=(const FastPairHttpNotifier&) = delete; - ~FastPairHttpNotifier() = default; - - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - // Notifies all observers of GetObservedDeviceRequest/Response - void NotifyOfRequest(const proto::GetObservedDeviceRequest& request); - void NotifyOfResponse(const proto::GetObservedDeviceResponse& response); - - // Notifies all observers of UserReadDevicesRequest/Response - void NotifyOfRequest(const proto::UserReadDevicesRequest& request); - void NotifyOfResponse(const proto::UserReadDevicesResponse& response); - - // Notifies all observers of UserWriteDeviceRequest/Response - void NotifyOfRequest(const proto::UserWriteDeviceRequest& request); - void NotifyOfResponse(const proto::UserWriteDeviceResponse& response); - - // Notifies all observers of UserDeleteDeviceRequest/Response - void NotifyOfRequest(const proto::UserDeleteDeviceRequest& request); - void NotifyOfResponse(const proto::UserDeleteDeviceResponse& response); - - private: - ObserverList observers_; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_HTTP_NOTIFIER_H_ diff --git a/fastpair/server_access/fast_pair_http_notifier_test.cc b/fastpair/server_access/fast_pair_http_notifier_test.cc deleted file mode 100644 index 953d17c9fd..0000000000 --- a/fastpair/server_access/fast_pair_http_notifier_test.cc +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/server_access/fast_pair_http_notifier.h" - -#include "gtest/gtest.h" -#include "internal/platform/count_down_latch.h" - -namespace nearby { -namespace fastpair { - -namespace { -class FastPairHttpNotifierObserver : public FastPairHttpNotifier::Observer { - public: - explicit FastPairHttpNotifierObserver(CountDownLatch* latch) { - latch_ = latch; - } - - void OnGetObservedDeviceRequest( - const proto::GetObservedDeviceRequest& request) override { - latch_->CountDown(); - get_observer_device_request_ = - &const_cast(request); - } - - void OnGetObservedDeviceResponse( - const proto::GetObservedDeviceResponse& response) override { - latch_->CountDown(); - get_observer_device_response_ = - &const_cast(response); - } - - // Called when HTTP RPC is made for UserReadDevicesRequest/Response - void OnUserReadDevicesRequest( - const proto::UserReadDevicesRequest& request) override { - latch_->CountDown(); - read_devices_request_ = - &const_cast(request); - } - void OnUserReadDevicesResponse( - const proto::UserReadDevicesResponse& response) override { - latch_->CountDown(); - read_devices_response_ = - &const_cast(response); - } - - // Called when HTTP RPC is made for UserWriteDeviceRequest/Response - void OnUserWriteDeviceRequest( - const proto::UserWriteDeviceRequest& request) override { - latch_->CountDown(); - write_device_request_ = - &const_cast(request); - } - void OnUserWriteDeviceResponse( - const proto::UserWriteDeviceResponse& response) override { - latch_->CountDown(); - write_device_response_ = - &const_cast(response); - } - - // Called when HTTP RPC is made for UserDeleteDeviceRequest/Response - void OnUserDeleteDeviceRequest( - const proto::UserDeleteDeviceRequest& request) override { - latch_->CountDown(); - delete_device_request_ = - &const_cast(request); - } - void OnUserDeleteDeviceResponse( - const proto::UserDeleteDeviceResponse& response) override { - latch_->CountDown(); - delete_device_response_ = - &const_cast(response); - } - - CountDownLatch* latch_; - proto::GetObservedDeviceRequest* get_observer_device_request_; - proto::GetObservedDeviceResponse* get_observer_device_response_; - proto::UserReadDevicesRequest* read_devices_request_; - proto::UserReadDevicesResponse* read_devices_response_; - proto::UserWriteDeviceRequest* write_device_request_; - proto::UserWriteDeviceResponse* write_device_response_; - proto::UserDeleteDeviceRequest* delete_device_request_; - proto::UserDeleteDeviceResponse* delete_device_response_; -}; - -TEST(FastPairHttpNotifierTest, TestNotifyGetObservedDeviceRequest) { - proto::GetObservedDeviceRequest request; - int64_t device_id; - CHECK(absl::SimpleHexAtoi("718C17", &device_id)); - request.set_device_id(device_id); - request.set_mode(proto::GetObservedDeviceRequest::MODE_RELEASE); - CountDownLatch latch(1); - FastPairHttpNotifierObserver observer(&latch); - FastPairHttpNotifier notifier; - notifier.AddObserver(&observer); - - notifier.NotifyOfRequest(request); - latch.Await(); - - EXPECT_EQ(observer.get_observer_device_request_, &request); - EXPECT_EQ(observer.get_observer_device_request_->device_id(), device_id); - EXPECT_EQ(observer.get_observer_device_request_->mode(), - proto::GetObservedDeviceRequest::MODE_RELEASE); -} - -TEST(FastPairHttpNotifierTest, TestNotifyGetObservedDeviceResponse) { - proto::GetObservedDeviceResponse response; - CountDownLatch latch(1); - FastPairHttpNotifierObserver observer(&latch); - FastPairHttpNotifier notifier; - notifier.AddObserver(&observer); - - notifier.NotifyOfResponse(response); - latch.Await(); - - EXPECT_EQ(observer.get_observer_device_response_, &response); -} - -TEST(FastPairHttpNotifierTest, TestNotifyUserReadDevicesRequest) { - proto::UserReadDevicesRequest request; - CountDownLatch latch(1); - FastPairHttpNotifierObserver observer(&latch); - FastPairHttpNotifier notifier; - notifier.AddObserver(&observer); - - notifier.NotifyOfRequest(request); - latch.Await(); - - EXPECT_EQ(observer.read_devices_request_, &request); -} - -TEST(FastPairHttpNotifierTest, TestNotifyUserReadDevicesResponse) { - proto::UserReadDevicesResponse response; - CountDownLatch latch(1); - FastPairHttpNotifierObserver observer(&latch); - FastPairHttpNotifier notifier; - notifier.AddObserver(&observer); - - notifier.NotifyOfResponse(response); - latch.Await(); - - EXPECT_EQ(observer.read_devices_response_, &response); -} - -TEST(FastPairHttpNotifierTest, TestNotifyUserWritedeviceRequest) { - proto::UserWriteDeviceRequest request; - CountDownLatch latch(1); - FastPairHttpNotifierObserver observer(&latch); - FastPairHttpNotifier notifier; - notifier.AddObserver(&observer); - - notifier.NotifyOfRequest(request); - latch.Await(); - - EXPECT_EQ(observer.write_device_request_, &request); -} - -TEST(FastPairHttpNotifierTest, TestNotifyUserWriteDeviceResponse) { - proto::UserWriteDeviceResponse response; - CountDownLatch latch(1); - FastPairHttpNotifierObserver observer(&latch); - FastPairHttpNotifier notifier; - notifier.AddObserver(&observer); - - notifier.NotifyOfResponse(response); - latch.Await(); - - EXPECT_EQ(observer.write_device_response_, &response); -} - -TEST(FastPairHttpNotifierTest, TestNotifyUserDeleteDeviceRequest) { - proto::UserDeleteDeviceRequest request; - CountDownLatch latch(1); - FastPairHttpNotifierObserver observer(&latch); - FastPairHttpNotifier notifier; - notifier.AddObserver(&observer); - - notifier.NotifyOfRequest(request); - latch.Await(); - - EXPECT_EQ(observer.delete_device_request_, &request); -} - -TEST(FastPairHttpNotifierTest, TestNotifyUserDeleteDeviceResponse) { - proto::UserDeleteDeviceResponse response; - CountDownLatch latch(1); - FastPairHttpNotifierObserver observer(&latch); - FastPairHttpNotifier notifier; - notifier.AddObserver(&observer); - - notifier.NotifyOfResponse(response); - latch.Await(); - - EXPECT_EQ(observer.delete_device_response_, &response); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/testing/BUILD b/fastpair/testing/BUILD deleted file mode 100644 index 8ab64f5fc3..0000000000 --- a/fastpair/testing/BUILD +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2022 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. - -licenses(["notice"]) - -cc_library( - name = "testing", - srcs = [ - "fast_pair_service_data_creator.cc", - ], - hdrs = [ - "fast_pair_service_data_creator.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "@com_google_absl//absl/strings", - ], -) diff --git a/fastpair/testing/fast_pair_service_data_creator.cc b/fastpair/testing/fast_pair_service_data_creator.cc deleted file mode 100644 index efbb2749b4..0000000000 --- a/fastpair/testing/fast_pair_service_data_creator.cc +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2022 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. - -#include "fastpair/testing/fast_pair_service_data_creator.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "absl/strings/escaping.h" - -namespace nearby { -namespace fastpair { - -FastPairServiceDataCreator::Builder::Builder() = default; - -FastPairServiceDataCreator::Builder::~Builder() = default; - -FastPairServiceDataCreator::Builder& -FastPairServiceDataCreator::Builder::SetHeader(uint8_t byte) { - header_ = byte; - return *this; -} - -FastPairServiceDataCreator::Builder& -FastPairServiceDataCreator::Builder::SetModelId(absl::string_view model_id) { - model_id_ = std::string(model_id); - return *this; -} - -FastPairServiceDataCreator::Builder& -FastPairServiceDataCreator::Builder::AddExtraFieldHeader(uint8_t header) { - extra_field_headers_.push_back(header); - return *this; -} - -FastPairServiceDataCreator::Builder& -FastPairServiceDataCreator::Builder::AddExtraField(absl::string_view field) { - extra_fields_.push_back(std::string(field)); - return *this; -} - -std::unique_ptr -FastPairServiceDataCreator::Builder::Build() { - return std::make_unique( - header_, model_id_, extra_field_headers_, extra_fields_); -} - -FastPairServiceDataCreator::FastPairServiceDataCreator( - std::optional header, std::optional model_id, - std::vector extra_field_headers, - std::vector extra_fields) - : header_(header), - model_id_(model_id), - extra_field_headers_(extra_field_headers), - extra_fields_(extra_fields) {} - -FastPairServiceDataCreator::~FastPairServiceDataCreator() = default; - -std::vector FastPairServiceDataCreator::CreateServiceData() { - if (extra_field_headers_.size() != extra_fields_.size()) { - return std::vector(); - } - - std::vector service_data; - - if (header_) service_data.push_back(header_.value()); - - if (model_id_) { - std::string model_id_bytes = absl::HexStringToBytes(model_id_.value()); - std::move(std::begin(model_id_bytes), std::end(model_id_bytes), - std::back_inserter(service_data)); - } - - for (size_t i = 0; i < extra_field_headers_.size(); i++) { - service_data.push_back(extra_field_headers_[i]); - std::string extra_field_bytes = absl::HexStringToBytes(extra_fields_[i]); - std::move(std::begin(extra_field_bytes), std::end(extra_field_bytes), - std::back_inserter(service_data)); - } - - return service_data; -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/testing/fast_pair_service_data_creator.h b/fastpair/testing/fast_pair_service_data_creator.h deleted file mode 100644 index 64fcef8845..0000000000 --- a/fastpair/testing/fast_pair_service_data_creator.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2022 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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_TESTING_FAST_PAIR_SERVICE_DATA_CREATOR_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_TESTING_FAST_PAIR_SERVICE_DATA_CREATOR_H_ - -#include -#include -#include -#include -#include -#include - -namespace nearby { -namespace fastpair { - -// Convenience class with Builder to create byte arrays which represent Fast -// Pair Service Data. -class FastPairServiceDataCreator { - public: - class Builder { - public: - Builder(); - Builder(const Builder&) = delete; - Builder& operator=(const Builder&) = delete; - ~Builder(); - - Builder& SetHeader(uint8_t byte); - Builder& SetModelId(std::string_view model_id); - Builder& AddExtraFieldHeader(uint8_t header); - Builder& AddExtraField(std::string_view field); - std::unique_ptr Build(); - - private: - std::optional header_; - std::optional model_id_ = std::nullopt; - std::vector extra_field_headers_; - std::vector extra_fields_; - }; - - FastPairServiceDataCreator(std::optional header, - std::optional model_id, - std::vector extra_field_headers, - std::vector extra_fields); - FastPairServiceDataCreator(const FastPairServiceDataCreator&) = delete; - FastPairServiceDataCreator& operator=(const FastPairServiceDataCreator&) = - delete; - ~FastPairServiceDataCreator(); - - std::vector CreateServiceData(); - - private: - std::optional header_; - std::optional model_id_; - std::vector extra_field_headers_; - std::vector extra_fields_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_TESTING_FAST_PAIR_SERVICE_DATA_CREATOR_H_ diff --git a/fastpair/ui/BUILD b/fastpair/ui/BUILD deleted file mode 100644 index 9173a348ed..0000000000 --- a/fastpair/ui/BUILD +++ /dev/null @@ -1,126 +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. - -licenses(["notice"]) - -cc_library( - name = "fast_pair_ui", - srcs = [ - "fast_pair/fast_pair_notification_controller.cc", - "fast_pair/fast_pair_presenter_impl.cc", - "ui_broker_impl.cc", - ], - hdrs = [ - "actions.h", - "fast_pair/fast_pair_notification_controller.h", - "fast_pair/fast_pair_presenter.h", - "fast_pair/fast_pair_presenter_impl.h", - "ui_broker.h", - "ui_broker_impl.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//fastpair/repository", - "//internal/base", - "//internal/platform:types", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - ], -) - -cc_library( - name = "fake_fast_pair_ui", - testonly = True, - hdrs = [ - "fast_pair/fake_fast_pair_notification_controller_observer.h", - "fast_pair/fake_fast_pair_presenter.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":fast_pair_ui", - "//fastpair/common", - "//fastpair/repository", - "//internal/platform:types", - ], -) - -cc_library( - name = "mock_fast_pair_ui", - hdrs = [ - "fast_pair/mock_fast_pair_notification_controller.h", - "mock_ui_broker.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - ":fast_pair_ui", - "//fastpair/common", - "//fastpair/repository", - "//internal/base", - "//testing/base/public:gunit_for_library", - ], -) - -cc_test( - name = "fast_pair_notification_controller_test", - srcs = [ - "fast_pair/fast_pair_notification_controller_test.cc", - ], - deps = [ - ":fake_fast_pair_ui", - ":fast_pair_ui", - "//fastpair/common", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_pair_presenter_test", - srcs = [ - "fast_pair/fast_pair_presenter_impl_test.cc", - ], - deps = [ - ":fake_fast_pair_ui", - ":fast_pair_ui", - "//fastpair/common", - "//fastpair/proto:fastpair_cc_proto", - "//internal/platform:types", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "ui_broker_test", - srcs = [ - "ui_broker_impl_test.cc", - ], - deps = [ - ":fake_fast_pair_ui", - ":fast_pair_ui", - "//internal/platform/implementation/g3", # build_cleaner: keep - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/fastpair/ui/actions.h b/fastpair/ui/actions.h deleted file mode 100644 index d8b85a896b..0000000000 --- a/fastpair/ui/actions.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_ACTIONS_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_ACTIONS_H_ - -namespace nearby { -namespace fastpair { - -enum class DiscoveryAction { - kUnknown = 0, - kPairToDevice = 1, - kSaveDeviceToAccount = 2, - kDismissedByUser = 3, - kDismissedByOs = 4, - kLearnMore = 5, - kDone = 6, - kDismissedByTimeout = 7, -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_ACTIONS_H_ diff --git a/fastpair/ui/fast_pair/fake_fast_pair_notification_controller_observer.h b/fastpair/ui/fast_pair/fake_fast_pair_notification_controller_observer.h deleted file mode 100644 index 0416beda40..0000000000 --- a/fastpair/ui/fast_pair/fake_fast_pair_notification_controller_observer.h +++ /dev/null @@ -1,78 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAKE_FAST_PAIR_NOTIFICATION_CONTROLLER_OBSERVER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAKE_FAST_PAIR_NOTIFICATION_CONTROLLER_OBSERVER_H_ - -#include -#include -#include -#include - -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/mutex_lock.h" - -namespace nearby { -namespace fastpair { -class FakeFastPairNotificationControllerObserver - : public FastPairNotificationController::Observer { - public: - explicit FakeFastPairNotificationControllerObserver( - CountDownLatch* on_device_updated_latch, - CountDownLatch* on_pairing_result_latch) { - on_device_updated_latch_ = on_device_updated_latch; - on_pairing_result_latch_ = on_pairing_result_latch; - } - - void OnUpdateDevice(FastPairDevice& device) override { - MutexLock lock(&mutex_); - device_ = &const_cast(device); - if (on_device_updated_latch_) { - on_device_updated_latch_->CountDown(); - } - } - - void OnPairingResult(FastPairDevice& device, bool success) override { - MutexLock lock(&mutex_); - pairing_result_ = success; - device_ = &const_cast(device); - if (on_pairing_result_latch_) { - on_pairing_result_latch_->CountDown(); - } - } - - FastPairDevice* GetDevice() { - MutexLock lock(&mutex_); - return device_; - } - - std::optional GetPairingResult() { - MutexLock lock(&mutex_); - return pairing_result_; - } - - private: - Mutex mutex_; - CountDownLatch* on_device_updated_latch_; - CountDownLatch* on_pairing_result_latch_; - FastPairDevice* device_ ABSL_GUARDED_BY(mutex_) = nullptr; - std::optional pairing_result_ ABSL_GUARDED_BY(mutex_); -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAKE_FAST_PAIR_NOTIFICATION_CONTROLLER_OBSERVER_H_ diff --git a/fastpair/ui/fast_pair/fake_fast_pair_presenter.h b/fastpair/ui/fast_pair/fake_fast_pair_presenter.h deleted file mode 100644 index 052fd95577..0000000000 --- a/fastpair/ui/fast_pair/fake_fast_pair_presenter.h +++ /dev/null @@ -1,77 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAKE_FAST_PAIR_PRESENTER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAKE_FAST_PAIR_PRESENTER_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include "fastpair/ui/fast_pair/fast_pair_presenter.h" -#include "fastpair/ui/fast_pair/fast_pair_presenter_impl.h" - -namespace nearby { -namespace fastpair { - -class FakeFastPairPresenter : public FastPairPresenter { - public: - void ShowDiscovery(FastPairDevice& device, - FastPairNotificationController& notification_controller, - DiscoveryCallback callback) override { - show_discovery_ = true; - version_changed_ = true; - callback(DiscoveryAction::kPairToDevice); - } - - void ShowPairingResult( - FastPairDevice& device, - FastPairNotificationController& notification_controller, - bool success) override { - pairing_result_changed_ = true; - } - - bool show_discovery() { return show_discovery_; } - - bool version_changed() { return version_changed_; } - - bool pairing_result_changed() { return pairing_result_changed_; } - - private: - bool show_discovery_ = false; - bool version_changed_ = false; - bool pairing_result_changed_ = false; -}; - -class FakeFastPairPresenterFactory : public FastPairPresenterImpl::Factory { - public: - std::unique_ptr CreateInstance() override { - auto fake_fast_pair_presenter = std::make_unique(); - fake_fast_pair_presenter_ = fake_fast_pair_presenter.get(); - return fake_fast_pair_presenter; - } - - FakeFastPairPresenter* fake_fast_pair_presenter() { - return fake_fast_pair_presenter_; - } - - protected: - FakeFastPairPresenter* fake_fast_pair_presenter_ = nullptr; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAKE_FAST_PAIR_PRESENTER_H_ diff --git a/fastpair/ui/fast_pair/fast_pair_notification_controller.cc b/fastpair/ui/fast_pair/fast_pair_notification_controller.cc deleted file mode 100644 index 60aa5b51fc..0000000000 --- a/fastpair/ui/fast_pair/fast_pair_notification_controller.cc +++ /dev/null @@ -1,72 +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. - -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" - -#include - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/actions.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { -void FastPairNotificationController::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void FastPairNotificationController::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -void FastPairNotificationController::NotifyShowDiscovery( - FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__; - for (Observer* observer : observers_.GetObservers()) { - observer->OnUpdateDevice(device); - } -} - -void FastPairNotificationController::NotifyShowPairingResult( - FastPairDevice& device, bool success) { - NEARBY_LOGS(INFO) << __func__; - for (Observer* observer : observers_.GetObservers()) { - observer->OnPairingResult(device, success); - } -} - -void FastPairNotificationController::ShowGuestDiscoveryNotification( - FastPairDevice& device, DiscoveryCallback callback) { - callback_ = std::move(callback); - NEARBY_LOGS(INFO) << __func__ << "Notify show guest discovery notification. "; - NotifyShowDiscovery(device); -} - -void FastPairNotificationController::ShowPairingResultNotification( - FastPairDevice& device, bool success) { - NEARBY_LOGS(INFO) << __func__ << "Notify show pairing result notification. "; - NotifyShowPairingResult(device, success); -} - -void FastPairNotificationController::OnDiscoveryClicked( - DiscoveryAction action) { - NEARBY_LOGS(INFO) << __func__ - << "Discovery action button is clicked in the app."; - DCHECK(callback_); - callback_(action); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/ui/fast_pair/fast_pair_notification_controller.h b/fastpair/ui/fast_pair/fast_pair_notification_controller.h deleted file mode 100644 index 617304cac4..0000000000 --- a/fastpair/ui/fast_pair/fast_pair_notification_controller.h +++ /dev/null @@ -1,74 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_NOTIFICATION_CONTROLLER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_NOTIFICATION_CONTROLLER_H_ - -#include "absl/functional/any_invocable.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/actions.h" -#include "internal/base/observer_list.h" - -namespace nearby { -namespace fastpair { - -using DiscoveryCallback = absl::AnyInvocable; - -enum class FastPairNotificationDismissReason { - kDismissedByUser, - kDismissedByOs, - kDismissedByTimeout, -}; -// This controller creates and manages messages for each FastPair corresponding -// notification event. -class FastPairNotificationController { - public: - class Observer { - public: - virtual ~Observer() = default; - virtual void OnUpdateDevice(FastPairDevice& device) = 0; - virtual void OnPairingResult(FastPairDevice& device, bool success) = 0; - }; - - FastPairNotificationController() = default; - ~FastPairNotificationController() = default; - FastPairNotificationController(const FastPairNotificationController&) = - delete; - FastPairNotificationController& operator=( - const FastPairNotificationController&) = delete; - - // Observer process - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - void NotifyShowDiscovery(FastPairDevice& device); - void NotifyShowPairingResult(FastPairDevice& device, bool success); - - // Creates and displays corresponding notification. - void ShowGuestDiscoveryNotification(FastPairDevice& device, - DiscoveryCallback callback); - - void ShowPairingResultNotification(FastPairDevice& device, bool success); - - // Triggers callback when the related action is clicked. - void OnDiscoveryClicked(DiscoveryAction action); - - private: - DiscoveryCallback callback_; - ObserverList observers_; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_NOTIFICATION_CONTROLLER_H_ diff --git a/fastpair/ui/fast_pair/fast_pair_notification_controller_test.cc b/fastpair/ui/fast_pair/fast_pair_notification_controller_test.cc deleted file mode 100644 index a417096953..0000000000 --- a/fastpair/ui/fast_pair/fast_pair_notification_controller_test.cc +++ /dev/null @@ -1,84 +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. - -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" - -#include - -#include "gtest/gtest.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fake_fast_pair_notification_controller_observer.h" -#include "internal/platform/count_down_latch.h" - -namespace nearby { -namespace fastpair { -namespace { - -const int64_t kDeviceId = 10148625; -const char kDeviceName[] = "Pixel Buds Pro"; -constexpr absl::string_view kModelId("9adb11"); -constexpr absl::string_view kBleAddress("AA:BB:CC:DD:EE:00"); - -TEST(FastPairNotificationControllerTest, ShowGuestDiscoveryNotification) { - FastPairNotificationController notification_controller; - proto::GetObservedDeviceResponse response; - DeviceMetadata device_metadata(response); - - FastPairDevice device(kModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - device.SetMetadata(device_metadata); - CountDownLatch on_update_device_latch(1); - CountDownLatch on_click_latch(1); - FakeFastPairNotificationControllerObserver observer(&on_update_device_latch, - nullptr); - notification_controller.AddObserver(&observer); - EXPECT_EQ(observer.GetDevice(), nullptr); - DiscoveryAction discovery_action = DiscoveryAction::kUnknown; - notification_controller.ShowGuestDiscoveryNotification( - device, [&](DiscoveryAction action) { - on_click_latch.CountDown(); - discovery_action = action; - }); - on_update_device_latch.Await(); - EXPECT_EQ(observer.GetDevice(), &device); - notification_controller.OnDiscoveryClicked(DiscoveryAction::kPairToDevice); - on_click_latch.Await(); - EXPECT_EQ(discovery_action, DiscoveryAction::kPairToDevice); -} - -TEST(FastPairNotificationControllerTest, ShowPairingResultNotification) { - FastPairNotificationController notification_controller; - proto::GetObservedDeviceResponse response; - DeviceMetadata device_metadata(response); - FastPairDevice device(kModelId, kBleAddress, - Protocol::kFastPairInitialPairing); - device.SetMetadata(device_metadata); - - CountDownLatch on_pairing_result_latch(1); - FakeFastPairNotificationControllerObserver observer(nullptr, - &on_pairing_result_latch); - notification_controller.AddObserver(&observer); - EXPECT_FALSE(observer.GetPairingResult().has_value()); - EXPECT_EQ(observer.GetDevice(), nullptr); - notification_controller.ShowPairingResultNotification(device, true); - on_pairing_result_latch.Await(); - EXPECT_EQ(observer.GetDevice(), &device); - EXPECT_TRUE(observer.GetPairingResult().has_value()); - EXPECT_TRUE(observer.GetPairingResult().value()); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/ui/fast_pair/fast_pair_presenter.h b/fastpair/ui/fast_pair/fast_pair_presenter.h deleted file mode 100644 index 50da908ad8..0000000000 --- a/fastpair/ui/fast_pair/fast_pair_presenter.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_H_ - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" - -namespace nearby { -namespace fastpair { - -// This Presenter creates and manages UI component with Notification Controller. -class FastPairPresenter { - public: - virtual void ShowDiscovery( - FastPairDevice& device, - FastPairNotificationController& notification_controller, - DiscoveryCallback callback) = 0; - virtual void ShowPairingResult( - FastPairDevice& device, - FastPairNotificationController& notification_controller, - bool success) = 0; - - virtual ~FastPairPresenter() = default; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_H_ diff --git a/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc b/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc deleted file mode 100644 index 7a5d98e55e..0000000000 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc +++ /dev/null @@ -1,60 +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. - -#include "fastpair/ui/fast_pair/fast_pair_presenter_impl.h" - -#include -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" - -namespace nearby { -namespace fastpair { - -// static -FastPairPresenterImpl::Factory* - FastPairPresenterImpl::Factory::g_test_factory_ = nullptr; - -// static -std::unique_ptr FastPairPresenterImpl::Factory::Create() { - if (g_test_factory_) { - return g_test_factory_->CreateInstance(); - } - return std::make_unique(); -} - -// static -void FastPairPresenterImpl::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -FastPairPresenterImpl::Factory::~Factory() = default; - -void FastPairPresenterImpl::ShowDiscovery( - FastPairDevice& device, - FastPairNotificationController& notification_controller, - DiscoveryCallback callback) { - notification_controller.ShowGuestDiscoveryNotification(device, - std::move(callback)); -} - -void FastPairPresenterImpl::ShowPairingResult( - FastPairDevice& device, - FastPairNotificationController& notification_controller, bool success) { - notification_controller.ShowPairingResultNotification(device, success); -} -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/ui/fast_pair/fast_pair_presenter_impl.h b/fastpair/ui/fast_pair/fast_pair_presenter_impl.h deleted file mode 100644 index f606658cad..0000000000 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl.h +++ /dev/null @@ -1,59 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_IMPL_H_ - -#include - -#include "fastpair/common/device_metadata.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include "fastpair/ui/fast_pair/fast_pair_presenter.h" - -namespace nearby { -namespace fastpair { - -class FastPairPresenterImpl : public FastPairPresenter { - public: - class Factory { - public: - static std::unique_ptr Create(); - - static void SetFactoryForTesting(Factory* g_test_factory); - - protected: - virtual ~Factory(); - virtual std::unique_ptr CreateInstance() = 0; - - private: - static Factory* g_test_factory_; - }; - - FastPairPresenterImpl() = default; - FastPairPresenterImpl(const FastPairPresenterImpl&) = delete; - FastPairPresenterImpl& operator=(const FastPairPresenterImpl&) = delete; - - void ShowDiscovery(FastPairDevice& device, - FastPairNotificationController& notification_controller, - DiscoveryCallback callback) override; - void ShowPairingResult( - FastPairDevice& device, - FastPairNotificationController& notification_controller, - bool success) override; -}; -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_IMPL_H_ diff --git a/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc b/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc deleted file mode 100644 index d3a00c5c06..0000000000 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc +++ /dev/null @@ -1,113 +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. - -#include "fastpair/ui/fast_pair/fast_pair_presenter_impl.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fake_fast_pair_notification_controller_observer.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include "internal/platform/count_down_latch.h" - -namespace nearby { -namespace fastpair { -const int64_t kDeviceId = 10148625; -constexpr absl::string_view kModelId = "000000"; -constexpr absl::string_view kAddress = "00:00:00:00:00:00"; -constexpr absl::string_view kPublicKey = "test public key"; -constexpr absl::string_view kInitialPairingdescription = - "InitialPairingdescription"; - -namespace { -// A gMock matcher to match proto values. Use this matcher like: -// request/response proto, expected_proto; -// EXPECT_THAT(proto, MatchesProto(expected_proto)); -MATCHER_P( - MatchesProto, expected_proto, - absl::StrCat(negation ? "does not match" : "matches", - testing::PrintToString(expected_proto.SerializeAsString()))) { - return arg.SerializeAsString() == expected_proto.SerializeAsString(); -} - -TEST(FastPairPresenterImplTest, ShowDiscovery) { - // Sets up proto::GetObservedDeviceResponse - proto::GetObservedDeviceResponse response_proto; - auto* device = response_proto.mutable_device(); - device->set_id(kDeviceId); - auto* observed_device_strings = response_proto.mutable_strings(); - observed_device_strings->set_initial_pairing_description( - kInitialPairingdescription); - DeviceMetadata device_metadata(response_proto); - FastPairDevice fast_pair_device(kModelId, kAddress, - Protocol::kFastPairInitialPairing); - - fast_pair_device.SetMetadata(device_metadata); - - FastPairNotificationController notification_controller; - CountDownLatch on_update_device_latch(1); - CountDownLatch on_click_latch(1); - FakeFastPairNotificationControllerObserver observer(&on_update_device_latch, - nullptr); - notification_controller.AddObserver(&observer); - DiscoveryAction discovery_action = DiscoveryAction::kUnknown; - FastPairPresenterImpl fast_pair_presenter; - fast_pair_presenter.ShowDiscovery(fast_pair_device, notification_controller, - [&](DiscoveryAction action) { - on_click_latch.CountDown(); - discovery_action = action; - }); - on_update_device_latch.Await(); - EXPECT_EQ(observer.GetDevice()->GetMetadata()->GetFastPairVersion(), - DeviceFastPairVersion::kV1); - EXPECT_THAT(observer.GetDevice()->GetMetadata()->GetResponse(), - MatchesProto(response_proto)); -} - -TEST(FastPairPresenterImplTest, ShowPairingResult) { - // Sets up proto::GetObservedDeviceResponse - proto::GetObservedDeviceResponse response_proto; - auto* device = response_proto.mutable_device(); - device->set_id(kDeviceId); - auto* observed_device_strings = response_proto.mutable_strings(); - observed_device_strings->set_initial_pairing_description( - kInitialPairingdescription); - DeviceMetadata device_metadata(response_proto); - FastPairDevice fast_pair_device(kModelId, kAddress, - Protocol::kFastPairInitialPairing); - - fast_pair_device.SetMetadata(device_metadata); - - FastPairNotificationController notification_controller; - CountDownLatch on_pairing_result_latch(1); - FakeFastPairNotificationControllerObserver observer(nullptr, - &on_pairing_result_latch); - notification_controller.AddObserver(&observer); - FastPairPresenterImpl fast_pair_presenter; - fast_pair_presenter.ShowPairingResult(fast_pair_device, - notification_controller, true); - on_pairing_result_latch.Await(); - EXPECT_EQ(observer.GetDevice()->GetMetadata()->GetFastPairVersion(), - DeviceFastPairVersion::kV1); - EXPECT_THAT(observer.GetDevice()->GetMetadata()->GetResponse(), - MatchesProto(response_proto)); - EXPECT_TRUE(observer.GetPairingResult().has_value()); - EXPECT_TRUE(observer.GetPairingResult().value()); -} -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/ui/fast_pair/mock_fast_pair_notification_controller.h b/fastpair/ui/fast_pair/mock_fast_pair_notification_controller.h deleted file mode 100644 index e8427c5792..0000000000 --- a/fastpair/ui/fast_pair/mock_fast_pair_notification_controller.h +++ /dev/null @@ -1,45 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_MOCK_FAST_PAIR_NOTIFICATION_CONTROLLER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_MOCK_FAST_PAIR_NOTIFICATION_CONTROLLER_H_ - -#include "gmock/gmock.h" -#include "fastpair/common/device_metadata.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" - -namespace nearby { -namespace fastpair { -class MockFastPairNotificationController - : public FastPairNotificationController { - public: - MOCK_METHOD(void, ShowGuestDiscoveryNotification, - (FastPairDevice & device, DiscoveryCallback)); - MOCK_METHOD(void, OnDiscoveryClicked, (DiscoveryAction)); - MOCK_METHOD(void, AddObserver, (Observer*)); - MOCK_METHOD(void, RemoveObserver, (Observer*)); - - void NotifyShowDiscovery(FastPairDevice& device) { - for (Observer* observer : observers_.GetObservers()) { - observer->OnUpdateDevice(device); - } - } - - private: - ObserverList observers_; -}; -} // namespace fastpair -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_MOCK_FAST_PAIR_NOTIFICATION_CONTROLLER_H_ diff --git a/fastpair/ui/mock_ui_broker.h b/fastpair/ui/mock_ui_broker.h deleted file mode 100644 index 70241c6870..0000000000 --- a/fastpair/ui/mock_ui_broker.h +++ /dev/null @@ -1,56 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_MOCK_UI_BROKER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_MOCK_UI_BROKER_H_ - -#include "gmock/gmock.h" -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include "fastpair/ui/ui_broker.h" -#include "internal/base/observer_list.h" - -namespace nearby { -namespace fastpair { - -class MockUIBroker : public UIBroker { - public: - MOCK_METHOD(void, ShowDiscovery, - (FastPairDevice&, FastPairNotificationController&), (override)); - - MOCK_METHOD(void, ShowPairingResult, - (FastPairDevice&, FastPairNotificationController&, bool), - (override)); - - void AddObserver(Observer* observer) override { - observers_.AddObserver(observer); - } - - void RemoveObserver(Observer* observer) override { - observers_.RemoveObserver(observer); - } - - void NotifyDiscoveryAction(FastPairDevice& device, DiscoveryAction action) { - for (auto& observer : observers_.GetObservers()) - observer->OnDiscoveryAction(device, action); - } - - private: - ObserverList observers_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_MOCK_UI_BROKER_H_ diff --git a/fastpair/ui/ui_broker.h b/fastpair/ui/ui_broker.h deleted file mode 100644 index a6cfe1f254..0000000000 --- a/fastpair/ui/ui_broker.h +++ /dev/null @@ -1,56 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_UI_BROKER_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_UI_BROKER_H_ - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/protocol.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" - -namespace nearby { -namespace fastpair { - -// The UIBroker is the entry point for the UI component in the FastPair system. -// It is responsible for brokering the 'show UI' calls to the correct Presenter -// implementation, and exposing user actions taken on that UI. -class UIBroker { - public: - class Observer { - public: - virtual ~Observer() = default; - virtual void OnDiscoveryAction(FastPairDevice& device, - DiscoveryAction action) = 0; - }; - - virtual ~UIBroker() = default; - - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; - - virtual void ShowDiscovery( - FastPairDevice& device, - FastPairNotificationController& notification_controller) = 0; - - virtual void ShowPairingResult( - FastPairDevice& device, - FastPairNotificationController& notification_controller, - bool success) = 0; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_UI_BROKER_H_ diff --git a/fastpair/ui/ui_broker_impl.cc b/fastpair/ui/ui_broker_impl.cc deleted file mode 100644 index 6b3c7b3c06..0000000000 --- a/fastpair/ui/ui_broker_impl.cc +++ /dev/null @@ -1,87 +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. - -#include "fastpair/ui/ui_broker_impl.h" - -#include -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/common/protocol.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fast_pair_presenter.h" -#include "fastpair/ui/fast_pair/fast_pair_presenter_impl.h" -#include "internal/platform/logging.h" - -namespace nearby { -namespace fastpair { - -UIBrokerImpl::UIBrokerImpl() - : fast_pair_presenter_(FastPairPresenterImpl::Factory::Create()) {} - -void UIBrokerImpl::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void UIBrokerImpl::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -void UIBrokerImpl::ShowDiscovery( - FastPairDevice& device, - FastPairNotificationController& notification_controller) { - switch (device.GetProtocol()) { - case Protocol::kFastPairInitialPairing: - case Protocol::kFastPairSubsequentPairing: - fast_pair_presenter_->ShowDiscovery( - device, notification_controller, [&](DiscoveryAction action) { - NEARBY_LOGS(VERBOSE) - << __func__ - << "ui broker notify discovery action of device: " << device; - NotifyDiscoveryAction(device, action); - }); - break; - case Protocol::kFastPairRetroactivePairing: - NEARBY_LOGS(ERROR) - << __func__ - << ": Retroactive Pairing should not show discovery Halfsheet."; - break; - } -} - -void UIBrokerImpl::ShowPairingResult( - FastPairDevice& device, - FastPairNotificationController& notification_controller, bool success) { - NEARBY_LOGS(VERBOSE) << __func__; - switch (device.GetProtocol()) { - case Protocol::kFastPairInitialPairing: - case Protocol::kFastPairSubsequentPairing: - fast_pair_presenter_->ShowPairingResult(device, notification_controller, - success); - break; - case Protocol::kFastPairRetroactivePairing: - // In this scenario, we don't show the error UI because it would be - // misleading, since a pair failure is a retroactive pair failure. - break; - } -} - -void UIBrokerImpl::NotifyDiscoveryAction(FastPairDevice& device, - DiscoveryAction action) { - for (auto& observer : observers_.GetObservers()) - observer->OnDiscoveryAction(device, action); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/ui/ui_broker_impl.h b/fastpair/ui/ui_broker_impl.h deleted file mode 100644 index 039b448bbb..0000000000 --- a/fastpair/ui/ui_broker_impl.h +++ /dev/null @@ -1,55 +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. - -#ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_BROKER_IMPL_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_UI_BROKER_IMPL_H_ - -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fast_pair_presenter.h" -#include "fastpair/ui/ui_broker.h" -#include "internal/base/observer_list.h" - -namespace nearby { -namespace fastpair { - -class UIBrokerImpl : public UIBroker { - public: - UIBrokerImpl(); - UIBrokerImpl(const UIBrokerImpl &) = delete; - UIBrokerImpl &operator=(const UIBrokerImpl &) = delete; - - void AddObserver(Observer *observer) override; - void RemoveObserver(Observer *observer) override; - void ShowDiscovery( - FastPairDevice &device, - FastPairNotificationController ¬ification_controller) override; - void ShowPairingResult( - FastPairDevice &device, - FastPairNotificationController ¬ification_controller, - bool success) override; - - private: - void NotifyDiscoveryAction(FastPairDevice &device, DiscoveryAction action); - - std::unique_ptr fast_pair_presenter_; - ObserverList observers_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_BROKER_IMPL_H_ diff --git a/fastpair/ui/ui_broker_impl_test.cc b/fastpair/ui/ui_broker_impl_test.cc deleted file mode 100644 index 8fe2910770..0000000000 --- a/fastpair/ui/ui_broker_impl_test.cc +++ /dev/null @@ -1,80 +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. - -#include "fastpair/ui/ui_broker_impl.h" - -#include - -#include "gtest/gtest.h" -#include "fastpair/ui/actions.h" -#include "fastpair/ui/fast_pair/fake_fast_pair_presenter.h" -#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include "fastpair/ui/ui_broker.h" - -namespace nearby { -namespace fastpair { -namespace { - -constexpr absl::string_view kModelId = "718C17"; -constexpr absl::string_view kAddress = "74:74:46:01:6C:21"; - -class UIBrokerImplTest : public ::testing::Test, public UIBroker::Observer { - protected: - void SetUp() override { - presenter_factory_ = std::make_unique(); - FastPairPresenterImpl::Factory::SetFactoryForTesting( - presenter_factory_.get()); - ui_broker_ = std::make_unique(); - ui_broker_->AddObserver(this); - } - - void OnDiscoveryAction(FastPairDevice& device, - DiscoveryAction action) override { - on_discovery_action_notified_ = true; - discovery_action_ = action; - } - - std::unique_ptr ui_broker_; - FastPairNotificationController notification_controller_; - std::unique_ptr presenter_factory_; - DiscoveryAction discovery_action_; - bool on_discovery_action_notified_ = false; -}; - -TEST_F(UIBrokerImplTest, ShowDiscovery) { - FastPairDevice device(kModelId, kAddress, Protocol::kFastPairInitialPairing); - ui_broker_->ShowDiscovery(device, notification_controller_); - EXPECT_TRUE(presenter_factory_->fake_fast_pair_presenter()->show_discovery()); - EXPECT_TRUE(on_discovery_action_notified_); - EXPECT_EQ(DiscoveryAction::kPairToDevice, discovery_action_); -} - -TEST_F(UIBrokerImplTest, ShowDiscoveryWithoutObserver) { - FastPairDevice device(kModelId, kAddress, Protocol::kFastPairInitialPairing); - ui_broker_->RemoveObserver(this); - ui_broker_->ShowDiscovery(device, notification_controller_); - EXPECT_TRUE(presenter_factory_->fake_fast_pair_presenter()->show_discovery()); - EXPECT_FALSE(on_discovery_action_notified_); -} - -TEST_F(UIBrokerImplTest, ShowPairingResult) { - FastPairDevice device(kModelId, kAddress, Protocol::kFastPairInitialPairing); - ui_broker_->ShowPairingResult(device, notification_controller_, true); - EXPECT_TRUE( - presenter_factory_->fake_fast_pair_presenter()->pairing_result_changed()); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/internal/analytics/BUILD b/internal/analytics/BUILD index b39ce58336..bd67c6eaa9 100644 --- a/internal/analytics/BUILD +++ b/internal/analytics/BUILD @@ -20,10 +20,10 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//fastpair:__subpackages__", "//location/nearby/analytics/cpp:__subpackages__", "//location/nearby/cpp/experiments:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ "//internal/proto/analytics:connections_log_cc_proto", diff --git a/internal/base/BUILD b/internal/base/BUILD index 689613f981..6c6d85aacb 100644 --- a/internal/base/BUILD +++ b/internal/base/BUILD @@ -22,11 +22,11 @@ cc_library( "observer_list.h", ], visibility = [ - "//fastpair:__subpackages__", "//internal/account:__subpackages__", "//internal/platform:__pkg__", "//internal/test:__pkg__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ "//internal/platform:types", @@ -44,9 +44,9 @@ cc_library( "bluetooth_address.h", ], visibility = [ - "//fastpair:__subpackages__", "//internal:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ "@com_google_absl//absl/strings", diff --git a/internal/network/BUILD b/internal/network/BUILD index 564d85d7c6..e2a2af5eef 100644 --- a/internal/network/BUILD +++ b/internal/network/BUILD @@ -25,11 +25,11 @@ cc_library( "utils.h", ], visibility = [ - "//fastpair:__subpackages__", "//internal:__pkg__", "//internal:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ "@com_google_absl//absl/status", @@ -54,11 +54,11 @@ cc_library( "http_status_code.h", ], visibility = [ - "//fastpair:__subpackages__", "//internal:__pkg__", "//internal:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":url", @@ -84,10 +84,10 @@ cc_library( ], defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"], visibility = [ - "//fastpair:__subpackages__", "//internal:__pkg__", "//internal:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":types", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 6b7b3aefe4..52d0ced01b 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -150,9 +150,9 @@ cc_library( ], visibility = [ "//connections/implementation:__subpackages__", - "//fastpair:__subpackages__", "//internal/platform/implementation:__subpackages__", "//presence:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":base", @@ -245,7 +245,6 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//fastpair:__subpackages__", "//internal/account:__subpackages__", "//internal/auth:__subpackages__", "//internal/auth/credential_store:__subpackages__", @@ -267,6 +266,7 @@ cc_library( "//location/nearby/testing/nearby_native:__subpackages__", "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":base", @@ -320,10 +320,10 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//fastpair:__subpackages__", "//internal/platform/implementation:__subpackages__", "//internal/test:__subpackages__", "//presence:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":base", @@ -355,9 +355,9 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//fastpair:__subpackages__", "//internal/platform/implementation:__subpackages__", "//presence:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":base", diff --git a/internal/platform/flags/BUILD b/internal/platform/flags/BUILD index 8be880bfbc..ca0c313472 100644 --- a/internal/platform/flags/BUILD +++ b/internal/platform/flags/BUILD @@ -19,11 +19,11 @@ cc_library( "nearby_platform_feature_flags.h", ], visibility = [ - "//fastpair:__subpackages__", "//internal:__subpackages__", "//location/nearby/cpp:__subpackages__", "//location/nearby/sharing:__subpackages__", "//location/nearby/testing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ "//internal/flags:flag_reader", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 7052b07e8a..bda8060e74 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -42,13 +42,13 @@ cc_library( name = "account_manager", hdrs = ["account_manager.h"], visibility = [ - "//fastpair:__subpackages__", "//internal/account:__pkg__", "//internal/platform/implementation:__subpackages__", "//internal/test:__subpackages__", "//location/nearby/cpp/sharing/clients/cpp:__subpackages__", "//location/nearby/sharing/sdk/quick_share_server:__pkg__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":account_info", @@ -107,7 +107,6 @@ cc_library( visibility = [ "//connections/implementation:__subpackages__", "//connections/implementation/analytics:__subpackages__", - "//fastpair:__subpackages__", "//internal/crypto_cros:__pkg__", "//internal/platform:__pkg__", "//internal/platform/implementation:__subpackages__", @@ -117,6 +116,7 @@ cc_library( "//location/nearby/cpp/sharing:__subpackages__", "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ "//internal/crypto_cros", @@ -169,12 +169,12 @@ cc_library( copts = ["-DNO_WEBRTC"], visibility = [ "//connections/implementation:__subpackages__", - "//fastpair/internal/mediums:__pkg__", "//internal/network:__subpackages__", "//internal/platform:__pkg__", "//internal/platform/implementation:__subpackages__", "//presence:__subpackages__", "//presence/implementation:__subpackages__", + "//third_party/nearby/fastpair/internal/mediums:__pkg__", ], deps = [ "//connections/implementation/proto:offline_wire_formats_cc_proto", diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index ed9b94b567..c5654bb064 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -136,7 +136,6 @@ cc_library( visibility = [ "//connections:__subpackages__", "//connections:partners", - "//fastpair:__subpackages__", "//internal/account:__subpackages__", "//internal/auth:__subpackages__", "//internal/crypto:__subpackages__", @@ -151,6 +150,7 @@ cc_library( "//location/nearby/sharing/sdk:__subpackages__", "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":comm", diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index b3252fd7a1..47fc7c206a 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -225,11 +225,11 @@ cc_library( "//chrome/chromeos/assistant/data_migration/lib:__pkg__", "//connections:__subpackages__", "//connections:partners", - "//fastpair:__subpackages__", "//internal/platform:__subpackages__", "//location/nearby:__subpackages__", "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], deps = [ ":comm", diff --git a/internal/platform/implementation/windows/generated/BUILD b/internal/platform/implementation/windows/generated/BUILD index 17f33234a5..676563e21a 100644 --- a/internal/platform/implementation/windows/generated/BUILD +++ b/internal/platform/implementation/windows/generated/BUILD @@ -42,10 +42,10 @@ cc_library( "shlwapi.lib", ], visibility = [ - "//fastpair:__subpackages__", "//internal:__subpackages__", "//internal/platform/implementation/windows:__subpackages__", "//location/nearby/apps/better_together/plugins:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/fastpair:__subpackages__", ], )