From 6b2f1b96eb26111e825375adfcc8077cad31ca4a Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Wed, 6 May 2026 13:52:54 -0700 Subject: [PATCH] remove unused code. PiperOrigin-RevId: 911531448 --- .github/workflows/validate.yaml | 12 - internal/interop/BUILD | 6 +- internal/platform/BUILD | 10 +- internal/platform/implementation/BUILD | 6 +- internal/platform/implementation/g3/BUILD | 2 +- .../platform/implementation/windows/BUILD | 2 +- presence/BUILD | 223 ----- presence/broadcast_options.h | 36 - presence/broadcast_options_test.cc | 53 -- presence/broadcast_request.h | 77 -- presence/credential_test.cc | 79 -- presence/data_element.h | 111 --- presence/data_types.h | 64 -- presence/device_motion.cc | 28 - presence/device_motion.h | 47 - presence/device_motion_test.cc | 61 -- presence/discovery_filter.cc | 36 - presence/discovery_filter.h | 43 - presence/discovery_filter_test.cc | 51 -- presence/discovery_options.h | 34 - presence/discovery_options_test.cc | 51 -- presence/fake_presence_client.cc | 67 -- presence/fake_presence_client.h | 73 -- presence/fake_presence_service.cc | 107 --- presence/fake_presence_service.h | 122 --- presence/fpp/BUILD | 93 -- presence/fpp/fpp/Cargo.lock | 25 - presence/fpp/fpp/Cargo.toml | 9 - presence/fpp/fpp/src/fspl_converter.rs | 37 - presence/fpp/fpp/src/fspl_converter_test.rs | 30 - presence/fpp/fpp/src/fused_presence_utils.rs | 107 --- presence/fpp/fpp/src/lib.rs | 37 - presence/fpp/fpp/src/presence_detector.rs | 131 --- .../fpp/fpp/src/presence_detector_test.rs | 105 --- presence/fpp/fpp_c_ffi/Cargo.lock | 105 --- presence/fpp/fpp_c_ffi/Cargo.toml | 11 - .../fpp/fpp_c_ffi/include/presence_detector.h | 148 ---- presence/fpp/fpp_c_ffi/src/handle_map.rs | 72 -- presence/fpp/fpp_c_ffi/src/lib.rs | 141 --- presence/fpp/fpp_manager.cc | 168 ---- presence/fpp/fpp_manager.h | 86 -- presence/fpp/fpp_manager_test.cc | 243 ----- presence/fpp/sensor_fusion_impl.cc | 68 -- presence/fpp/sensor_fusion_impl.h | 51 -- presence/fpp/sensor_fusion_test.cc | 110 --- presence/implementation/BUILD | 493 ----------- presence/implementation/action_factory.cc | 106 --- presence/implementation/action_factory.h | 45 - .../implementation/action_factory_test.cc | 107 --- .../implementation/advertisement_decoder.h | 59 -- .../advertisement_decoder_impl.cc | 287 ------ .../advertisement_decoder_impl.h | 51 -- .../advertisement_decoder_new_format_test.cc | 156 ---- .../advertisement_decoder_rust_impl.cc | 241 ----- .../advertisement_decoder_rust_impl.h | 61 -- .../advertisement_decoder_test.cc | 226 ----- .../implementation/advertisement_factory.cc | 236 ----- .../implementation/advertisement_factory.h | 63 -- .../advertisement_factory_test.cc | 148 ---- .../implementation/advertisement_filter.cc | 119 --- .../implementation/advertisement_filter.h | 46 - .../advertisement_filter_test.cc | 174 ---- .../implementation/base_broadcast_request.cc | 112 --- .../implementation/base_broadcast_request.h | 102 --- .../base_broadcast_request_test.cc | 94 -- presence/implementation/broadcast_manager.cc | 269 ------ presence/implementation/broadcast_manager.h | 109 --- .../implementation/broadcast_manager_test.cc | 177 ---- .../implementation/connection_authenticator.h | 103 --- .../connection_authenticator_impl.cc | 197 ----- .../connection_authenticator_impl.h | 85 -- .../connection_authenticator_impl_test.cc | 272 ------ presence/implementation/credential_manager.h | 115 --- .../implementation/credential_manager_impl.cc | 834 ------------------ .../implementation/credential_manager_impl.h | 262 ------ .../credential_manager_impl_test.cc | 721 --------------- presence/implementation/ldt.cc | 109 --- presence/implementation/ldt.h | 76 -- presence/implementation/ldt_stub.c | 47 - presence/implementation/ldt_test.cc | 98 -- presence/implementation/mediums/BUILD | 70 -- .../mediums/advertisement_data.h | 34 - presence/implementation/mediums/ble.h | 111 --- presence/implementation/mediums/ble_test.cc | 177 ---- presence/implementation/mediums/mediums.h | 41 - .../mock_connection_authenticator.h | 63 -- .../implementation/mock_credential_manager.h | 86 -- .../implementation/mock_service_controller.h | 82 -- presence/implementation/np_ldt.h | 125 --- presence/implementation/scan_manager.cc | 280 ------ presence/implementation/scan_manager.h | 109 --- presence/implementation/scan_manager_test.cc | 453 ---------- presence/implementation/sensor_fusion.h | 153 ---- presence/implementation/service_controller.h | 76 -- .../implementation/service_controller_impl.cc | 91 -- .../implementation/service_controller_impl.h | 110 --- .../service_controller_impl_test.cc | 102 --- presence/power_mode.h | 35 - presence/presence_action.cc | 31 - presence/presence_action.h | 41 - presence/presence_action_test.cc | 59 -- presence/presence_client.h | 85 -- presence/presence_client_impl.cc | 98 -- presence/presence_client_impl.h | 75 -- presence/presence_client_test.cc | 151 ---- presence/presence_device.cc | 172 ---- presence/presence_device.h | 129 --- presence/presence_device_provider.cc | 261 ------ presence/presence_device_provider.h | 94 -- presence/presence_device_provider_test.cc | 296 ------- presence/presence_device_test.cc | 201 ----- presence/presence_identity_test.cc | 44 - presence/presence_service.h | 72 -- presence/presence_service_impl.cc | 83 -- presence/presence_service_impl.h | 109 --- presence/presence_service_test.cc | 152 ---- presence/presence_zone.cc | 82 -- presence/presence_zone.h | 108 --- presence/presence_zone_test.cc | 221 ----- presence/proto/BUILD | 29 - presence/proto/presence_frame.proto | 205 ----- presence/rust/README | 1 - presence/scan_request.h | 151 ---- presence/scan_request_builder.cc | 89 -- presence/scan_request_builder.h | 56 -- presence/scan_request_builder_test.cc | 194 ---- 126 files changed, 13 insertions(+), 15052 deletions(-) delete mode 100644 presence/BUILD delete mode 100644 presence/broadcast_options.h delete mode 100644 presence/broadcast_options_test.cc delete mode 100644 presence/broadcast_request.h delete mode 100644 presence/credential_test.cc delete mode 100644 presence/data_element.h delete mode 100644 presence/data_types.h delete mode 100644 presence/device_motion.cc delete mode 100644 presence/device_motion.h delete mode 100644 presence/device_motion_test.cc delete mode 100644 presence/discovery_filter.cc delete mode 100644 presence/discovery_filter.h delete mode 100644 presence/discovery_filter_test.cc delete mode 100644 presence/discovery_options.h delete mode 100644 presence/discovery_options_test.cc delete mode 100644 presence/fake_presence_client.cc delete mode 100644 presence/fake_presence_client.h delete mode 100644 presence/fake_presence_service.cc delete mode 100644 presence/fake_presence_service.h delete mode 100644 presence/fpp/BUILD delete mode 100644 presence/fpp/fpp/Cargo.lock delete mode 100644 presence/fpp/fpp/Cargo.toml delete mode 100644 presence/fpp/fpp/src/fspl_converter.rs delete mode 100644 presence/fpp/fpp/src/fspl_converter_test.rs delete mode 100644 presence/fpp/fpp/src/fused_presence_utils.rs delete mode 100644 presence/fpp/fpp/src/lib.rs delete mode 100644 presence/fpp/fpp/src/presence_detector.rs delete mode 100644 presence/fpp/fpp/src/presence_detector_test.rs delete mode 100644 presence/fpp/fpp_c_ffi/Cargo.lock delete mode 100644 presence/fpp/fpp_c_ffi/Cargo.toml delete mode 100644 presence/fpp/fpp_c_ffi/include/presence_detector.h delete mode 100644 presence/fpp/fpp_c_ffi/src/handle_map.rs delete mode 100644 presence/fpp/fpp_c_ffi/src/lib.rs delete mode 100644 presence/fpp/fpp_manager.cc delete mode 100644 presence/fpp/fpp_manager.h delete mode 100644 presence/fpp/fpp_manager_test.cc delete mode 100644 presence/fpp/sensor_fusion_impl.cc delete mode 100644 presence/fpp/sensor_fusion_impl.h delete mode 100644 presence/fpp/sensor_fusion_test.cc delete mode 100644 presence/implementation/BUILD delete mode 100644 presence/implementation/action_factory.cc delete mode 100644 presence/implementation/action_factory.h delete mode 100644 presence/implementation/action_factory_test.cc delete mode 100644 presence/implementation/advertisement_decoder.h delete mode 100644 presence/implementation/advertisement_decoder_impl.cc delete mode 100644 presence/implementation/advertisement_decoder_impl.h delete mode 100644 presence/implementation/advertisement_decoder_new_format_test.cc delete mode 100644 presence/implementation/advertisement_decoder_rust_impl.cc delete mode 100644 presence/implementation/advertisement_decoder_rust_impl.h delete mode 100644 presence/implementation/advertisement_decoder_test.cc delete mode 100644 presence/implementation/advertisement_factory.cc delete mode 100644 presence/implementation/advertisement_factory.h delete mode 100644 presence/implementation/advertisement_factory_test.cc delete mode 100644 presence/implementation/advertisement_filter.cc delete mode 100644 presence/implementation/advertisement_filter.h delete mode 100644 presence/implementation/advertisement_filter_test.cc delete mode 100644 presence/implementation/base_broadcast_request.cc delete mode 100644 presence/implementation/base_broadcast_request.h delete mode 100644 presence/implementation/base_broadcast_request_test.cc delete mode 100644 presence/implementation/broadcast_manager.cc delete mode 100644 presence/implementation/broadcast_manager.h delete mode 100644 presence/implementation/broadcast_manager_test.cc delete mode 100644 presence/implementation/connection_authenticator.h delete mode 100644 presence/implementation/connection_authenticator_impl.cc delete mode 100644 presence/implementation/connection_authenticator_impl.h delete mode 100644 presence/implementation/connection_authenticator_impl_test.cc delete mode 100644 presence/implementation/credential_manager.h delete mode 100644 presence/implementation/credential_manager_impl.cc delete mode 100644 presence/implementation/credential_manager_impl.h delete mode 100644 presence/implementation/credential_manager_impl_test.cc delete mode 100644 presence/implementation/ldt.cc delete mode 100644 presence/implementation/ldt.h delete mode 100644 presence/implementation/ldt_stub.c delete mode 100644 presence/implementation/ldt_test.cc delete mode 100644 presence/implementation/mediums/BUILD delete mode 100644 presence/implementation/mediums/advertisement_data.h delete mode 100644 presence/implementation/mediums/ble.h delete mode 100644 presence/implementation/mediums/ble_test.cc delete mode 100644 presence/implementation/mediums/mediums.h delete mode 100644 presence/implementation/mock_connection_authenticator.h delete mode 100644 presence/implementation/mock_credential_manager.h delete mode 100644 presence/implementation/mock_service_controller.h delete mode 100644 presence/implementation/np_ldt.h delete mode 100644 presence/implementation/scan_manager.cc delete mode 100644 presence/implementation/scan_manager.h delete mode 100644 presence/implementation/scan_manager_test.cc delete mode 100644 presence/implementation/sensor_fusion.h delete mode 100644 presence/implementation/service_controller.h delete mode 100644 presence/implementation/service_controller_impl.cc delete mode 100644 presence/implementation/service_controller_impl.h delete mode 100644 presence/implementation/service_controller_impl_test.cc delete mode 100644 presence/power_mode.h delete mode 100644 presence/presence_action.cc delete mode 100644 presence/presence_action.h delete mode 100644 presence/presence_action_test.cc delete mode 100644 presence/presence_client.h delete mode 100644 presence/presence_client_impl.cc delete mode 100644 presence/presence_client_impl.h delete mode 100644 presence/presence_client_test.cc delete mode 100644 presence/presence_device.cc delete mode 100644 presence/presence_device.h delete mode 100644 presence/presence_device_provider.cc delete mode 100644 presence/presence_device_provider.h delete mode 100644 presence/presence_device_provider_test.cc delete mode 100644 presence/presence_device_test.cc delete mode 100644 presence/presence_identity_test.cc delete mode 100644 presence/presence_service.h delete mode 100644 presence/presence_service_impl.cc delete mode 100644 presence/presence_service_impl.h delete mode 100644 presence/presence_service_test.cc delete mode 100644 presence/presence_zone.cc delete mode 100644 presence/presence_zone.h delete mode 100644 presence/presence_zone_test.cc delete mode 100644 presence/proto/BUILD delete mode 100644 presence/proto/presence_frame.proto delete mode 100644 presence/rust/README delete mode 100644 presence/scan_request.h delete mode 100644 presence/scan_request_builder.cc delete mode 100644 presence/scan_request_builder.h delete mode 100644 presence/scan_request_builder_test.cc diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 7d7d8621..3c84c33d 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -48,15 +48,3 @@ jobs: - uses: actions/checkout@v6 - name: Build Connections run: CC=clang-18 CXX=clang-18++ BAZEL_CXXOPTS="-std=c++20" bazel build --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc=true --copt='-DGITHUB_BUILD' //connections:core -# - name: Build Presence -# run: CC=clang-18 CXX=clang-18++ BAZEL_CXXOPTS="-std=c++20" bazel build --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc=true --copt='-DGITHUB_BUILD' //presence - - build-rust-linux: - name: Build Rust on Linux - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - name: Build FPP - run: cargo build --manifest-path presence/fpp/fpp/Cargo.toml diff --git a/internal/interop/BUILD b/internal/interop/BUILD index ee6deda7..f90f8936 100644 --- a/internal/interop/BUILD +++ b/internal/interop/BUILD @@ -35,7 +35,7 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":authentication_status", @@ -54,8 +54,8 @@ cc_library( ], visibility = [ "//connections:__subpackages__", - "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], ) @@ -70,7 +70,7 @@ cc_library( ], compatible_with = ["//buildenv/target:non_prod"], visibility = [ - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":authentication_status", diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 77fc1061..d077fda5 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -164,7 +164,7 @@ cc_library( visibility = [ "//connections/implementation:__subpackages__", "//internal/platform/implementation:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":base", @@ -191,7 +191,7 @@ cc_library( "//connections/implementation:__pkg__", "//connections/v3:__pkg__", "//internal/interop:__pkg__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":logging", @@ -293,7 +293,7 @@ cc_library( "//connections:__subpackages__", "//internal/platform/implementation:__subpackages__", "//internal/test:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":base", @@ -349,7 +349,7 @@ cc_library( "//connections:__subpackages__", "//internal/platform/implementation:__subpackages__", "//internal/test:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":base", @@ -404,7 +404,7 @@ cc_library( visibility = [ "//connections:__subpackages__", "//internal/platform/implementation:__subpackages__", - "//presence:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":base", diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 225e78c7..b1d9877e 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -49,8 +49,8 @@ cc_library( "//internal/test:__subpackages__", "//location/nearby/analytics/cpp:__subpackages__", "//location/nearby/cpp/sharing:__subpackages__", - "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ "//internal/base:file_path", @@ -112,8 +112,8 @@ cc_library( "//internal/network:__subpackages__", "//internal/platform:__pkg__", "//internal/platform/implementation:__subpackages__", - "//presence:__subpackages__", - "//presence/implementation:__subpackages__", + "//third_party/nearby/presence:__subpackages__", + "//third_party/nearby/presence/implementation:__subpackages__", ], deps = [ "//connections/implementation/proto:offline_wire_formats_cc_proto", diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index 4aa9171c..4fee0569 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -193,8 +193,8 @@ cc_library( "//internal/weave:__subpackages__", "//location/nearby/cpp:__subpackages__", "//location/nearby/sharing/sdk:__subpackages__", - "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":comm", diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 0ba7f3dd..b7e93a57 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -328,8 +328,8 @@ cc_library( "//connections:partners", "//internal/platform:__subpackages__", "//location/nearby:__subpackages__", - "//presence:__subpackages__", "//sharing:__subpackages__", + "//third_party/nearby/presence:__subpackages__", ], deps = [ ":crypto", # build_cleaner: keep diff --git a/presence/BUILD b/presence/BUILD deleted file mode 100644 index 858a5ec9..00000000 --- a/presence/BUILD +++ /dev/null @@ -1,223 +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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -package(default_visibility = ["//:__subpackages__"]) - -licenses(["notice"]) - -cc_library( - name = "presence", - srcs = [ - "presence_client_impl.cc", - "presence_device_provider.cc", - "presence_service_impl.cc", - ], - hdrs = [ - "presence_client.h", - "presence_client_impl.h", - "presence_device_provider.h", - "presence_service.h", - "presence_service_impl.h", - ], - deps = [ - ":types", - "//internal/interop:authentication_status", - "//internal/interop:authentication_transport_interface", - "//internal/interop:device", - "//internal/platform:base", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:local_credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "//presence/implementation:internal", # build_cleaner: keep - "//presence/implementation/mediums", - "//presence/proto:presence_frame_cc_proto", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings:string_view", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", - ], -) - -cc_library( - name = "test_support", - testonly = 1, - srcs = [ - "fake_presence_client.cc", - "fake_presence_service.cc", - ], - hdrs = [ - "fake_presence_client.h", - "fake_presence_service.h", - ], - deps = [ - ":presence", - ":types", - "//internal/interop:device", - "//internal/interop:test_support", - "//internal/platform:types", - "//internal/proto:metadata_cc_proto", - "//presence/implementation:internal", # build_cleaner: keep - "@com_google_absl//absl/status:statusor", - ], -) - -cc_library( - name = "types", - srcs = [ - "device_motion.cc", - "discovery_filter.cc", - "presence_action.cc", - "presence_device.cc", - "presence_zone.cc", - "scan_request_builder.cc", - ], - hdrs = [ - "broadcast_options.h", - "broadcast_request.h", - "data_element.h", - "data_types.h", - "device_motion.h", - "discovery_filter.h", - "discovery_options.h", - "power_mode.h", - "presence_action.h", - "presence_device.h", - "presence_zone.h", - "scan_request.h", - "scan_request_builder.h", - ], - deps = [ - "//connections/implementation/proto:offline_wire_formats_cc_proto", - "//internal/interop:device", - "//internal/platform:base", - "//internal/platform:connection_info", - "//internal/platform:logging", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", - ], -) - -cc_test( - name = "types_test", - size = "small", - srcs = [ - "broadcast_options_test.cc", - "device_motion_test.cc", - "discovery_filter_test.cc", - "discovery_options_test.cc", - "presence_action_test.cc", - "presence_device_test.cc", - "presence_identity_test.cc", - "presence_zone_test.cc", - "scan_request_builder_test.cc", - ], - shard_count = 6, - deps = [ - ":types", - "//connections/implementation/proto:offline_wire_formats_cc_proto", - "//internal/platform:connection_info", - "//internal/platform:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/types:variant", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "credential_test", - size = "small", - srcs = [ - "credential_test.cc", - "presence_identity_test.cc", - ], - shard_count = 6, - deps = [ - "//internal/platform:uuid", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "presence_test", - size = "small", - srcs = [ - "presence_client_test.cc", - "presence_device_provider_test.cc", - "presence_service_test.cc", - ], - shard_count = 6, - deps = [ - ":presence", - ":types", - "//internal/crypto", - "//internal/interop:authentication_status", - "//internal/interop:authentication_transport_interface", - "//internal/interop:device", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "//presence/implementation:internal", - "//presence/implementation:internal_test", - "//presence/proto:presence_frame_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) diff --git a/presence/broadcast_options.h b/presence/broadcast_options.h deleted file mode 100644 index 18d11440..00000000 --- a/presence/broadcast_options.h +++ /dev/null @@ -1,36 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_OPTIONS_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_OPTIONS_H_ - -#include -namespace nearby { -namespace presence { -struct BroadcastOptions { - const std::int64_t reporting_interval_millis; -}; - -inline bool operator==(const BroadcastOptions& o1, const BroadcastOptions& o2) { - return o1.reporting_interval_millis == o2.reporting_interval_millis; -} - -inline bool operator!=(const BroadcastOptions& o1, const BroadcastOptions& o2) { - return !(o1 == o2); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_OPTIONS_H_ diff --git a/presence/broadcast_options_test.cc b/presence/broadcast_options_test.cc deleted file mode 100644 index e2e5c381..00000000 --- a/presence/broadcast_options_test.cc +++ /dev/null @@ -1,53 +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. - -#include "presence/broadcast_options.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { - -constexpr std::int64_t kReportingIntervalMillis1 = 1000; -constexpr std::int64_t kReportingIntervalMillis2 = 2000; -TEST(BroadcastOptionsTest, NoDefaultConstructor) { - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST(BroadcastOptionsTest, ExplicitInitEquals) { - BroadcastOptions option1 = {kReportingIntervalMillis1}; - BroadcastOptions option2 = {kReportingIntervalMillis1}; - EXPECT_EQ(option1, option2); - EXPECT_EQ(option1.reporting_interval_millis, kReportingIntervalMillis1); -} - -TEST(BroadcastOptionsTest, ExplicitInitNotEquals) { - BroadcastOptions option1 = {kReportingIntervalMillis1}; - BroadcastOptions option2 = {kReportingIntervalMillis2}; - EXPECT_NE(option1, option2); -} - -TEST(BroadcastOptionsTest, CopyInitEquals) { - BroadcastOptions option1 = {kReportingIntervalMillis1}; - BroadcastOptions option2 = {option1}; - - EXPECT_EQ(option1, option2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/broadcast_request.h b/presence/broadcast_request.h deleted file mode 100644 index 598ffdf3..00000000 --- a/presence/broadcast_request.h +++ /dev/null @@ -1,77 +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_PRESENCE_BROADCAST_REQUEST_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_REQUEST_H_ - -#include -#include - -#include "absl/types/variant.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/power_mode.h" - -namespace nearby { -namespace presence { - -// Broadcast parameter for presence features. -struct PresenceBroadcast { - struct BroadcastSection { - // Presence identity type. - ::nearby::internal::IdentityType identity = - ::nearby::internal::IdentityType::IDENTITY_TYPE_UNSPECIFIED; - - // Additional Data Elements. - // The Presence SDK generates: - // - Salt, - // - (Private/Trusted/Public/Provisioned) Identity, - // - TX power, - // - Advertisement signature - // Data Elements when they are required in the advertisement. Other Data - // Elements are provided by the client application. - // Nearby SDK encrypts Data ELements before broadcasting if a non-public - // `PresenceIdentity` is provided. - std::vector extended_properties; - - // Account name used to select private credentials. - std::string account_name; - - // Manager app id, used to select private credentials. - std::string manager_app_id; - }; - - std::vector sections; -}; - -// Broadcast request for legacy Android T, which needs to provide credential -// and salt in the broadcast parameters. -// TODO(b/243443813) - Support Legacy Broadcast Request -struct LegacyPresenceBroadcast {}; - -// Nearby Presence advertisement request options. -struct BroadcastRequest { - // Calibrated TX power. The broadcast recipient uses it to calculate the - // distance between both devices. - int tx_power; - - // The broadcast frequency hint. - PowerMode power_mode; - - absl::variant variant; -}; - -} // namespace presence -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_REQUEST_H_ diff --git a/presence/credential_test.cc b/presence/credential_test.cc deleted file mode 100644 index 8b1ba211..00000000 --- a/presence/credential_test.cc +++ /dev/null @@ -1,79 +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. - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/platform/uuid.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::internal::LocalCredential; -using ::nearby::internal::SharedCredential; -using ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; - -using ::protobuf_matchers::EqualsProto; - -TEST(CredentialsTest, NoDefaultConstructor) { - EXPECT_FALSE(std::is_trivially_constructible::value); - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST(CredentialsTest, InitSharedCredential) { - SharedCredential pc1 = {}; - SharedCredential pc2 = {}; - EXPECT_THAT(pc1, EqualsProto(pc2)); - pc1.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(pc1, ::testing::Not(EqualsProto(pc2))); - pc2.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(pc1, EqualsProto(pc2)); -} - -TEST(CredentialsTest, InitLocalCredential) { - LocalCredential pc1 = {}; - LocalCredential pc2 = {}; - EXPECT_THAT(pc1, EqualsProto(pc2)); - pc1.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(pc1, ::testing::Not(EqualsProto(pc2))); - pc2.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(pc1, EqualsProto(pc2)); -} - -TEST(CredentialsTest, CopyLocalCredential) { - LocalCredential pc1 = {}; - pc1.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - auto salts = pc1.mutable_consumed_salts(); - salts->insert(std::pair(15, true)); - LocalCredential pc1_copy = {pc1}; - EXPECT_THAT(pc1, EqualsProto(pc1_copy)); -} - -TEST(CredentialsTest, CopySharedCredential) { - SharedCredential pc1 = {}; - pc1.set_identity_type(IDENTITY_TYPE_PRIVATE_GROUP); - for (const uint8_t byte : nearby::Uuid().data()) { - pc1.mutable_secret_id()->push_back(byte); - } - SharedCredential pc1_copy = {pc1}; - EXPECT_THAT(pc1, EqualsProto(pc1_copy)); -} -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/data_element.h b/presence/data_element.h deleted file mode 100644 index eb2ffebb..00000000 --- a/presence/data_element.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_DATA_ELEMENT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_DATA_ELEMENT_H_ - -#include - -#include -#include -#include - -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -namespace nearby { -namespace presence { - -// Reserved Action types when the field type is kActionFieldType. -// The values are bit numbers in BE ordering. -// TODO(b/338107166): these are out of date, need to be updated to latest spec -enum class ActionBit { - kCallTransferAction = 4, - kActiveUnlockAction = 8, - kNearbyShareAction = 9, - kInstantTetheringAction = 10, - kPhoneHubAction = 11, - kPresenceManagerAction = 12, - kFinderAction = 13, - kFastPairSassAction = 14, - kTapToTransferAction = 15, - kLastAction -}; - -// helpful for enumerating overall all possible action bit types, this must be -// kept in sync with the above enum -constexpr std::initializer_list kAllActionBits = { - ActionBit::kCallTransferAction, ActionBit::kActiveUnlockAction, - ActionBit::kNearbyShareAction, ActionBit::kInstantTetheringAction, - ActionBit::kPhoneHubAction, ActionBit::kPresenceManagerAction, - ActionBit::kFinderAction, ActionBit::kFastPairSassAction, - ActionBit::kTapToTransferAction}; - -/** Describes a custom Data element in NP advertisement. */ -class DataElement { - public: - // The field types listed below require special processing when generating and - // parsing NP advertisements. - static constexpr int kSaltFieldType = 0; - static constexpr int kPrivateGroupIdentityFieldType = 1; - static constexpr int kContactsGroupIdentityFieldType = 2; - static constexpr int kPublicIdentityFieldType = 3; - static constexpr int kTxPowerFieldType = 5; - static constexpr int kActionFieldType = 6; - static constexpr int kModelIdFieldType = 7; - static constexpr int kEddystoneIdFieldType = 8; - static constexpr int kAccountKeyDataFieldType = 9; - static constexpr int kConnectionStatusFieldType = 10; - static constexpr int kBatteryFieldType = 11; - static constexpr int kAdvertisementSignature = 12; - static constexpr int kContextTimestampFieldType = 13; - // Maximum allowed Data Element's value length - static constexpr int kMaxDataElementLength = 15; - // Maximum allowed Data Element's type - static constexpr int kMaxDataElementType = 15; - // The DE header is (length << kDataElementLengthShift | type) - static constexpr int kDataElementLengthShift = 4; - - DataElement(uint16_t type, absl::string_view value) - : type_(type), value_(value) {} - - DataElement(uint16_t type, uint8_t value) - : type_(type), - value_(reinterpret_cast(&value), sizeof(value)) {} - - explicit DataElement(ActionBit action) - : DataElement(kActionFieldType, static_cast(action)) {} - - ~DataElement() = default; - - uint16_t GetType() const { return type_; } - absl::string_view GetValue() const { return value_; } - - private: - uint16_t type_; - std::string value_; -}; - -inline bool operator==(const DataElement& i1, const DataElement& i2) { - return i1.GetType() == i2.GetType() && i1.GetValue() == i2.GetValue(); -} - -inline std::ostream& operator<<(std::ostream& os, const DataElement& elem) { - return os << "DataElement(" << elem.GetType() << ", " - << absl::BytesToHexString(elem.GetValue()) << ")"; -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_DATA_ELEMENT_H_ diff --git a/presence/data_types.h b/presence/data_types.h deleted file mode 100644 index 48fdde74..00000000 --- a/presence/data_types.h +++ /dev/null @@ -1,64 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_SCAN_CALLBACK_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_SCAN_CALLBACK_H_ - -#include - -#include "absl/functional/any_invocable.h" -#include "internal/platform/logging.h" -#include "presence/presence_device.h" - -namespace nearby { -namespace presence { - -// Unique Scan Session Identifier. -using ScanSessionId = uint64_t; - -// Callers would provide the implementation of these callbacks. If callers -// don't need these signal updates, they can skip with the provided default -// empty functions. -struct ScanCallback { - // Updates client with the result of start scanning. - absl::AnyInvocable start_scan_cb = [](absl::Status) {}; - - // Reports a {@link PresenceDevice} being discovered. - absl::AnyInvocable on_discovered_cb = - [](PresenceDevice) {}; - - // Reports a {@link PresenceDevice} information(distance, and etc) - // changed. - absl::AnyInvocable on_updated_cb = [](PresenceDevice) { - }; - - // Reports a {@link PresenceDevice} is no longer within range. - absl::AnyInvocable on_lost_cb = [](PresenceDevice) {}; -}; - -// Unique Broadcast Session Identifier. -using BroadcastSessionId = uint64_t; - -// Callers would provide the implementation of these callbacks. If callers -// don't need these signal updates, they can skip with the provided default -// empty functions. -struct BroadcastCallback { - absl::AnyInvocable start_broadcast_cb = [](absl::Status) { - }; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_SCAN_CALLBACK_H_ diff --git a/presence/device_motion.cc b/presence/device_motion.cc deleted file mode 100644 index 8b79e3f6..00000000 --- a/presence/device_motion.cc +++ /dev/null @@ -1,28 +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. - -#include "presence/device_motion.h" - -namespace nearby { -namespace presence { - -DeviceMotion::DeviceMotion(MotionType motion_type, float confidence) noexcept - : motion_type_(motion_type), confidence_(confidence) {} -DeviceMotion::MotionType DeviceMotion::GetMotionType() const { - return motion_type_; -} -float DeviceMotion::GetConfidence() const { return confidence_; } - -} // namespace presence -} // namespace nearby diff --git a/presence/device_motion.h b/presence/device_motion.h deleted file mode 100644 index 439b5349..00000000 --- a/presence/device_motion.h +++ /dev/null @@ -1,47 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_DEVICE_MOTION_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_DEVICE_MOTION_H_ - -namespace nearby { -namespace presence { -class DeviceMotion { - public: - enum class MotionType { - kPointAndHold = 0, - kStationaryAndHold = 1, - }; - DeviceMotion(MotionType motion_type = MotionType::kPointAndHold, - float confidence = 0) noexcept; - MotionType GetMotionType() const; - float GetConfidence() const; - - private: - const MotionType motion_type_; - const float confidence_; -}; - -inline bool operator==(const DeviceMotion& m1, const DeviceMotion& m2) { - return m1.GetMotionType() == m2.GetMotionType() && - m1.GetConfidence() == m2.GetConfidence(); -} -inline bool operator!=(const DeviceMotion& m1, const DeviceMotion& m2) { - return !(m1 == m2); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_DEVICE_MOTION_H_ diff --git a/presence/device_motion_test.cc b/presence/device_motion_test.cc deleted file mode 100644 index 1155903a..00000000 --- a/presence/device_motion_test.cc +++ /dev/null @@ -1,61 +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. - -#include "presence/device_motion.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { -static const DeviceMotion::MotionType kDefaultMotionType = - DeviceMotion::MotionType::kPointAndHold; -static const float kDefaultConfidence = 0; -static const float kConfidenceForTest = 0.1; -TEST(DeviceMotionTest, DefaultConstructorWorks) { - DeviceMotion motion; - EXPECT_EQ(motion.GetMotionType(), kDefaultMotionType); - EXPECT_EQ(motion.GetConfidence(), kDefaultConfidence); -} - -TEST(DeviceMotionTest, DefaultEquals) { - DeviceMotion motion1; - DeviceMotion motion2; - EXPECT_EQ(motion1, motion2); -} - -TEST(DeviceMotionTest, ExplicitInitEquals) { - DeviceMotion motion1 = {kDefaultMotionType, kConfidenceForTest}; - DeviceMotion motion2 = {kDefaultMotionType, kConfidenceForTest}; - EXPECT_EQ(motion1, motion2); - EXPECT_EQ(motion1.GetConfidence(), kConfidenceForTest); -} - -TEST(DeviceMotionTest, ExplicitInitNotEquals) { - DeviceMotion motion1 = {kDefaultMotionType, kConfidenceForTest}; - DeviceMotion motion2 = {kDefaultMotionType}; - EXPECT_NE(motion1, motion2); -} - -TEST(DeviceMotionTest, CopyInitEquals) { - DeviceMotion motion1; - DeviceMotion motion2 = {motion1}; - EXPECT_EQ(motion1, motion2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/discovery_filter.cc b/presence/discovery_filter.cc deleted file mode 100644 index 453309a5..00000000 --- a/presence/discovery_filter.cc +++ /dev/null @@ -1,36 +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. - -#include "presence/discovery_filter.h" - -namespace nearby { -namespace presence { - -using ::nearby::internal::IdentityType; - -DiscoveryFilter::DiscoveryFilter( - const std::vector& actions, - const std::vector& identities, - const std::vector& zones) noexcept - : actions_(actions), identities_(identities), zones_(zones) {} -std::vector DiscoveryFilter::GetActions() const { - return actions_; -} -std::vector DiscoveryFilter::GetIdentities() const { - return identities_; -} -std::vector DiscoveryFilter::GetZones() const { return zones_; } - -} // namespace presence -} // namespace nearby diff --git a/presence/discovery_filter.h b/presence/discovery_filter.h deleted file mode 100644 index 06b72413..00000000 --- a/presence/discovery_filter.h +++ /dev/null @@ -1,43 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_FILTER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_FILTER_H_ - -#include - -#include "internal/proto/credential.pb.h" -#include "presence/presence_action.h" -#include "presence/presence_zone.h" -namespace nearby { -namespace presence { -class DiscoveryFilter { - public: - DiscoveryFilter(const std::vector& = {}, - const std::vector<::nearby::internal::IdentityType>& = {}, - const std::vector& = {}) noexcept; - std::vector GetActions() const; - std::vector<::nearby::internal::IdentityType> GetIdentities() const; - std::vector GetZones() const; - - private: - const std::vector actions_; - const std::vector<::nearby::internal::IdentityType> identities_; - const std::vector zones_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_FILTER_H_ diff --git a/presence/discovery_filter_test.cc b/presence/discovery_filter_test.cc deleted file mode 100644 index c85f8f83..00000000 --- a/presence/discovery_filter_test.cc +++ /dev/null @@ -1,51 +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. - -#include "presence/discovery_filter.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::IdentityType; - -const PresenceAction kTestAction = {1}; -const IdentityType kTestIdentity = {IdentityType::IDENTITY_TYPE_CONTACTS_GROUP}; - -TEST(DiscoveryFilterTest, DefaultConstructorWorks) { - DiscoveryFilter filter; - EXPECT_EQ(filter.GetActions().size(), 0); - EXPECT_EQ(filter.GetIdentities().size(), 0); - EXPECT_EQ(filter.GetZones().size(), 0); -} - -TEST(DiscoveryFilterTest, PartiallyInitializationWorks) { - DiscoveryFilter filter1{{kTestAction}, {kTestIdentity}}; - DiscoveryFilter filter2{{kTestAction}}; - EXPECT_EQ(filter1.GetActions(), filter2.GetActions()); - EXPECT_NE(filter1.GetIdentities(), filter2.GetIdentities()); - EXPECT_EQ(filter1.GetZones(), filter2.GetZones()); - - EXPECT_EQ(filter1.GetActions()[0], kTestAction); - EXPECT_EQ(filter1.GetIdentities()[0], kTestIdentity); - EXPECT_EQ(filter1.GetZones().capacity(), 0); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/discovery_options.h b/presence/discovery_options.h deleted file mode 100644 index 44dcfc0b..00000000 --- a/presence/discovery_options.h +++ /dev/null @@ -1,34 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_OPTIONS_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_OPTIONS_H_ - -namespace nearby { -namespace presence { -struct DiscoveryOptions { - const bool local_wifi_only_; -}; - -inline bool operator==(const DiscoveryOptions& o1, const DiscoveryOptions& o2) { - return o1.local_wifi_only_ == o2.local_wifi_only_; -} - -inline bool operator!=(const DiscoveryOptions& o1, const DiscoveryOptions& o2) { - return !(o1 == o2); -} - -} // namespace presence -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_PRESENCE_DISCOVERY_OPTIONS_H_ diff --git a/presence/discovery_options_test.cc b/presence/discovery_options_test.cc deleted file mode 100644 index 631ed12f..00000000 --- a/presence/discovery_options_test.cc +++ /dev/null @@ -1,51 +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. - -#include "presence/discovery_options.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { - -constexpr bool kTestLocalWifiOnly = false; -TEST(DiscoveryOptionsTest, NoDefaultConstructor) { - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST(DiscoveryOptionsTest, ExplicitInitEquals) { - DiscoveryOptions option1 = {kTestLocalWifiOnly}; - DiscoveryOptions option2 = {kTestLocalWifiOnly}; - EXPECT_EQ(option1, option2); - EXPECT_EQ(option1.local_wifi_only_, kTestLocalWifiOnly); -} - -TEST(DiscoveryOptionsTest, ExplicitInitNotEquals) { - DiscoveryOptions option1 = {kTestLocalWifiOnly}; - DiscoveryOptions option2 = {!kTestLocalWifiOnly}; - EXPECT_NE(option1, option2); -} - -TEST(DiscoveryOptionsTest, CopyInitEquals) { - DiscoveryOptions option1 = {kTestLocalWifiOnly}; - DiscoveryOptions option2 = {option1}; - EXPECT_EQ(option1, option2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/fake_presence_client.cc b/presence/fake_presence_client.cc deleted file mode 100644 index 44e73440..00000000 --- a/presence/fake_presence_client.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 "presence/fake_presence_client.h" - - -#include -#include -#include - -#include "presence/data_types.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -absl::StatusOr FakePresenceClient::StartScan( - ScanRequest scan_request, ScanCallback callback) { - current_scan_session_id_++; - active_scan_sessions_.push_back(current_scan_session_id_); - absl::StatusOr scan_session_id(current_scan_session_id_); - callback_ = std::move(callback); - return scan_session_id; -} - -void FakePresenceClient::StopScan(ScanSessionId id) { - auto position = - std::find(active_scan_sessions_.begin(), active_scan_sessions_.end(), id); - if (position != active_scan_sessions_.end()) { - active_scan_sessions_.erase(position); - } -} - -std::vector FakePresenceClient::GetActiveScanSessions() { - return active_scan_sessions_; -} - -void FakePresenceClient::CallStartScanCallback(absl::Status status) { - callback_.start_scan_cb(status); -} - -void FakePresenceClient::CallOnDiscovered(PresenceDevice device) { - callback_.on_discovered_cb(device); -} - -void FakePresenceClient::CallOnUpdated(PresenceDevice device) { - callback_.on_updated_cb(device); -} - -void FakePresenceClient::CallOnLost(PresenceDevice device) { - callback_.on_lost_cb(device); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/fake_presence_client.h b/presence/fake_presence_client.h deleted file mode 100644 index b2a6d816..00000000 --- a/presence/fake_presence_client.h +++ /dev/null @@ -1,73 +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_PRESENCE_FAKE_PRESENCE_CLIENT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_CLIENT_H_ - -#include -#include - -#include "absl/status/statusor.h" -#include "presence/broadcast_request.h" -#include "presence/presence_client.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -class FakePresenceClient : public PresenceClient { - public: - FakePresenceClient() = default; - FakePresenceClient(const FakePresenceClient&) = delete; - FakePresenceClient(FakePresenceClient&&) = default; - FakePresenceClient& operator=(const FakePresenceClient&) = delete; - ~FakePresenceClient() = default; - - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - - void StopScan(ScanSessionId session_id) override; - - // Not Implemented. - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override { - return 0; - } - - // Not Implemented. - void StopBroadcast(BroadcastSessionId session_id) override {} - - // Not Implemented. - std::optional GetLocalDevice() override { - return std::nullopt; - } - - - std::vector GetActiveScanSessions(); - void CallStartScanCallback(absl::Status status); - void CallOnDiscovered(PresenceDevice device); - void CallOnUpdated(PresenceDevice device); - void CallOnLost(PresenceDevice device); - - private: - uint64_t current_scan_session_id_; - ScanCallback callback_; - std::vector active_scan_sessions_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_CLIENT_H_ diff --git a/presence/fake_presence_service.cc b/presence/fake_presence_service.cc deleted file mode 100644 index ff06221a..00000000 --- a/presence/fake_presence_service.cc +++ /dev/null @@ -1,107 +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. - -#include "presence/fake_presence_service.h" - -#include -#include -#include - -#include "internal/interop/device_provider.h" -#include "internal/platform/borrowable.h" -#include "presence/fake_presence_client.h" - -namespace nearby { -namespace presence { - -FakePresenceService::FakePresenceService() = default; - -std::unique_ptr FakePresenceService::CreatePresenceClient() { - auto fake = std::make_unique(); - most_recent_fake_presence_client_ = fake.get(); - return std::move(fake); -} - -// Not implemented. -absl::StatusOr FakePresenceService::StartScan( - ScanRequest scan_request, ScanCallback callback) { - return absl::Status(absl::StatusCode::kCancelled, - "StartScan not implemented yet"); -} - -// Not implemented. -void FakePresenceService::StopScan(ScanSessionId session_id) {} - -// Not implemented. -absl::StatusOr FakePresenceService::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - return absl::Status(absl::StatusCode::kCancelled, - "StartBroadcast not implemented yet"); -} - -// Not implemented. -void FakePresenceService::StopBroadcast(BroadcastSessionId session_id) {} - -void FakePresenceService::UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& metadata, - bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) { - metadata_ = metadata; - - if (!regen_credentials) { - // No need to call back on credentials_generated_cb. - return; - } - - if (gen_credentials_status_.ok()) { - std::move(credentials_generated_cb.credentials_generated_cb)( - shared_credentials_); - } else { - std::move(credentials_generated_cb.credentials_generated_cb)( - gen_credentials_status_); - } -} - -NearbyDeviceProvider* FakePresenceService::GetLocalDeviceProvider() { - return provider_; -} - -void FakePresenceService::GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - if (get_public_credentials_status_.ok()) { - std::move(callback.credentials_fetched_cb)(shared_credentials_); - return; - } - - std::move(callback.credentials_fetched_cb)(get_public_credentials_status_); -} - -void FakePresenceService::UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) { - if (update_remote_public_credentials_status_.ok()) { - remote_shared_credentials_ = remote_public_creds; - } - - std::move(credentials_updated_cb.credentials_updated_cb)( - update_remote_public_credentials_status_); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/fake_presence_service.h b/presence/fake_presence_service.h deleted file mode 100644 index 81dca042..00000000 --- a/presence/fake_presence_service.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_SERVICE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_SERVICE_H_ - -#include "internal/interop/device_provider.h" -#include "internal/interop/fake_device_provider.h" -#include "internal/platform/borrowable.h" -#include "internal/proto/metadata.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/presence_client.h" -#include "presence/presence_service.h" - -namespace nearby { -namespace presence { - -class FakePresenceClient; - -class FakePresenceService : public PresenceService { - public: - FakePresenceService(); - ~FakePresenceService() override { lender_.Release(); } - - // PresenceService: - std::unique_ptr CreatePresenceClient() override; - - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - - void StopScan(ScanSessionId session_id) override; - - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override; - - void StopBroadcast(BroadcastSessionId session_id) override; - - void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& metadata, - bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - - NearbyDeviceProvider* GetLocalDeviceProvider() override; - - ::nearby::internal::DeviceIdentityMetaData GetDeviceIdentityMetaData() - override { - return metadata_; - } - - void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) override; - void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) override; - - // Use for testing. Call this to set the response to - // `UpdateLocalDeviceMetadata`. - void SetUpdateLocalDeviceMetadataResponse( - absl::Status status, - std::vector shared_credentials) { - shared_credentials_ = shared_credentials; - gen_credentials_status_ = status; - } - - FakePresenceClient* GetMostRecentFakePresenceClient() { - return most_recent_fake_presence_client_; - } - - // Used for testing to verify the remote credentials set. - std::vector GetRemoteSharedCredentials() { - return remote_shared_credentials_; - } - - void SetUpdateRemoteSharedCredentialsResult(absl::Status status) { - update_remote_public_credentials_status_ = status; - } - - void SetLocalPublicCredentialsResult( - absl::Status status, - std::vector shared_credentials) { - get_public_credentials_status_ = status; - shared_credentials_ = shared_credentials; - } - - void SetDeviceProvider(NearbyDeviceProvider* provider) { - provider_ = provider; - } - - private: - FakePresenceClient* most_recent_fake_presence_client_ = nullptr; - std::vector shared_credentials_; - std::vector remote_shared_credentials_; - absl::Status gen_credentials_status_; - absl::Status update_remote_public_credentials_status_; - absl::Status get_public_credentials_status_; - ::nearby::internal::DeviceIdentityMetaData metadata_; - NearbyDeviceProvider* provider_; - ::nearby::Lender lender_{this}; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_SERVICE_H_ diff --git a/presence/fpp/BUILD b/presence/fpp/BUILD deleted file mode 100644 index 6e5d738d..00000000 --- a/presence/fpp/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 -# -# 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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -licenses(["notice"]) - -cc_library( - name = "fpp_manager", - srcs = [ - "fpp_manager.cc", - ], - hdrs = ["fpp_manager.h"], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//internal/platform:logging", - "//presence:types", - "//presence/fpp/fpp_c_ffi", - "//presence/implementation:sensor_fusion", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - ], -) - -cc_library( - name = "sensor_fusion_impl", - srcs = [ - "sensor_fusion_impl.cc", - ], - hdrs = ["sensor_fusion_impl.h"], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - ":fpp_manager", - "//presence/implementation:sensor_fusion", - "@com_google_absl//absl/status", - ], -) - -cc_test( - name = "fpp_manager_test", - size = "small", - srcs = ["fpp_manager_test.cc"], - deps = [ - ":fpp_manager", - "//presence/implementation:sensor_fusion", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "sensor_fusion_test", - size = "small", - srcs = ["sensor_fusion_test.cc"], - deps = [ - ":sensor_fusion_impl", - "//presence/implementation:sensor_fusion", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) diff --git a/presence/fpp/fpp/Cargo.lock b/presence/fpp/fpp/Cargo.lock deleted file mode 100644 index be2b9180..00000000 --- a/presence/fpp/fpp/Cargo.lock +++ /dev/null @@ -1,25 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "fpp" -version = "0.1.0" -dependencies = [ - "itertools", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] diff --git a/presence/fpp/fpp/Cargo.toml b/presence/fpp/fpp/Cargo.toml deleted file mode 100644 index b3de1c90..00000000 --- a/presence/fpp/fpp/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "fpp" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -itertools = "0.10.5" diff --git a/presence/fpp/fpp/src/fspl_converter.rs b/presence/fpp/fpp/src/fspl_converter.rs deleted file mode 100644 index 6b03f6b8..00000000 --- a/presence/fpp/fpp/src/fspl_converter.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 -// -// 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. - -const ADVERTISE_TX_POWER_HIGH_DB: i32 = 1; - -const FSPL_AT_1_METER_DB: i32 = 40; - -const MEASURED_POWER_AT_1_METER_DB_AT_HIGH_TX_POWER: i32 = -60; - -pub fn compute_distance_meters_at_high_tx_power(rssi: i32) -> f64 { - let nominal_tx_power = ADVERTISE_TX_POWER_HIGH_DB; - let antenna_gain = - (nominal_tx_power - FSPL_AT_1_METER_DB) - MEASURED_POWER_AT_1_METER_DB_AT_HIGH_TX_POWER; - let tx_power_at_0_meters = nominal_tx_power - antenna_gain; - compute_distance_meters(tx_power_at_0_meters, rssi) -} - -pub fn compute_distance_meters(tx_power_at_0_meters: i32, rssi: i32) -> f64 { - let fspl = tx_power_at_0_meters - rssi; - ble_fspl_to_meters(fspl) -} - -fn ble_fspl_to_meters(fspl: i32) -> f64 { - let base: f64 = 10.0; - base.powi((fspl - FSPL_AT_1_METER_DB) / 20) -} diff --git a/presence/fpp/fpp/src/fspl_converter_test.rs b/presence/fpp/fpp/src/fspl_converter_test.rs deleted file mode 100644 index efa273c8..00000000 --- a/presence/fpp/fpp/src/fspl_converter_test.rs +++ /dev/null @@ -1,30 +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. - -use crate::fspl_converter::compute_distance_meters_at_high_tx_power; - -#[test] -fn test_short_distance() { - assert_eq!(compute_distance_meters_at_high_tx_power(-40), 0.1); -} - -#[test] -fn test_medium_distance() { - assert_eq!(compute_distance_meters_at_high_tx_power(-60), 1.0); -} - -#[test] -fn test_large_distance() { - assert_eq!(compute_distance_meters_at_high_tx_power(-80), 10.0); -} diff --git a/presence/fpp/fpp/src/fused_presence_utils.rs b/presence/fpp/fpp/src/fused_presence_utils.rs deleted file mode 100644 index 48b2dd0e..00000000 --- a/presence/fpp/fpp/src/fused_presence_utils.rs +++ /dev/null @@ -1,107 +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. - -pub(crate) const DEFAULT_TAP_DISTANCE_THRESHOLD_METERS: f64 = AMBIGUITY_METERS + 0.02; -pub(crate) const DEFAULT_REACH_DISTANCE_THRESHOLD_METERS: f64 = AMBIGUITY_METERS + 0.5; -pub(crate) const DEFAULT_SHORT_RANGE_DISTANCE_THRESHOLD_METERS: f64 = AMBIGUITY_METERS + 1.2; -pub(crate) const DEFAULT_LONG_RANGE_DISTANCE_THRESHOLD_METERS: f64 = AMBIGUITY_METERS + 3.0; -pub(crate) const DEFAULT_CONSECUTIVE_SCANS_REQUIRED: u8 = 2; -const AMBIGUITY_METERS: f64 = 0.06; - -/// Proximity state from device to another in terms of actionability -#[derive(Eq, Hash, Copy, Clone, PartialEq, Debug)] -#[repr(C)] -pub enum ProximityState { - /// Unknown proximity state - Unknown, - /// The device is within a tap zone (<0.02m) - Tap, - /// The device is within a reach zone (<0.5m) - Reach, - /// The device is within a short range zone (<1.2m) - ShortRange, - /// The device is within a long range zone (<3.0m) - LongRange, - /// The device is at a far range - Far, -} - -/// Represents the confidence levels for a given measurement -#[derive(Copy, Clone, PartialEq, Debug)] -#[repr(C)] -pub enum MeasurementConfidence { - /// Measurement confidence is low, the default for BLE medium - Low, - /// Measurement confidence is medium - Medium, - /// Measurement confidence is High - High, - /// Measurement confidence is unknown - Unknown, -} - -/// Data sources that are used to track presence -#[derive(Copy, Clone, PartialEq, Debug)] -#[repr(C)] -pub enum PresenceDataSource { - /// Data source for proximity estimate is BLE - Ble, - /// Data source for proximity estimate is UWB - Uwb, - /// Data source for proximity estimate is NAN - Nan, - /// Data source for proximity estimate is unknown - Unknown, -} - -/// A PII-stripped subset of Bluetooth scan result -#[repr(C)] -pub struct BleScanResult { - /// Device ID of the nearby device - pub device_id: u64, - /// Transmitting power of signal - pub tx_power: MaybeTxPower, - /// RSSI value - pub rssi: i32, - /// Time scan result was obtained - pub elapsed_real_time_millis: u64, -} - -/// Enum representing an optional tx power value -#[repr(C)] -pub enum MaybeTxPower { - /// Valid TX power with associated data value - Valid(i32), - /// Absent Tx Power - Invalid, -} - -/// Describes the most accurate and recent measurement for a given device -#[derive(Copy, Clone, PartialEq, Debug)] -#[repr(C)] -pub struct ProximityEstimate { - /// Device ID of the nearby device - pub device_id: u64, - /// Distance to the nearby device in meters - pub distance_meters: f64, - /// Measurement confidence of the estimate - pub distance_confidence: MeasurementConfidence, - /// The time the proximity estimate was obtained (milliseconds since the - /// program start time) - pub elapsed_real_time_millis: u64, - /// Proximity state zone of the nearby device - pub proximity_state: ProximityState, - /// Medium through which the proximity estimate was computed - pub source: PresenceDataSource, -} diff --git a/presence/fpp/fpp/src/lib.rs b/presence/fpp/fpp/src/lib.rs deleted file mode 100644 index ef30da9e..00000000 --- a/presence/fpp/fpp/src/lib.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 -// -// 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. - -#![deny( - missing_docs, - clippy::indexing_slicing, - clippy::unwrap_used, - clippy::panic, - clippy::expect_used -)] - -//! Processes raw scan results from BLE, UWB and NAN and outputs proximity estimates/zones - -mod fspl_converter; - -/// Fused presence Utils -pub mod fused_presence_utils; - -/// Presence detector module -pub mod presence_detector; - -#[cfg(test)] -mod fspl_converter_test; - -#[cfg(test)] -mod presence_detector_test; diff --git a/presence/fpp/fpp/src/presence_detector.rs b/presence/fpp/fpp/src/presence_detector.rs deleted file mode 100644 index 7f613ab5..00000000 --- a/presence/fpp/fpp/src/presence_detector.rs +++ /dev/null @@ -1,131 +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. - -use std::collections::{HashMap, VecDeque}; -use std::time::{Instant, SystemTime}; - -use itertools::Itertools; - -use crate::fspl_converter::compute_distance_meters_at_high_tx_power; -use crate::fused_presence_utils::{ - BleScanResult, MaybeTxPower, MeasurementConfidence, PresenceDataSource, ProximityEstimate, - ProximityState, DEFAULT_CONSECUTIVE_SCANS_REQUIRED, - DEFAULT_LONG_RANGE_DISTANCE_THRESHOLD_METERS, DEFAULT_REACH_DISTANCE_THRESHOLD_METERS, - DEFAULT_SHORT_RANGE_DISTANCE_THRESHOLD_METERS, DEFAULT_TAP_DISTANCE_THRESHOLD_METERS, -}; - -const MAX_RSSI_FILTER_VALUE: i32 = 10; -const DEFAULT_ESTIMATED_DISTANCE_DATA_TTL_MILLIS: u128 = 4000; - -/// Static function for getting proximity state from threshold -fn get_proximity_state_from_threshold(distance_meters: f64) -> ProximityState { - if distance_meters <= DEFAULT_TAP_DISTANCE_THRESHOLD_METERS { - return ProximityState::Tap; - } - if distance_meters <= DEFAULT_REACH_DISTANCE_THRESHOLD_METERS { - return ProximityState::Reach; - } - if distance_meters <= DEFAULT_SHORT_RANGE_DISTANCE_THRESHOLD_METERS { - return ProximityState::ShortRange; - } - if distance_meters <= DEFAULT_LONG_RANGE_DISTANCE_THRESHOLD_METERS { - return ProximityState::LongRange; - } - ProximityState::Far -} - -/// Tracks and computes proximity/presence state events. -pub struct PresenceDetector { - start_time: Instant, - last_range_update_time: RangingUpdateTime, - best_proximity_estimate_per_device: HashMap, - transition_history: VecDeque, -} - -struct RangingUpdateTime(u128); - -impl RangingUpdateTime { - pub fn is_expired(&self) -> bool { - let elapsed_real_time_millis = Instant::now().elapsed().as_millis(); - elapsed_real_time_millis - self.0 > DEFAULT_ESTIMATED_DISTANCE_DATA_TTL_MILLIS - } - - pub fn update(&mut self, start_time: Instant) { - self.0 = Instant::now().duration_since(start_time).as_millis(); - } -} - -impl PresenceDetector { - /// Creates a new instance of presence detector - pub fn new() -> Self { - PresenceDetector { - start_time: Instant::now(), - last_range_update_time: RangingUpdateTime(0), - best_proximity_estimate_per_device: HashMap::new(), - transition_history: VecDeque::with_capacity( - (DEFAULT_CONSECUTIVE_SCANS_REQUIRED + 1).into(), - ), - } - } - - /// Updates the presence detector with a new scan result and returns the - /// current proximity estimate - pub fn on_ble_scan_result( - &mut self, - ble_scan_result: BleScanResult, - ) -> Option { - let device_id = ble_scan_result.device_id; - if ble_scan_result.rssi > MAX_RSSI_FILTER_VALUE { - return self.best_proximity_estimate_per_device.get(&device_id).copied(); - } - if self.last_range_update_time.is_expired() { - self.transition_history.clear(); - } - let mut tx_power: i32 = 0; - if let MaybeTxPower::Valid(some_tx_power) = ble_scan_result.tx_power { - tx_power = some_tx_power; - } - let rssi = ble_scan_result.rssi + tx_power; - let distance_meters = compute_distance_meters_at_high_tx_power(rssi); - let new_proximity_estimate = ProximityEstimate { - device_id, - distance_confidence: MeasurementConfidence::Low, - distance_meters, - proximity_state: get_proximity_state_from_threshold(distance_meters), - elapsed_real_time_millis: Instant::now().duration_since(self.start_time).as_millis() - as u64, - source: PresenceDataSource::Ble, - }; - self.transition_history.push_front(new_proximity_estimate.proximity_state); - self.transition_history.truncate(DEFAULT_CONSECUTIVE_SCANS_REQUIRED.into()); - if self.transition_history.iter().unique().count() == 1 - && self.transition_history.len() == DEFAULT_CONSECUTIVE_SCANS_REQUIRED.into() - { - self.best_proximity_estimate_per_device.insert(device_id, new_proximity_estimate); - self.last_range_update_time.update(self.start_time); - } - self.best_proximity_estimate_per_device.get(&device_id).copied() - } - - /// Returns the current proximity estimate for a given device - pub fn get_proximity_estimate(&self, device_id: u64) -> Option { - self.best_proximity_estimate_per_device.get(&device_id).copied() - } -} - -impl Default for PresenceDetector { - fn default() -> Self { - Self::new() - } -} diff --git a/presence/fpp/fpp/src/presence_detector_test.rs b/presence/fpp/fpp/src/presence_detector_test.rs deleted file mode 100644 index 1d35f187..00000000 --- a/presence/fpp/fpp/src/presence_detector_test.rs +++ /dev/null @@ -1,105 +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. - -use crate::fused_presence_utils::*; -use crate::presence_detector::*; - -const BLE_SCAN_RESULT_REACH_ZONE: BleScanResult = BleScanResult { - device_id: 1234, - tx_power: { MaybeTxPower::Invalid }, - rssi: -40, - elapsed_real_time_millis: 123456, -}; - -const BLE_SCAN_RESULT_BAD_RSSI: BleScanResult = BleScanResult { - rssi: 127, - ..BLE_SCAN_RESULT_REACH_ZONE -}; - -const BLE_SCAN_RESULT_SHORT_RANGE_ZONE: BleScanResult = BleScanResult { - rssi: -60, - ..BLE_SCAN_RESULT_REACH_ZONE -}; - -const REACH_PROXIMITY_ESTIMATE: ProximityEstimate = ProximityEstimate { - device_id: 1234, - distance_meters: 0.1, - distance_confidence: MeasurementConfidence::Low, - elapsed_real_time_millis: 0, - proximity_state: ProximityState::Reach, - source: PresenceDataSource::Ble, -}; - -const SHORT_RANGE_PROXIMITY_ESTIMATE: ProximityEstimate = ProximityEstimate { - distance_meters: 1.0, - proximity_state: ProximityState::ShortRange, - ..REACH_PROXIMITY_ESTIMATE -}; - -#[test] -fn test_on_ble_scan_result_success() { - // Tests that the proximity state stored for each device is the accurate one after two - // consecutive scan results - let mut presence_detector = PresenceDetector::new(); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - None - ); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - Some(ProximityEstimate { - device_id: 1234, - distance_meters: 0.1, - distance_confidence: MeasurementConfidence::Low, - elapsed_real_time_millis: 0, - proximity_state: ProximityState::Reach, - source: PresenceDataSource::Ble - }) - ); -} - -#[test] -fn test_on_ble_scan_result_bad_rssi() { - // Tests that scan results with bad RSSIs are ignored - let mut presence_detector = PresenceDetector::new(); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - None - ); - - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_BAD_RSSI), - None - ); -} -#[test] -fn test_on_ble_scan_result_transition_to_new_zone() { - let mut presence_detector = PresenceDetector::new(); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - None - ); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_REACH_ZONE), - Some(REACH_PROXIMITY_ESTIMATE) - ); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_SHORT_RANGE_ZONE), - Some(REACH_PROXIMITY_ESTIMATE) - ); - assert_eq!( - presence_detector.on_ble_scan_result(BLE_SCAN_RESULT_SHORT_RANGE_ZONE), - Some(SHORT_RANGE_PROXIMITY_ESTIMATE) - ); -} diff --git a/presence/fpp/fpp_c_ffi/Cargo.lock b/presence/fpp/fpp_c_ffi/Cargo.lock deleted file mode 100644 index 99bf6078..00000000 --- a/presence/fpp/fpp_c_ffi/Cargo.lock +++ /dev/null @@ -1,105 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "fpp" -version = "0.1.0" -dependencies = [ - "itertools", -] - -[[package]] -name = "fpp_c_ffi" -version = "0.1.0" -dependencies = [ - "fpp", - "lazy_static", - "rand", -] - -[[package]] -name = "getrandom" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.144" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/presence/fpp/fpp_c_ffi/Cargo.toml b/presence/fpp/fpp_c_ffi/Cargo.toml deleted file mode 100644 index 301a85c3..00000000 --- a/presence/fpp/fpp_c_ffi/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "fpp_c_ffi" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -fpp = {path = "../fpp"} -lazy_static = "1.4.0" -rand = "0.8.5" diff --git a/presence/fpp/fpp_c_ffi/include/presence_detector.h b/presence/fpp/fpp_c_ffi/include/presence_detector.h deleted file mode 100644 index 7bc03aa5..00000000 --- a/presence/fpp/fpp_c_ffi/include/presence_detector.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 -// -// 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. - -#ifndef PRESENCE_DETECTOR_H_ -#define PRESENCE_DETECTOR_H_ - -#include -#include -#include -#include -#include - -// Represents the confidence levels for a given measurement -enum class MeasurementConfidence { - /// Measurement confidence is low, the default for BLE medium - Low, - /// Measurement confidence is medium - Medium, - /// Measurement confidence is High - High, - /// Measurement confidence is unknown - Unknown, -}; - -/// Data sources that are used to track presence -enum class PresenceDataSource { - /// Data source for proximity estimate is BLE - Ble, - /// Data source for proximity estimate is UWB - Uwb, - /// Data source for proximity estimate is NAN - Nan, - /// Data source for proximity estimate is unknown - Unknown, -}; - -/// Proximity state from device to another in terms of actionability -enum class ProximityState { - /// Unknown proximity state - Unknown, - /// The device is within a tap zone (<0.02m) - Tap, - /// The device is within a reach zone (<0.5m) - Reach, - /// The device is within a short range zone (<1.2m) - ShortRange, - /// The device is within a long range zone (<3.0m) - LongRange, - /// The device is at a far range - Far, -}; - -/// Wraps the handle ID to an underlying PresenceDetector object -struct PresenceDetectorHandle { - uint64_t handle; -}; - -/// Enum representing an optional tx power value -struct MaybeTxPower { - enum class Tag { - /// Valid TX power with associated data value - Valid, - /// Absent Tx Power - Invalid, - }; - - struct Valid_Body { - int32_t _0; - }; - - Tag tag; - union { - Valid_Body valid; - }; -}; - -/// A PII-stripped subset of Bluetooth scan result -struct BleScanResult { - /// Device ID of the nearby device - uint64_t device_id; - /// Transmitting power of signal - MaybeTxPower tx_power; - /// RSSI value - int32_t rssi; - /// Time scan result was obtained - uint64_t elapsed_real_time_millis; -}; - -/// Describes the most accurate and recent measurement for a given device -struct ProximityEstimate { - /// Device ID of the nearby device - uint64_t device_id; - /// Distance to the nearby device in meters - double distance_meters; - /// Measurement confidence of the estimate - MeasurementConfidence distance_confidence; - /// The time the proximity estimate was obtained - uint64_t elapsed_real_time_millis; - /// Proximity state zone of the nearby device - ProximityState proximity_state; - /// Medium through which the proximity estimate was computed - PresenceDataSource source; -}; - -extern "C" { - -/// Creates a new presence detector object and returns the handle for the new -/// object -PresenceDetectorHandle presence_detector_create(); - -/// Updates PresenceDetector with a new scan result and returns an error code -/// if unsuccessful -/// -/// # Safety -/// -/// Ensure that the output parameter refers to an initialized instance -int32_t update_ble_scan_result(PresenceDetectorHandle presence_detector_handle, - BleScanResult ble_scan_result, - ProximityEstimate *proximity_estimate); - -/// Gets the current proximity estimate for a given device ID -/// -/// # Safety -/// -/// Ensure that the output parameter refers to an initialized instance -int32_t get_proximity_estimate(PresenceDetectorHandle presence_detector_handle, - uint64_t device_id, - ProximityEstimate *proximity_estimate); - -/// De-allocates memory for a presence detector object -int presence_detector_free(PresenceDetectorHandle presence_detector_handle); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // PRESENCE_DETECTOR_H_ diff --git a/presence/fpp/fpp_c_ffi/src/handle_map.rs b/presence/fpp/fpp_c_ffi/src/handle_map.rs deleted file mode 100644 index 0f9566a9..00000000 --- a/presence/fpp/fpp_c_ffi/src/handle_map.rs +++ /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 -// -// 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. - -use core::marker::PhantomData; -use fpp::presence_detector::PresenceDetector; -use lazy_static::lazy_static; -use rand::Rng; -use std::collections::HashMap; -use std::sync::{Mutex, MutexGuard}; - -pub(crate) struct HandleMap { - _marker: PhantomData, - map: HashMap, -} - -impl HandleMap { - pub(crate) fn init() -> Self { - Self { - _marker: Default::default(), - map: HashMap::new(), - } - } - - /// inserts an entry into the map and returns the randomly generated handle to the entry - pub(crate) fn insert(&mut self, data: T) -> u64 { - let mut rng = rand::thread_rng(); - let mut handle: u64 = rng.gen(); - - while self.map.contains_key(&handle) { - handle = rng.gen(); - } - - assert!(self.map.insert(handle, data).is_none()); - handle - } - - /// Removes an entry at a given handle returning an Option of the owned value - pub(crate) fn remove(&mut self, handle: &u64) -> Option { - self.map.remove(handle) - } - - /// Gets a reference to the entry stored at the specified handle - pub(crate) fn get(&mut self, handle: &u64) -> Option<&mut T> { - self.map.get_mut(handle) - } -} - -// Returns a threadsafe instance of the global static hashmap tracking the PresenceDetector handles -pub(crate) fn get_presence_detector_handle_map( -) -> MutexGuard<'static, HandleMap>> { - PRESENCE_DETECTOR_HANDLE_MAP - .lock() - .unwrap_or_else(|err_guard| err_guard.into_inner()) -} - -// Global hashmap to track valid pointers, this is a safety precaution to make sure we are not -// reading from unsafe memory address's passed in by the caller -lazy_static! { - static ref PRESENCE_DETECTOR_HANDLE_MAP: Mutex>> = - Mutex::new(HandleMap::init()); -} diff --git a/presence/fpp/fpp_c_ffi/src/lib.rs b/presence/fpp/fpp_c_ffi/src/lib.rs deleted file mode 100644 index b0c536f7..00000000 --- a/presence/fpp/fpp_c_ffi/src/lib.rs +++ /dev/null @@ -1,141 +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. - -#![deny( - missing_docs, - clippy::indexing_slicing, - clippy::unwrap_used, - clippy::panic, - clippy::expect_used -)] - -//! Rust FFI wrapper for PresenceDetector. Can be called from C/C++ clients - -use fpp::fused_presence_utils::*; -use fpp::presence_detector::*; - -use crate::handle_map::get_presence_detector_handle_map; - -mod handle_map; - -/// Wraps the handle ID to an underlying PresenceDetector object -#[repr(C)] -pub struct PresenceDetectorHandle { - handle: u64, -} - -/// Enum class representing possible outputs of proximity data processing call -#[repr(C)] -pub enum ComputationStatus { - /// Returned if the proximity estimate calculation was successful - Success, - /// Returned if there is no computed proximity estimate - NoComputedProximityEstimate, - /// Returned if the handle is invalid - InvalidPresenceDetectorHandleError, - /// Returned if the output parameter is null - NullOutputParameterError, -} - -impl ComputationStatus { - fn to_status_code(&self) -> i32 { - match self { - /// Status codes 100+ are considered errors - Self::Success => 1, - Self::NoComputedProximityEstimate => 2, - Self::InvalidPresenceDetectorHandleError => 101, - Self::NullOutputParameterError => 102, - } - } -} - -/// Creates a new presence detector object and returns the handle for the new -/// object -#[no_mangle] -pub extern "C" fn presence_detector_create() -> PresenceDetectorHandle { - let handle = get_presence_detector_handle_map().insert(Box::new(PresenceDetector::new())); - PresenceDetectorHandle { handle } -} - -/// Updates PresenceDetector with a new scan result and returns an error code if -/// unsuccessful -/// -/// # Safety -/// -/// Ensure that the output parameter refers to an initialized instance -#[no_mangle] -pub unsafe extern "C" fn update_ble_scan_result( - presence_detector_handle: PresenceDetectorHandle, - ble_scan_result: BleScanResult, - proximity_estimate: *mut ProximityEstimate, -) -> i32 { - if let Some(presence_detector) = - get_presence_detector_handle_map().get(&presence_detector_handle.handle) - { - if let Some(current_proximity_estimate) = - presence_detector.on_ble_scan_result(ble_scan_result) - { - if let Some(proximity_estimate) = proximity_estimate.as_mut() { - *proximity_estimate = current_proximity_estimate; - ComputationStatus::Success.to_status_code() - } else { - ComputationStatus::NullOutputParameterError.to_status_code() - } - } else { - ComputationStatus::NoComputedProximityEstimate.to_status_code() - } - } else { - ComputationStatus::InvalidPresenceDetectorHandleError.to_status_code() - } -} - -/// Gets the current proximity estimate for a given device ID -/// -/// # Safety -/// -/// Ensure that the output parameter refers to an initialized instance -#[no_mangle] -pub unsafe extern "C" fn get_proximity_estimate( - presence_detector_handle: PresenceDetectorHandle, - device_id: u64, - proximity_estimate: *mut ProximityEstimate, -) -> i32 { - if let Some(presence_detector) = - get_presence_detector_handle_map().get(&presence_detector_handle.handle) - { - presence_detector.get_proximity_estimate(device_id).map(|current_proximity_estimate| { - if let Some(proximity_estimate) = proximity_estimate.as_mut() { - *proximity_estimate = current_proximity_estimate; - return ComputationStatus::Success.to_status_code(); - } - ComputationStatus::NullOutputParameterError.to_status_code() - }); - } - - ComputationStatus::InvalidPresenceDetectorHandleError.to_status_code() -} - -/// De-allocates memory for a presence detector object -#[no_mangle] -pub extern "C" fn presence_detector_free( - presence_detector_handle: PresenceDetectorHandle, -) -> std::os::raw::c_int { - if let Some(presence_detector) = - get_presence_detector_handle_map().remove(&presence_detector_handle.handle) - { - let _ = *presence_detector; - return ComputationStatus::Success.to_status_code(); - } - ComputationStatus::InvalidPresenceDetectorHandleError.to_status_code() -} diff --git a/presence/fpp/fpp_manager.cc b/presence/fpp/fpp_manager.cc deleted file mode 100644 index e7d9efc8..00000000 --- a/presence/fpp/fpp_manager.cc +++ /dev/null @@ -1,168 +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. - -#include "presence/fpp/fpp_manager.h" - -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "internal/platform/logging.h" -#include "presence/fpp/fpp_c_ffi/include/presence_detector.h" -#include "presence/implementation/sensor_fusion.h" -#include "presence/presence_zone.h" - -namespace nearby { -namespace presence { - -namespace { -// See -// https://source.corp.google.com/piper///depot/google3/third_party/nearby/presence/fpp/fpp_c_ffi/src/lib.rs;l=49 -// for constants definition -constexpr int kSuccess = 1; -constexpr int kNoComputedProximityEstimate = 2; -constexpr int kInvalidPresenceDetectorHandleError = 101; -constexpr int kNullOutputParameterError = 102; - -// Converts optional tx power to the rust api compatible equivalent -MaybeTxPower ConvertTxPower(std::optional txPower) { - if (txPower.has_value()) { - return {MaybeTxPower::Tag::Valid, {txPower.value()}}; - } - return {MaybeTxPower::Tag::Invalid, {}}; -} - -// Converts FPP ProximityState struct to NP RangeType struct -PresenceZone::DistanceBoundary::RangeType ConvertProximityStateToRangeType( - ProximityState proximity_state) { - switch (proximity_state) { - case ProximityState::Tap: - return PresenceZone::DistanceBoundary::RangeType::kWithinTap; - case ProximityState::Reach: - return PresenceZone::DistanceBoundary::RangeType::kWithinReach; - case ProximityState::ShortRange: - case ProximityState::LongRange: - case ProximityState::Far: - return PresenceZone::DistanceBoundary::RangeType::kFar; - case ProximityState::Unknown: - default: - LOG(WARNING) << "Proximity state is unknown"; - return PresenceZone::DistanceBoundary::RangeType::kRangeUnknown; - } -} -} // namespace - -absl::Status FppManager::UpdateBleScanResult(uint64_t device_id, - std::optional txPower, - int rssi, - uint64_t elapsed_realtime_millis) { - if (zone_transition_callbacks_.empty()) { - return absl::InternalError("No callback registered"); - } - BleScanResult ble_scan_result = {device_id, ConvertTxPower(txPower), rssi, - elapsed_realtime_millis}; - ProximityEstimate default_proximity_estimate = - ProximityEstimate{device_id, - /*distanceMeters=*/0.0, - MeasurementConfidence::Unknown, - /*elapsedRealtime=*/0, - ProximityState::Unknown, - PresenceDataSource::Ble}; - ProximityEstimate old_proximity_estimate = - current_proximity_estimates_.contains(device_id) - ? current_proximity_estimates_[device_id] - : default_proximity_estimate; - ProximityEstimate new_proximity_estimate = default_proximity_estimate; - int status_code = update_ble_scan_result( - presence_detector_handle_, ble_scan_result, &new_proximity_estimate); - if (status_code == kNoComputedProximityEstimate) { - LOG(INFO) << "Insufficient number of scan results available to " - "compute proximity state"; - return absl::OkStatus(); - } - if (status_code == kSuccess) { - current_proximity_estimates_[device_id] = new_proximity_estimate; - CheckPresenceZoneChanged(device_id, old_proximity_estimate, - new_proximity_estimate); - return absl::OkStatus(); - } - LOG(WARNING) - << "Could not successfully update FPP with new scan result: Error code=" - << status_code; - return absl::InternalError(GetStatusStringFromCode(status_code)); -} - -void FppManager::RegisterZoneTransitionListener( - uint64_t callback_id, ZoneTransitionCallback callback) { - zone_transition_callbacks_[callback_id] = std::move(callback); -} - -void FppManager::UnregisterZoneTransitionListener(uint64_t callback_id) { - zone_transition_callbacks_.erase(callback_id); -} - -void FppManager::ResetProximityStateData() { - current_proximity_estimates_.clear(); -} - -std::optional FppManager::GetRangingData(uint64_t device_id) { - return ConvertProximityEstimateToRangingData( - current_proximity_estimates_[device_id]); -} - -// Converts FPP ProximityEstimate struct to NP RangingData struct -RangingData FppManager::ConvertProximityEstimateToRangingData( - ProximityEstimate estimate) { - RangingMeasurement ranging_measurement = { - /*confidenceLevel=*/0.0, static_cast(estimate.distance_meters)}; - RangingPosition ranging_position = { - ranging_measurement, /*azimuth=*/std::nullopt, - /*elevation=*/std::nullopt, estimate.elapsed_real_time_millis}; - ZoneTransition zone_transition = { - ConvertProximityStateToRangeType(estimate.proximity_state), - /*confidenceLevel=*/0.0}; - return {DataSource::kBle, ranging_position, zone_transition, - std::vector()}; -} - -void FppManager::CheckPresenceZoneChanged(uint64_t device_id, - ProximityEstimate old_estimate, - ProximityEstimate new_estimate) { - if (old_estimate.proximity_state != new_estimate.proximity_state) { - LOG(WARNING) << "Updating zone transition callbacks with new zone. Zone=" - << static_cast(new_estimate.proximity_state); - for (auto& pair : zone_transition_callbacks_) { - pair.second.on_proximity_zone_changed( - device_id, - ConvertProximityStateToRangeType(new_estimate.proximity_state)); - } - } -} - -std::string FppManager::GetStatusStringFromCode(int status_code) { - switch (status_code) { - case kInvalidPresenceDetectorHandleError: - return "INVALID_PRESENCE_DETECTOR_HANDLE"; - case kNullOutputParameterError: - return "NULL_OUTPUT_PARAMETER"; - default: - LOG(WARNING) << "Error code is unknown"; - return "UNKNOWN_ERROR"; - } -} - -} // namespace presence -} // namespace nearby diff --git a/presence/fpp/fpp_manager.h b/presence/fpp/fpp_manager.h deleted file mode 100644 index cecdb21e..00000000 --- a/presence/fpp/fpp_manager.h +++ /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 -// -// 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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_FPP_FPP_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_FPP_FPP_MANAGER_H_ - -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "presence/fpp/fpp_c_ffi/include/presence_detector.h" -#include "presence/implementation/sensor_fusion.h" -#include "presence/presence_zone.h" - -namespace nearby { -namespace presence { - -// Manages fused presence updates and serves as a sync -> async converter class -// between fpp and NP sensor fusion -class FppManager { - public: - using RangeType = PresenceZone::DistanceBoundary::RangeType; - - FppManager() { presence_detector_handle_ = presence_detector_create(); } - ~FppManager() { presence_detector_free(presence_detector_handle_); } - - /** Updates FPP with new BLE scan results. Returns status code */ - absl::Status UpdateBleScanResult(uint64_t device_id, - std::optional txPower, int rssi, - uint64_t elapsed_realtime_millis); - /** - * Adds callback for updates of proximity zone transitions. - */ - void RegisterZoneTransitionListener(uint64_t callback_id, - ZoneTransitionCallback callback); - - /** - * Unregister callback for updates of proximity zone transitions. - */ - void UnregisterZoneTransitionListener(uint64_t callback_id); - - /** - * Clears all proximity state data - */ - void ResetProximityStateData(); - - /* - * Converts ProximityEstimate to a NP compatible struct - */ - RangingData ConvertProximityEstimateToRangingData(ProximityEstimate estimate); - - /** - * Gets the most recent ranging data for a given device - */ - std::optional GetRangingData(uint64_t device_id); - - /* - * Converts a status code to a string representation - */ - std::string GetStatusStringFromCode(int status_code); - - private: - void CheckPresenceZoneChanged(uint64_t device_id, - ProximityEstimate old_estimate, - ProximityEstimate new_estimate); - absl::flat_hash_map current_proximity_estimates_; - absl::flat_hash_map - zone_transition_callbacks_; - PresenceDetectorHandle presence_detector_handle_; -}; -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_FPP_FPP_MANAGER_H_ diff --git a/presence/fpp/fpp_manager_test.cc b/presence/fpp/fpp_manager_test.cc deleted file mode 100644 index 6911e06f..00000000 --- a/presence/fpp/fpp_manager_test.cc +++ /dev/null @@ -1,243 +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. - -#include "presence/fpp/fpp_manager.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "presence/implementation/sensor_fusion.h" - -namespace nearby { -namespace presence { -namespace { -constexpr uint64_t kDeviceId = 1234; -constexpr int kReachRssi = -40; -constexpr int kShortRangeRssi = -60; -constexpr int kCallbackId = 12345; - -TEST(FppManager, UpdateBleScanResultSuccess) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/0)); - // State is only computed after second consecutive scan is fulfilled - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - EXPECT_TRUE(callback_called); -} - -TEST(FppManager, ZoneTransitionDetected) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - // ProximityEstimate is only computed after consecutive scans is fulfilled - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - EXPECT_TRUE(callback_called); - callback_called = false; - - // Update with new zone - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kShortRangeRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - EXPECT_FALSE(callback_called); - // Update with consecutive scan of new zone - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kShortRangeRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kFar); - EXPECT_TRUE(callback_called); -} - -TEST(FppManager, ConvertProximityEstimateToRangingData) { - FppManager manager; - ProximityEstimate proximity_estimate = - ProximityEstimate{kDeviceId, - 0.1, - MeasurementConfidence::Low, - 0, - ProximityState::Reach, - PresenceDataSource::Ble}; - RangingData rangingData = - manager.ConvertProximityEstimateToRangingData(proximity_estimate); - EXPECT_EQ(rangingData.data_source, DataSource::kBle); - EXPECT_EQ(rangingData.position.distance.value, 0.1f); - EXPECT_EQ(rangingData.zone_transition->confidence_level, 0.0f); - EXPECT_EQ(rangingData.zone_transition->distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - ProximityEstimate unknown_proximity_estimate = - ProximityEstimate{kDeviceId, - 0.0, - MeasurementConfidence::Low, - 0, - ProximityState::Unknown, - PresenceDataSource::Ble}; - RangingData unknown_rangingData = - manager.ConvertProximityEstimateToRangingData(unknown_proximity_estimate); - EXPECT_EQ(unknown_rangingData.zone_transition->distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kRangeUnknown); - ProximityEstimate tap_proximity_estimate = - ProximityEstimate{kDeviceId, - 0.03, - MeasurementConfidence::Low, - 0, - ProximityState::Tap, - PresenceDataSource::Ble}; - RangingData tap_rangingData = - manager.ConvertProximityEstimateToRangingData(tap_proximity_estimate); - EXPECT_EQ(tap_rangingData.zone_transition->distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinTap); -} - -TEST(FppManager, UpdateBleScanResultWithTxPowerSuccess) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/20, kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/20, kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinTap); - EXPECT_TRUE(callback_called); -} - -TEST(FppManager, UnregisterZoneTransitionListener) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_TRUE(callback_called); - callback_called = false; - - // Unregister listener and update with new zone - manager.UnregisterZoneTransitionListener(kCallbackId); - EXPECT_EQ(manager - .UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kShortRangeRssi, - /*elapsed_real_time_millis=*/0) - .code(), - absl::StatusCode::kInternal); - EXPECT_EQ(manager - .UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kShortRangeRssi, - /*elapsed_real_time_millis=*/0) - .code(), - absl::StatusCode::kInternal); - EXPECT_FALSE(callback_called); -} - -TEST(FppManager, ResetProximityStateData) { - FppManager manager; - bool callback_called = false; - manager.RegisterZoneTransitionListener( - kCallbackId, - {.on_proximity_zone_changed = - [&callback_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - callback_called = true; - }}); - ASSERT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/0)); - // State is only computed after second consecutive scan is fulfilled - ASSERT_OK(manager.UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, - kReachRssi, - /*elapsed_real_time_millis=*/2000)); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); - EXPECT_TRUE(callback_called); - - // Reset proximity state data - manager.ResetProximityStateData(); - EXPECT_EQ(manager.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kRangeUnknown); -} - -TEST(FppManager, GetStatusStringFromCode) { - FppManager manager; - EXPECT_EQ(manager.GetStatusStringFromCode(101), - "INVALID_PRESENCE_DETECTOR_HANDLE"); - EXPECT_EQ(manager.GetStatusStringFromCode(102), "NULL_OUTPUT_PARAMETER"); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/fpp/sensor_fusion_impl.cc b/presence/fpp/sensor_fusion_impl.cc deleted file mode 100644 index 2bda18b5..00000000 --- a/presence/fpp/sensor_fusion_impl.cc +++ /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 -// -// 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. - -#include "presence/fpp/sensor_fusion_impl.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "presence/fpp/fpp_manager.h" - -namespace nearby { -namespace presence { -std::vector SensorFusionImpl::GetDataSources( - uint64_t elapsed_realtime_millis, - const std::vector& available_sources) { - // TODO(b/264547688) - Implement - return std::vector(); -} -absl::Status SensorFusionImpl::UpdateBleScanResult( - uint64_t device_id, std::optional txPower, int rssi, - uint64_t elapsed_realtime_millis) { - return fpp_manager_.UpdateBleScanResult(device_id, txPower, rssi, - elapsed_realtime_millis); -} -void SensorFusionImpl::UpdateUwbRangingResult(uint64_t device_id, - RangingPosition position) { - // TODO(b/264547688) - Implement -} - -void SensorFusionImpl::RequestZoneTransitionUpdates( - ZoneTransitionCallback callback) { - int callback_id = ++id_generator_; - callback.on_callback_id_generated(callback_id); - fpp_manager_.RegisterZoneTransitionListener(callback_id, std::move(callback)); -} - -void SensorFusionImpl::RequestDeviceMotionUpdates( - SensorFusion::DeviceMotionCallback callback) { - // TODO(b/264547688) - Implement -} -void SensorFusionImpl::RemoveDeviceMotionUpdates( - SensorFusion::DeviceMotionCallback callback) { - // TODO(b/264547688) - Implement -} - -void SensorFusionImpl::RemoveZoneTransitionUpdates(uint64_t callback_id) { - fpp_manager_.UnregisterZoneTransitionListener(callback_id); -} - -std::optional SensorFusionImpl::GetRangingData( - uint64_t device_id) { - return fpp_manager_.GetRangingData(device_id); -} -} // namespace presence -} // namespace nearby diff --git a/presence/fpp/sensor_fusion_impl.h b/presence/fpp/sensor_fusion_impl.h deleted file mode 100644 index ac37b6a8..00000000 --- a/presence/fpp/sensor_fusion_impl.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 -// -// 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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_FPP_SENSOR_FUSION_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_FPP_SENSOR_FUSION_IMPL_H_ - -#include -#include - -#include "presence/fpp/fpp_manager.h" -#include "presence/implementation/sensor_fusion.h" - -namespace nearby { -namespace presence { - -class SensorFusionImpl : public SensorFusion { - public: - ~SensorFusionImpl() = default; - std::vector GetDataSources( - uint64_t elapsed_realtime_millis, - const std::vector& available_sources) override; - absl::Status UpdateBleScanResult(uint64_t device_id, - std::optional txPower, int rssi, - uint64_t elapsed_realtime_millis) override; - void UpdateUwbRangingResult(uint64_t device_id, - RangingPosition position) override; - void RequestZoneTransitionUpdates(ZoneTransitionCallback callback) override; - void RemoveZoneTransitionUpdates(uint64_t callback_id) override; - void RequestDeviceMotionUpdates(DeviceMotionCallback callback) override; - void RemoveDeviceMotionUpdates(DeviceMotionCallback callback) override; - std::optional GetRangingData(uint64_t device_id) override; - - private: - FppManager fpp_manager_; - int id_generator_ = 0; -}; -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_FPP_SENSOR_FUSION_IMPL_H_ diff --git a/presence/fpp/sensor_fusion_test.cc b/presence/fpp/sensor_fusion_test.cc deleted file mode 100644 index aee34d7b..00000000 --- a/presence/fpp/sensor_fusion_test.cc +++ /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 -// -// 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. - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "presence/fpp/sensor_fusion_impl.h" - -namespace nearby { -namespace presence { -namespace { -constexpr uint64_t kDeviceId = 1234; -constexpr int kReachRssi = -40; - -TEST(SensorFusion, RequestZoneTransitionUpdatesSuccess) { - SensorFusionImpl sensor_fusion_impl; - bool callback_called = false; - bool callback2_called = false; - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_callback_id_generated = [&callback_called](uint64_t callback_id) { - callback_called = true; - EXPECT_EQ(callback_id, 1); - }}); - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_callback_id_generated = [&callback2_called](uint64_t callback_id2) { - callback2_called = true; - EXPECT_EQ(callback_id2, 2); - }}); - EXPECT_TRUE(callback2_called); -} - -TEST(SensorFusion, RemoveZoneTransitionUpdates) { - SensorFusionImpl sensor_fusion_impl; - bool callback_called = false; - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_callback_id_generated = [&callback_called](uint64_t callback_id) { - callback_called = true; - EXPECT_EQ(callback_id, 1); - }}); - sensor_fusion_impl.RemoveZoneTransitionUpdates(1); - EXPECT_EQ( - sensor_fusion_impl - .UpdateBleScanResult(kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0) - .code(), - absl::StatusCode::kInternal); -} - -TEST(SensorFusion, UpdateBleScanResult) { - SensorFusionImpl sensor_fusion_impl; - bool proximity_zone_changed_called = false; - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_proximity_zone_changed = - [&proximity_zone_changed_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - proximity_zone_changed_called = true; - }}); - EXPECT_OK(sensor_fusion_impl.UpdateBleScanResult( - kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(sensor_fusion_impl.UpdateBleScanResult( - kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0)); - - EXPECT_TRUE(proximity_zone_changed_called); -} - -TEST(SensorFusion, GetRangingData) { - SensorFusionImpl sensor_fusion_impl; - bool proximity_zone_changed_called = false; - sensor_fusion_impl.RequestZoneTransitionUpdates( - {.on_proximity_zone_changed = - [&proximity_zone_changed_called]( - uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType range_type) { - proximity_zone_changed_called = true; - }}); - EXPECT_OK(sensor_fusion_impl.UpdateBleScanResult( - kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0)); - EXPECT_OK(sensor_fusion_impl.UpdateBleScanResult( - kDeviceId, /*txPower=*/std::nullopt, kReachRssi, - /*elapsed_real_time_millis=*/0)); - - EXPECT_TRUE(proximity_zone_changed_called); - - EXPECT_EQ(sensor_fusion_impl.GetRangingData(kDeviceId) - ->zone_transition.value() - .distance_range_type, - PresenceZone::DistanceBoundary::RangeType::kWithinReach); -} -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/BUILD b/presence/implementation/BUILD deleted file mode 100644 index 5afccce1..00000000 --- a/presence/implementation/BUILD +++ /dev/null @@ -1,493 +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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -licenses(["notice"]) - -filegroup( - name = "presence_internal_common_srcs", - srcs = [ - "action_factory.cc", - "advertisement_factory.cc", - "advertisement_filter.cc", - "base_broadcast_request.cc", - "broadcast_manager.cc", - "connection_authenticator_impl.cc", - "credential_manager_impl.cc", - "ldt.cc", - "scan_manager.cc", - "service_controller_impl.cc", - ], -) - -filegroup( - name = "presence_internal_common_hdrs", - srcs = [ - "action_factory.h", - "advertisement_decoder.h", - "advertisement_decoder_impl.h", - "advertisement_factory.h", - "advertisement_filter.h", - "base_broadcast_request.h", - "broadcast_manager.h", - "connection_authenticator.h", - "connection_authenticator_impl.h", - "credential_manager.h", - "credential_manager_impl.h", - "ldt.h", - "scan_manager.h", - "service_controller.h", - "service_controller_impl.h", - ], -) - -cc_library( - name = "internal", - srcs = [ - "advertisement_decoder_rust_impl.cc", - ":presence_internal_common_srcs", - ], - hdrs = [ - "advertisement_decoder_rust_impl.h", - ":presence_internal_common_hdrs", - ], - defines = ["USE_RUST_DECODER=1"], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//internal/crypto", - "//internal/crypto_cros", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform:uuid", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "//presence:types", - "//presence/implementation/mediums", - "@beto-core//:ldt_np_adv_ffi", - "@beto-core//:np_c_ffi_types", - "@beto-core//:np_cpp_ffi", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/container:flat_hash_set", - "@com_google_absl//absl/hash", - "@com_google_absl//absl/log:check", - "@com_google_absl//absl/log:die_if_null", - "@com_google_absl//absl/random", - "@com_google_absl//absl/random:distributions", - "@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", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:optional", - "@com_google_absl//absl/types:span", - "@com_google_absl//absl/types:variant", - ], -) - -cc_library( - name = "internal_deprecated", - srcs = [ - "advertisement_decoder_impl.cc", - ":presence_internal_common_srcs", - ], - hdrs = [ - "advertisement_decoder_impl.h", - ":presence_internal_common_hdrs", - ], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//devtools/rust:rust_okay_here", - "//internal/crypto", - "//internal/crypto_cros", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:types", - "//internal/platform:uuid", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "//internal/proto:metadata_cc_proto", - "//presence:types", - "//presence/implementation/mediums", - "@beto-core//:ldt_np_adv_ffi", - "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/container:flat_hash_set", - "@com_google_absl//absl/hash", - "@com_google_absl//absl/log:check", - "@com_google_absl//absl/log:die_if_null", - "@com_google_absl//absl/random", - "@com_google_absl//absl/random:distributions", - "@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", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:optional", - "@com_google_absl//absl/types:span", - "@com_google_absl//absl/types:variant", - ], -) - -cc_library( - name = "sensor_fusion", - hdrs = ["sensor_fusion.h"], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//presence:types", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/status", - ], -) - -cc_library( - name = "internal_test", - testonly = True, - srcs = [ - ], - hdrs = [ - "mock_connection_authenticator.h", - "mock_credential_manager.h", - "mock_service_controller.h", - ], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - ":internal", - "//internal/platform/implementation:comm", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings:string_view", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "advertisement_decoder_test", - size = "small", - srcs = ["advertisement_decoder_test.cc"], - deps = [ - ":internal_deprecated", - "//internal/platform:base", - "//internal/proto:credential_cc_proto", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "advertisement_decoder_new_format_test", - size = "small", - srcs = ["advertisement_decoder_new_format_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "//internal/proto:credential_cc_proto", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "advertisement_filter_test", - size = "small", - srcs = ["advertisement_filter_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "//internal/proto:credential_cc_proto", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "advertisement_factory_test", - size = "small", - srcs = ["advertisement_factory_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "//internal/proto:credential_cc_proto", - "//presence:types", - "//presence/implementation/mediums", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "broadcast_manager_test", - size = "small", - srcs = ["broadcast_manager_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/proto:credential_cc_proto", - "//presence/implementation/mediums", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "ldt_test", - size = "small", - srcs = ["ldt_test.cc"], - deps = [ - ":internal", - "//internal/platform:base", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "base_broadcast_request_test", - srcs = ["base_broadcast_request_test.cc"], - deps = [ - ":internal", - "//internal/proto:credential_cc_proto", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/types:variant", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "action_factory_test", - size = "small", - srcs = ["action_factory_test.cc"], - deps = [ - ":internal", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "connection_authenticator_impl_test", - size = "small", - srcs = ["connection_authenticator_impl_test.cc"], - deps = [ - ":internal", - "//internal/crypto", - "//internal/crypto_cros", - "//internal/proto:credential_cc_proto", - "//internal/proto:local_credential_cc_proto", - "//presence/proto:presence_frame_cc_proto", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "credential_manager_impl_test", - size = "small", - srcs = ["credential_manager_impl_test.cc"], - deps = [ - ":internal", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//net/proto2/contrib/parse_proto:testing", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "scan_manager_test", - size = "small", - srcs = ["scan_manager_test.cc"], - deps = [ - ":internal", - ":internal_test", - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:logging", - "//internal/platform:mac_address", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//presence:types", - "//presence/implementation/mediums", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) - -cc_test( - name = "service_controller_impl_test", - size = "small", - srcs = ["service_controller_impl_test.cc"], - deps = [ - ":internal", - ":internal_test", - "//internal/platform:comm", - "//internal/platform:test_util", - "//internal/platform:types", - "//internal/platform/implementation:comm", - "//internal/platform/implementation:types", - "//internal/proto:credential_cc_proto", - "//net/proto2/contrib/parse_proto:testing", - "//presence/implementation/mediums", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/time", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) diff --git a/presence/implementation/action_factory.cc b/presence/implementation/action_factory.cc deleted file mode 100644 index fe4a6e45..00000000 --- a/presence/implementation/action_factory.cc +++ /dev/null @@ -1,106 +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 "presence/implementation/action_factory.h" - -#include -#include -#include - -#include "internal/platform/logging.h" -#include "presence/data_element.h" -#include "presence/implementation/base_broadcast_request.h" - -namespace nearby { -namespace presence { - -constexpr int kContentTimestampMask = 0x0F; -constexpr int kContentTimestampShift = 28; -constexpr int kEmptyMask = 0; -constexpr int kActionSizeInBits = 32; - -namespace { - -int GetActionMask(ActionBit action) { - int bit = static_cast(action); - if (bit < 0 || bit >= kActionSizeInBits) { - LOG(WARNING) << "Unsupported action " << static_cast(action); - return kEmptyMask; - } - return 1 << (kActionSizeInBits - 1 - bit); -} - -// The reverse of `GetActionMask()` -ActionBit GetActionFromBit(int bit) { - return ActionBit(kActionSizeInBits - 1 - bit); -} - -int GetMask(const DataElement& element) { - int type = element.GetType(); - switch (type) { - case DataElement::kContextTimestampFieldType: { - auto value = element.GetValue(); - if (!value.empty()) { - return (value[0] & kContentTimestampMask) << kContentTimestampShift; - } else { - LOG(WARNING) << "Context timestamp Data Element without value"; - return kEmptyMask; - } - } - case DataElement::kActionFieldType: { - if (element.GetValue().empty()) { - LOG(WARNING) << "Action Data Element without value"; - return kEmptyMask; - } - return GetActionMask(ActionBit(element.GetValue()[0])); - } - } - LOG(WARNING) << "Data Element " << type - << " not supported in base advertisement"; - return kEmptyMask; -} - -} // namespace - -Action ActionFactory::CreateAction( - const std::vector& data_elements) { - Action action = {.action = 0}; - std::for_each(data_elements.begin(), data_elements.end(), - [&](const auto& element) { - int mask = GetMask(element); - action.action |= mask; - }); - return action; -} - -void ActionFactory::DecodeAction(const Action& action, - std::vector& output) { - uint8_t context_timestamp = - (action.action >> kContentTimestampShift) & kContentTimestampMask; - if (context_timestamp) { - output.emplace_back(DataElement::kContextTimestampFieldType, - context_timestamp); - } - constexpr int kFirstUsedBit = - kActionSizeInBits - static_cast(ActionBit::kLastAction); - for (int i = kFirstUsedBit; i < kContentTimestampShift; i++) { - int bit_mask = 1 << i; - if (action.action & bit_mask) { - output.emplace_back(DataElement(GetActionFromBit(i))); - } - } -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/action_factory.h b/presence/implementation/action_factory.h deleted file mode 100644 index b2a43880..00000000 --- a/presence/implementation/action_factory.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_PRESENCE_IMPLEMENTATION_ACTION_FACTORY_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ACTION_FACTORY_H_ - -#include - -#include "presence/data_element.h" -#include "presence/implementation/base_broadcast_request.h" - -namespace nearby { -namespace presence { - -// Defines the mapping between Data Elements and Actions in the Base NP -// advertisement. -class ActionFactory { - public: - // Returns an Action for Base NP advertisement from a collection of Data - // Elements. Data Elements unsupported in the Base NP advertisement are - // ignored. - static Action CreateAction(const std::vector& data_elements); - - // Decodes a Base NP Action into a list of Data Elements. The Data Elements - // are appended to the `output` list. - // - // DecodeAction is effectively a reverse operation of CreateAction. - static void DecodeAction(const Action& action, - std::vector& output); -}; -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ACTION_FACTORY_H_ diff --git a/presence/implementation/action_factory_test.cc b/presence/implementation/action_factory_test.cc deleted file mode 100644 index 63db1990..00000000 --- a/presence/implementation/action_factory_test.cc +++ /dev/null @@ -1,107 +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 "presence/implementation/action_factory.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "presence/data_element.h" -#include "presence/implementation/base_broadcast_request.h" - -namespace nearby { -namespace presence { -namespace { - -using ::testing::ElementsAre; - -constexpr uint32_t kActiveUnlockBitMask = 1 << 23; -constexpr uint32_t kFastPairBitMask = 1 << 17; - -TEST(ActionFactory, CreateActiveUnlockAction) { - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - - Action action = ActionFactory::CreateAction(data_elements); - - EXPECT_EQ(action.action, kActiveUnlockBitMask); -} - -TEST(ActionFactory, CreateActiveIgnoresUnsupportedActions) { - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - // The action is 32 bit, so the valid range is [0-31] - data_elements.emplace_back(ActionBit(-1)); - data_elements.emplace_back(ActionBit(32)); - Action action = ActionFactory::CreateAction(data_elements); - - EXPECT_EQ(action.action, kActiveUnlockBitMask); -} - -TEST(ActionFactory, CreateContextTimestamp) { - const std::string kTimestamp = absl::HexStringToBytes("0B"); - - std::vector data_elements; - data_elements.emplace_back(DataElement::kContextTimestampFieldType, - kTimestamp); - - Action action = ActionFactory::CreateAction(data_elements); - - EXPECT_EQ(action.action, 0x0BU << 28); -} - -TEST(ActionFactory, CreateContextTimestampAndFastPair) { - const std::string kTimestamp = absl::HexStringToBytes("0B"); - - std::vector data_elements; - data_elements.emplace_back(DataElement::kContextTimestampFieldType, - kTimestamp); - data_elements.emplace_back(ActionBit::kFastPairSassAction); - - Action action = ActionFactory::CreateAction(data_elements); - - EXPECT_EQ(action.action, (0x0BU << 28) | kFastPairBitMask); -} - -TEST(ActionFactory, DecodeActiveUnlockAction) { - constexpr Action kAction = {.action = kActiveUnlockBitMask}; - std::vector data_elements; - - ActionFactory::DecodeAction(kAction, data_elements); - - EXPECT_THAT( - data_elements, - ElementsAre(DataElement(DataElement(ActionBit::kActiveUnlockAction)))); -} - -TEST(ActionFactory, DecodeContextTimestampAndFastPair) { - constexpr Action kAction = {.action = (0x0BU << 28) | kFastPairBitMask}; - std::vector data_elements; - - ActionFactory::DecodeAction(kAction, data_elements); - - EXPECT_THAT( - data_elements, - ElementsAre(DataElement(DataElement::kContextTimestampFieldType, - absl::HexStringToBytes("0B")), - DataElement(DataElement(ActionBit::kFastPairSassAction)))); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_decoder.h b/presence/implementation/advertisement_decoder.h deleted file mode 100644 index 3c5d444b..00000000 --- a/presence/implementation/advertisement_decoder.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT 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_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_DECODER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_DECODER_H_ - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" - -namespace nearby { -namespace presence { - -// The structured decoded form of a detected Nearby Presence advertisement -struct Advertisement { - uint8_t version = 0; - std::vector data_elements; - absl::StatusOr public_credential = - absl::NotFoundError(""); - internal::IdentityType identity_type = internal::IDENTITY_TYPE_UNSPECIFIED; - std::string metadata_key; -}; - -// Interface for decoding Nearby Presence advertisements from a payload of raw -// bytes into a structured, decrypted, and decoded format -class AdvertisementDecoder { - public: - // Is needed otherwise deleting an instance via a pointer to a base class - // results in undefined behavior - virtual ~AdvertisementDecoder() = default; - - // Returns the structured and decoded contents of an advertisement given a - // payload of bytes as a string. Returns an error if the advertisement is - // misformatted or if it couldn't be decrypted. - virtual absl::StatusOr DecodeAdvertisement( - absl::string_view advertisement) = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_DECODER_H_ diff --git a/presence/implementation/advertisement_decoder_impl.cc b/presence/implementation/advertisement_decoder_impl.cc deleted file mode 100644 index fec04c85..00000000 --- a/presence/implementation/advertisement_decoder_impl.cc +++ /dev/null @@ -1,287 +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 "presence/implementation/advertisement_decoder_impl.h" - -#include -#include -#include -#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 "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "internal/platform/logging.h" -#include "presence/data_element.h" -#include "presence/implementation/action_factory.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/ldt.h" - -namespace nearby { -namespace presence { - -namespace { - -constexpr uint8_t kDataTypeMask = - (1 << DataElement::kDataElementLengthShift) - 1; - -constexpr int kAdvertisementVersion = 0; - -constexpr int kEncryptedIdentityAdditionalLength = - kSaltSize + kBaseMetadataSize; -constexpr int kEddystoneAdditionalLength = 20; - -uint8_t GetDataElementType(uint8_t header) { return header & kDataTypeMask; } - -size_t GetDataElementLength(uint8_t header) { - return header >> DataElement::kDataElementLengthShift; -} - -// Verifies if the DE header describes a valid DE in v0 advertisement. -bool IsDataElementAllowed(uint8_t header) { - uint8_t data_type = GetDataElementType(header); - size_t length = GetDataElementLength(header); - switch (data_type) { - case DataElement::kSaltFieldType: - return length == 2; - case DataElement::kPublicIdentityFieldType: - return length == 0; - case DataElement::kPrivateGroupIdentityFieldType: - case DataElement::kContactsGroupIdentityFieldType: - return length >= 2 && length <= 6; - case DataElement::kTxPowerFieldType: - return length == 1; - case DataElement::kActionFieldType: - return length >= 1 && length <= 3; - case DataElement::kModelIdFieldType: - return length == 3; - case DataElement::kEddystoneIdFieldType: - return length == 0; - case DataElement::kAccountKeyDataFieldType: - return length <= 12; - case DataElement::kConnectionStatusFieldType: - return length <= 3; - case DataElement::kBatteryFieldType: - return length <= 3; - default: - return false; - } -} - -bool IsEncryptedIdentity(int data_type) { - return data_type == DataElement::kPrivateGroupIdentityFieldType || - data_type == DataElement::kContactsGroupIdentityFieldType; -} - -bool IsIdentity(int data_type) { - return data_type == DataElement::kPublicIdentityFieldType || - IsEncryptedIdentity(data_type); -} - -internal::IdentityType GetIdentityType(int data_type) { - switch (data_type) { - case DataElement::kPrivateGroupIdentityFieldType: - return internal::IDENTITY_TYPE_PRIVATE_GROUP; - case DataElement::kContactsGroupIdentityFieldType: - return internal::IDENTITY_TYPE_CONTACTS_GROUP; - case DataElement::kPublicIdentityFieldType: - return internal::IDENTITY_TYPE_PUBLIC; - } - return internal::IDENTITY_TYPE_UNSPECIFIED; -} - -// Returns the real length of a DE in v0 advertisement, which may be larger than -// the value in the header. -size_t GetDataElementTrueLength(uint8_t header) { - uint8_t data_type = GetDataElementType(header); - size_t length = GetDataElementLength(header); - if (IsEncryptedIdentity(data_type)) { - // The length of an encrypted DE is 16 bytes of overhead (salt + metadata - // key) + the actual payload, which is too long to fit in the 4-bit DE - // length field. - length += kEncryptedIdentityAdditionalLength; - } else if (data_type == DataElement::kEddystoneIdFieldType) { - // Length in the header is set to EID length minus 20, because EID is longer - // than 15 (the maximum length that can be stored in 4 bits. - length += kEddystoneAdditionalLength; - } - return length; -} - -absl::StatusOr ParseDataElement(const absl::string_view input, - size_t& index) { - if (index >= input.size()) { - return absl::OutOfRangeError(absl::StrFormat( - "Data element (%s) is %d bytes long. Expected more than %d", - absl::BytesToHexString(input), input.size(), index)); - } - uint8_t header = input[index]; - if (!IsDataElementAllowed(header)) { - return absl::InvalidArgumentError( - absl::StrFormat("Unsupported Data Element 0x%x", header)); - } - uint8_t data_type = GetDataElementType(header); - size_t length = GetDataElementTrueLength(header); - ++index; - size_t start = index; - index += length; - if (index > input.size()) { - return absl::OutOfRangeError(absl::StrFormat( - "Data element (%s) is %d bytes long. Expected at least %d", - absl::BytesToHexString(input), input.size(), index)); - } - VLOG(1) << "Type: " << static_cast(data_type) - << " length: " << static_cast(length) - << " DE: " << absl::BytesToHexString(input.substr(start, length)); - return DataElement(data_type, input.substr(start, length)); -} -} // namespace - -void DecodeBaseAction(absl::string_view serialized_action, - Advertisement& decoded_advertisement) { - if (serialized_action.empty() || serialized_action.size() > 3) { - LOG(WARNING) << "Base NP action \'" - << absl::BytesToHexString(serialized_action) - << "\' has wrong length " << serialized_action.size() - << " , expected size in range [1 - 3]"; - return; - } - // Action, 0-2 bytes in Big Endian order. - Action action = {.action = 0}; - for (int i = 0; i < serialized_action.size(); ++i) { - int offset = (sizeof(uint32_t) - 1 - i) * 8; - action.action |= serialized_action[i] << offset; - } - - ActionFactory::DecodeAction(action, decoded_advertisement.data_elements); -} - -absl::StatusOr DecryptLdt( - const std::vector& credentials, - absl::string_view salt, absl::string_view encrypted_contents, - Advertisement& decoded_advertisement) { - if (credentials.empty()) { - return absl::UnavailableError("No credentials"); - } - for (const auto& credential : credentials) { - absl::StatusOr encryptor = LdtEncryptor::Create( - credential.key_seed(), credential.metadata_encryption_key_tag_v0()); - if (encryptor.ok()) { - absl::StatusOr result = - encryptor->DecryptAndVerify(encrypted_contents, salt); - if (result.ok() && result->size() > kBaseMetadataSize) { - decoded_advertisement.public_credential = credential; - decoded_advertisement.metadata_key = - result->substr(0, kBaseMetadataSize); - return result->substr(kBaseMetadataSize); - } - } - } - return absl::UnavailableError( - "Couldn't decrypt the message with any credentials"); -} - -absl::Status DecryptDataElements( - const std::vector& credentials, - const DataElement& elem, Advertisement& decoded_advertisement) { - if (elem.GetValue().size() <= kEncryptedIdentityAdditionalLength) { - return absl::OutOfRangeError(absl::StrFormat( - "Encrypted identity data element is too short - %d bytes", - elem.GetValue().size())); - } - absl::string_view salt = elem.GetValue().substr(0, kSaltSize); - decoded_advertisement.data_elements.emplace_back(DataElement::kSaltFieldType, - salt); - absl::string_view encrypted = elem.GetValue().substr(kSaltSize); - absl::StatusOr decrypted = - DecryptLdt(credentials, salt, encrypted, decoded_advertisement); - if (!decrypted.ok()) { - LOG(WARNING) << "Failed to decrypt advertisement, status: " - << decrypted.status(); - return decrypted.status(); - } - size_t index = 0; - while (index < decrypted->size()) { - absl::StatusOr internal_elem = - ParseDataElement(*decrypted, index); - if (!internal_elem.ok()) { - LOG(WARNING) << "Failed to read data element, status: " - << internal_elem.status(); - return internal_elem.status(); - } - if (internal_elem->GetType() == DataElement::kActionFieldType) { - DecodeBaseAction(internal_elem->GetValue(), decoded_advertisement); - } else { - decoded_advertisement.data_elements.push_back(*std::move(internal_elem)); - } - } - return absl::OkStatus(); -} - -absl::StatusOr AdvertisementDecoderImpl::DecodeAdvertisement( - absl::string_view advertisement) { - Advertisement decoded_advertisement = Advertisement{}; - std::vector result; - LOG(INFO) << "Advertisement: " << absl::BytesToHexString(advertisement); - if (advertisement.empty()) { - return absl::OutOfRangeError("Empty advertisement"); - } - uint8_t version = advertisement[0]; - VLOG(1) << "Version: " << version; - if (version != kAdvertisementVersion) { - return absl::UnimplementedError(absl::StrFormat( - "Advertisement version (%d) is not supported", version)); - } - decoded_advertisement.version = version; - size_t index = 1; - absl::StatusOr decrypted; - while (index < advertisement.size()) { - absl::StatusOr elem = ParseDataElement(advertisement, index); - if (!elem.ok()) { - LOG(WARNING) << "Failed to read data element, status: " << elem.status(); - return elem.status(); - } - if (IsIdentity(elem->GetType())) { - decoded_advertisement.identity_type = GetIdentityType(elem->GetType()); - } - if (IsEncryptedIdentity(elem->GetType())) { - if (credentials_map_ == nullptr) { - return absl::FailedPreconditionError("Missing credentials"); - } - auto identity_type_specific_creds = - (*credentials_map_)[decoded_advertisement.identity_type]; - absl::Status status = DecryptDataElements(identity_type_specific_creds, - *elem, decoded_advertisement); - if (!status.ok()) { - return status; - } - } else { - if (elem->GetType() == DataElement::kActionFieldType) { - DecodeBaseAction(elem->GetValue(), decoded_advertisement); - } else { - decoded_advertisement.data_elements.push_back(*std::move(elem)); - } - } - } - - return std::move(decoded_advertisement); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_decoder_impl.h b/presence/implementation/advertisement_decoder_impl.h deleted file mode 100644 index c3e7e592..00000000 --- a/presence/implementation/advertisement_decoder_impl.h +++ /dev/null @@ -1,51 +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_PRESENCE_ADVERTISEMENT_DECODER_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_IMPL_H_ - -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "presence/implementation/advertisement_decoder.h" - -namespace nearby { -namespace presence { - -// Implements the C++ backed parsing and decrypting of advertisement bytes -class AdvertisementDecoderImpl : public AdvertisementDecoder { - public: - AdvertisementDecoderImpl() = default; - explicit AdvertisementDecoderImpl( - absl::flat_hash_map>* - credentials_map) - : credentials_map_(credentials_map) {} - - absl::StatusOr DecodeAdvertisement( - absl::string_view advertisement) override; - - private: - absl::flat_hash_map>* - credentials_map_ = nullptr; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_IMPL_H_ diff --git a/presence/implementation/advertisement_decoder_new_format_test.cc b/presence/implementation/advertisement_decoder_new_format_test.cc deleted file mode 100644 index ef78c828..00000000 --- a/presence/implementation/advertisement_decoder_new_format_test.cc +++ /dev/null @@ -1,156 +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 -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.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/escaping.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/implementation/advertisement_decoder_rust_impl.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::ByteArray; // NOLINT -using ::nearby::internal::IdentityType; // NOLINT -using ::nearby::internal::SharedCredential; // NOLINT -using ::testing::ElementsAre; -using ::testing::status::StatusIs; - -TEST(AdvertisementDecoderImpl, DecodePublicAdvertisement) { - std::string V0AdvPlaintextBytes = - "00" // Adv Header V0 unencrypted - "1503"; // length 1 Tx Power DE value 3 - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvPlaintextBytes)); - ASSERT_OK(result); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(result->version, 0); - EXPECT_THAT(result->data_elements, - ElementsAre(DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("03")))); -} - -TEST(AdvertisementDecoderImpl, DecodePublicAdvertisementMultiDe) { - std::string V0AdvPlaintextMultiDeBytes = - "00" // Adv Header V0 unencrypted - "1505" // length 1 Tx Power DE value 5 - "260040"; // length 2 actions de with NearbyShare bit set - - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - absl::StatusOr result = decoder.DecodeAdvertisement( - absl::HexStringToBytes(V0AdvPlaintextMultiDeBytes)); - ASSERT_OK(result); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(result->version, 0); - EXPECT_THAT(result->data_elements, - ElementsAre(DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("05")), - DataElement(ActionBit::kNearbyShareAction))); -} - -// V0 encrypted advertisement data - ripped out of np_adv/tests/examples_v0.rs -TEST(AdvertisementDecoderImpl, DecodeEncryptedAdvertisement) { - std::string V0AdvEncryptedBytes = "042222D82212EF16DBF872F2A3A7C0FA5248EC"; - ByteArray seed({ - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - }); - ByteArray known_mac({0x09, 0xFE, 0x9E, 0x81, 0xB7, 0x3E, 0x5E, 0xCC, - 0x76, 0x59, 0x57, 0x71, 0xE0, 0x1F, 0xFB, 0x34, - 0x38, 0xE7, 0x5F, 0x24, 0xA7, 0x69, 0x56, 0xA0, - 0xB8, 0xEA, 0x67, 0xD1, 0x1C, 0x3E, 0x36, 0xFD}); - SharedCredential public_credential; - public_credential.set_key_seed(seed.AsStringView()); - public_credential.set_metadata_encryption_key_tag_v0( - known_mac.AsStringView()); - public_credential.set_id(12345678); - absl::flat_hash_map> - credentials; - credentials[IdentityType::IDENTITY_TYPE_PRIVATE_GROUP].push_back( - public_credential); - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(&credentials); - - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvEncryptedBytes)); - ASSERT_OK(result); - EXPECT_EQ(result->public_credential.value().id(), public_credential.id()); - EXPECT_EQ(result->public_credential.value().key_seed(), - public_credential.key_seed()); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_EQ(result->version, 0); - EXPECT_THAT(result->data_elements, - ElementsAre(DataElement(DataElement::kSaltFieldType, - absl::HexStringToBytes("2222")), - DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("03")))); -} - -TEST(AdvertisementDecoderImpl, DecodeEncryptedAdvertisementNoCreds) { - std::string V0AdvEncryptedBytes = "042222D82212EF16DBF872F2A3A7C0FA5248EC"; - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvEncryptedBytes)); - EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnavailable)); -} - -TEST(AdvertisementDecoderImpl, V1AdvCurrentlyUnsupported) { - std::string V1Adv = - "20" // Version header V1 - "00" // format - "02" // section len - "1503"; // Tx power value 3 - - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V1Adv)); - EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnimplemented)); -} - -TEST(AdvertisementDecoderImpl, V0InvalidEmptyAdv) { - std::string V1Adv = "00"; - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(V1Adv)); - EXPECT_THAT(result, StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST(AdvertisementDecoderImpl, V0InvalidAdvContents) { - std::string invalid_v0_adv = - "00" // Adv Header V0 unencrypted - "3503"; // length 3 Tx Power DE with only 1 byte - AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(); - absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes(invalid_v0_adv)); - EXPECT_THAT(result, StatusIs(absl::StatusCode::kInvalidArgument)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_decoder_rust_impl.cc b/presence/implementation/advertisement_decoder_rust_impl.cc deleted file mode 100644 index 9ff10320..00000000 --- a/presence/implementation/advertisement_decoder_rust_impl.cc +++ /dev/null @@ -1,241 +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 "presence/implementation/advertisement_decoder_rust_impl.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "np_cpp_ffi_types.h" -#include "nearby_protocol.h" -#include "internal/platform/logging.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" - -namespace nearby { -namespace presence { -namespace { - -absl::StatusOr<::nearby_protocol::ActionType> MapAction( - const ActionBit action) { - return ::nearby_protocol::ActionType::TryBuildFromU8( - static_cast(action)); -} - -void AddActionsToAdvertisement(const nearby_protocol::V0Actions& parsed_actions, - Advertisement& advertisement) { - for (const auto action : kAllActionBits) { - auto action_type = MapAction(action); - if (!action_type.ok()) { - LOG(WARNING) << "Advertisement contains an unsupported action bit: " - << (int)action; - continue; - } - if (parsed_actions.HasAction(*action_type)) { - advertisement.data_elements.push_back(DataElement(action)); - } - } -} - -void ProcessDataElement(const nearby_protocol::V0DataElement& data_element, - Advertisement& advertisement) { - switch (data_element.GetKind()) { - case nearby_protocol::V0DataElementKind::TxPower: { - advertisement.data_elements.push_back(DataElement( - DataElement::kTxPowerFieldType, data_element.AsTxPower().GetAsI8())); - return; - } - case nearby_protocol::V0DataElementKind::Actions: { - AddActionsToAdvertisement(data_element.AsActions(), advertisement); - return; - } - default: { - LOG(WARNING) << "Unsupported data element type: " - << (int)data_element.GetKind(); - } - } -} - -internal::IdentityType GetIdentityType( - nearby_protocol::DeserializedV0IdentityKind identity) { - switch (identity) { - case np_ffi::internal::DeserializedV0IdentityKind::Plaintext: - return internal::IdentityType::IDENTITY_TYPE_PUBLIC; - case np_ffi::internal::DeserializedV0IdentityKind::Decrypted: - return internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; - } -} - -absl::StatusOr<::nearby::internal::SharedCredential> FindById( - std::vector<::nearby::internal::SharedCredential> private_credentials, - uint64_t id) { - auto cred = - std::find_if(private_credentials.begin(), private_credentials.end(), - [&id](const auto& x) { return x.id() == id; }); - if (cred == private_credentials.end()) { - return absl::NotFoundError("No credential found with id: " + - std::to_string(id)); - } - return *cred; -} - -absl::Status ProcessLegibleV0Adv( - nearby_protocol::LegibleDeserializedV0Advertisement legible_adv, - std::vector<::nearby::internal::SharedCredential> private_credentials, - Advertisement& advertisement) { - advertisement.identity_type = GetIdentityType(legible_adv.GetIdentityKind()); - - auto num_des = legible_adv.GetNumberOfDataElements(); - auto payload = legible_adv.IntoPayload(); - - // TODO(b/333126765): salt isn't a DE, we should restructure the - // Advertisement struct to reflect this - if (advertisement.identity_type == - internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP) { - auto cred_details = payload.TryGetIdentityDetails(); - if (!cred_details.ok()) { - return cred_details.status(); - } - - advertisement.public_credential = - FindById(private_credentials, cred_details->cred_id); - - // TODO(b/333126765): update salt to use unsigned char * to remove cast - std::string salt(reinterpret_cast(cred_details->salt), 2); - advertisement.data_elements.push_back(DataElement(0x00, salt)); - - std::string metadata_key( - reinterpret_cast(cred_details->identity_token), 14); - advertisement.metadata_key = std::move(metadata_key); - } - - for (int i = 0; i < num_des; i++) { - auto de_result = payload.TryGetDataElement(i); - if (!de_result.ok()) { - return de_result.status(); - } - ProcessDataElement(*de_result, advertisement); - } - return absl::OkStatus(); -} - -absl::Status ProcessV0Advertisement( - nearby_protocol::DeserializedV0Advertisement result, - std::vector<::nearby::internal::SharedCredential> private_credentials, - Advertisement& adv) { - switch (result.GetKind()) { - case nearby_protocol::DeserializedV0AdvertisementKind::Legible: - return ProcessLegibleV0Adv(result.IntoLegible(), private_credentials, - adv); - break; - case nearby_protocol::DeserializedV0AdvertisementKind:: - NoMatchingCredentials: { - return absl::UnavailableError( - "Couldn't decrypt the message with any credentials"); - } - } -} - -} // namespace - -absl::StatusOr AdvertisementDecoderImpl::DecodeAdvertisement( - absl::string_view advertisement) { - auto byte_buffer = nearby_protocol::ByteBuffer< - nearby_protocol::MAX_ADV_PAYLOAD_SIZE>::TryFromString(advertisement); - if (!byte_buffer.ok()) { - return absl::InvalidArgumentError("Invalid length advertisement"); - } - - Advertisement decoded_advertisement; - const nearby_protocol::RawAdvertisementPayload payload(byte_buffer.value()); - auto deserialize_result = - nearby_protocol::Deserializer::DeserializeAdvertisement(payload, - cred_book_); - - switch (deserialize_result.GetKind()) { - case np_ffi::internal::DeserializeAdvertisementResultKind::Error: { - return absl::InvalidArgumentError("Invalid advertisement format"); - } - case np_ffi::internal::DeserializeAdvertisementResultKind::V1: { - return absl::UnimplementedError( - absl::StrFormat("V1 Advertisement format is not supported")); - } - case np_ffi::internal::DeserializeAdvertisementResultKind::V0: { - decoded_advertisement.version = 0; - auto result = - ProcessV0Advertisement(deserialize_result.IntoV0(), - private_credentials_, decoded_advertisement); - if (!result.ok()) { - return result; - } - break; - } - } - - return decoded_advertisement; -} - -nearby_protocol::CredentialBook -AdvertisementDecoderImpl::InitializeCredentialBook( - absl::flat_hash_map>* - credentials_map) { - if (credentials_map == nullptr) { - nearby_protocol::CredentialSlab slab; - nearby_protocol::CredentialBook cred_book(slab); - return cred_book; - } - - nearby_protocol::CredentialSlab slab; - for (const auto& credential : (*credentials_map) - [internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP]) { - // Make sure the vector is not empty, as this is a prerequisite of the Rust - // code we call into. - std::vector metadata_bytes(1); - if (!credential.encrypted_metadata_bytes_v0().empty()) { - metadata_bytes = - std::vector(credential.encrypted_metadata_bytes_v0().begin(), - credential.encrypted_metadata_bytes_v0().end()); - } - nearby_protocol::MatchedCredentialData matched_cred(credential.id(), - metadata_bytes); - - auto key_seed = credential.key_seed(); - std::array key_seed_array; - std::copy(key_seed.begin(), key_seed.end(), key_seed_array.data()); - - auto tag = credential.metadata_encryption_key_tag_v0(); - std::array tag_array; - std::copy(tag.begin(), tag.end(), tag_array.data()); - - auto matchable_credential = nearby_protocol::V0MatchableCredential( - key_seed_array, tag_array, matched_cred); - slab.AddV0Credential(matchable_credential); - } - nearby_protocol::CredentialBook cred_book(slab); - return cred_book; -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_decoder_rust_impl.h b/presence/implementation/advertisement_decoder_rust_impl.h deleted file mode 100644 index b2444e7d..00000000 --- a/presence/implementation/advertisement_decoder_rust_impl.h +++ /dev/null @@ -1,61 +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_PRESENCE_ADVERTISEMENT_DECODER_RUST_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_RUST_IMPL_H_ - -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "nearby_protocol.h" -#include "presence/implementation/advertisement_decoder.h" - -namespace nearby { -namespace presence { - -// Implements the Rust backed parsing and decrypting of advertisement bytes -class AdvertisementDecoderImpl : public AdvertisementDecoder { - public: - AdvertisementDecoderImpl() - : cred_book_(InitializeCredentialBook(nullptr)), - private_credentials_( - std::vector<::nearby::internal::SharedCredential>()) {} - - explicit AdvertisementDecoderImpl( - absl::flat_hash_map>* - credentials_map) - : cred_book_(InitializeCredentialBook(credentials_map)), - private_credentials_( - (*credentials_map) - [internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP]) {} - - absl::StatusOr DecodeAdvertisement( - absl::string_view advertisement) override; - - private: - nearby_protocol::CredentialBook InitializeCredentialBook( - absl::flat_hash_map>* - credentials_map); - nearby_protocol::CredentialBook cred_book_; - std::vector<::nearby::internal::SharedCredential> private_credentials_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_IMPL_H_ diff --git a/presence/implementation/advertisement_decoder_test.cc b/presence/implementation/advertisement_decoder_test.cc deleted file mode 100644 index 5b2a70d4..00000000 --- a/presence/implementation/advertisement_decoder_test.cc +++ /dev/null @@ -1,226 +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 "presence/implementation/advertisement_decoder.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.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/escaping.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder_impl.h" -#include "presence/scan_request.h" -#include "presence/scan_request_builder.h" - -namespace nearby { -namespace presence { - -namespace { -using ::nearby::ByteArray; // NOLINT -using ::nearby::internal::IdentityType; // NOLINT -using ::nearby::internal::SharedCredential; // NOLINT -using ::testing::ElementsAre; -using ::testing::UnorderedElementsAre; -using ::testing::status::StatusIs; - -constexpr absl::string_view kAccountName = "test account"; - -ScanRequest GetScanRequest() { - return {.account_name = std::string(kAccountName), - .identity_types = { - IdentityType::IDENTITY_TYPE_PRIVATE_GROUP, - IdentityType::IDENTITY_TYPE_CONTACTS_GROUP, - IdentityType::IDENTITY_TYPE_PUBLIC, - }}; -} - -ScanRequest GetScanRequest(std::vector credentials) { - LegacyPresenceScanFilter scan_filter = {.remote_public_credentials = - credentials}; - return ScanRequestBuilder() - .SetAccountName(kAccountName) - .AddIdentityType(IdentityType::IDENTITY_TYPE_PRIVATE_GROUP) - .AddIdentityType(IdentityType::IDENTITY_TYPE_CONTACTS_GROUP) - .AddIdentityType(IdentityType::IDENTITY_TYPE_PUBLIC) - .Build(); -} - -SharedCredential GetPublicCredential() { - // Values copied from LDT tests - ByteArray seed({204, 219, 36, 137, 233, 252, 172, 66, 179, 147, 72, - 184, 148, 30, 209, 154, 29, 54, 14, 117, 224, 152, - 200, 193, 94, 107, 28, 194, 182, 32, 205, 57}); - ByteArray known_mac({0xB4, 0xC5, 0x9F, 0xA5, 0x99, 0x24, 0x1B, 0x81, - 0x75, 0x8D, 0x97, 0x6B, 0x5A, 0x62, 0x1C, 0x05, - 0x23, 0x2F, 0xE1, 0xBF, 0x89, 0xAE, 0x59, 0x87, - 0xCA, 0x25, 0x4C, 0x35, 0x54, 0xDC, 0xE5, 0x0E}); - SharedCredential public_credential; - public_credential.set_key_seed(seed.AsStringView()); - public_credential.set_metadata_encryption_key_tag_v0( - known_mac.AsStringView()); - return public_credential; -} - -TEST(AdvertisementDecoderImpl, - DecodeBaseNpV0PublicIdentityWithTxAndActionFields) { - AdvertisementDecoderImpl decoder; - // v0 public identity, power and action, action value 8 for active unlock. - // These values all come from - // //third_party/nearby/presence/implementation/advertisement_factory_test.cc - auto result = - decoder.DecodeAdvertisement(absl::HexStringToBytes("000315FF260080")); - - ASSERT_OK(result); - EXPECT_THAT(result->data_elements, - UnorderedElementsAre( - DataElement(DataElement::kPublicIdentityFieldType, ""), - DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("ff")), - DataElement(DataElement(ActionBit::kActiveUnlockAction)))); -} - -TEST(AdvertisementDecoderImpl, DecodeBaseNpPublicAdvertisement) { - const std::string salt = "AB"; - AdvertisementDecoderImpl decoder; - - const absl::StatusOr result = decoder.DecodeAdvertisement( - absl::HexStringToBytes("002041420337C1C2C31BEE")); - - ASSERT_OK(result); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(result->version, 0); - EXPECT_THAT( - result->data_elements, - ElementsAre(DataElement(DataElement::kSaltFieldType, salt), - DataElement(DataElement::kPublicIdentityFieldType, ""), - DataElement(DataElement::kModelIdFieldType, - absl::HexStringToBytes("C1C2C3")), - DataElement(DataElement::kBatteryFieldType, - absl::HexStringToBytes("EE")))); -} - -TEST(AdvertisementDecoderImpl, DecodeBaseNpWithTxAndActionFields) { - std::string salt = "AB"; - AdvertisementDecoderImpl decoder; - - auto result = decoder.DecodeAdvertisement( - absl::HexStringToBytes("0020414203155036B04180")); - - ASSERT_OK(result); - EXPECT_THAT(result->data_elements, - UnorderedElementsAre( - DataElement(DataElement::kSaltFieldType, salt), - DataElement(DataElement::kPublicIdentityFieldType, ""), - DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("50")), - DataElement(DataElement::kContextTimestampFieldType, - absl::HexStringToBytes("0B")), - DataElement(DataElement(ActionBit::kTapToTransferAction)), - DataElement(DataElement(ActionBit::kNearbyShareAction)))); -} - -TEST(AdvertisementDecoderImpl, DecodeBaseNpPrivateAdvertisement) { - std::string salt = "AB"; - ByteArray metadata_key( - {205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174}); - absl::flat_hash_map> - credentials; - credentials[IdentityType::IDENTITY_TYPE_PRIVATE_GROUP].push_back( - GetPublicCredential()); - AdvertisementDecoderImpl decoder(&credentials); - - absl::StatusOr result = decoder.DecodeAdvertisement( - absl::HexStringToBytes("00514142b8412efb0bc657ba514baf4d1b50ddc842cd1c")); - ASSERT_OK(result); - EXPECT_EQ(result->metadata_key, metadata_key.AsStringView()); - EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_THAT(result->data_elements, - ElementsAre(DataElement(DataElement::kSaltFieldType, salt), - DataElement(DataElement::kTxPowerFieldType, - absl::HexStringToBytes("05")), - DataElement(DataElement::kActionFieldType, - absl::HexStringToBytes("08")))); -} - -TEST(AdvertisementDecoderImpl, InvalidEncryptedContent) { - std::string salt = "AB"; - ByteArray metadata_key( - {205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174}); - absl::flat_hash_map> - credentials; - credentials[IdentityType::IDENTITY_TYPE_PRIVATE_GROUP].push_back( - GetPublicCredential()); - AdvertisementDecoderImpl decoder(&credentials); - - EXPECT_THAT(decoder.DecodeAdvertisement(absl::HexStringToBytes( - "00414142f085d661ac8cb110e792e7faeb736294")), - StatusIs(absl::StatusCode::kOutOfRange)); -} - -TEST(AdvertisementDecoderImpl, UnsupportedDataElement) { - std::string valid_header_and_salt = absl::HexStringToBytes("00204142"); - AdvertisementDecoderImpl decoder; - - EXPECT_THAT(decoder.DecodeAdvertisement(valid_header_and_salt + - absl::HexStringToBytes("0D")), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST(AdvertisementDecoderImpl, InvalidAdvertisementFieldTooShort) { - AdvertisementDecoderImpl decoder; - - // 0x59 header means 5 bytes long Account Key Data but only 4 bytes follow. - EXPECT_THAT( - decoder.DecodeAdvertisement(absl::HexStringToBytes("0059A0A1A2A3")), - StatusIs(absl::StatusCode::kOutOfRange)); -} - -TEST(AdvertisementDecoderImpl, ZeroLengthPayload) { - AdvertisementDecoderImpl decoder; - - // A action with type 0xA and no payload - const absl::StatusOr result = - decoder.DecodeAdvertisement(absl::HexStringToBytes("000A")); - - ASSERT_OK(result); - EXPECT_THAT(result->data_elements, ElementsAre(DataElement(0xA, ""))); -} - -TEST(AdvertisementDecoderImpl, EmptyAdvertisement) { - AdvertisementDecoderImpl decoder; - - EXPECT_THAT(decoder.DecodeAdvertisement(""), - StatusIs(absl::StatusCode::kOutOfRange)); -} - -TEST(AdvertisementDecoderImpl, UnsupportedAdvertisementVersion) { - AdvertisementDecoderImpl decoder; - - EXPECT_THAT(decoder.DecodeAdvertisement( - absl::HexStringToBytes("012041420318CD29EEFF")), - StatusIs(absl::StatusCode::kUnimplemented)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_factory.cc b/presence/implementation/advertisement_factory.cc deleted file mode 100644 index 87c74183..00000000 --- a/presence/implementation/advertisement_factory.cc +++ /dev/null @@ -1,236 +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 "presence/implementation/advertisement_factory.h" - -#include -#include -#include -#include -#include - -#include "absl/base/attributes.h" -#include "absl/status/status.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "absl/types/variant.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/logging.h" -#include "internal/platform/uuid.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/ldt.h" -#include "presence/implementation/mediums/advertisement_data.h" - -namespace nearby { -namespace presence { - -namespace { -using ::nearby::internal::IdentityType; -constexpr uint8_t kBaseVersion = 0; -constexpr size_t kMaxBaseNpAdvSize = 26; - -absl::StatusOr CreateDataElementHeader(size_t length, - unsigned data_type) { - if (length > DataElement::kMaxDataElementLength) { - return absl::InvalidArgumentError( - absl::StrFormat("Unsupported Data Element length: %d", length)); - } - if (data_type > DataElement::kMaxDataElementType) { - return absl::InvalidArgumentError( - absl::StrFormat("Unsupported Data Element type: %d", data_type)); - } - return (length << DataElement::kDataElementLengthShift) | data_type; -} - -absl::Status AppendDataElement(unsigned data_type, - absl::string_view data_element, - std::string& output) { - auto header = CreateDataElementHeader(data_element.size(), data_type); - if (!header.ok()) { - LOG(WARNING) << "Can't add Data element type: " << data_type - << ", length: " << data_element.size(); - return header.status(); - } - output.push_back(*header); - output.insert(output.end(), data_element.begin(), data_element.end()); - return absl::OkStatus(); -} - -uint8_t GetIdentityFieldType(IdentityType type) { - switch (type) { - case IdentityType::IDENTITY_TYPE_PRIVATE_GROUP: - return DataElement::kPrivateGroupIdentityFieldType; - case IdentityType::IDENTITY_TYPE_CONTACTS_GROUP: - return DataElement::kContactsGroupIdentityFieldType; - case IdentityType::IDENTITY_TYPE_PUBLIC: - ABSL_FALLTHROUGH_INTENDED; - default: - return DataElement::kPublicIdentityFieldType; - } -} - -std::string SerializeAction(const Action& action) { - std::string output; - uint32_t input = action.action; - for (int i = 3; i >= 0; --i) { - if (input == 0) { - return output; - } - int shift = 8 * i; - output.push_back(static_cast((input >> shift) & 0xFF)); - input &= (1 << shift) - 1; - } - return output; -} - -bool RequiresCredentials(IdentityType identity_type) { - return identity_type == IdentityType::IDENTITY_TYPE_PRIVATE_GROUP || - identity_type == IdentityType::IDENTITY_TYPE_CONTACTS_GROUP; -} -} // namespace - -absl::StatusOr AdvertisementFactory::CreateAdvertisement( - const BaseBroadcastRequest& request, - absl::optional credential) const { - AdvertisementData advert = {}; - if (absl::holds_alternative( - request.variant)) { - return CreateBaseNpAdvertisement(request, std::move(credential)); - } - return advert; -} - -absl::StatusOr -AdvertisementFactory::CreateBaseNpAdvertisement( - const BaseBroadcastRequest& request, - absl::optional credential) const { - const auto& presence = - absl::get(request.variant); - std::string payload; - payload.reserve(kMaxBaseNpAdvSize); - payload.push_back(kBaseVersion); - absl::Status result; - std::string tx_power = {static_cast(request.tx_power)}; - std::string action = SerializeAction(presence.action); - uint8_t identity_type = - GetIdentityFieldType(presence.credential_selector.identity_type); - bool needs_encryption = - identity_type != DataElement::kPublicIdentityFieldType; - if (needs_encryption) { - if (request.salt.size() != kSaltSize) { - return absl::InvalidArgumentError( - absl::StrFormat("Unsupported salt size %d", request.salt.size())); - } - if (!credential) { - return absl::FailedPreconditionError("Missing credentials"); - } - std::string unencrypted; - result = AppendDataElement(DataElement::kTxPowerFieldType, tx_power, - unencrypted); - if (!result.ok()) { - return result; - } - result = - AppendDataElement(DataElement::kActionFieldType, action, unencrypted); - if (!result.ok()) { - return result; - } - VLOG(1) << "Unencrypted advertisement payload " - << absl::BytesToHexString(unencrypted); - absl::StatusOr encrypted = - EncryptDataElements(*credential, request.salt, unencrypted); - if (!encrypted.ok()) { - return encrypted.status(); - } - if (encrypted->size() <= kBaseMetadataSize) { - return absl::OutOfRangeError( - absl::StrFormat("Encrypted identity DE is too short - %d bytes. " - "Expected more than %d", - encrypted->size(), kBaseMetadataSize)); - } - - // The Identity DE header does not include the length of salt nor metadata. - absl::StatusOr identity_header = CreateDataElementHeader( - encrypted->size() - kBaseMetadataSize, identity_type); - if (!identity_header.ok()) { - return identity_header.status(); - } - payload.push_back(*identity_header); - // In the encrypted format, salt is not a DE (thus no header) - payload.append(request.salt); - payload.append(*encrypted); - } else { - result = AppendDataElement(identity_type, "", payload); - if (!result.ok()) { - return result; - } - if (!request.salt.empty()) { - result = - AppendDataElement(DataElement::kSaltFieldType, request.salt, payload); - if (!result.ok()) { - return result; - } - } - result = - AppendDataElement(DataElement::kTxPowerFieldType, tx_power, payload); - if (!result.ok()) { - return result; - } - result = AppendDataElement(DataElement::kActionFieldType, action, payload); - if (!result.ok()) { - return result; - } - } - return AdvertisementData{.is_extended_advertisement = false, - .content = payload}; -} -absl::StatusOr AdvertisementFactory::EncryptDataElements( - const LocalCredential& credential, absl::string_view salt, - absl::string_view data_elements) const { - if (credential.metadata_encryption_key_v0().size() != kBaseMetadataSize) { - return absl::FailedPreconditionError(absl::StrFormat( - "Metadata key size %d, expected %d", - credential.metadata_encryption_key_v0().size(), kBaseMetadataSize)); - } - - // HMAC is not used during encryption, so we can pass an empty value. - absl::StatusOr encryptor = - LdtEncryptor::Create(credential.key_seed(), /*known_hmac=*/""); - if (!encryptor.ok()) { - return encryptor.status(); - } - std::string plaintext = - absl::StrCat(credential.metadata_encryption_key_v0(), data_elements); - return encryptor->Encrypt(plaintext, salt); -} - -absl::StatusOr AdvertisementFactory::GetCredentialSelector( - const BaseBroadcastRequest& request) { - if (absl::holds_alternative( - request.variant)) { - const auto& presence = - absl::get(request.variant); - if (RequiresCredentials(presence.credential_selector.identity_type)) { - return presence.credential_selector; - } - } - return absl::NotFoundError("credentials not required"); -} -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_factory.h b/presence/implementation/advertisement_factory.h deleted file mode 100644 index 54211944..00000000 --- a/presence/implementation/advertisement_factory.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_PRESENCE_ADVERTISEMENT_FACTORY_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_FACTORY_H_ - -#include - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/mediums/advertisement_data.h" - -namespace nearby { -namespace presence { - -// Builds BLE advertisements from broadcast requests. -class AdvertisementFactory { - public: - using LocalCredential = internal::LocalCredential; - - // Returns a `CredentialSelector` if credentials are required to create an - // advertisement from the `request`. - static absl::StatusOr GetCredentialSelector( - const BaseBroadcastRequest& request); - - // Returns a BLE advertisement for given `request. - absl::StatusOr CreateAdvertisement( - const BaseBroadcastRequest& request, - absl::optional credential) const; // NOLINT - - absl::StatusOr CreateAdvertisement( - const BaseBroadcastRequest& request) const { - return CreateAdvertisement(request, - absl::optional()); // NOLINT - } - - private: - absl::StatusOr CreateBaseNpAdvertisement( - const BaseBroadcastRequest& request, - absl::optional credential) const; // NOLINT - absl::StatusOr EncryptDataElements( - const LocalCredential& credential, absl::string_view salt, - absl::string_view data_elements) const; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_FACTORY_H_ diff --git a/presence/implementation/advertisement_factory_test.cc b/presence/implementation/advertisement_factory_test.cc deleted file mode 100644 index 8c2897f8..00000000 --- a/presence/implementation/advertisement_factory_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 "presence/implementation/advertisement_factory.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 "internal/platform/byte_array.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/action_factory.h" -#include "presence/implementation/mediums/advertisement_data.h" - -namespace nearby { -namespace presence { - -namespace { - -using ::nearby::ByteArray; // NOLINT -using ::nearby::internal::IdentityType; -using ::nearby::internal::LocalCredential; // NOLINT -using ::testing::NiceMock; -using ::testing::Return; -using ::testing::status::StatusIs; - -LocalCredential CreateLocalCredential(IdentityType identity_type) { - // Values copied from LDT tests - ByteArray seed({204, 219, 36, 137, 233, 252, 172, 66, 179, 147, 72, - 184, 148, 30, 209, 154, 29, 54, 14, 117, 224, 152, - 200, 193, 94, 107, 28, 194, 182, 32, 205, 57}); - ByteArray metadata_key( - {205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174}); - - LocalCredential private_credential; - private_credential.set_identity_type(identity_type); - private_credential.set_key_seed(seed.AsStringView()); - private_credential.set_metadata_encryption_key_v0( - metadata_key.AsStringView()); - return private_credential; -} - -TEST(AdvertisementFactory, CreateAdvertisementFromPrivateIdentity) { - std::string account_name = "Test account"; - std::string salt = "AB"; - constexpr IdentityType kIdentity = IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - Action action = ActionFactory::CreateAction(data_elements); - BaseBroadcastRequest request = - BaseBroadcastRequest(BasePresenceRequestBuilder(kIdentity) - .SetAccountName(account_name) - .SetSalt(salt) - .SetTxPower(5) - .SetAction(action)); - - absl::StatusOr result = - AdvertisementFactory().CreateAdvertisement( - request, CreateLocalCredential(kIdentity)); - - ASSERT_OK(result); - EXPECT_FALSE(result->is_extended_advertisement); - EXPECT_EQ(absl::BytesToHexString(result->content), - "00514142b8412efb0bc657ba514baf4d1b50ddc842cd1c"); -} - -TEST(AdvertisementFactory, CreateAdvertisementFromTrustedIdentity) { - std::string account_name = "Test account"; - std::string salt = "AB"; - constexpr IdentityType kIdentity = IdentityType::IDENTITY_TYPE_CONTACTS_GROUP; - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - data_elements.emplace_back(ActionBit::kPresenceManagerAction); - Action action = ActionFactory::CreateAction(data_elements); - BaseBroadcastRequest request = - BaseBroadcastRequest(BasePresenceRequestBuilder(kIdentity) - .SetAccountName(account_name) - .SetSalt(salt) - .SetTxPower(5) - .SetAction(action)); - - absl::StatusOr result = - AdvertisementFactory().CreateAdvertisement( - request, CreateLocalCredential(kIdentity)); - - ASSERT_OK(result); - EXPECT_FALSE(result->is_extended_advertisement); - EXPECT_EQ(absl::BytesToHexString(result->content), - "0052414257a35c020f1c547d7e169303196d75da7118ba"); -} - -TEST(AdvertisementFactory, CreateAdvertisementFromPublicIdentity) { - std::string salt = "AB"; - constexpr IdentityType kIdentity = IdentityType::IDENTITY_TYPE_PUBLIC; - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - Action action = ActionFactory::CreateAction(data_elements); - BaseBroadcastRequest request = - BaseBroadcastRequest(BasePresenceRequestBuilder(kIdentity) - .SetSalt(salt) - .SetTxPower(5) - .SetAction(action)); - - absl::StatusOr result = - AdvertisementFactory().CreateAdvertisement(request); - - ASSERT_OK(result); - EXPECT_FALSE(result->is_extended_advertisement); - EXPECT_EQ(absl::BytesToHexString(result->content), "00032041421505260080"); -} - -TEST(AdvertisementFactory, CreateAdvertisementFailsWhenSaltIsTooShort) { - std::string salt = "AB"; - constexpr IdentityType kIdentity = internal::IDENTITY_TYPE_PRIVATE_GROUP; - std::vector data_elements; - data_elements.emplace_back(ActionBit::kActiveUnlockAction); - Action action = ActionFactory::CreateAction(data_elements); - BaseBroadcastRequest request = - BaseBroadcastRequest(BasePresenceRequestBuilder(kIdentity) - .SetSalt(salt) - .SetTxPower(5) - .SetAction(action)); - // Override the salt with invalid value - request.salt = "C"; - - EXPECT_THAT(AdvertisementFactory().CreateAdvertisement(request), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_filter.cc b/presence/implementation/advertisement_filter.cc deleted file mode 100644 index e3b5bb37..00000000 --- a/presence/implementation/advertisement_filter.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT 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 "presence/implementation/advertisement_filter.h" - -#include -#include - -#include "absl/types/variant.h" -#include "internal/platform/logging.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -bool Contains(const std::vector& data_elements, - const DataElement& data_element) { - return std::find(data_elements.begin(), data_elements.end(), data_element) != - data_elements.end(); -} - -bool ContainsAll(const std::vector& data_elements, - const std::vector& extended_properties) { - for (const auto& filter_element : extended_properties) { - if (!Contains(data_elements, filter_element)) { - return false; - } - } - return true; -} - -bool ContainsAny(const std::vector& data_elements, - const std::vector& actions) { - if (actions.empty()) { - return true; - } - for (int action : actions) { - if (Contains(data_elements, DataElement(ActionBit(action)))) { - return true; - } - } - return false; -} - -bool AdvertisementFilter::MatchesScanFilter( - const Advertisement& advertisement) { - // Verify the identity is one requested in the scan_request. - // Per the Public API of scan_request, if identity_types provided in the - // scan_request is empty then decode advertisements of every identity type - auto requested_identity_types = scan_request_.identity_types; - if (!requested_identity_types.empty() && - !(std::find( - requested_identity_types.begin(), requested_identity_types.end(), - advertisement.identity_type) != requested_identity_types.end())) { - LOG(INFO) << "Skipping advertisement with identity type: " - << advertisement.identity_type - << " because that identity type was not requested in the scan " - "request"; - return false; - } - - // The advertisement matches the scan request when it matches at least - // one of the filters in the request. - if (scan_request_.scan_filters.empty()) { - return true; - } - - // NOLINT is used to suppress google3-legacy-absl-backport lints because the - // the suggestion is not compatible with Chrome - for (const auto& filter : scan_request_.scan_filters) { - if (absl::holds_alternative(filter)) { // NOLINT - if (MatchesScanFilter(advertisement.data_elements, - absl::get(filter))) { // NOLINT - return true; - } - } else if (absl::holds_alternative( // NOLINT - filter)) { - if (MatchesScanFilter( - advertisement.data_elements, - absl::get(filter))) { // NOLINT - return true; - } - } - } - return false; -} - -bool AdvertisementFilter::MatchesScanFilter( - const std::vector& data_elements, - const PresenceScanFilter& filter) { - // The advertisement must contain all Data Elements in scan request. - return ContainsAll(data_elements, filter.extended_properties); -} - -bool AdvertisementFilter::MatchesScanFilter( - const std::vector& data_elements, - const LegacyPresenceScanFilter& filter) { - // The advertisement must: - // * contain any Action from scan request, - // * contain all Data Elements in scan request. - return ContainsAny(data_elements, filter.actions) && - ContainsAll(data_elements, filter.extended_properties); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/advertisement_filter.h b/presence/implementation/advertisement_filter.h deleted file mode 100644 index 2e2db1e4..00000000 --- a/presence/implementation/advertisement_filter.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT 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_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_FILTER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_FILTER_H_ - -#include - -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -class AdvertisementFilter { - public: - explicit AdvertisementFilter(ScanRequest scan_request) - : scan_request_(scan_request) {} - - // Returns true if the decoded advertisement in `data_elements` matches the - // filters in `scan_request`. - bool MatchesScanFilter(const Advertisement& adv); - - private: - bool MatchesScanFilter(const std::vector& data_elements, - const PresenceScanFilter& filter); - bool MatchesScanFilter(const std::vector& data_elements, - const LegacyPresenceScanFilter& filter); - ScanRequest scan_request_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_ADVERTISEMENT_FILTER_H_ diff --git a/presence/implementation/advertisement_filter_test.cc b/presence/implementation/advertisement_filter_test.cc deleted file mode 100644 index ff3a1dfd..00000000 --- a/presence/implementation/advertisement_filter_test.cc +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT 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 "presence/implementation/advertisement_filter.h" - -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/scan_request.h" -#include "presence/scan_request_builder.h" - -namespace nearby { -namespace presence { -namespace { - -TEST(AdvertisementFilter, MatchesScanFilterNoFilterPasses) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - ScanRequest empty_scan_request = {}; - AdvertisementFilter adv_filter(empty_scan_request); - - // A scan request without scan filters matches any advertisement - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.data_elements = {DataElement( - DataElement::kPrivateGroupIdentityFieldType, "payload")}})); - EXPECT_TRUE(adv_filter.MatchesScanFilter({})); -} - -TEST(AdvertisementFilter, MatchesPresenceScanFilter) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - DataElement model_id = - DataElement(DataElement::kModelIdFieldType, "model id"); - DataElement salt = DataElement(DataElement::kSaltFieldType, "salt"); - DataElement salt2 = DataElement(DataElement::kSaltFieldType, "salt 2"); - PresenceScanFilter filter = {.extended_properties = {model_id, salt}}; - - AdvertisementFilter adv_filter( - ScanRequestBuilder().AddScanFilter(filter).Build()); - - EXPECT_FALSE(adv_filter.MatchesScanFilter({})); - EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {salt}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, salt2, model_id}})); - EXPECT_FALSE( - adv_filter.MatchesScanFilter({.data_elements = {salt2, model_id}})); -} - -TEST(AdvertisementFilter, MatchesLegacyPresenceScanFilter) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - DataElement model_id = - DataElement(DataElement::kModelIdFieldType, "model id"); - DataElement salt = DataElement(DataElement::kSaltFieldType, "salt"); - DataElement salt2 = DataElement(DataElement::kSaltFieldType, "salt 2"); - LegacyPresenceScanFilter filter = {.extended_properties = {model_id, salt}}; - - AdvertisementFilter adv_filter( - ScanRequestBuilder().AddScanFilter(filter).Build()); - - EXPECT_FALSE(adv_filter.MatchesScanFilter(Advertisement{})); - EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {salt}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, salt2, model_id}})); - EXPECT_FALSE(adv_filter.MatchesScanFilter( - Advertisement{.data_elements = {salt2, model_id}})); -} - -TEST(AdvertisementFilter, - EncryptedIdentityFilterIgnoresPublicIdentityAdvertisement) { - AdvertisementFilter adv_filter( - {.identity_types = { - internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP, - internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP}}); - - EXPECT_FALSE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC})); - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP})); -} - -TEST(AdvertisementFilter, PublicIdentityFilterMatchesPublicIdentityAdv) { - AdvertisementFilter adv_filter( - {.identity_types = {internal::IdentityType::IDENTITY_TYPE_PUBLIC}}); - - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC})); - EXPECT_FALSE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP})); -} - -TEST(AdvertisementFilter, EmptyIdentityFilterMatchesAllAdvIdentityTypes) { - AdvertisementFilter adv_filter({}); - - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC})); - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP})); -} - -TEST(AdvertisementFilter, MatchesLegacyPresenceScanFilterWithActions) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - DataElement model_id = - DataElement(DataElement::kModelIdFieldType, "model id"); - DataElement salt = DataElement(DataElement::kSaltFieldType, "salt"); - DataElement ttt_action = DataElement(ActionBit::kTapToTransferAction); - LegacyPresenceScanFilter filter = { - .actions = {static_cast(ActionBit::kActiveUnlockAction), - static_cast(ActionBit::kTapToTransferAction)}, - .extended_properties = {model_id, salt}}; - - AdvertisementFilter adv_filter( - ScanRequestBuilder().AddScanFilter(filter).Build()); - - EXPECT_FALSE( - adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}})); - EXPECT_TRUE(adv_filter.MatchesScanFilter( - {.data_elements = {salt, ttt_action, model_id}})); -} - -TEST(AdvertisementFilter, MatchesMultipleFilters) { - std::vector adv = { - DataElement(DataElement::kPrivateGroupIdentityFieldType, "payload")}; - DataElement model_id = - DataElement(DataElement::kModelIdFieldType, "model id"); - DataElement salt = DataElement(DataElement::kSaltFieldType, "salt"); - DataElement ttt_action = DataElement(ActionBit::kTapToTransferAction); - PresenceScanFilter presence_filter = {.extended_properties = {model_id}}; - LegacyPresenceScanFilter legacy_filter = { - .actions = {static_cast(ActionBit::kActiveUnlockAction), - static_cast(ActionBit::kTapToTransferAction)}, - .extended_properties = {salt}}; - - AdvertisementFilter adv_filter(ScanRequestBuilder() - .AddScanFilter(presence_filter) - .AddScanFilter(legacy_filter) - .Build()); - - EXPECT_TRUE(adv_filter.MatchesScanFilter({.data_elements = {model_id}})); - EXPECT_TRUE( - adv_filter.MatchesScanFilter({.data_elements = {salt, ttt_action}})); - EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {ttt_action}})); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/base_broadcast_request.cc b/presence/implementation/base_broadcast_request.cc deleted file mode 100644 index 30dda102..00000000 --- a/presence/implementation/base_broadcast_request.cc +++ /dev/null @@ -1,112 +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 "presence/implementation/base_broadcast_request.h" - -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/logging.h" -#include "presence/broadcast_request.h" -#include "presence/implementation/action_factory.h" - -namespace nearby { -namespace presence { - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetSalt( - absl::string_view salt) { - if (salt.size() != kSaltSize) { - LOG(WARNING) << "Unsupported salt length: " << salt.size(); - } else { - salt_ = std::string(salt); - } - return *this; -} -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetTxPower( - int8_t tx_power) { - tx_power_ = tx_power; - return *this; -} - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetAction( - const Action& action) { - action_ = action; - return *this; -} - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetPowerMode( - PowerMode power_mode) { - power_mode_ = power_mode; - return *this; -} - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetAccountName( - absl::string_view account_name) { - account_name_ = std::string(account_name); - return *this; -} - -BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetManagerAppId( - absl::string_view manager_app_id) { - manager_app_id_ = std::string(manager_app_id); - return *this; -} - -BasePresenceRequestBuilder::operator BaseBroadcastRequest() const { - BaseBroadcastRequest::BasePresence presence{ - .credential_selector = {.manager_app_id = manager_app_id_, - .account_name = account_name_, - .identity_type = identity_}, - .action = action_}; - - std::string bytes(kSaltSize, 0); - RandBytes(const_cast(bytes.data()), bytes.size()); - - BaseBroadcastRequest broadcast_request{ - .variant = presence, - .salt = salt_.size() == kSaltSize ? salt_ : bytes, - .tx_power = tx_power_, - .power_mode = power_mode_}; - return broadcast_request; -} - -absl::StatusOr BaseBroadcastRequest::Create( - const BroadcastRequest& request) { - if (absl::holds_alternative(request.variant)) { - const auto& presence_request = - absl::get(request.variant); - if (presence_request.sections.empty()) { - return absl::InvalidArgumentError("Missing broadcast sections"); - } - if (presence_request.sections.size() > 1) { - LOG(WARNING) << "Only first section is used in BLE 4.2 advertisement"; - } - const PresenceBroadcast::BroadcastSection& section = - presence_request.sections.front(); - return BaseBroadcastRequest( - BasePresenceRequestBuilder(section.identity) - .SetTxPower(request.tx_power) - .SetAction(ActionFactory::CreateAction(section.extended_properties)) - .SetPowerMode(request.power_mode) - .SetManagerAppId(section.manager_app_id) - .SetAccountName(section.account_name)); - } - return absl::UnimplementedError("Request not supported"); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/base_broadcast_request.h b/presence/implementation/base_broadcast_request.h deleted file mode 100644 index 36821ccc..00000000 --- a/presence/implementation/base_broadcast_request.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BASE_BROADCAST_REQUEST_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BASE_BROADCAST_REQUEST_H_ - -#include - -#include -#include - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "absl/types/variant.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/broadcast_request.h" -#include "presence/power_mode.h" - -namespace nearby { -namespace presence { - -constexpr int8_t kUnspecifiedTxPower = -128; -constexpr size_t kSaltSize = 2; -// The identity metadata size in the base advertisement -constexpr size_t kBaseMetadataSize = 14; - -/** Defines the action (intended actions) of base NP advertisement */ -struct Action { - uint32_t action; -}; - -/** Defines a Nearby Presence broadcast request */ -struct BaseBroadcastRequest { - // Creates `BaseBroadcastRequest` from the public API request in - // `BroadcastRequest`. - static absl::StatusOr Create( - const BroadcastRequest& request); - - struct BasePresence { - CredentialSelector credential_selector; - Action action; - }; - struct BaseFastPair { - struct Discoverable { - std::string model_id; - }; - struct Nondiscoverable { - std::string account_key_data; - std::string battery_info; - }; - absl::variant advertisement; - }; - struct BaseEddystone { - std::string ephemeral_id; - }; - absl::variant variant; - std::string salt; - int8_t tx_power; - unsigned int interval_ms; - PowerMode power_mode; -}; - -/** Builds a brodacast request variant with NP identity for BLE 4.2 */ -class BasePresenceRequestBuilder { - public: - explicit BasePresenceRequestBuilder( - const nearby::internal::IdentityType& identity) - : identity_(identity) {} - BasePresenceRequestBuilder& SetSalt(absl::string_view salt); - BasePresenceRequestBuilder& SetTxPower(int8_t tx_power); - BasePresenceRequestBuilder& SetAction(const Action& action); - BasePresenceRequestBuilder& SetPowerMode(PowerMode power_mode); - BasePresenceRequestBuilder& SetAccountName(absl::string_view account_name); - BasePresenceRequestBuilder& SetManagerAppId(absl::string_view manager_app_id); - - explicit operator BaseBroadcastRequest() const; - - private: - nearby::internal::IdentityType identity_; - std::string salt_; - int8_t tx_power_ = kUnspecifiedTxPower; - Action action_; - PowerMode power_mode_ = PowerMode::kNoPower; - std::string account_name_; - std::string manager_app_id_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BASE_BROADCAST_REQUEST_H_ diff --git a/presence/implementation/base_broadcast_request_test.cc b/presence/implementation/base_broadcast_request_test.cc deleted file mode 100644 index b27040b3..00000000 --- a/presence/implementation/base_broadcast_request_test.cc +++ /dev/null @@ -1,94 +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 "presence/implementation/base_broadcast_request.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/types/variant.h" -#include "internal/proto/credential.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_element.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::IdentityType; -using ::testing::status::StatusIs; - -TEST(BroadcastRequestTest, CreateBasePresenceRequest) { - nearby::internal::IdentityType identity; - constexpr int8_t kTxPower = -13; - - BaseBroadcastRequest request = BaseBroadcastRequest( - BasePresenceRequestBuilder(identity).SetTxPower(kTxPower).SetPowerMode( - PowerMode::kBalanced)); - - EXPECT_TRUE(absl::holds_alternative( - request.variant)); - EXPECT_EQ(request.salt.size(), 2); - EXPECT_EQ(request.tx_power, kTxPower); - EXPECT_EQ(request.power_mode, PowerMode::kBalanced); -} - -TEST(BroadcastRequestTest, CreateFromPresenceRequest) { - constexpr int8_t kTxPower = 30; - constexpr uint32_t kExpectedAction = - (1 << 23); // encoded kActiveUnlockAction - std::string account_name = "Test account"; - std::string manager_app_id = "Manager app id"; - PresenceBroadcast::BroadcastSection section = { - .identity = internal::IDENTITY_TYPE_PUBLIC, - .extended_properties = {DataElement( - DataElement(ActionBit::kActiveUnlockAction))}, - .account_name = account_name, - .manager_app_id = manager_app_id}; - PresenceBroadcast presence_request = {.sections = {section}}; - BroadcastRequest input = {.tx_power = kTxPower, .variant = presence_request}; - - absl::StatusOr request = - BaseBroadcastRequest::Create(input); - - ASSERT_OK(request); - EXPECT_THAT(request->tx_power, kTxPower); - EXPECT_THAT(absl::get(request->variant) - .credential_selector.identity_type, - IdentityType::IDENTITY_TYPE_PUBLIC); - EXPECT_THAT(absl::get(request->variant) - .action.action, - kExpectedAction); - EXPECT_THAT(absl::get(request->variant) - .credential_selector.account_name, - account_name); - EXPECT_THAT(absl::get(request->variant) - .credential_selector.manager_app_id, - manager_app_id); -} - -TEST(BroadcastRequestTest, CreateFromEmptyPresenceRequestFails) { - BroadcastRequest empty = { - .variant = PresenceBroadcast(), - }; - - EXPECT_THAT(BaseBroadcastRequest::Create(empty), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/broadcast_manager.cc b/presence/implementation/broadcast_manager.cc deleted file mode 100644 index 088083b3..00000000 --- a/presence/implementation/broadcast_manager.cc +++ /dev/null @@ -1,269 +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 "presence/implementation/broadcast_manager.h" - -#include -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/status/status.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/logging.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/implementation/advertisement_factory.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/mediums/advertisement_data.h" - -namespace nearby { -namespace presence { -namespace { - -using AdvertisingCallback = ::nearby::api::ble::BleMedium::AdvertisingCallback; -using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; -using LocalCredential = internal::LocalCredential; - -uint16_t SaltToInt(absl::string_view salt) { - if (salt.length() < 2) return 0; - uint16_t b0 = salt[0]; - uint16_t b1 = salt[1]; - return b0 << 8 | b1; -} -std::string SaltFromInt(uint16_t x) { - std::string salt; - salt.resize(2); - salt[0] = x >> 8 & 0xFF; - salt[1] = x & 0xFF; - return salt; -} - -// Selects a salt that has not been used yet. The salt is added to -// `credential.consumed_salts`. -// We may fail to find an unused salt. In this unlikely event, an already -// consumed salt is returned. -std::string SelectSalt(LocalCredential& credential, - absl::string_view preferred_salt) { - // NP certificate guidelines say that we should try to get an unused salt 128 - // times. - constexpr int kMaxSaltSelectRetries = 128; - - uint16_t s = SaltToInt(preferred_salt); - for (int i = 0; i < kMaxSaltSelectRetries; i++) { - if (!credential.consumed_salts().contains(s)) { - break; - } - s = nearby::RandData(); - } - credential.mutable_consumed_salts()->insert({s, true}); - return SaltFromInt(s); -} - -} // namespace - -absl::StatusOr BroadcastManager::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - absl::StatusOr request = - BaseBroadcastRequest::Create(broadcast_request); - if (!request.ok()) { - LOG(WARNING) << "Invalid broadcast request, reason: " << request.status(); - callback.start_broadcast_cb(request.status()); - return request.status(); - } - BroadcastSessionId id = GenerateBroadcastSessionId(); - RunOnServiceControllerThread( - "start-broadcast", - [this, id, power_mode = broadcast_request.power_mode, request = *request, - broadcast_callback = std::move( - callback)]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - sessions_.insert({id, BroadcastSessionState( - std::move(broadcast_callback), power_mode)}); - FetchCredentials(id, std::move(request)); - }); - return id; -} - -void BroadcastManager::FetchCredentials( - BroadcastSessionId id, BaseBroadcastRequest broadcast_request) { - absl::StatusOr credential_selector = - AdvertisementFactory::GetCredentialSelector(broadcast_request); - if (!credential_selector.ok()) { - // Public advertisement, we don't need credential to advertise. - Advertise(id, broadcast_request, /*credentials=*/{}); - return; - } - credential_manager_->GetLocalCredentials( - *credential_selector, - GetLocalCredentialsResultCallback{ - .credentials_fetched_cb = - [this, id, broadcast_request = std::move(broadcast_request), - selector = *credential_selector]( - absl::StatusOr< - std::vector<::nearby::internal::LocalCredential>> - credentials) { - if (!credentials.ok()) { - LOG(WARNING) << "Failed to fetch credentials, status: " - << credentials.status(); - NotifyStartCallbackStatus(id, credentials.status()); - return; - } - RunOnServiceControllerThread( - "advertise-non-public", - [this, id, broadcast_request = std::move(broadcast_request), - credentials = std::move(*credentials), - selector = std::move(selector)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) mutable { - absl::optional credential = - Advertise(id, broadcast_request, credentials); - if (credential) { - credential_manager_->UpdateLocalCredential( - selector, std::move(*credential), - {[](absl::Status status) { - if (!status.ok()) { - LOG(WARNING) << "Failed to update private " - "credential, status: " - << status; - } - }}); - } - }); - }}); -} - -absl::optional BroadcastManager::SelectCredential( // NOLINT - BaseBroadcastRequest& broadcast_request, - std::vector credentials) { - if (credentials.empty()) { - return absl::optional(); // NOLINT - } - auto credential = - std::min_element(credentials.begin(), credentials.end(), - [](const LocalCredential& a, const LocalCredential& b) { - return a.start_time_millis() < b.start_time_millis(); - }); - if (credential == credentials.end()) { - LOG(WARNING) << "No active credentials"; - return absl::optional(); // NOLINT - } - std::string salt = SelectSalt(*credential, broadcast_request.salt); - if (salt != broadcast_request.salt) { - VLOG(1) << "Changed salt"; - broadcast_request.salt = salt; - } - return *credential; -} - -absl::optional BroadcastManager::Advertise( // NOLINT - BroadcastSessionId id, BaseBroadcastRequest broadcast_request, - std::vector credentials) { - auto it = sessions_.find(id); - if (it == sessions_.end()) { - LOG(INFO) << "Broadcast session terminated, id: " << id; - return absl::optional(); // NOLINT - } - absl::optional credential = // NOLINT - SelectCredential(broadcast_request, std::move(credentials)); - absl::StatusOr advertisement = - AdvertisementFactory().CreateAdvertisement(broadcast_request, credential); - if (!advertisement.ok()) { - LOG(WARNING) << "Can't create advertisement, reason: " - << advertisement.status(); - NotifyStartCallbackStatus(id, advertisement.status()); - return absl::optional(); // NOLINT - } - std::unique_ptr session = - mediums_->GetBle().StartAdvertising( - *advertisement, it->second.GetPowerMode(), - AdvertisingCallback{ - .start_advertising_result = [this, id](absl::Status status) { - NotifyStartCallbackStatus(id, status); - }}); - if (!session) { - NotifyStartCallbackStatus(id, - absl::InternalError("Can't start advertising")); - return absl::optional(); // NOLINT - } - it->second.SetAdvertisingSession(std::move(session)); - return credential; -} - -void BroadcastManager::NotifyStartCallbackStatus(BroadcastSessionId id, - absl::Status status) { - RunOnServiceControllerThread("started-broadcast-cb", - [this, id, status]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) { - auto it = sessions_.find(id); - if (it == sessions_.end()) { - return; - } - it->second.CallStartedCallback(status); - if (!status.ok()) { - // Delete failed session. - sessions_.erase(it); - } - }); -} - -void BroadcastManager::StopBroadcast(BroadcastSessionId id) { - RunOnServiceControllerThread( - "stop-broadcast", [this, id]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(executor_) { - auto it = sessions_.find(id); - if (it == sessions_.end()) { - VLOG(1) << absl::StrFormat("BroadcastSession(0x%x) not found", id); - return; - } - it->second.StopAdvertising(); - sessions_.erase(it); - }); -} - -BroadcastSessionId BroadcastManager::GenerateBroadcastSessionId() { - return nearby::RandData(); -} - -void BroadcastManager::BroadcastSessionState::SetAdvertisingSession( - std::unique_ptr session) { - advertising_session_ = std::move(session); -} - -void BroadcastManager::BroadcastSessionState::CallStartedCallback( - absl::Status status) { - BroadcastCallback callback = std::move(broadcast_callback_); - if (callback.start_broadcast_cb) { - callback.start_broadcast_cb(status); - } -} - -void BroadcastManager::BroadcastSessionState::StopAdvertising() { - std::unique_ptr advertising_session = - std::move(advertising_session_); - if (advertising_session) { - absl::Status status = advertising_session->stop_advertising(); - if (!status.ok()) { - LOG(WARNING) << "StopAdvertising error: " << status; - } - } -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/broadcast_manager.h b/presence/implementation/broadcast_manager.h deleted file mode 100644 index aedf2fec..00000000 --- a/presence/implementation/broadcast_manager.h +++ /dev/null @@ -1,109 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BROADCAST_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BROADCAST_MANAGER_H_ - -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/credential_manager.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/power_mode.h" - -namespace nearby { -namespace presence { - -// The instance of BroadcastManager is owned by {@code ServiceControllerImpl}. -// Helping service controller to manage broadcast requests and callbacks. - -class BroadcastManager { - public: - using SingleThreadExecutor = ::nearby::SingleThreadExecutor; - using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; - using Runnable = ::nearby::Runnable; - using LocalCredential = internal::LocalCredential; - BroadcastManager(Mediums& mediums, CredentialManager& credential_manager, - SingleThreadExecutor& executor) { - mediums_ = &mediums, credential_manager_ = &credential_manager, - executor_ = &executor; - } - ~BroadcastManager() = default; - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback); - void StopBroadcast(BroadcastSessionId); - - private: - Mediums* mediums_; - CredentialManager* credential_manager_; - SingleThreadExecutor* executor_; - class BroadcastSessionState { - public: - explicit BroadcastSessionState(BroadcastCallback broadcast_callback, - PowerMode power_mode) - : broadcast_callback_(std::move(broadcast_callback)), - power_mode_(power_mode) {} - - void SetAdvertisingSession(std::unique_ptr session); - void CallStartedCallback(absl::Status status); - void StopAdvertising(); - - PowerMode GetPowerMode() { return power_mode_; } - - private: - BroadcastCallback broadcast_callback_; - PowerMode power_mode_; - std::unique_ptr advertising_session_; - }; - BroadcastSessionId GenerateBroadcastSessionId(); - void NotifyStartCallbackStatus(BroadcastSessionId id, absl::Status status); - void RunOnServiceControllerThread(absl::string_view name, Runnable runnable) { - executor_->Execute(std::string(name), std::move(runnable)); - } - void FetchCredentials(BroadcastSessionId id, - BaseBroadcastRequest broadcast_request) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - absl::optional SelectCredential( // NOLINT - BaseBroadcastRequest& broadcast_request, - std::vector credentials); - - // Returns the private credential, if any, selected to generate the - // advertisement. A salt used in the advertisement is added to the returned - // private credential. The caller must save it in the storage. - absl::optional Advertise( // NOLINT - BroadcastSessionId id, BaseBroadcastRequest broadcast_request, - std::vector credentials) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - absl::flat_hash_map sessions_ - ABSL_GUARDED_BY(*executor_); -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_BROADCAST_MANAGER_H_ diff --git a/presence/implementation/broadcast_manager_test.cc b/presence/implementation/broadcast_manager_test.cc deleted file mode 100644 index 32effaf9..00000000 --- a/presence/implementation/broadcast_manager_test.cc +++ /dev/null @@ -1,177 +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 "presence/implementation/broadcast_manager.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/future.h" -#include "internal/platform/medium_environment.h" -#include "internal/proto/credential.pb.h" -#include "presence/implementation/credential_manager_impl.h" -#include "presence/implementation/mediums/mediums.h" - -namespace nearby { -namespace presence { -namespace { - -using FeatureFlags = ::nearby::FeatureFlags::Flags; -using internal::IdentityType; -using ::nearby::CountDownLatch; -using ::nearby::MediumEnvironment; -using ::testing::status::StatusIs; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{}, -}; - -constexpr absl::string_view kAccountName = "Test account"; -constexpr int8_t kTxPower = 30; - -BroadcastRequest CreateBroadcastRequest(IdentityType identity) { - PresenceBroadcast::BroadcastSection section = { - .identity = identity, - .extended_properties = {DataElement( - DataElement(ActionBit::kActiveUnlockAction))}, - .account_name = std::string(kAccountName)}; - PresenceBroadcast presence_request = {.sections = {section}}; - BroadcastRequest request = {.tx_power = kTxPower, - .variant = presence_request}; - return request; -} - -class MediumEnvironmentStarter { - public: - MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } - ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } -}; - -class BroadcastManagerTest : public testing::TestWithParam { - protected: - void TearDown() override { - MediumEnvironment::Instance().Sync(); - // Finish pending tasks before destroying BroadcastManager - executor_.Shutdown(); - } - bool IsAdvertising() { - WaitForServiceControllerTasks(); - MediumEnvironment::Instance().Sync(); - return MediumEnvironment::Instance() - .GetBleMediumStatus(*mediums_.GetBle().GetImpl()) - ->is_advertising; - } - BroadcastCallback CreateBroadcastCallback() { - return BroadcastCallback{.start_broadcast_cb = [this](absl::Status status) { - start_broadcast_status_.Set(status); - }}; - } - - void WaitForServiceControllerTasks() { - CountDownLatch latch(1); - executor_.Execute([&]() { latch.CountDown(); }); - latch.Await(); - } - - // The medium environment must be initialized (started) before the service - // controller. - MediumEnvironmentStarter env_; - nearby::Future start_broadcast_status_; - BroadcastCallback broadcast_callback_{ - .start_broadcast_cb = [this](absl::Status status) { - start_broadcast_status_.Set(status); - }}; - Mediums mediums_; - SingleThreadExecutor executor_; - CredentialManagerImpl credential_manager_{&executor_}; - BroadcastManager broadcast_manager_{mediums_, credential_manager_, executor_}; -}; - -INSTANTIATE_TEST_SUITE_P(ParametrisedBroadcastManagerTest, BroadcastManagerTest, - testing::ValuesIn(kTestCases)); - -TEST_P(BroadcastManagerTest, StartBroadcastPublicIdentity) { - absl::StatusOr session = - broadcast_manager_.StartBroadcast( - CreateBroadcastRequest(internal::IDENTITY_TYPE_PUBLIC), - CreateBroadcastCallback()); - - EXPECT_OK(session); - EXPECT_TRUE(start_broadcast_status_.Get().ok()); - EXPECT_OK(start_broadcast_status_.Get().GetResult()); - EXPECT_TRUE(IsAdvertising()); -} - -TEST_P(BroadcastManagerTest, StartAndStopBroadcast) { - absl::StatusOr session = - broadcast_manager_.StartBroadcast( - CreateBroadcastRequest(internal::IDENTITY_TYPE_PUBLIC), - CreateBroadcastCallback()); - ASSERT_OK(session); - EXPECT_TRUE(IsAdvertising()); - - broadcast_manager_.StopBroadcast(*session); - EXPECT_FALSE(IsAdvertising()); -} - -TEST_P(BroadcastManagerTest, StopBroadcastTwiceNoSideEffects) { - absl::StatusOr session = - broadcast_manager_.StartBroadcast( - CreateBroadcastRequest(internal::IDENTITY_TYPE_PUBLIC), - CreateBroadcastCallback()); - ASSERT_OK(session); - EXPECT_TRUE(IsAdvertising()); - - broadcast_manager_.StopBroadcast(*session); - broadcast_manager_.StopBroadcast(*session); -} - -TEST_P(BroadcastManagerTest, StopBroadcastInvalidSessionNoSideEffects) { - broadcast_manager_.StopBroadcast(123456); -} - -TEST_P(BroadcastManagerTest, StartBroadcastInvalidRequestFails) { - absl::StatusOr session = - broadcast_manager_.StartBroadcast(BroadcastRequest{}, - CreateBroadcastCallback()); - - EXPECT_THAT(session, StatusIs(absl::StatusCode::kInvalidArgument)); - EXPECT_TRUE(start_broadcast_status_.Get().ok()); - EXPECT_THAT(start_broadcast_status_.Get().GetResult(), - StatusIs(absl::StatusCode::kInvalidArgument)); - EXPECT_FALSE(IsAdvertising()); -} - -TEST_P(BroadcastManagerTest, StartBroadcastPrivateIdentityFails) { - // TODO(b/256249404): Support private identity. - absl::StatusOr session = - broadcast_manager_.StartBroadcast( - CreateBroadcastRequest(internal::IDENTITY_TYPE_PRIVATE_GROUP), - CreateBroadcastCallback()); - - ASSERT_OK(session); - EXPECT_TRUE(start_broadcast_status_.Get().ok()); - EXPECT_THAT(start_broadcast_status_.Get().GetResult(), - StatusIs(absl::StatusCode::kNotFound)); - EXPECT_FALSE(IsAdvertising()); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/connection_authenticator.h b/presence/implementation/connection_authenticator.h deleted file mode 100644 index 7a9b2cb8..00000000 --- a/presence/implementation/connection_authenticator.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_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_H_ - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" - -namespace nearby { -namespace presence { - -class ConnectionAuthenticator { - public: - struct OneWayInitiatorData { - std::string shared_credential_hash; - }; - - struct TwoWayInitiatorData { - std::string shared_credential_hash; - std::string private_key_signature; - }; - - struct ResponderData { - std::string private_key_signature; - }; - - using InitiatorData = absl::variant; - - virtual ~ConnectionAuthenticator() = default; - - // Builds a signed message to be returned to Nearby Connections for - // authentication on the other side of the connection. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // local_credential - The local credential used to sign the derived - // information. If this is std::nullopt, then we will be - // performing one-way authentication. - // shared_credential - The shared credential used to decrypt the advertisement - // from the remote device. - virtual absl::StatusOr BuildSignedMessageAsInitiator( - absl::string_view ukey2_secret, - std::optional local_credential, - const internal::SharedCredential& shared_credential) const = 0; - - // Builds a signed message to be returned to Nearby Connections for - // authentication on the other side of the connection. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // local_credential - The local credential used to sign the derived - // information so the initiator can verify against our - // shared credential. - virtual absl::StatusOr BuildSignedMessageAsResponder( - absl::string_view ukey2_secret, - const internal::LocalCredential& local_credential) const = 0; - - // Verifies a signed message received from the responder (broadcaster) of the - // Nearby Presence advertisement. - // authentication_data - the data required to verify the connection, received - // from the responder. - // ukey2_secret - the shared secret derived from the ukey2 handshake in NC. - // shared_credentials - the set of shared credentials that can be used to - // verify the responder data. - virtual absl::Status VerifyMessageAsInitiator( - ResponderData authentication_data, absl::string_view ukey2_secret, - const std::vector& shared_credentials) - const = 0; - - // Verifies a signed message received from the Nearby Connections peer. - // Returns the matched local credential if the verification was successful. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // received_frame - The received frame from Nearby Connections. - // local_credentials - The set of local credentials that may contain the - // required keyseed hash. - // shared_credentials - The set of shared credentials that can be used to - // verify the signed contents of the frame. - virtual absl::StatusOr VerifyMessageAsResponder( - absl::string_view ukey2_secret, InitiatorData initiator_data, - const std::vector& local_credentials, - const std::vector& shared_credentials) - const = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_H_ diff --git a/presence/implementation/connection_authenticator_impl.cc b/presence/implementation/connection_authenticator_impl.cc deleted file mode 100644 index cbe68aa2..00000000 --- a/presence/implementation/connection_authenticator_impl.cc +++ /dev/null @@ -1,197 +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 "presence/implementation/connection_authenticator_impl.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/types/variant.h" -#include "internal/crypto/ed25519.h" -#include "internal/crypto_cros/hkdf.h" -#include "internal/crypto_cros/secure_util.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" - -namespace nearby { -namespace presence { - -namespace { -constexpr int kPresenceAuthenticatorVersion = 1; -constexpr int kPresenceAuthenticatorHkdfKeySize = 32; -constexpr char kBroadcasterMessageHeader[] = - "Nearby Presence Broadcaster Signature"; -constexpr char kDiscovererMessageHeader[] = - "Nearby Presence Discoverer Signature"; -constexpr char kHkdfSalt[] = "Google Nearby"; -constexpr char kBroadcasterHkdfInfo[] = - "Nearby Presence Broadcaster Credential Hash"; -constexpr char kDiscovererHkdfInfo[] = - "Nearby Presence Discoverer Credential Hash"; -} // namespace - -absl::StatusOr -ConnectionAuthenticatorImpl::BuildSignedMessageAsInitiator( - absl::string_view ukey2_secret, - std::optional local_credential, - const internal::SharedCredential& shared_credential) const { - auto shared_credential_hash = crypto::HkdfSha256( - absl::StrCat(ukey2_secret, shared_credential.key_seed()), kHkdfSalt, - kDiscovererHkdfInfo, kPresenceAuthenticatorHkdfKeySize); - if (local_credential.has_value()) { - // two-way authentication, private identity. - auto signer = crypto::Ed25519Signer::Create( - (*local_credential).connection_signing_key().key()); - if (!signer.ok()) { - return signer.status(); - } - auto pkey_signature = - signer->Sign(absl::StrCat(kDiscovererMessageHeader, ukey2_secret)); - if (!pkey_signature.has_value()) { - return absl::InternalError("Signing using private key failed."); - } - return ConnectionAuthenticator::TwoWayInitiatorData{ - .shared_credential_hash = shared_credential_hash, - .private_key_signature = *pkey_signature, - }; - } - // one-way authentication, trusted identity. - return ConnectionAuthenticator::OneWayInitiatorData{ - .shared_credential_hash = shared_credential_hash, - }; -} - -absl::StatusOr -ConnectionAuthenticatorImpl::BuildSignedMessageAsResponder( - absl::string_view ukey2_secret, - const internal::LocalCredential& local_credential) const { - auto signer = crypto::Ed25519Signer::Create( - local_credential.connection_signing_key().key()); - if (!signer.ok()) { - return signer.status(); - } - auto pkey_signature = - signer->Sign(absl::StrCat(kBroadcasterMessageHeader, ukey2_secret)); - if (!pkey_signature.has_value()) { - return absl::InternalError("Signing using private key failed."); - } - return ConnectionAuthenticator::ResponderData{.private_key_signature = - *pkey_signature}; -} - -absl::Status ConnectionAuthenticatorImpl::VerifyMessageAsInitiator( - ResponderData authentication_data, absl::string_view ukey2_secret, - const std::vector& shared_credentials) const { - if (authentication_data.private_key_signature.empty()) { - return absl::InvalidArgumentError("Empty private key signature."); - } - for (const auto& shared_credential : shared_credentials) { - auto verifier = crypto::Ed25519Verifier::Create( - shared_credential.connection_signature_verification_key()); - if (!verifier.ok()) { - continue; - } - // Verify ED25519 signature, returning true if verification succeeded. - if (verifier - ->Verify(absl::StrCat(kBroadcasterMessageHeader, ukey2_secret), - authentication_data.private_key_signature) - .ok()) { - return absl::OkStatus(); - } - } - return absl::InternalError("Unable to verify responder's private key sig."); -} - -absl::StatusOr -ConnectionAuthenticatorImpl::VerifyMessageAsResponder( - absl::string_view ukey2_secret, InitiatorData initiator_data, - const std::vector& local_credentials, - const std::vector& shared_credentials) const { - std::string shared_credential_hash; - std::optional matched_local_credential; - if (absl::holds_alternative(initiator_data)) { - // one-way. we only need to verify if the hash matches one of our - // local credentials. - auto auth_data = absl::get(initiator_data); - if (auth_data.shared_credential_hash.size() != - kPresenceAuthenticatorHkdfKeySize) { - return absl::InvalidArgumentError("Invalid shared credential hash size."); - } - for (const auto& local_credential : local_credentials) { - // Verify Credential ID hash. - auto cid_hash = crypto::HkdfSha256( - absl::StrCat(ukey2_secret, local_credential.key_seed()), kHkdfSalt, - kDiscovererHkdfInfo, kPresenceAuthenticatorHkdfKeySize); - if (crypto::SecureMemEqual(cid_hash.c_str(), - auth_data.shared_credential_hash.c_str(), - kPresenceAuthenticatorHkdfKeySize)) { - matched_local_credential = local_credential; - } - } - } else { - // two-way. we need to verify if the hash matches one of our local - // credentials _and_ make sure it matches one of our shared credentials. - // We want to check each shared credential to verify using its public key. - - // Match the local credential. - auto auth_data = absl::get(initiator_data); - if (auth_data.shared_credential_hash.size() != - kPresenceAuthenticatorHkdfKeySize) { - return absl::InvalidArgumentError("Invalid shared credential hash size."); - } - if (auth_data.private_key_signature.empty()) { - return absl::InvalidArgumentError("Empty private key signature."); - } - for (const auto& local_credential : local_credentials) { - // Verify Credential ID hash. - auto cid_hash = crypto::HkdfSha256( - absl::StrCat(ukey2_secret, local_credential.key_seed()), kHkdfSalt, - kDiscovererHkdfInfo, kPresenceAuthenticatorHkdfKeySize); - if (crypto::SecureMemEqual(cid_hash.c_str(), - auth_data.shared_credential_hash.c_str(), - kPresenceAuthenticatorHkdfKeySize)) { - matched_local_credential = local_credential; - } - } - // Now, match our shared credential. - std::optional matched_shared_credential; - for (const auto& shared_credential : shared_credentials) { - auto verifier = crypto::Ed25519Verifier::Create( - shared_credential.connection_signature_verification_key()); - if (!verifier.ok() || - verifier - ->Verify(absl::StrCat(kDiscovererMessageHeader, ukey2_secret), - auth_data.private_key_signature) - .ok()) { - matched_shared_credential = shared_credential; - break; - } - } - if (!matched_shared_credential.has_value()) { - return absl::InternalError("Unable to verify shared credential."); - } - } - if (matched_local_credential.has_value()) { - return *matched_local_credential; - } - return absl::InternalError("Unable to verify local credential."); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/connection_authenticator_impl.h b/presence/implementation/connection_authenticator_impl.h deleted file mode 100644 index 25f42ddc..00000000 --- a/presence/implementation/connection_authenticator_impl.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_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_IMPL_H_ - -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" -#include "presence/implementation/connection_authenticator.h" - -namespace nearby { -namespace presence { - -class ConnectionAuthenticatorImpl : public ConnectionAuthenticator { - public: - // Builds a signed message to be returned to Nearby Connections for - // authentication on the other side of the connection. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // local_credential - The local credential used to sign the derived - // information. If this is std::nullopt, then we will be - // performing one-way authentication. - // shared_credential - The shared credential used to decrypt the advertisement - // from the remote device. - absl::StatusOr BuildSignedMessageAsInitiator( - absl::string_view ukey2_secret, - std::optional local_credential, - const internal::SharedCredential& shared_credential) const override; - - // Builds a signed message to be returned to Nearby Connections for - // authentication on the other side of the connection. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // local_credential - The local credential used to sign the derived - // information so the initiator can verify against our - // shared credential. - absl::StatusOr BuildSignedMessageAsResponder( - absl::string_view ukey2_secret, - const internal::LocalCredential& local_credential) const override; - - // Verifies a signed message received from the responder (broadcaster) of the - // Nearby Presence advertisement. - // authentication_data - the data required to verify the connection, received - // from the responder. - // ukey2_secret - the shared secret derived from the ukey2 handshake in NC. - // shared_credentials - the set of shared credentials that can be used to - // verify the responder data. - absl::Status VerifyMessageAsInitiator( - ResponderData authentication_data, absl::string_view ukey2_secret, - const std::vector& shared_credentials) - const override; - - // Verifies a signed message received from the Nearby Connections peer. - // ukey2_secret - The shared secret derived from the UKEY2 handshake in NC. - // received_frame - The received frame from Nearby Connections. - // local_credentials - The set of local credentials that may contain the - // required keyseed hash. - // shared_credentials - The set of shared credentials that can be used to - // verify the signed contents of the frame. - absl::StatusOr VerifyMessageAsResponder( - absl::string_view ukey2_secret, InitiatorData initiator_data, - const std::vector& local_credentials, - const std::vector& shared_credentials) - const override; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CONNECTION_AUTHENTICATOR_IMPL_H_ diff --git a/presence/implementation/connection_authenticator_impl_test.cc b/presence/implementation/connection_authenticator_impl_test.cc deleted file mode 100644 index e28eb477..00000000 --- a/presence/implementation/connection_authenticator_impl_test.cc +++ /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. - -#include "presence/implementation/connection_authenticator_impl.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/crypto/ed25519.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" - -namespace nearby { -namespace presence { -namespace { - -using ::protobuf_matchers::EqualsProto; -using ::testing::status::StatusIs; - -constexpr char kUkey2Secret[] = {0x34, 0x56, 0x78, 0x90}; -constexpr char kKeySeed1[] = {1, 2, 3, 4, 5, 6, 7, 8}; -constexpr char kKeySeed2[] = {8, 7, 6, 5, 4, 3, 2, 1}; - -internal::LocalCredential BuildLocalCredential( - const crypto::Ed25519KeyPair& key_pair, absl::string_view key_seed) { - internal::LocalCredential local_credential; - local_credential.mutable_connection_signing_key()->set_key( - absl::StrCat(key_pair.private_key, key_pair.public_key)); - local_credential.set_key_seed(key_seed); - return local_credential; -} - -internal::SharedCredential BuildSharedCredential( - const crypto::Ed25519KeyPair& key_pair, absl::string_view key_seed) { - internal::SharedCredential shared_credential; - shared_credential.set_connection_signature_verification_key( - key_pair.public_key); - shared_credential.set_key_seed(key_seed); - return shared_credential; -} - -class PresenceAuthenticatorTest : public ::testing::Test { - protected: - void SetUp() override { - auto key_pair_or_status = crypto::Ed25519Signer::CreateNewKeyPair(); - ASSERT_OK_AND_ASSIGN(auto key_pair1, key_pair_or_status); - auto key_pair2_or_status = crypto::Ed25519Signer::CreateNewKeyPair(); - ASSERT_OK_AND_ASSIGN(auto key_pair2, key_pair2_or_status); - initiator_local_credential_ = BuildLocalCredential(key_pair1, kKeySeed1); - initiator_shared_credential_ = BuildSharedCredential(key_pair1, kKeySeed1); - initiator_shared_credential_wrong_key_ = - BuildSharedCredential(key_pair2, kKeySeed1); - responder_local_credential_ = BuildLocalCredential(key_pair2, kKeySeed2); - responder_shared_credential_ = BuildSharedCredential(key_pair2, kKeySeed2); - responder_shared_credential_wrong_key_ = - BuildSharedCredential(key_pair1, kKeySeed2); - } - - internal::LocalCredential initiator_local_credential_; - internal::LocalCredential responder_local_credential_; - internal::SharedCredential initiator_shared_credential_; - internal::SharedCredential initiator_shared_credential_wrong_key_; - internal::SharedCredential responder_shared_credential_; - internal::SharedCredential responder_shared_credential_wrong_key_; -}; - -TEST_F(PresenceAuthenticatorTest, TestTwoWayInitiatorSignResponderVerify) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - auto local_credential = responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_}); - ASSERT_TRUE(local_credential.ok()); - EXPECT_THAT(*local_credential, EqualsProto(responder_local_credential_)); -} - -TEST_F(PresenceAuthenticatorTest, TestOneWayInitiatorSignResponderVerify) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN( - ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, std::nullopt, responder_shared_credential_)); - auto local_credential = responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_}); - ASSERT_TRUE(local_credential.ok()); - EXPECT_THAT(*local_credential, EqualsProto(responder_local_credential_)); -} - -TEST_F(PresenceAuthenticatorTest, TestResponderSignInitiatorVerify) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::ResponderData auth_data, - responder_authenticator.BuildSignedMessageAsResponder( - kUkey2Secret, responder_local_credential_)); - EXPECT_OK(initiator_authenticator.VerifyMessageAsInitiator( - auth_data, kUkey2Secret, {responder_shared_credential_})); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyNoSharedCredentialMatchFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {}, {initiator_shared_credential_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestOneWayInitiatorSignResponderVerifyNoMatchCredentialFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN( - ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, std::nullopt, responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {}, {initiator_shared_credential_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestOneWayInitiatorSignResponderVerifyNoCredentialFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN( - ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, std::nullopt, responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {}, {}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyNoMatchCredentialFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {}, {initiator_shared_credential_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyWrongKeyFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_wrong_key_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestResponderSignInitiatorVerifyNoMatchCredentialFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::ResponderData auth_data, - responder_authenticator.BuildSignedMessageAsResponder( - kUkey2Secret, responder_local_credential_)); - EXPECT_THAT(initiator_authenticator.VerifyMessageAsInitiator( - auth_data, kUkey2Secret, {}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestResponderSignInitiatorVerifyWrongKeyFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::ResponderData auth_data, - responder_authenticator.BuildSignedMessageAsResponder( - kUkey2Secret, responder_local_credential_)); - EXPECT_THAT( - initiator_authenticator.VerifyMessageAsInitiator( - auth_data, kUkey2Secret, {responder_shared_credential_wrong_key_}), - StatusIs(absl::StatusCode::kInternal)); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyNoCidHashFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - std::get(auth_data) - .shared_credential_hash.clear(); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_wrong_key_}), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST_F(PresenceAuthenticatorTest, - TestTwoWayInitiatorSignResponderVerifyNoPkeySigFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, initiator_local_credential_, - responder_shared_credential_)); - std::get(auth_data) - .private_key_signature.clear(); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_wrong_key_}), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST_F(PresenceAuthenticatorTest, - TestOneWayInitiatorSignResponderVerifyNoCidHashFails) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN( - ConnectionAuthenticator::InitiatorData auth_data, - initiator_authenticator.BuildSignedMessageAsInitiator( - kUkey2Secret, std::nullopt, responder_shared_credential_)); - std::get(auth_data) - .shared_credential_hash.clear(); - EXPECT_THAT(responder_authenticator.VerifyMessageAsResponder( - kUkey2Secret, auth_data, {responder_local_credential_}, - {initiator_shared_credential_}), - StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST_F(PresenceAuthenticatorTest, - TestResponderSignInitiatorVerifyNoPkeySigFail) { - ConnectionAuthenticatorImpl responder_authenticator; - ConnectionAuthenticatorImpl initiator_authenticator; - ASSERT_OK_AND_ASSIGN(ConnectionAuthenticator::ResponderData auth_data, - responder_authenticator.BuildSignedMessageAsResponder( - kUkey2Secret, responder_local_credential_)); - auth_data.private_key_signature.clear(); - EXPECT_THAT(initiator_authenticator.VerifyMessageAsInitiator( - auth_data, kUkey2Secret, {responder_shared_credential_}), - StatusIs(absl::StatusCode::kInvalidArgument)); -} -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/credential_manager.h b/presence/implementation/credential_manager.h deleted file mode 100644 index 2d4e088b..00000000 --- a/presence/implementation/credential_manager.h +++ /dev/null @@ -1,115 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_H_ - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" - -namespace nearby { -namespace presence { - -using SubscriberId = uint64_t; - -/* - * The instance of CredentialManager is owned by {@code ServiceControllerImpl}. - * Helping service controller to manage local credentials and coordinate with - * downloaded remote credentials. - */ -class CredentialManager { - public: - CredentialManager() = default; - virtual ~CredentialManager() = default; - - // Used to (re)generate user’s private and public credentials. - // The generated private credentials will be saved to creds storage. - // The generated public credentials will be returned inside the - // credentials_generated_cb for manager app to upload to web. - // The user’s own public credentials won’t be saved on local credential - // storage. - virtual void GenerateCredentials( - const nearby::internal::DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - - // Update remote public credentials. - virtual void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) = 0; - - virtual void UpdateLocalCredential( - const CredentialSelector& credential_selector, - nearby::internal::LocalCredential credential, - SaveCredentialsResultCallback result_callback) = 0; - - // Used to fetch private creds when broadcasting. - virtual void GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) = 0; - - // Used to fetch local/remote public creds based on the value - // of public_credential_type. - virtual void GetPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) = 0; - - // Subscribes for public credentials updates. The `callback` is triggered when - // the public credentials are fetched initially, and then every time the - // credentials change. - virtual SubscriberId SubscribeForPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) = 0; - - // Unsubscribes from public credentials updates. No new callbacks will be - // triggered after this function returns. If there is a callback already - // running, that callback may continue after - // `UnsubscribeFromPublicCredentials()` return. - virtual void UnsubscribeFromPublicCredentials(SubscriberId id) = 0; - - // Decrypts the device identity metadata from a public credential. - // Returns an empty string if decryption fails. - virtual std::string DecryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string) = 0; - - // If `regen_credentials` is set to true, regenerating credentials. - virtual void SetDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - - virtual ::nearby::internal::DeviceIdentityMetaData - GetDeviceIdentityMetaData() = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_H_ diff --git a/presence/implementation/credential_manager_impl.cc b/presence/implementation/credential_manager_impl.cc deleted file mode 100644 index d49d2f56..00000000 --- a/presence/implementation/credential_manager_impl.cc +++ /dev/null @@ -1,834 +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 "presence/implementation/credential_manager_impl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "absl/types/span.h" -#include "absl/types/variant.h" -#include "internal/crypto_cros/aead.h" -#include "internal/crypto_cros/ec_private_key.h" -#include "internal/crypto_cros/hkdf.h" -#include "internal/platform/base64_utils.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/crypto.h" -#include "internal/platform/future.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/logging.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" -#include "presence/data_types.h" -#include "presence/implementation/base_broadcast_request.h" -#include "presence/implementation/ldt.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::Base64Utils; -using ::nearby::Crypto; -using ::nearby::Exception; -using ::nearby::ExceptionOr; -using ::nearby::Future; -using ::nearby::internal::IdentityType; -using ::nearby::internal::LocalCredential; -using ::nearby::internal::SharedCredential; - -// Key to retrieve local device's Private/Public Key Credentials from key store. -constexpr char kPairedKeyAliasPrefix[] = "nearby_presence_paired_key_alias_"; - -// Use an empty string because Chromium only supports 1 account. -// Windows & Apple will have their own Identity Provider. -constexpr absl::string_view kEmptyAccountName = ""; - -// The expected number of valid local credentials to be stored on local device. -constexpr int kExpectedValidLocalCredtialSize = 6; -// The expiration time in days for a credential. -constexpr int kCredentialLifeCycleDays = 5; -// The minimum size of bytes to generate credential id. -constexpr int kExpectedByteSizeOfCredentialId = 8; - -// Returns a random duration in [0, max_duration] range. -absl::Duration RandomDuration(absl::Duration max_duration) { - uint32_t random = nearby::RandData(); - return max_duration * random / std::numeric_limits::max(); -} - -std::string CustomizeBytesSize(absl::string_view bytes, size_t len) { - return crypto::HkdfSha256( - /*ikm=*/std::string(bytes), // NOLINT - /*salt=*/std::string(CredentialManagerImpl::kAuthenticityKeyByteSize, 0), - /*info=*/"", /*derived_key_size=*/len); -} - -} // namespace - -// Returns a positive long value extracted from a byte array. -int64_t GenerateIdFromByteArray(const ByteArray& input) { - size_t inputLength = input.size(); - - ByteArray processed_bytes(kExpectedByteSizeOfCredentialId); - // Only use first 8 bytes if the input is longer than 8 bytes. - if (inputLength > kExpectedByteSizeOfCredentialId) { - processed_bytes.CopyAt(0, input); - } else { - // Extend the input with zeros if it's shorter than 8 bytes - processed_bytes.CopyAt(kExpectedByteSizeOfCredentialId - inputLength, - input); - } - - int64_t id = 0; - for (int i = 0; i < kExpectedByteSizeOfCredentialId; ++i) { - id |= (static_cast(processed_bytes.data()[i]) << (8 * i)); - } - if (id == std::numeric_limits::min()) - return std::numeric_limits::max(); - return std::abs(id); -} - -void CredentialManagerImpl::GenerateCredentials( - const DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) { - std::vector public_credentials; - std::vector private_credentials; - - for (auto identity_type : identity_types) { - absl::Time start_time = SystemClock::ElapsedRealtime(); - absl::Duration gap = credential_life_cycle_days * absl::Hours(24); - for (int index = 0; index < contiguous_copy_of_credentials; index++) { - auto public_private_credentials = - CreateLocalCredential(device_identity_metadata, identity_type, - start_time, start_time + gap); - if (public_private_credentials.second.identity_type() != - IdentityType::IDENTITY_TYPE_UNSPECIFIED) { - private_credentials.push_back(public_private_credentials.first); - public_credentials.push_back(public_private_credentials.second); - } - start_time += gap; - } - } - - // Create credential_storage object and invoke SaveCredentials. - credential_storage_ptr_->SaveCredentials( - manager_app_id, kEmptyAccountName, private_credentials, - public_credentials, PublicCredentialType::kLocalPublicCredential, - SaveCredentialsResultCallback{ - .credentials_saved_cb = - [this, manager_app_id = std::string(manager_app_id), - account_name = kEmptyAccountName, - callback = std::move(credentials_generated_cb), - public_credentials](absl::Status status) mutable { - if (!status.ok()) { - LOG(WARNING) << "Save credentials failed with: " << status; - std::move(callback.credentials_generated_cb)(status); - return; - } - std::move(callback.credentials_generated_cb)( - std::move(public_credentials)); - RunOnServiceControllerThread( - "local-creds-changed", - [this, manager_app_id = std::string(manager_app_id), - account_name = std::string(account_name)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnCredentialsChanged( - manager_app_id, account_name, - PublicCredentialType::kLocalPublicCredential); - }); - }}); -} - -void CredentialManagerImpl::UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) { - credential_storage_ptr_->SaveCredentials( - manager_app_id, account_name, /* private_credentials */ {}, - remote_public_creds, PublicCredentialType::kRemotePublicCredential, - SaveCredentialsResultCallback{ - .credentials_saved_cb = - [this, manager_app_id = std::string(manager_app_id), - account_name = std::string(account_name), - callback = std::move(credentials_updated_cb)]( - absl::Status status) mutable { - if (!status.ok()) { - LOG(WARNING) - << "Update remote credentials failed with: " << status; - } else { - RunOnServiceControllerThread( - "remote-creds-changed", - [this, manager_app_id = std::string(manager_app_id), - account_name = std::string(account_name)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - OnCredentialsChanged( - manager_app_id, account_name, - PublicCredentialType::kRemotePublicCredential); - }); - } - std::move(callback.credentials_updated_cb)(status); - }}); -} - -std::pair -CredentialManagerImpl::CreateLocalCredential( - const DeviceIdentityMetaData& device_identity_metadata, - IdentityType identity_type, absl::Time start_time, absl::Time end_time) { - LocalCredential private_credential; - private_credential.set_start_time_millis(absl::ToUnixMillis(start_time)); - private_credential.set_end_time_millis(absl::ToUnixMillis(end_time)); - private_credential.set_identity_type(identity_type); - - // Creates an AES key to encrypt the whole broadcast. - std::string secret_key(kAuthenticityKeyByteSize, 0); - RandBytes(const_cast(secret_key.data()), - secret_key.size()); - private_credential.set_key_seed(secret_key); - - // Uses SHA-256 algorithm to generate the credential ID from the - // authenticity key - auto secret_id = Crypto::Sha256(secret_key); - // Does not expect to fail here since Crypto::Sha256 should not return - // empty ByteArray. - CHECK(!secret_id.Empty()) << "Crypto::Sha256 failed!"; - - private_credential.set_id(GenerateIdFromByteArray(secret_id)); - - std::string alias = Base64Utils::Encode(secret_id); - auto prefixedAlias = kPairedKeyAliasPrefix + alias; - - // Generate key pair. Store the private key in private credential. - auto key_pair = crypto::ECPrivateKey::Create(); - std::vector private_key; - key_pair->ExportPrivateKey(&private_key); - private_credential.mutable_connection_signing_key()->set_key( - std::string(private_key.begin(), private_key.end())); - // Create an AES key to encrypt the device identity metadata. - std::string metadata_key(kBaseMetadataSize, 0); - RandBytes(const_cast(metadata_key.data()), - metadata_key.size()); - private_credential.set_metadata_encryption_key_v0(metadata_key); - - // Generate the public credential - std::vector public_key; - key_pair->ExportPublicKey(&public_key); - - return std::pair( - private_credential, - CreatePublicCredential(private_credential, device_identity_metadata, - public_key)); -} - -SharedCredential CredentialManagerImpl::CreatePublicCredential( - const LocalCredential& private_credential, - const DeviceIdentityMetaData& device_identity_metadata, - const std::vector& public_key) { - // The start time in the public credential should be decreased by a random - // value in 0 - 3 hours range. - // The end time should be increased by a random value in 0 - 3 hours range. - // This improves privacy by making it harder to correlate certificates. - absl::Time start_time = - absl::FromUnixMillis(private_credential.start_time_millis()) - - RandomDuration(absl::Hours(3)); - absl::Time end_time = - absl::FromUnixMillis(private_credential.end_time_millis()) + - RandomDuration(absl::Hours(3)); - SharedCredential public_credential; - public_credential.set_identity_type(private_credential.identity_type()); - public_credential.set_id(private_credential.id()); - public_credential.set_key_seed(private_credential.key_seed()); - public_credential.set_start_time_millis(absl::ToUnixMillis(start_time)); - public_credential.set_end_time_millis(absl::ToUnixMillis(end_time)); - // Set up the public key. Note, we are setting the "connection" key but we are - // not setting the "advertisement" key because the latter is not used yet. - public_credential.set_connection_signature_verification_key( - std::string(public_key.begin(), public_key.end())); - - auto metadata_encryption_key_tag = - Crypto::Sha256(private_credential.metadata_encryption_key_v0()); - public_credential.set_metadata_encryption_key_tag_v0( - std::string(metadata_encryption_key_tag.AsStringView())); - - auto encrypted_meta_data = EncryptDeviceIdentityMetaData( - private_credential.metadata_encryption_key_v0(), - private_credential.key_seed(), - device_identity_metadata.SerializeAsString()); - - if (encrypted_meta_data.empty()) { - LOG(ERROR) << "Fails to encrypt the device identity metadata."; - public_credential.set_identity_type( - IdentityType::IDENTITY_TYPE_UNSPECIFIED); - return public_credential; - } - - public_credential.set_encrypted_metadata_bytes_v0(encrypted_meta_data); - return public_credential; -} - -std::string CredentialManagerImpl::DecryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string) { - crypto::Aead aead(crypto::Aead::AeadAlgorithm::AES_256_GCM); - - std::vector derived_key = - ExtendMetadataEncryptionKey(metadata_encryption_key); - aead.Init(derived_key); - - auto iv = CustomizeBytesSize(key_seed, CredentialManagerImpl::kAesGcmIVSize); - std::vector iv_bytes(iv.begin(), iv.end()); - std::vector encrypted_metadata_bytes(metadata_string.begin(), - metadata_string.end()); - - auto result = aead.Open(encrypted_metadata_bytes, - /*nonce=*/ - iv_bytes, - /*additional_data=*/absl::Span()); - - return std::string(result.value().begin(), result.value().end()); -} - -std::string CredentialManagerImpl::EncryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string) { - crypto::Aead aead(crypto::Aead::AeadAlgorithm::AES_256_GCM); - - std::vector derived_key = - ExtendMetadataEncryptionKey(metadata_encryption_key); - - aead.Init(derived_key); - - auto iv = CustomizeBytesSize(key_seed, kAesGcmIVSize); - std::vector iv_bytes(iv.begin(), iv.end()); - - std::vector metadata_bytes(metadata_string.begin(), - metadata_string.end()); - metadata_bytes.resize(metadata_string.size()); - - auto encrypted = aead.Seal(metadata_bytes, - /*nonce=*/ - iv_bytes, - /*additional_data=*/absl::Span()); - - return std::string(encrypted.begin(), encrypted.end()); -} - -std::vector CredentialManagerImpl::ExtendMetadataEncryptionKey( - absl::string_view metadata_encryption_key) { - return crypto::HkdfSha256( - std::vector(metadata_encryption_key.begin(), - metadata_encryption_key.end()), - /*salt=*/absl::Span(), - /*info=*/absl::Span(), kNearbyPresenceNumBytesAesGcmKeySize); -} - -void CredentialManagerImpl::GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - credential_storage_ptr_->GetLocalCredentials( - credential_selector, - GetLocalCredentialsResultCallback{ - .credentials_fetched_cb = - [this, credential_selector, callback = std::move(callback)]( - absl::StatusOr> - get_local_credentials_result) mutable { - if (!get_local_credentials_result.ok()) { - callback.credentials_fetched_cb( - get_local_credentials_result.status()); - return; - } - - CheckCredentialsAndRefillIfNeeded( - credential_selector, - /* credentials_list_variant */ - &get_local_credentials_result.value(), - /* callback_for_local_credentials */ - std::move(callback), - /* callback_for_shared_credentials */ - std::nullopt); - }, - }); -} - -void CredentialManagerImpl::GetPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) { - // Not going to refill for remote SharedCredentials. - if (public_credential_type == PublicCredentialType::kRemotePublicCredential) { - credential_storage_ptr_->GetPublicCredentials( - credential_selector, public_credential_type, std::move(callback)); - return; - } - - credential_storage_ptr_->GetPublicCredentials( - credential_selector, public_credential_type, - GetPublicCredentialsResultCallback{ - .credentials_fetched_cb = - [this, credential_selector, callback = std::move(callback)]( - absl::StatusOr> - get_shared_credentials_result) mutable { - if (!get_shared_credentials_result.ok()) { - callback.credentials_fetched_cb( - get_shared_credentials_result.status()); - return; - } - - CheckCredentialsAndRefillIfNeeded( - credential_selector, - /* credentials_list_variant */ - &get_shared_credentials_result.value(), - /* callback_for_local_credentials */ std::nullopt, - /* callback_for_shared_credentials */ - std::move(callback)); - }, - }); -} - -ExceptionOr> -CredentialManagerImpl::GetLocalCredentialsSync( - const CredentialSelector& credential_selector, absl::Duration timeout) { - Future> result; - GetLocalCredentials(credential_selector, - {.credentials_fetched_cb = - [result](absl::StatusOr> - credentials) mutable { - if (!credentials.ok()) { - result.SetException({Exception::kFailed}); - } else { - result.Set(std::move(*credentials)); - } - }}); - return result.Get(timeout); -} - -ExceptionOr> -CredentialManagerImpl::GetPublicCredentialsSync( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, absl::Duration timeout) { - Future> result; - GetPublicCredentials( - credential_selector, public_credential_type, - {.credentials_fetched_cb = - [result](absl::StatusOr> - credentials) mutable { - if (!credentials.ok()) { - result.SetException({Exception::kFailed}); - } else { - result.Set(std::move(*credentials)); - } - }}); - return result.Get(timeout); -} - -// TODO(b/326063431): The intent of this method is likely for -// GetPublicCredentials() to be called after the AddSubscriber() calls, but -// it's unlikely that this is happening on a real device. Manually verify. -SubscriberId CredentialManagerImpl::SubscribeForPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) { - SubscriberId id = nearby::RandData(); - RunOnServiceControllerThread( - "add-subscriber", - [this, key = SubscriberKey{credential_selector, public_credential_type}, - id, callback = std::move(callback)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - AddSubscriber(key, id, std::move(callback)); - }); - GetPublicCredentials(credential_selector, public_credential_type, - CreateNotifySubscribersCallback( - {credential_selector, public_credential_type})); - return id; -} - -void CredentialManagerImpl::UnsubscribeFromPublicCredentials(SubscriberId id) { - RunOnServiceControllerThread("remove-subscriber", - [this, id]() ABSL_EXCLUSIVE_LOCKS_REQUIRED( - *executor_) { RemoveSubscriber(id); }); -} - -void CredentialManagerImpl::AddSubscriber( - SubscriberKey key, SubscriberId id, - GetPublicCredentialsResultCallback callback) { - subscribers_[key].push_back(Subscriber(id, std::move(callback))); -} - -void CredentialManagerImpl::RemoveSubscriber(SubscriberId id) { - for (auto& entry : subscribers_) { - auto it = std::find_if( - entry.second.begin(), entry.second.end(), - [&](Subscriber& subscriber) { return subscriber.GetId() == id; }); - if (it != entry.second.end()) { - entry.second.erase(it); - if (subscribers_[entry.first].empty()) { - subscribers_.erase(entry.first); - } - return; - } - } -} - -absl::flat_hash_set -CredentialManagerImpl::GetSubscribedIdentities( - absl::string_view manager_app_id, absl::string_view account_name, - PublicCredentialType credential_type) const { - absl::flat_hash_set identities; - for (auto& entry : subscribers_) { - const SubscriberKey& key = entry.first; - if (key.public_credential_type == credential_type && - key.credential_selector.manager_app_id == manager_app_id && - key.credential_selector.account_name == account_name) { - identities.insert(key.credential_selector.identity_type); - } - } - return identities; -} - -void CredentialManagerImpl::OnCredentialsChanged( - absl::string_view manager_app_id, absl::string_view account_name, - PublicCredentialType credential_type) { - LOG(INFO) << "OnCredentialsChanged for app " << manager_app_id << ", account " - << account_name; - for (IdentityType identity_type : - GetSubscribedIdentities(manager_app_id, account_name, credential_type)) { - CredentialSelector credential_selector = { - .manager_app_id = std::string(manager_app_id), - .account_name = std::string(account_name), - .identity_type = identity_type}; - GetPublicCredentials(credential_selector, credential_type, - CreateNotifySubscribersCallback( - {credential_selector, credential_type})); - } -} - -GetPublicCredentialsResultCallback -CredentialManagerImpl::CreateNotifySubscribersCallback(SubscriberKey key) { - return GetPublicCredentialsResultCallback{ - .credentials_fetched_cb = - [this, - key](absl::StatusOr> credentials) { - if (!credentials.ok()) { - LOG(WARNING) << "Failed to get public credentials: error code: " - << credentials.status(); - return; - } - RunOnServiceControllerThread( - "notify-subscribers", - [this, key, credentials = std::move(*credentials)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NotifySubscribers(key, credentials); - }); - }}; -} - -void CredentialManagerImpl::NotifySubscribers( - const SubscriberKey& key, std::vector credentials) { - // We are on `executor_` thread, so we can iterate over `subscribers_` - // without locking. - auto it = subscribers_.find(key); - if (it == subscribers_.end()) { - LOG(WARNING) << "No subscribers for (app: " - << key.credential_selector.manager_app_id - << ", account: " << key.credential_selector.account_name - << ", identity type: " - << static_cast(key.credential_selector.identity_type) - << ", credential type: " - << static_cast(key.public_credential_type) << ")"; - return; - } - for (auto& subscriber : it->second) { - subscriber.NotifyCredentialsFetched(credentials); - } -} - -void CredentialManagerImpl::Subscriber::NotifyCredentialsFetched( - std::vector& credentials) { - callback_.credentials_fetched_cb(credentials); -} - -void CredentialManagerImpl::UpdateLocalCredential( - const CredentialSelector& credential_selector, - nearby::internal::LocalCredential credential, - SaveCredentialsResultCallback result_callback) { - credential_storage_ptr_->UpdateLocalCredential( - credential_selector.manager_app_id, credential_selector.account_name, - std::move(credential), std::move(result_callback)); -} - -void CredentialManagerImpl::CheckCredentialsAndRefillIfNeeded( - const CredentialSelector& credential_selector, - absl::variant*, - std::vector*> - credential_list_variant, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials) { - bool invoked_for_local = false; - int valid_credentials_count = 0; - int64_t current_time_millis = - absl::ToUnixMillis(SystemClock::ElapsedRealtime()); - int64_t last_valid_end_time_millis = current_time_millis; - - std::vector valid_local_credentials; - std::vector valid_shared_credentials; - if (absl::holds_alternative*>( - credential_list_variant) && - callback_for_local_credentials.has_value()) { - invoked_for_local = true; - for (auto& credential : - *absl::get*>( - credential_list_variant)) { - if (credential.end_time_millis() < current_time_millis) { - continue; - } - valid_credentials_count++; - if (last_valid_end_time_millis < credential.end_time_millis()) { - last_valid_end_time_millis = credential.end_time_millis(); - } - valid_local_credentials.push_back(credential); - } - } else if (absl::holds_alternative< - std::vector*>( - credential_list_variant) && - callback_for_shared_credentials.has_value()) { - for (auto& credential : - *absl::get*>( - credential_list_variant)) { - if (credential.end_time_millis() < current_time_millis) { - continue; - } - valid_credentials_count++; - if (last_valid_end_time_millis < credential.end_time_millis()) { - last_valid_end_time_millis = credential.end_time_millis(); - } - valid_shared_credentials.push_back(credential); - } - } else { - LOG(ERROR) << "Bad parameters for CheckCredentialsAndRefillIfNeeded"; - return; - } - - // Most invokes are expected to return early here as it already got enough - // valid credentials, no need to refill. - // Otherwise, the long process of refill (another read, merge, then save) - // would start. - if (valid_credentials_count >= kExpectedValidLocalCredtialSize) { - if (invoked_for_local) { - callback_for_local_credentials.value().credentials_fetched_cb( - valid_local_credentials); - } else { - callback_for_shared_credentials.value().credentials_fetched_cb( - valid_shared_credentials); - } - return; - } - - // Already got the valid credential list for either local or shared. - // Now get the other credentials list from storage, prune them, and begin - // the process of appending new credentials onto them. - if (invoked_for_local) { - credential_storage_ptr_->GetPublicCredentials( - credential_selector, PublicCredentialType::kLocalPublicCredential, - GetPublicCredentialsResultCallback{ - .credentials_fetched_cb = - [this, current_time_millis, last_valid_end_time_millis, - credential_selector, - valid_local_credentials = std::move(valid_local_credentials), - valid_shared_credentials = std::move(valid_shared_credentials), - callback_for_local_credentials = - std::move(callback_for_local_credentials), - callback_for_shared_credentials = - std::move(callback_for_shared_credentials)]( - absl::StatusOr< - std::vector> - result) mutable { - if (!result.ok()) { - callback_for_local_credentials.value() - .credentials_fetched_cb(result.status()); - return; - } - for (const auto& credential : result.value()) { - if (credential.end_time_millis() >= current_time_millis) { - valid_shared_credentials.push_back(credential); - } - } - - RefillRemainingValidCredentialsWithNewCredentials( - credential_selector, valid_local_credentials, - valid_shared_credentials, - /*start_time_to_generate_new_credentials_millis=*/ - last_valid_end_time_millis, - std::move(callback_for_local_credentials), - std::move(callback_for_shared_credentials)); - }, - }); - } else { - credential_storage_ptr_->GetLocalCredentials( - credential_selector, - GetLocalCredentialsResultCallback{ - .credentials_fetched_cb = - [this, current_time_millis, last_valid_end_time_millis, - credential_selector, - valid_local_credentials = std::move(valid_local_credentials), - valid_shared_credentials = std::move(valid_shared_credentials), - callback_for_local_credentials = - std::move(callback_for_local_credentials), - callback_for_shared_credentials = - std::move(callback_for_shared_credentials)]( - absl::StatusOr< - std::vector> - result) mutable { - if (!result.ok()) { - callback_for_local_credentials.value() - .credentials_fetched_cb(result.status()); - return; - } - for (const auto& credential : result.value()) { - if (credential.end_time_millis() >= current_time_millis) { - valid_local_credentials.push_back( - credential); // RESTORE TODO - } - } - - RefillRemainingValidCredentialsWithNewCredentials( - credential_selector, valid_local_credentials, - valid_shared_credentials, - /*start_time_to_generate_new_credentials_millis=*/ - last_valid_end_time_millis, - std::move(callback_for_local_credentials), - std::move(callback_for_shared_credentials)); - }, - }); - } -} - -void CredentialManagerImpl::RefillRemainingValidCredentialsWithNewCredentials( - const CredentialSelector& credential_selector, - std::vector valid_local_credentials, - std::vector valid_shared_credentials, - int64_t start_time_to_generate_new_credentials_millis, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials) { - // The number of valid credentials has already been determined by pruning - // valid_local_credentials and valid_shared_credentials. They must match - // in size. - int valid_credentials_count = valid_local_credentials.size(); - CHECK_EQ(valid_credentials_count, valid_shared_credentials.size()); - - std::vector newly_generated_local_credentials; - std::vector newly_generated_shared_credentials; - - // Generate more credential pairs to refill the expired ones. - auto start_time = - absl::FromUnixMillis(start_time_to_generate_new_credentials_millis); - auto gap = kCredentialLifeCycleDays * absl::Hours(24); - for (int i = 0; i < kExpectedValidLocalCredtialSize - valid_credentials_count; - i++) { - auto pair = CreateLocalCredential(device_identity_metadata_, - credential_selector.identity_type, - start_time, start_time + gap); - newly_generated_local_credentials.push_back(std::move(pair.first)); - newly_generated_shared_credentials.push_back(std::move(pair.second)); - start_time += gap; - } - - // Now merge newly generated credentials to already existing valid ones. - valid_local_credentials.insert(valid_local_credentials.end(), - newly_generated_local_credentials.begin(), - newly_generated_local_credentials.end()); - valid_shared_credentials.insert(valid_shared_credentials.end(), - newly_generated_shared_credentials.begin(), - newly_generated_shared_credentials.end()); - - // Save merged local and shared credential lists to storage - credential_storage_ptr_->SaveCredentials( - credential_selector.manager_app_id, credential_selector.account_name, - valid_local_credentials, valid_shared_credentials, - PublicCredentialType::kLocalPublicCredential, - SaveCredentialsResultCallback{ - .credentials_saved_cb = - [this, valid_local_credentials, valid_shared_credentials, - callback_for_local_credentials = - std::move(callback_for_local_credentials), - callback_for_shared_credentials = - std::move(callback_for_shared_credentials)]( - absl::Status status) mutable { - OnCredentialRefillComplete( - std::move(status), valid_local_credentials, - valid_shared_credentials, - std::move(callback_for_local_credentials), - std::move(callback_for_shared_credentials)); - }, - }); -} - -void CredentialManagerImpl::OnCredentialRefillComplete( - absl::Status save_credentials_status, - std::vector valid_local_credentials, - std::vector valid_shared_credentials, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials) { - if (!save_credentials_status.ok()) { - LOG(ERROR) << "Save credentials failed with: " << save_credentials_status; - if (callback_for_local_credentials.has_value()) { - callback_for_local_credentials.value().credentials_fetched_cb( - save_credentials_status); - } else { - callback_for_shared_credentials.value().credentials_fetched_cb( - save_credentials_status); - } - return; - } - - if (callback_for_local_credentials.has_value()) { - callback_for_local_credentials.value().credentials_fetched_cb( - valid_local_credentials); - } else { - callback_for_shared_credentials.value().credentials_fetched_cb( - valid_shared_credentials); - } -} - -bool CredentialManagerImpl::WaitForLatch(absl::string_view method_name, - CountDownLatch* latch) { - Exception await_exception = latch->Await(); - if (!await_exception.Ok()) { - LOG(ERROR) << "Blocked in " << method_name - << " with exeception code: " << await_exception.value; - return false; - } - return true; -} -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/credential_manager_impl.h b/presence/implementation/credential_manager_impl.h deleted file mode 100644 index 9cd2c99e..00000000 --- a/presence/implementation/credential_manager_impl.h +++ /dev/null @@ -1,262 +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_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_IMPL_H_ - -#include -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "absl/log/die_if_null.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "absl/types/variant.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/credential_storage_impl.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/implementation/credential_manager.h" - -namespace nearby { -namespace presence { - -class CredentialManagerImpl : public CredentialManager { - public: - using IdentityType = ::nearby::internal::IdentityType; - using DeviceIdentityMetaData = ::nearby::internal::DeviceIdentityMetaData; - - explicit CredentialManagerImpl(SingleThreadExecutor* executor) - : executor_(ABSL_DIE_IF_NULL(executor)) { - credential_storage_ptr_ = std::make_unique(); - } - - // Test purpose only. - CredentialManagerImpl( - SingleThreadExecutor* executor, - std::unique_ptr credential_storage_ptr) - : executor_(ABSL_DIE_IF_NULL(executor)), - credential_storage_ptr_(std::move(credential_storage_ptr)) {} - - // AES only supports key sizes of 16, 24 or 32 bytes. - static constexpr int kAuthenticityKeyByteSize = 32; - - // Length of key in bytes required by AES-GCM encryption. - static constexpr size_t kNearbyPresenceNumBytesAesGcmKeySize = 32; - - // Modify this to 12 after use real AES. - static constexpr int kAesGcmIVSize = 12; - - void GenerateCredentials( - const DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - - void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) override; - - void UpdateLocalCredential( - const CredentialSelector& credential_selector, - nearby::internal::LocalCredential credential, - SaveCredentialsResultCallback result_callback) override; - - void GetLocalCredentials(const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) override; - - // Blocking version of `GetLocalCredentials` - nearby::ExceptionOr> - GetLocalCredentialsSync(const CredentialSelector& credential_selector, - absl::Duration timeout); - - // Used to fetch local/remote public creds based on the value of - // public_credential_type. - void GetPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) override; - - // Blocking version of `GetPublicCredentials`. - ::nearby::ExceptionOr> - GetPublicCredentialsSync(const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - absl::Duration timeout); - - SubscriberId SubscribeForPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) override; - - void UnsubscribeFromPublicCredentials(SubscriberId id) override; - - std::string DecryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string) override; - - std::pair - CreateLocalCredential(const DeviceIdentityMetaData& device_identity_metadata, - IdentityType identity_type, absl::Time start_time, - absl::Time end_time); - - nearby::internal::SharedCredential CreatePublicCredential( - const nearby::internal::LocalCredential& private_credential, - const DeviceIdentityMetaData& device_identity_metadata, - const std::vector& public_key); - - virtual std::string EncryptDeviceIdentityMetaData( - absl::string_view metadata_encryption_key, absl::string_view key_seed, - absl::string_view metadata_string); - - // Extend the key from 16 bytes to 32 bytes. - std::vector ExtendMetadataEncryptionKey( - absl::string_view metadata_encryption_key); - - void SetDeviceIdentityMetaData( - const DeviceIdentityMetaData& device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override { - device_identity_metadata_ = device_identity_metadata; - if (regen_credentials) { - GenerateCredentials(device_identity_metadata, manager_app_id, - identity_types, credential_life_cycle_days, - contiguous_copy_of_credentials, - std::move(credentials_generated_cb)); - } - } - - ::nearby::internal::DeviceIdentityMetaData GetDeviceIdentityMetaData() - override { - return device_identity_metadata_; - } - - private: - struct SubscriberKey { - CredentialSelector credential_selector; - PublicCredentialType public_credential_type; - template - friend H AbslHashValue(H h, const SubscriberKey& key) { - return H::combine(std::move(h), key.credential_selector, - key.public_credential_type); - } - friend bool operator==(const SubscriberKey& a, const SubscriberKey& b) { - return a.public_credential_type == b.public_credential_type && - a.credential_selector == b.credential_selector; - } - }; - class Subscriber { - public: - Subscriber(SubscriberId id, GetPublicCredentialsResultCallback callback) - : callback_(std::move(callback)), id_(id) {} - - SubscriberId GetId() const { return id_; } - - // Notifies the subscriber about fetched credentials. - void NotifyCredentialsFetched( - std::vector<::nearby::internal::SharedCredential>& credentials); - - private: - GetPublicCredentialsResultCallback callback_; - SubscriberId id_; - }; - - void RunOnServiceControllerThread(absl::string_view name, - Runnable&& runnable) { - executor_->Execute(std::string(name), std::move(runnable)); - } - - bool WaitForLatch(absl::string_view method_name, CountDownLatch* latch); - - // The similar flow to check-expired-then-refill-if-needed is needed in both - // GetLocalCredentials() and GetPublicCredentials(). The high level flow is: - // check if there're expired creds from the result credentials list from - // GetLocal/GetPublic, if some creds expired, prune the expired, merge with - // newly generated ones. Then get the corresponding(local/shared) creds list - // from the storage, also prune expired, merge with newly - // generated. Then finally, save the newly merged two lists (local & shared) - // to storage. For re-use purpose, this private function is made to be able - // to take in different parameters from both GetLocalCredentials() and - // GetPublicCredentials(). - void CheckCredentialsAndRefillIfNeeded( - const CredentialSelector& credential_selector, - absl::variant*, - std::vector*> - credential_list_variant, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials); - void RefillRemainingValidCredentialsWithNewCredentials( - const CredentialSelector& credential_selector, - std::vector valid_local_credentials, - std::vector valid_shared_credentials, - int64_t start_time_to_generate_new_credentials_millis, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials); - void OnCredentialRefillComplete( - absl::Status save_credentials_status, - std::vector valid_local_credentials, - std::vector valid_shared_credentials, - std::optional - callback_for_local_credentials, - std::optional - callback_for_shared_credentials); - - void OnCredentialsChanged(absl::string_view manager_app_id, - absl::string_view account_name, - PublicCredentialType credential_type) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void NotifySubscribers( - const SubscriberKey& key, - std::vector<::nearby::internal::SharedCredential> credentials) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void AddSubscriber(SubscriberKey key, SubscriberId id, - GetPublicCredentialsResultCallback callback) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void RemoveSubscriber(SubscriberId id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - absl::flat_hash_set GetSubscribedIdentities( - absl::string_view manager_app_id, absl::string_view account_name, - PublicCredentialType credential_type) const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - GetPublicCredentialsResultCallback CreateNotifySubscribersCallback( - SubscriberKey key); - - absl::flat_hash_map> subscribers_ - ABSL_GUARDED_BY(*executor_); - SingleThreadExecutor* executor_; - std::unique_ptr credential_storage_ptr_; - DeviceIdentityMetaData device_identity_metadata_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_CREDENTIAL_MANAGER_IMPL_H_ diff --git a/presence/implementation/credential_manager_impl_test.cc b/presence/implementation/credential_manager_impl_test.cc deleted file mode 100644 index 44d37659..00000000 --- a/presence/implementation/credential_manager_impl_test.cc +++ /dev/null @@ -1,721 +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 "presence/implementation/credential_manager_impl.h" - -#include -#include -#include -#include -#include - -#include "net/proto2/contrib/parse_proto/testing.h" -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/credential_storage_impl.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/logging.h" -#include "internal/platform/medium_environment.h" -#include "internal/proto/credential.pb.h" -#include "presence/implementation/base_broadcast_request.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::CountDownLatch; -using ::nearby::Crypto; -using ::nearby::MediumEnvironment; -using ::nearby::internal::IdentityType; -using ::nearby::internal::LocalCredential; - -using ::nearby::internal::DeviceIdentityMetaData; -using ::nearby::internal::SharedCredential; -using ::nearby::internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP; -using ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; -using ::protobuf_matchers::EqualsProto; -using ::testing::UnorderedPointwise; -using ::testing::status::StatusIs; - -constexpr absl::string_view kManagerAppId = "TEST_MANAGER_APP"; -constexpr absl::string_view kAccountName = ""; -constexpr int kExpectedPresenceCredentialListSize = 6; -constexpr int kExpectedPresenceCredentialValidDays = 5; - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_PHONE); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address("FF:FF:FF:FF:FF:FF"); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} - -CredentialSelector BuildDefaultCredentialSelector() { - CredentialSelector credential_selector; - credential_selector.manager_app_id = std::string(kManagerAppId); - credential_selector.account_name = std::string(kAccountName); - credential_selector.identity_type = IDENTITY_TYPE_PRIVATE_GROUP; - return credential_selector; -} - -class CredentialManagerImplTest : public ::testing::Test { - public: - class MockCredentialStorage : public nearby::CredentialStorageImpl { - public: - MOCK_METHOD(void, SaveCredentials, - (absl::string_view manager_app_id, - absl::string_view account_name, - const std::vector& private_credentials, - const std::vector& public_credentials, - PublicCredentialType public_credential_type, - SaveCredentialsResultCallback callback), - (override)); - MOCK_METHOD( - void, GetPublicCredentials, - (const ::nearby::presence::CredentialSelector& credential_selector, - ::nearby::presence::PublicCredentialType public_credential_type, - ::nearby::presence::GetPublicCredentialsResultCallback callback), - (override)); - }; - - class FakeCredentialStorage : public nearby::CredentialStorageImpl { - public: - // nearby::CredentialStorageImpl: - void SaveCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& private_credentials, - const std::vector& public_credentials, - PublicCredentialType public_credential_type, - SaveCredentialsResultCallback callback) override { - // Capture the credentials before actually saving them, so that they - // can be manipulated later on. - private_credentials_ = private_credentials; - public_credentials_ = public_credentials; - - nearby::CredentialStorageImpl::SaveCredentials( - manager_app_id, account_name, private_credentials, public_credentials, - public_credential_type, std::move(callback)); - } - void GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) override { - if (private_credentials_.has_value()) { - callback.credentials_fetched_cb(private_credentials_.value()); - } else { - nearby::CredentialStorageImpl::GetLocalCredentials(credential_selector, - std::move(callback)); - } - } - void GetPublicCredentials( - const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) override { - if (public_credentials_.has_value()) { - callback.credentials_fetched_cb(public_credentials_.value()); - } else { - nearby::CredentialStorageImpl::GetPublicCredentials( - credential_selector, public_credential_type, std::move(callback)); - } - } - - std::optional> - public_credentials_; - std::optional> - private_credentials_; - }; - - class MockCredentialManager : public CredentialManagerImpl { - public: - explicit MockCredentialManager(SingleThreadExecutor* executor) - : CredentialManagerImpl(executor) {} - MOCK_METHOD(std::string, EncryptDeviceIdentityMetaData, - (absl::string_view metadata_encryption_key, - absl::string_view key_seed, absl::string_view metadata_string), - (override)); - }; - - ~CredentialManagerImplTest() override { executor_.Shutdown(); } - - // Waits for active tasks in the background thread to complete. - void Fence() { - // A runnable on medium environment thread can add a task on "our" executor, - // and vice-versa. We need to wait for tasks on both threads in a loop a few - // times to make sure that all tasks have finished. - for (int i = 0; i < 3; i++) { - MediumEnvironment::Instance().Sync(); - CountDownLatch latch(1); - executor_.Execute([&]() { latch.CountDown(); }); - latch.Await(); - } - } - - void AddLocalIdentity(absl::string_view manager_app_id, - absl::string_view account_name, - IdentityType identity_type) { - auto public_credentials = GenerateCredentialsSync( - CreateTestDeviceIdentityMetaData(), manager_app_id, {identity_type}, - /*credential_life_cycle_days=*/kExpectedPresenceCredentialValidDays, - /*contiguous_copy_of_credentials=*/1); - EXPECT_OK(public_credentials); - } - - absl::StatusOr> GenerateCredentialsSync( - const DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials) { - absl::StatusOr> public_credentials; - - CountDownLatch latch(1); - credential_manager_.GenerateCredentials( - device_identity_metadata, manager_app_id, identity_types, - credential_life_cycle_days, contiguous_copy_of_credentials, - {.credentials_generated_cb = - [&](absl::StatusOr> credentials) { - public_credentials = credentials; - latch.CountDown(); - }}); - EXPECT_TRUE(latch.Await().Ok()); - - return public_credentials; - } - - std::vector GetLocalCredentialsSync( - CredentialSelector credential_selector) { - auto private_credentials = credential_manager_.GetLocalCredentialsSync( - credential_selector, absl::Seconds(1)); - EXPECT_TRUE(private_credentials.ok()); - return private_credentials.GetResult(); - } - - std::vector GetPublicCredentialsSync( - CredentialSelector credential_selector, - PublicCredentialType public_credential_type) { - auto public_credentials = credential_manager_.GetPublicCredentialsSync( - credential_selector, public_credential_type, absl::Seconds(1)); - EXPECT_TRUE(public_credentials.ok()); - return public_credentials.GetResult(); - } - - protected: - SingleThreadExecutor executor_; - CredentialManagerImpl credential_manager_{&executor_}; - MockCredentialManager mock_credential_manager_{&executor_}; -}; - -TEST_F(CredentialManagerImplTest, CreateOneCredentialSuccessfully) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - constexpr absl::Time kStartTime = absl::FromUnixSeconds(100000); - constexpr absl::Time kEndTime = absl::FromUnixSeconds(200000); - - auto credentials = credential_manager_.CreateLocalCredential( - device_identity_metadata, IDENTITY_TYPE_PRIVATE_GROUP, kStartTime, - kEndTime); - - LocalCredential private_credential = credentials.first; - // Verify the private credential. - EXPECT_EQ(private_credential.identity_type(), IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_NE(private_credential.id(), 0); - EXPECT_EQ(private_credential.start_time_millis(), - absl::ToUnixMillis(kStartTime)); - EXPECT_EQ(private_credential.end_time_millis(), absl::ToUnixMillis(kEndTime)); - EXPECT_EQ(private_credential.key_seed().size(), - CredentialManagerImpl::kAuthenticityKeyByteSize); - EXPECT_FALSE(private_credential.connection_signing_key().key().empty()); - EXPECT_EQ(private_credential.metadata_encryption_key_v0().size(), - kBaseMetadataSize); - - SharedCredential public_credential = credentials.second; - // Verify the public credential. - EXPECT_EQ(public_credential.identity_type(), IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_NE(public_credential.id(), 0); - EXPECT_EQ(private_credential.id(), public_credential.id()); - EXPECT_EQ(private_credential.key_seed(), public_credential.key_seed()); - EXPECT_LE(public_credential.start_time_millis(), - absl::ToUnixMillis(kStartTime)); - EXPECT_GE(public_credential.start_time_millis(), - absl::ToUnixMillis(kStartTime - absl::Hours(3))); - EXPECT_GE(public_credential.end_time_millis(), absl::ToUnixMillis(kEndTime)); - EXPECT_LE(public_credential.end_time_millis(), - absl::ToUnixMillis(kEndTime + absl::Hours(3))); - EXPECT_EQ(Crypto::Sha256(private_credential.metadata_encryption_key_v0()) - .AsStringView(), - public_credential.metadata_encryption_key_tag_v0()); - EXPECT_FALSE( - public_credential.connection_signature_verification_key().empty()); - EXPECT_FALSE(public_credential.encrypted_metadata_bytes_v0().empty()); - - auto decrypted_metadata = credential_manager_.DecryptDeviceIdentityMetaData( - private_credential.metadata_encryption_key_v0(), - public_credential.key_seed(), - public_credential.encrypted_metadata_bytes_v0()); - - EXPECT_EQ(device_identity_metadata.SerializeAsString(), decrypted_metadata); -} - -TEST_F(CredentialManagerImplTest, GenerateCredentialsSuccessfully) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identityTypes{IDENTITY_TYPE_PRIVATE_GROUP}; - absl::Time previous_start_time; - absl::Time previous_end_time; - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identityTypes, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - EXPECT_OK(public_credentials); - EXPECT_EQ(public_credentials->size(), kExpectedPresenceCredentialListSize); - - for (int i = 0; i < kExpectedPresenceCredentialListSize; i++) { - SharedCredential& public_credential = public_credentials->at(i); - EXPECT_EQ(public_credential.identity_type(), IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_NE(public_credential.id(), 0); - absl::Time start_time_millis = - absl::FromUnixMillis(public_credential.start_time_millis()); - absl::Time end_time_millis = - absl::FromUnixMillis(public_credential.end_time_millis()); - if (i > 0) { - EXPECT_GT(start_time_millis, previous_start_time); - EXPECT_GE(previous_end_time, start_time_millis); - EXPECT_GT(end_time_millis, previous_end_time); - } - EXPECT_LT(start_time_millis + - absl::Hours(24) * kExpectedPresenceCredentialValidDays, - end_time_millis); - EXPECT_FALSE(public_credential.encrypted_metadata_bytes_v0().empty()); - previous_start_time = start_time_millis; - previous_end_time = end_time_millis; - } -} - -TEST_F(CredentialManagerImplTest, - SubscribeCallsCallbackWithExistingCredentials) { - absl::StatusOr> public_credentials1; - absl::StatusOr> public_credentials2; - AddLocalIdentity(kManagerAppId, kAccountName, IDENTITY_TYPE_PRIVATE_GROUP); - - SubscriberId id1 = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{.manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials1 = std::move(credentials); - }}); - SubscriberId id2 = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{.manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials2 = std::move(credentials); - }}); - - Fence(); - EXPECT_OK(public_credentials1); - EXPECT_OK(public_credentials2); - EXPECT_EQ(public_credentials1->size(), kExpectedPresenceCredentialListSize); - EXPECT_EQ(public_credentials2->size(), kExpectedPresenceCredentialListSize); - // Cleanup - credential_manager_.UnsubscribeFromPublicCredentials(id1); - credential_manager_.UnsubscribeFromPublicCredentials(id2); - Fence(); -} - -TEST_F(CredentialManagerImplTest, - SubscribeCallsCallbackWithUpdatedCredentials) { - absl::StatusOr> public_credentials; - - SubscriberId id = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{.manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials = std::move(credentials); - }}); - Fence(); - EXPECT_THAT(public_credentials, StatusIs(absl::StatusCode::kUnknown)); - - AddLocalIdentity(kManagerAppId, kAccountName, IDENTITY_TYPE_PRIVATE_GROUP); - - Fence(); - ASSERT_OK(public_credentials); - EXPECT_EQ(public_credentials->size(), kExpectedPresenceCredentialListSize); - // Cleanup - credential_manager_.UnsubscribeFromPublicCredentials(id); - Fence(); -} - -TEST_F(CredentialManagerImplTest, NoCallbacksAfterUnsubscribe) { - absl::StatusOr> public_credentials; - SubscriberId id = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{.manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials = std::move(credentials); - }}); - - credential_manager_.UnsubscribeFromPublicCredentials(id); - AddLocalIdentity(kManagerAppId, kAccountName, IDENTITY_TYPE_PRIVATE_GROUP); - - Fence(); - EXPECT_THAT(public_credentials, StatusIs(absl::StatusCode::kUnknown)); -} - -TEST_F(CredentialManagerImplTest, - GenerateCredentialsSuccessfullyButStoreFailed) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - auto credential_storage_ptr = - std::make_unique(); - EXPECT_CALL(*credential_storage_ptr, SaveCredentials) - .WillOnce(::testing::Invoke( - [](absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& private_credentials, - const std::vector& public_credentials, - PublicCredentialType public_credential_type, - SaveCredentialsResultCallback callback) { - callback.credentials_saved_cb( - absl::FailedPreconditionError("Expected failure")); - })); - credential_manager_ = - CredentialManagerImpl(&executor_, std::move(credential_storage_ptr)); - std::vector identityTypes{IDENTITY_TYPE_PRIVATE_GROUP}; - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identityTypes, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - EXPECT_THAT(public_credentials, - StatusIs(absl::StatusCode::kFailedPrecondition)); -} - -TEST_F(CredentialManagerImplTest, UpdateRemotePublicCredentialsSuccessfully) { - SharedCredential public_credential_for_test; - public_credential_for_test.set_identity_type( - IdentityType::IDENTITY_TYPE_CONTACTS_GROUP); - std::vector public_credentials{ - {public_credential_for_test}}; - - nearby::CountDownLatch updated_latch(1); - UpdateRemotePublicCredentialsCallback update_credentials_cb{ - .credentials_updated_cb = - [&updated_latch](absl::Status status) { - if (status.ok()) { - updated_latch.CountDown(); - } - }, - }; - - credential_manager_.UpdateRemotePublicCredentials( - kManagerAppId, kAccountName, public_credentials, - std::move(update_credentials_cb)); - - EXPECT_TRUE(updated_latch.Await().Ok()); -} - -TEST_F(CredentialManagerImplTest, - UpdateRemotePublicCredentialsNotifiesSubscribers) { - absl::StatusOr> subscribed_credentials; - SharedCredential public_credential_for_test; - public_credential_for_test.set_identity_type( - IdentityType::IDENTITY_TYPE_PRIVATE_GROUP); - std::vector public_credentials{ - {public_credential_for_test}}; - nearby::CountDownLatch updated_latch(1); - UpdateRemotePublicCredentialsCallback update_credentials_cb{ - .credentials_updated_cb = - [&updated_latch](absl::Status status) { - if (status.ok()) { - updated_latch.CountDown(); - } - }, - }; - SubscriberId id1 = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{ - .manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = internal::IDENTITY_TYPE_PRIVATE_GROUP}, - PublicCredentialType::kRemotePublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - subscribed_credentials = std::move(credentials); - }}); - SubscriberId id2 = credential_manager_.SubscribeForPublicCredentials( - CredentialSelector{ - .manager_app_id = std::string(kManagerAppId), - .account_name = std::string(kAccountName), - .identity_type = internal::IDENTITY_TYPE_CONTACTS_GROUP}, - PublicCredentialType::kRemotePublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - // This callback should not be called because there are no Trusted - // credentials in this test. - GTEST_FAIL(); - }}); - - credential_manager_.UpdateRemotePublicCredentials( - kManagerAppId, kAccountName, public_credentials, - std::move(update_credentials_cb)); - - EXPECT_TRUE(updated_latch.Await().Ok()); - Fence(); - EXPECT_OK(subscribed_credentials); - EXPECT_EQ(subscribed_credentials->size(), 1); - credential_manager_.UnsubscribeFromPublicCredentials(id1); - credential_manager_.UnsubscribeFromPublicCredentials(id2); -} - -TEST_F(CredentialManagerImplTest, GetLocalCredentialsFailed) { - absl::StatusOr> private_credentials; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - credential_manager_.GetLocalCredentials( - credential_selector, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - private_credentials = std::move(credentials); - }}); - - EXPECT_THAT(private_credentials, StatusIs(absl::StatusCode::kNotFound)); -} - -TEST_F(CredentialManagerImplTest, GetPublicCredentialsFailed) { - absl::StatusOr> public_credentials; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - CountDownLatch latch(1); - credential_manager_.GetPublicCredentials( - credential_selector, PublicCredentialType::kLocalPublicCredential, - {.credentials_fetched_cb = - [&](absl::StatusOr> credentials) { - public_credentials = std::move(credentials); - latch.CountDown(); - }}); - EXPECT_TRUE(latch.Await().Ok()); - - EXPECT_THAT(public_credentials, StatusIs(absl::StatusCode::kNotFound)); -} - -TEST_F(CredentialManagerImplTest, GetCredentialsSuccessfully) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - EXPECT_OK(public_credentials); - EXPECT_EQ(public_credentials->size(), kExpectedPresenceCredentialListSize); - - auto private_credentials = GetLocalCredentialsSync(credential_selector); - EXPECT_FALSE(private_credentials.empty()); -} - -TEST_F(CredentialManagerImplTest, PublicCredentialsFailEncryption) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - absl::StatusOr> public_credentials; - auto credential_manager_ptr = - std::make_unique( - &executor_); - EXPECT_CALL(*credential_manager_ptr, EncryptDeviceIdentityMetaData) - .WillOnce(::testing::Invoke( - [](absl::string_view metadata_encryption_key, - absl::string_view key_seed, - absl::string_view metadata_string) { return ""; })); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - - CountDownLatch latch(1); - credential_manager_ptr->GenerateCredentials( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, 1, - {.credentials_generated_cb = - [&](absl::StatusOr> credentials) { - public_credentials = std::move(credentials); - latch.CountDown(); - }}); - EXPECT_TRUE(latch.Await().Ok()); - - EXPECT_THAT(public_credentials, StatusIs(absl::StatusCode::kInvalidArgument)); -} - -TEST_F(CredentialManagerImplTest, UpdateLocalCredential) { - constexpr int kSelectedCredentialId = 2; - constexpr uint16_t kSalt = 1000; - absl::Status update_status = absl::UnknownError(""); - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP, - IDENTITY_TYPE_CONTACTS_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - - auto private_credentials = GetLocalCredentialsSync(credential_selector); - EXPECT_EQ(kExpectedPresenceCredentialListSize, private_credentials.size()); - - ASSERT_OK(public_credentials); - - // Modify a private credential - auto credential = private_credentials.at(kSelectedCredentialId); - EXPECT_TRUE( - private_credentials.at(kSelectedCredentialId).consumed_salts().empty()); - credential.mutable_consumed_salts()->insert({kSalt, true}); - - credential_manager_.UpdateLocalCredential( - credential_selector, credential, - {[&](absl::Status status) { update_status = status; }}); - - EXPECT_OK(update_status); - - // Verify that the modified credential has the new field in the new - // retrieved list of credentials. - auto modified_private_credentials = - GetLocalCredentialsSync(credential_selector); - EXPECT_TRUE(modified_private_credentials.at(kSelectedCredentialId) - .consumed_salts() - .at(kSalt)); -} - -TEST_F(CredentialManagerImplTest, EncryptAndDecryptDeviceIdentityMetaData) { - constexpr absl::string_view kMetadataEncryptionKeyBase16 = - "6331578C6E244074111B2ED0BBDB"; - constexpr absl::string_view kSeed = "123456"; - - auto encrypted_meta_data = credential_manager_.EncryptDeviceIdentityMetaData( - kMetadataEncryptionKeyBase16, kSeed, - CreateTestDeviceIdentityMetaData().SerializeAsString()); - - auto decrypted_meta_data = credential_manager_.DecryptDeviceIdentityMetaData( - kMetadataEncryptionKeyBase16, kSeed, encrypted_meta_data); - - DeviceIdentityMetaData device_identity_metadata; - ASSERT_TRUE(device_identity_metadata.ParseFromString(decrypted_meta_data)); - EXPECT_EQ(device_identity_metadata.device_id(), "\x12\xab\xcd"); - EXPECT_EQ(device_identity_metadata.device_type(), - internal::DeviceType::DEVICE_TYPE_PHONE); - EXPECT_EQ(device_identity_metadata.device_name(), "NP test device"); - EXPECT_EQ(device_identity_metadata.bluetooth_mac_address(), - "FF:FF:FF:FF:FF:FF"); -} - -TEST_F(CredentialManagerImplTest, RefillCredentialsInGetLocalCredentials) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, 1); - - EXPECT_OK(public_credentials); - EXPECT_EQ(1, public_credentials->size()); - - // only generate 1 creds, expecting GetLocal would trigger refill to - // kExpectedPresenceCredentialListSize. - auto private_credentials = GetLocalCredentialsSync(credential_selector); - EXPECT_EQ(kExpectedPresenceCredentialListSize, private_credentials.size()); -} - -TEST_F(CredentialManagerImplTest, RefillCredentialsInGetSharedCredentials) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, 1); - EXPECT_OK(public_credentials); - EXPECT_EQ(1, public_credentials->size()); - - // Only generated 1 creds, expecting GetPublicCredentials for - // kLocalPublicCredential type would trigger refill to - // kExpectedPresenceCredentialListSize. - auto refilled_public_credentials = GetPublicCredentialsSync( - credential_selector, PublicCredentialType::kLocalPublicCredential); - EXPECT_EQ(kExpectedPresenceCredentialListSize, - refilled_public_credentials.size()); -} - -TEST_F(CredentialManagerImplTest, RefillExpiredCredsInGetLocal) { - auto device_identity_metadata = CreateTestDeviceIdentityMetaData(); - std::vector identity_types{IDENTITY_TYPE_PRIVATE_GROUP}; - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - auto credential_storage = - std::make_unique(); - auto* credential_storage_ptr = credential_storage.get(); - credential_manager_ = - CredentialManagerImpl(&executor_, std::move(credential_storage)); - - auto public_credentials = GenerateCredentialsSync( - device_identity_metadata, kManagerAppId, identity_types, - kExpectedPresenceCredentialValidDays, - kExpectedPresenceCredentialListSize); - - ASSERT_OK(public_credentials); - EXPECT_EQ(public_credentials->size(), kExpectedPresenceCredentialListSize); - - // Now that we have generated kExpectedPresenceCredentialListSize valid creds, - // tweak the first credential's end time, in both credential lists, to - // make them expired. - auto expiry_time = absl::ToUnixMillis(absl::Now() - absl::Hours(1)); - credential_storage_ptr->private_credentials_.value() - .at(0) - .set_end_time_millis(expiry_time); - credential_storage_ptr->public_credentials_.value().at(0).set_end_time_millis( - expiry_time); - - auto old_private_credentials = - credential_storage_ptr->private_credentials_.value(); - - auto refilled_private_credentials = - GetLocalCredentialsSync(credential_selector); - EXPECT_EQ(kExpectedPresenceCredentialListSize, - refilled_private_credentials.size()); - - // Verifying the expired one private_credentials->at(0) is pruned in the new - // list. - EXPECT_EQ(old_private_credentials.at(1).secret_id(), - refilled_private_credentials.at(0).secret_id()); - // Verifying the new generated cred's start time is the same as previously - // existing list's last cred's end time. - EXPECT_EQ( - old_private_credentials.at(5).end_time_millis(), - refilled_private_credentials.at(kExpectedPresenceCredentialListSize - 1) - .start_time_millis()); -} - -} // namespace - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/ldt.cc b/presence/implementation/ldt.cc deleted file mode 100644 index 28eac763..00000000 --- a/presence/implementation/ldt.cc +++ /dev/null @@ -1,109 +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 "presence/implementation/ldt.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_format.h" -#include "absl/strings/string_view.h" -#ifdef NEARBY_CHROMIUM -#include "third_party/nearby/src/presence/implementation/np_ldt.h" -#else -#include "np_ldt.h" -#endif - -namespace nearby { -namespace presence { - -namespace { -// NP LDT library says that 0 is returned when `NpLdtCreate()` fails. -constexpr uint64_t kInvalidLdtHandle = 0; - -template -T FromStringView(absl::string_view data) { - T result{ - .bytes = {0}, - }; - memcpy(result.bytes, data.data(), - std::min(sizeof(result.bytes), data.size())); - return result; -} -} // namespace - -LdtEncryptor::LdtEncryptor(LdtEncryptor&& other) - : ldt_encrypt_handle_(other.ldt_encrypt_handle_), - ldt_decrypt_handle_(other.ldt_decrypt_handle_) { - other.ldt_encrypt_handle_.handle = kInvalidLdtHandle; - other.ldt_decrypt_handle_.handle = kInvalidLdtHandle; -} - -LdtEncryptor::~LdtEncryptor() { - if (ldt_encrypt_handle_.handle != kInvalidLdtHandle) { - NpLdtEncryptClose(ldt_encrypt_handle_); - } - if (ldt_decrypt_handle_.handle != kInvalidLdtHandle) { - NpLdtDecryptClose(ldt_decrypt_handle_); - } -} - -absl::StatusOr LdtEncryptor::Create( - absl::string_view key_seed, absl::string_view known_hmac) { - NpLdtEncryptHandle encrypt_handle = - NpLdtEncryptCreate(FromStringView(key_seed)); - NpLdtDecryptHandle decrypt_handle = - NpLdtDecryptCreate(FromStringView(key_seed), - FromStringView(known_hmac)); - if (encrypt_handle.handle == kInvalidLdtHandle) { - return absl::UnavailableError("Failed to create LDT encryptor"); - } - if (decrypt_handle.handle == kInvalidLdtHandle) { - return absl::UnavailableError("Failed to create LDT decrypter"); - } - - return LdtEncryptor(encrypt_handle, decrypt_handle); -} - -absl::StatusOr LdtEncryptor::Encrypt(absl::string_view data, - absl::string_view salt) { - std::string encrypted = std::string(data); - NP_LDT_RESULT result = NpLdtEncrypt( - ldt_encrypt_handle_, reinterpret_cast(encrypted.data()), - encrypted.size(), FromStringView(salt)); - if (result == NP_LDT_SUCCESS) { - return encrypted; - } - return absl::InternalError( - absl::StrFormat("LDT encryption failed, errorcode %d", result)); -} - -absl::StatusOr LdtEncryptor::DecryptAndVerify( - absl::string_view data, absl::string_view salt) { - std::string encrypted = std::string(data); - NP_LDT_RESULT result = NpLdtDecryptAndVerify( - ldt_decrypt_handle_, reinterpret_cast(encrypted.data()), - encrypted.size(), FromStringView(salt)); - if (result == NP_LDT_SUCCESS) { - return encrypted; - } - return absl::InternalError( - absl::StrFormat("LDT encryption failed, errorcode %d", result)); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/ldt.h b/presence/implementation/ldt.h deleted file mode 100644 index d86ecc10..00000000 --- a/presence/implementation/ldt.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_PRESENCE_IMPLEMENTATION_LDT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_LDT_H_ - -#include -#include - -#ifdef NEARBY_CHROMIUM -#include "third_party/nearby/src/presence/implementation/np_ldt.h" -#else -#include "np_ldt.h" -#endif - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" - -namespace nearby { -namespace presence { - -// C++ abstraction on top of LDT C API. -class LdtEncryptor { - public: - LdtEncryptor(const LdtEncryptor&) = delete; - LdtEncryptor(LdtEncryptor&& other); - LdtEncryptor& operator=(const LdtEncryptor&) = delete; - LdtEncryptor& operator=(LdtEncryptor&& other) { - std::swap(ldt_encrypt_handle_, other.ldt_encrypt_handle_); - std::swap(ldt_decrypt_handle_, other.ldt_decrypt_handle_); - return *this; - } - ~LdtEncryptor(); - - // Creates an instance of `LdtEncryptor`. - // `key_seed` is used to generate LDT encryption and decryption keys. - // `known_hmac` is used during decryption to verify if the message was - // encrypted with the expected key. - static absl::StatusOr Create(absl::string_view key_seed, - absl::string_view known_hmac); - - // Encrypts `data`, which must be 16 - 31 bytes long. - absl::StatusOr Encrypt(absl::string_view data, - absl::string_view salt); - - // Decrypts `data` and verifies if it was encrypted with a key generated from - // `key_seed`. - absl::StatusOr DecryptAndVerify(absl::string_view data, - absl::string_view salt); - - private: - explicit LdtEncryptor(NpLdtEncryptHandle ldt_encrypt_handle, - NpLdtDecryptHandle ldt_decrypt_handle) - : ldt_encrypt_handle_(ldt_encrypt_handle), - ldt_decrypt_handle_(ldt_decrypt_handle) {} - // An opaque handle to the underlying LDT implementation. It can be null iff - // this object has already been destroyed. - NpLdtEncryptHandle ldt_encrypt_handle_; - NpLdtDecryptHandle ldt_decrypt_handle_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_LDT_H_ diff --git a/presence/implementation/ldt_stub.c b/presence/implementation/ldt_stub.c deleted file mode 100644 index cc930bd5..00000000 --- a/presence/implementation/ldt_stub.c +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT 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 "presence/implementation/np_ldt.h" - -// Placeholder, empty implementations of LDT utilities. They will be replaced -// with implementations in Rust. - -NpLdtEncryptHandle NpLdtEncryptCreate(NpLdtKeySeed key_seed) { - NpLdtEncryptHandle handle = {0}; - return handle; -} - -NpLdtDecryptHandle NpLdtDecryptCreate(NpLdtKeySeed key_seed, - NpMetadataKeyHmac hmac_tag) { - NpLdtDecryptHandle handle = {0}; - return handle; -} - -NP_LDT_RESULT NpLdtEncryptClose(NpLdtEncryptHandle handle) { - return NP_LDT_SUCCESS; -} - -NP_LDT_RESULT NpLdtDecryptClose(NpLdtDecryptHandle handle) { - return NP_LDT_SUCCESS; -} - -NP_LDT_RESULT NpLdtEncrypt(NpLdtEncryptHandle handle, uint8_t* buffer, - size_t buffer_len, NpLdtSalt salt) { - return NP_LDT_SUCCESS; -} - -NP_LDT_RESULT NpLdtDecryptAndVerify(NpLdtDecryptHandle handle, uint8_t* buffer, - size_t buffer_len, NpLdtSalt salt) { - return NP_LDT_SUCCESS; -} \ No newline at end of file diff --git a/presence/implementation/ldt_test.cc b/presence/implementation/ldt_test.cc deleted file mode 100644 index b574cc7d..00000000 --- a/presence/implementation/ldt_test.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 "presence/implementation/ldt.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/statusor.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "internal/platform/byte_array.h" - -namespace nearby { -namespace presence { - -namespace { -using ::nearby::ByteArray; - -// Test data from Android tests. -constexpr absl::string_view kKeySeedBase16 = - "CCDB2489E9FCAC42B39348B8941ED19A1D360E75E098C8C15E6B1CC2B620CD39"; -constexpr absl::string_view kKnownMacBase16 = - "B4C59FA599241B81758D976B5A621C05232FE1BF89AE5987CA254C3554DCE50E"; -constexpr absl::string_view kPlainTextBase16 = - "CD683FE1A1D1F846543D0A13D4AEA40040C8D67B"; -constexpr absl::string_view kCipherTextBase16 = - "61E481C12F4DE24F2D4AB22D8908F80D3A3F9B40"; -constexpr absl::string_view kSaltBase16 = "0C0F"; - -TEST(Ldt, EncryptAndDecrypt) { - // Test data copied from NP LDT tests - ByteArray seed({204, 219, 36, 137, 233, 252, 172, 66, 179, 147, 72, - 184, 148, 30, 209, 154, 29, 54, 14, 117, 224, 152, - 200, 193, 94, 107, 28, 194, 182, 32, 205, 57}); - ByteArray known_mac({0xB4, 0xC5, 0x9F, 0xA5, 0x99, 0x24, 0x1B, 0x81, - 0x75, 0x8D, 0x97, 0x6B, 0x5A, 0x62, 0x1C, 0x05, - 0x23, 0x2F, 0xE1, 0xBF, 0x89, 0xAE, 0x59, 0x87, - 0xCA, 0x25, 0x4C, 0x35, 0x54, 0xDC, 0xE5, 0x0E}); - ByteArray test_data({205, 104, 63, 225, 161, 209, 248, 70, 84, 61, - 10, 19, 212, 174, 164, 0, 64, 200, 214, 123}); - ByteArray salt({12, 15}); - - absl::StatusOr encryptor = - LdtEncryptor::Create(seed.AsStringView(), known_mac.AsStringView()); - ASSERT_OK(encryptor); - absl::StatusOr encrypted = - encryptor->Encrypt(test_data.AsStringView(), salt.AsStringView()); - ASSERT_OK(encrypted); - absl::StatusOr decrypted = - encryptor->DecryptAndVerify(*encrypted, salt.AsStringView()); - ASSERT_OK(decrypted); - EXPECT_EQ(*decrypted, test_data.AsStringView()); -} - -TEST(Ldt, EncryptAndroidData) { - absl::StatusOr encryptor = - LdtEncryptor::Create(absl::HexStringToBytes(kKeySeedBase16), - absl::HexStringToBytes(kKnownMacBase16)); - ASSERT_OK(encryptor); - - absl::StatusOr encrypted = - encryptor->Encrypt(absl::HexStringToBytes(kPlainTextBase16), - absl::HexStringToBytes(kSaltBase16)); - - ASSERT_OK(encrypted); - EXPECT_EQ(*encrypted, absl::HexStringToBytes(kCipherTextBase16)); -} - -TEST(Ldt, DecryptAndroidData) { - absl::StatusOr encryptor = - LdtEncryptor::Create(absl::HexStringToBytes(kKeySeedBase16), - absl::HexStringToBytes(kKnownMacBase16)); - ASSERT_OK(encryptor); - - absl::StatusOr decrypted = - encryptor->DecryptAndVerify(absl::HexStringToBytes(kCipherTextBase16), - absl::HexStringToBytes(kSaltBase16)); - - ASSERT_OK(decrypted); - EXPECT_EQ(*decrypted, absl::HexStringToBytes(kPlainTextBase16)); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/mediums/BUILD b/presence/implementation/mediums/BUILD deleted file mode 100644 index 80dc9214..00000000 --- a/presence/implementation/mediums/BUILD +++ /dev/null @@ -1,70 +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. - -load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") - -licenses(["notice"]) - -cc_library( - name = "mediums", - srcs = [ - ], - hdrs = [ - "advertisement_data.h", - "ble.h", - "mediums.h", - ], - visibility = [ - "//presence:__subpackages__", - ], - deps = [ - "//internal/platform:base", - "//internal/platform:comm", - "//internal/platform:uuid", - "//internal/platform/implementation:comm", - "//presence:types", - ], -) - -cc_test( - name = "mediums_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:uuid", - "//internal/platform/implementation:comm", - "//presence:types", - "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/status", - "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", - "@com_google_googletest//:gtest_main", - ] + select({ - "@platforms//os:windows": [ - "//internal/platform/implementation/windows", - ], - "//conditions:default": [ - "//internal/platform/implementation/g3", - ], - }), -) diff --git a/presence/implementation/mediums/advertisement_data.h b/presence/implementation/mediums/advertisement_data.h deleted file mode 100644 index 654f89b9..00000000 --- a/presence/implementation/mediums/advertisement_data.h +++ /dev/null @@ -1,34 +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_PRESENCE_IMPLEMENTATION_MEDIUMS_ADVERTISEMENT_DATA_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_ADVERTISEMENT_DATA_H_ - -#include - -namespace nearby { -namespace presence { - -// Nearby Presence advertisement data over the air. -struct AdvertisementData { - // If true, the advertisement needs to be broadcasted over BLE 5.0. - bool is_extended_advertisement; - // The advertised data. - std::string content; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_ADVERTISEMENT_DATA_H_ diff --git a/presence/implementation/mediums/ble.h b/presence/implementation/mediums/ble.h deleted file mode 100644 index 715c0b9b..00000000 --- a/presence/implementation/mediums/ble.h +++ /dev/null @@ -1,111 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_BLE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_BLE_H_ - -#include -#include - -#include "internal/platform/ble.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/uuid.h" -#include "presence/implementation/mediums/advertisement_data.h" -#include "presence/power_mode.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -/** Presence advertisement service data uuid. */ -ABSL_CONST_INIT const nearby::Uuid kPresenceServiceUuid(0x0000fcf100001000, - 0x800000805f9b34fb); - -/* - * This Ble class utilizes platform/ble BleMedium, provides ble functions - * for presence logic layer to invoke. - * This class would have states like if ble is available or not, if it's doing - * broadcast/scan. - */ -class Ble { - public: - using TxPowerLevel = ::nearby::api::ble::TxPowerLevel; - using ScanningSession = ::nearby::api::ble::BleMedium::ScanningSession; - using ScanningCallback = ::nearby::api::ble::BleMedium::ScanningCallback; - using AdvertiseParameters = ::nearby::api::ble::AdvertiseParameters; - using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; - using AdvertisingCallback = - ::nearby::api::ble::BleMedium::AdvertisingCallback; - using BleAdvertisementData = ::nearby::api::ble::BleAdvertisementData; - using BleMedium = ::nearby::api::ble::BleMedium; - - explicit Ble(nearby::BluetoothAdapter& bluetooth_adapter) - : medium_(bluetooth_adapter) {} - - bool IsAvailable() const { return medium_.IsValid(); } - - // Starts broadcasting NP advertisement in `payload`. The caller should use - // the returned `AdvertisingSession` to stop the broadcast. - std::unique_ptr StartAdvertising( - const AdvertisementData& payload, PowerMode power_mode, - AdvertisingCallback callback) { - BleAdvertisementData advertising_data = { - .is_extended_advertisement = payload.is_extended_advertisement}; - advertising_data.service_data.insert( - {kPresenceServiceUuid, nearby::ByteArray(payload.content)}); - AdvertiseParameters advertise_set_parameters = { - .tx_power_level = ConvertPowerModeToPowerLevel(power_mode), - .is_connectable = true, - }; - return medium_.StartAdvertising(advertising_data, advertise_set_parameters, - std::move(callback)); - } - - // Starts scanning for NP advertisements. The caller should use the returned - // `ScanningSession` to stop scanning. - std::unique_ptr StartScanning(ScanRequest scan_request, - ScanningCallback callback) { - return medium_.StartScanning( - kPresenceServiceUuid, - ConvertPowerModeToPowerLevel(scan_request.power_mode), - std::move(callback)); - } - - // Provides access to platform implementation. It's used in tests. - BleMedium* GetImpl() const { return medium_.GetImpl(); } - - private: - TxPowerLevel ConvertPowerModeToPowerLevel(PowerMode power_mode) { - switch (power_mode) { - case PowerMode::kNoPower: - return TxPowerLevel::kUnknown; - case PowerMode::kLowPower: - return TxPowerLevel::kLow; - case PowerMode::kBalanced: - return TxPowerLevel::kMedium; - case PowerMode::kLowLatency: - return TxPowerLevel::kHigh; - } - return TxPowerLevel::kUnknown; - } - - nearby::BleMedium medium_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_BLE_H_ diff --git a/presence/implementation/mediums/ble_test.cc b/presence/implementation/mediums/ble_test.cc deleted file mode 100644 index 70633ad7..00000000 --- a/presence/implementation/mediums/ble_test.cc +++ /dev/null @@ -1,177 +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 "presence/implementation/mediums/ble.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/time/time.h" -#include "absl/types/variant.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/feature_flags.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/uuid.h" -#include "presence/data_element.h" -#include "presence/implementation/mediums/advertisement_data.h" -#include "presence/power_mode.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -namespace { - -using FeatureFlags = ::nearby::FeatureFlags::Flags; -using BleMediumStatus = ::nearby::MediumEnvironment::BleMediumStatus; -using ScanningSession = ::nearby::api::ble::BleMedium::ScanningSession; -using TxPowerLevel = ::nearby::api::ble::TxPowerLevel; -using ScanningCallback = ::nearby::api::ble::BleMedium::ScanningCallback; -using Uuid = ::nearby::Uuid; -using ::nearby::api::ble::BleAdvertisementData; -using ::nearby::api::ble::BlePeripheral; -using AdvertisingCallback = ::nearby::api::ble::BleMedium::AdvertisingCallback; -using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{}, -}; - -class BleTest : public testing::TestWithParam { - public: - constexpr static absl::Duration kWaitDuration = absl::Milliseconds(1000); - - std::string account_name_ = "Test-Name"; - constexpr static PowerMode kPowerMode = PowerMode::kBalanced; - std::vector identity_types_ = { - nearby::internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP, - }; - std::vector extended_properties_ = { - DataElement{DataElement::kTxPowerFieldType, "-10"}}; - std::vector > - filters_ = {PresenceScanFilter{ - .scan_type = ScanType::kPresenceScan, - .extended_properties = extended_properties_, - }}; - constexpr static bool kUseBle = true; - constexpr static ScanType kScanType = ScanType::kPresenceScan; - constexpr static bool kScanOnlyWhenScreenOn = true; - - ScanRequest scan_request_ = { - .account_name = account_name_, - .identity_types = identity_types_, - .scan_filters = filters_, - .use_ble = kUseBle, - .scan_type = kScanType, - .power_mode = kPowerMode, - .scan_only_when_screen_on = kScanOnlyWhenScreenOn, - }; - - protected: - std::optional GetBleStatus(const Ble& ble) { - return env_.GetBleMediumStatus(*ble.GetImpl()); - } - nearby::MediumEnvironment& env_{nearby::MediumEnvironment::Instance()}; -}; - -INSTANTIATE_TEST_SUITE_P(ParametrisedBleTest, BleTest, - ::testing::ValuesIn(kTestCases)); - -// Using MediumEnvironment to verify the start&stop StartScanning callback flows -// are working as intended. -TEST_P(BleTest, CanStartThenStopScanning) { - env_.Start(); - ::nearby::BluetoothAdapter adapter; - Ble ble(adapter); - - ScanRequest scan_request{ - .power_mode = PowerMode::kBalanced, - }; - ScanningCallback scanning_callback; - nearby::CountDownLatch started_scanning_latch(1); - - std::unique_ptr scannning_session = ble.StartScanning( - scan_request, ScanningCallback{ - .start_scanning_result = - [&started_scanning_latch](absl::Status status) { - if (status.ok()) { - started_scanning_latch.CountDown(); - } - }, - }); - - EXPECT_TRUE(started_scanning_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(GetBleStatus(ble).has_value() && - GetBleStatus(ble).value().is_scanning == true); - absl::Status stop_scanning_status = scannning_session->stop_scanning(); - EXPECT_OK(stop_scanning_status); - EXPECT_TRUE(GetBleStatus(ble).has_value() && - GetBleStatus(ble).value().is_scanning == false); - env_.Stop(); -} - -TEST_P(BleTest, AdvertiseAndScan) { - // Create two Ble devices, one advertises, the other one scans, and verify - // that the NP advertisement was sent from one to the other. - env_.Start(); - nearby::BluetoothAdapter client_adapter; - Ble client(client_adapter); - nearby::BluetoothAdapter server_adapter; - Ble server(server_adapter); - AdvertisementData advert_data = {.is_extended_advertisement = false, - .content = "my advertisement"}; - ScanRequest scan_request{ - .power_mode = PowerMode::kBalanced, - }; - nearby::CountDownLatch advertise_latch(1); - nearby::CountDownLatch scan_latch(1); - std::vector advertisements; - std::unique_ptr scanning_session = client.StartScanning( - scan_request, - ScanningCallback{.advertisement_found_cb = - [&](BlePeripheral::UniqueId peripheral_id, - BleAdvertisementData advertisement_data) { - advertisements.push_back(advertisement_data); - scan_latch.CountDown(); - }}); - std::unique_ptr - advertising_session = server.StartAdvertising( - advert_data, PowerMode::kBalanced, - AdvertisingCallback{ - .start_advertising_result = [&](absl::Status status) { - advertise_latch.CountDown(); - }}); - - EXPECT_TRUE(advertise_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(scan_latch.Await(kWaitDuration).result()); - EXPECT_OK(scanning_session->stop_scanning()); - EXPECT_OK(advertising_session->stop_advertising()); - ASSERT_FALSE(advertisements.empty()); - EXPECT_EQ(advertisements[0] - .service_data.find(kPresenceServiceUuid) - ->second.AsStringView(), - advert_data.content); - env_.Stop(); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/mediums/mediums.h b/presence/implementation/mediums/mediums.h deleted file mode 100644 index a47679da..00000000 --- a/presence/implementation/mediums/mediums.h +++ /dev/null @@ -1,41 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_MEDIUMS_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_MEDIUMS_H_ - -#include "internal/platform/bluetooth_adapter.h" -#include "presence/implementation/mediums/ble.h" - -namespace nearby { -namespace presence { - -/* - * This class owns medium instance like Ble and etc. And the instance of - * this class will be owned in {@code ServiceControllerImpl}. - */ -class Mediums { - public: - // Returns a handle to the Ble medium. - Ble& GetBle() { return ble_; } - - private: - nearby::BluetoothAdapter adapter_; - Ble ble_{adapter_}; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_MEDIUMS_H_ diff --git a/presence/implementation/mock_connection_authenticator.h b/presence/implementation/mock_connection_authenticator.h deleted file mode 100644 index 24e860eb..00000000 --- a/presence/implementation/mock_connection_authenticator.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CONNECTION_AUTHENTICATOR_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CONNECTION_AUTHENTICATOR_H_ - -#include -#include - -#include "gmock/gmock.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" -#include "presence/implementation/connection_authenticator.h" - -namespace nearby { -namespace presence { - -/* - * This class is for unit tests, mocking {@code ConnectionAuthenticator} - * functions in `PresenceDeviceProviderTest`. - */ -class MockConnectionAuthenticator : public ConnectionAuthenticator { - public: - MOCK_METHOD(absl::StatusOr, BuildSignedMessageAsInitiator, - (absl::string_view ukey2_secret, - std::optional local_credential, - const internal::SharedCredential& shared_credential), - (const, override)); - MOCK_METHOD(absl::StatusOr, BuildSignedMessageAsResponder, - (absl::string_view ukey2_secret, - const internal::LocalCredential& local_credential), - (const, override)); - MOCK_METHOD( - absl::Status, VerifyMessageAsInitiator, - (ResponderData authentication_data, absl::string_view ukey2_secret, - const std::vector& shared_credentials), - (const, override)); - MOCK_METHOD( - absl::StatusOr, VerifyMessageAsResponder, - (absl::string_view ukey2_secret, InitiatorData initiator_data, - const std::vector& local_credentials, - const std::vector& shared_credentials), - (const, override)); -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CONNECTION_AUTHENTICATOR_H_ diff --git a/presence/implementation/mock_credential_manager.h b/presence/implementation/mock_credential_manager.h deleted file mode 100644 index 64d6e848..00000000 --- a/presence/implementation/mock_credential_manager.h +++ /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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CREDENTIAL_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CREDENTIAL_MANAGER_H_ - -#include -#include - -#include "gmock/gmock.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/implementation/credential_manager.h" - -namespace nearby { -namespace presence { - -class MockCredentialManager : public CredentialManager { - public: - MOCK_METHOD( - void, GenerateCredentials, - (const nearby::internal::DeviceIdentityMetaData& device_identity_metadata, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb), - (override)); - MOCK_METHOD(void, UpdateRemotePublicCredentials, - (absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb), - (override)); - MOCK_METHOD(void, UpdateLocalCredential, - (const CredentialSelector& credential_selector, - nearby::internal::LocalCredential credential, - SaveCredentialsResultCallback result_callback), - (override)); - MOCK_METHOD(void, GetLocalCredentials, - (const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback), - (override)); - MOCK_METHOD(void, GetPublicCredentials, - (const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback), - (override)); - MOCK_METHOD(SubscriberId, SubscribeForPublicCredentials, - (const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback), - (override)); - MOCK_METHOD(void, UnsubscribeFromPublicCredentials, (SubscriberId id), - (override)); - MOCK_METHOD(std::string, DecryptDeviceIdentityMetaData, - (absl::string_view metadata_encryption_key, - absl::string_view key_seed, absl::string_view metadata_string), - (override)); - MOCK_METHOD( - void, SetDeviceIdentityMetaData, - (const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb), - (override)); - MOCK_METHOD(::nearby::internal::DeviceIdentityMetaData, - GetDeviceIdentityMetaData, (), (override)); -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_CREDENTIAL_MANAGER_H_ diff --git a/presence/implementation/mock_service_controller.h b/presence/implementation/mock_service_controller.h deleted file mode 100644 index 90c3b31d..00000000 --- a/presence/implementation/mock_service_controller.h +++ /dev/null @@ -1,82 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_SERVICE_CONTROLLER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_SERVICE_CONTROLLER_H_ - -#include -#include - -#include "gmock/gmock.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/implementation/service_controller.h" - -namespace nearby { -namespace presence { - -/* - * This class is for unit test, mocking {@code ServiceController} functions. - */ -class MockServiceController : public ServiceController { - public: - MockServiceController() = default; - ~MockServiceController() override = default; - - MOCK_METHOD(absl::StatusOr, StartScan, - (ScanRequest scan_request, ScanCallback callback), (override)); - MOCK_METHOD(void, StopScan, (ScanSessionId session_id), (override)); - MOCK_METHOD(absl::StatusOr, StartBroadcast, - (BroadcastRequest broadcast_request, BroadcastCallback callback), - (override)); - MOCK_METHOD(void, StopBroadcast, (BroadcastSessionId session_id), (override)); - MOCK_METHOD( - void, UpdateLocalDeviceMetadata, - (const ::nearby::internal::Metadata& metadata, bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb), - (override)); - MOCK_METHOD( - void, UpdateDeviceIdentityMetaData, - (const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb), - (override)); - MOCK_METHOD(::nearby::internal::DeviceIdentityMetaData, - GetDeviceIdentityMetaData, (), (override)); - MOCK_METHOD(void, GetLocalPublicCredentials, - (const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback), - (override)); - MOCK_METHOD(void, UpdateRemotePublicCredentials, - (absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb), - (override)); - MOCK_METHOD(void, GetLocalCredentials, - (const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback), - (override)); -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MOCK_SERVICE_CONTROLLER_H_ diff --git a/presence/implementation/np_ldt.h b/presence/implementation/np_ldt.h deleted file mode 100644 index 9047c12a..00000000 --- a/presence/implementation/np_ldt.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_NP_LDT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_NP_LDT_H_ - -// 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. -// C API for Rust implementation of LDT [1], tailored to Nearby Presence's -// BLE 4.2 legacy format advertisement parsing usecase. -// -// [1] https://eprint.iacr.org/2017/841.pdf - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -// Individual encrypt/decrypt API, useful when creating advertisements or when -// decrypting advertisements from a known origin - -// The allocated handle to use for encryption -typedef struct { - uint64_t handle; -} NpLdtEncryptHandle; - -// The allocated handle to use for decryption -typedef struct { - uint64_t handle; -} NpLdtDecryptHandle; - -// Key material from the Nearby Presence credential from which keys will be -// derived. -typedef struct { - uint8_t bytes[32]; -} NpLdtKeySeed; - -typedef struct { - uint8_t bytes[32]; -} NpMetadataKeyHmac; - -typedef struct { - uint8_t bytes[2]; -} NpLdtSalt; - -// Possible result codes returned from the LDT NP API's -typedef enum { - // Call to api was succesful - NP_LDT_SUCCESS = 0, - // Payload of invalid length was provided must be >= 16 and <=31 bytes - NP_LDT_ERROR_INVALID_LENGTH = -1, - // The provided metadata hmac did not match the calculated hmac on call to - // decrypt and verify - NP_LDT_ERROR_MAC_MISMATCH = -2, -} NP_LDT_RESULT; - -// Allocate an LDT-XTS-AES128 Decryption cipher using the "swap" mix function. -// -// `key_seed` is the key material from the Nearby Presence credential from which -// the LDT key will be derived. -// 'hmac_tag' is the hmac auth tag calculated on the metadata key used to verify -// decryption was successful -// -// Returns 0 on error, or a non-zero handle on success. -NpLdtDecryptHandle NpLdtDecryptCreate(NpLdtKeySeed key_seed, - NpMetadataKeyHmac hmac_tag); - -// Allocate an LDT-XTS-AES128 Encryption cipher using the "swap" mix function. -// -// `key_seed` is the key material from the Nearby Presence credential from which -// the LDT key will be derived. -// -// Returns 0 on error, or a non-zero handle on success. -NpLdtEncryptHandle NpLdtEncryptCreate(NpLdtKeySeed key_seed); - -// Release allocated resources for an NpLdtEncryptHandle -// -// Returns 0 on success or an NP_LDT_RESULT error code on failure -NP_LDT_RESULT NpLdtEncryptClose(NpLdtEncryptHandle handle); - -// Release allocated resources for an NpLdtDecryptHandle -// -// Returns 0 on success or an NP_LDT_RESULT error code on failure -NP_LDT_RESULT NpLdtDecryptClose(NpLdtDecryptHandle handle); - -// Encrypt a 16-31 byte buffer in-place. -// -// `buffer` is a pointer to a 16-31 byte plaintext, with length in `buffer_len`. -// `salt` is the big-endian 2 byte salt that will be used in the Nearby -// Presence advertisement, which will be incorporated into the tweaks LDT uses -// while encrypting. -// -// Returns 0 on success, in which case `buffer` will now contain ciphertext. -// Returns an NP_LDT_RESULT error code on failure -NP_LDT_RESULT NpLdtEncrypt(NpLdtEncryptHandle handle, uint8_t* buffer, - size_t buffer_len, NpLdtSalt salt); - -// Decrypt a 16-31 byte buffer in-place. -// -// `buffer` is a pointer to a 16-31 byte ciphertext, with length in -// `buffer_len`. -// `salt` is the big-endian 2 byte salt found in the Nearby Presence -// advertisement, which will be incorporated into the tweaks LDT uses while -// decrypting. -// -// Returns 0 on success, in which case `buffer` will now contain plaintext. -// Returns an NP_LDT_RESULT error code on failure -NP_LDT_RESULT NpLdtDecryptAndVerify(NpLdtDecryptHandle handle, uint8_t* buffer, - size_t buffer_len, NpLdtSalt salt); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_NP_LDT_H_ diff --git a/presence/implementation/scan_manager.cc b/presence/implementation/scan_manager.cc deleted file mode 100644 index 3f6d7e03..00000000 --- a/presence/implementation/scan_manager.cc +++ /dev/null @@ -1,280 +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 "presence/implementation/scan_manager.h" - -#include - -#include -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/status/status.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "internal/platform/future.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/crypto.h" -#include "internal/platform/logging.h" -#include "presence//implementation/advertisement_filter.h" -#include "presence/data_element.h" -#include "presence/data_types.h" -#include "presence/device_motion.h" -#include "presence/implementation/advertisement_decoder.h" -#include "presence/implementation/mediums/ble.h" -#include "presence/presence_action.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -namespace { -using BleAdvertisementData = ::nearby::api::ble::BleAdvertisementData; -using BlePeripheral = ::nearby::api::ble::BlePeripheral; -using ScanningSession = ::nearby::api::ble::BleMedium::ScanningSession; -using ScanningCallback = ::nearby::api::ble::BleMedium::ScanningCallback; -} // namespace - -ScanSessionId ScanManager::StartScan(ScanRequest scan_request, - ScanCallback cb) { - ScanSessionId id = nearby::RandData(); - RunOnServiceControllerThread( - "start-scan", - [this, id, scan_request, - scan_callback = - std::move(cb)]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) mutable { - ScanningCallback callback = ScanningCallback{ - .start_scanning_result = - [start_scan_client = std::move(scan_callback.start_scan_cb)]( - absl::Status ble_status) mutable { - start_scan_client(ble_status); - }, - .advertisement_found_cb = - [this, id](BlePeripheral::UniqueId peripheral_id, - BleAdvertisementData data) { - RunOnServiceControllerThread( - "notify-found-ble", - [this, id, data = std::move(data), peripheral_id]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NotifyFoundBle(id, data, peripheral_id); - }); - }, - .advertisement_lost_cb = - [this, id](BlePeripheral::UniqueId peripheral_id) { - RunOnServiceControllerThread( - "notify-lost-ble", - [this, id, peripheral_id]() ABSL_EXCLUSIVE_LOCKS_REQUIRED( - *executor_) { NotifyLostBle(id, peripheral_id); }); - }}; - FetchCredentials(id, scan_request); - scan_sessions_.insert( - {id, ScanSessionState{ - .request = scan_request, - .callback = std::move(scan_callback), - .decoder = AdvertisementDecoderImpl(), - .advertisement_filter = AdvertisementFilter(scan_request), - .scanning_session = mediums_->GetBle().StartScanning( - scan_request, std::move(callback))}}); - }); - return id; -} - -void ScanManager::StopScan(ScanSessionId id) { - RunOnServiceControllerThread( - "stop-scan", [this, id]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - auto it = scan_sessions_.find(id); - if (it == scan_sessions_.end()) { - return; - } - if (it->second.scanning_session) { - absl::Status status = it->second.scanning_session->stop_scanning(); - if (!status.ok()) { - LOG(WARNING) << "StopScan error: " << status; - } - } - scan_sessions_.erase(it); - }); -} - -void ScanManager::NotifyFoundBle(ScanSessionId id, BleAdvertisementData data, - BlePeripheral::UniqueId peripheral_id) { - auto it = scan_sessions_.find(id); - if (it == scan_sessions_.end()) { - return; - } - - auto advertisement_data = - data.service_data[kPresenceServiceUuid].AsStringView(); - - auto advert = it->second.decoder.DecodeAdvertisement(advertisement_data); - if (!advert.ok()) { - // This advertisement is not relevant to the current element, skip. - return; - } - - std::string remote_address = absl::StrCat(absl::Hex(peripheral_id)); - if (it->second.advertisement_filter.MatchesScanFilter(*advert)) { - internal::DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_bluetooth_mac_address(remote_address); - - if (!device_unique_id_to_endpoint_id_map_.contains(peripheral_id)) { - PresenceDevice device(DeviceMotion(), device_identity_metadata, - advert->identity_type); - // Ok if the advertisement is for trusted/private identity. - if (advert->public_credential.ok()) { - device.SetDecryptSharedCredential(*(advert->public_credential)); - } - device.AddExtendedProperties(advert->data_elements); - for (const auto& data_element : advert->data_elements) { - if (data_element.GetType() == DataElement::kActionFieldType) { - device.AddAction(PresenceAction(static_cast( - static_cast(data_element.GetValue()[0])))); - } - } - - device_unique_id_to_endpoint_id_map_.emplace(peripheral_id, - device.GetEndpointId()); - - it->second.callback.on_discovered_cb(std::move(device)); - } else { - PresenceDevice device( - device_unique_id_to_endpoint_id_map_.at(peripheral_id)); - device.SetDeviceIdentityMetaData(device_identity_metadata); - // Ok if the advertisement is for trusted/private identity. - if (advert->public_credential.ok()) { - device.SetDecryptSharedCredential(*(advert->public_credential)); - } - device.AddExtendedProperties(advert->data_elements); - for (const auto& data_element : advert->data_elements) { - if (data_element.GetType() == DataElement::kActionFieldType) { - device.AddAction(PresenceAction(static_cast( - static_cast(data_element.GetValue()[0])))); - } - } - - it->second.callback.on_updated_cb(std::move(device)); - } - } -} - -void ScanManager::NotifyLostBle(ScanSessionId id, - BlePeripheral::UniqueId peripheral_id) { - auto it = scan_sessions_.find(id); - if (it == scan_sessions_.end()) { - return; - } - - std::string remote_address = absl::StrCat(absl::Hex(peripheral_id)); - if (device_unique_id_to_endpoint_id_map_.contains(peripheral_id)) { - internal::DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_bluetooth_mac_address( - std::string(remote_address)); - PresenceDevice device( - device_unique_id_to_endpoint_id_map_.at(peripheral_id)); - device.SetDeviceIdentityMetaData(device_identity_metadata); - - device_unique_id_to_endpoint_id_map_.erase(peripheral_id); - - it->second.callback.on_lost_cb(std::move(device)); - } -} - -std::vector GetCredentialSelectors( - const ScanRequest& scan_request) { - std::vector all_types = { - nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP, - nearby::internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP, - nearby::internal::IdentityType::IDENTITY_TYPE_PUBLIC}; - std::vector selectors; - for (auto identity_type : - (scan_request.identity_types.empty() ? all_types - : scan_request.identity_types)) { - selectors.push_back( - CredentialSelector{.manager_app_id = scan_request.manager_app_id, - .account_name = scan_request.account_name, - .identity_type = identity_type}); - } - return selectors; -} - -void ScanManager::FetchCredentials(ScanSessionId id, - const ScanRequest& scan_request) { - std::vector credential_selectors = - GetCredentialSelectors(scan_request); - for (const CredentialSelector& selector : credential_selectors) { - // Not fetching for PUBLIC. - if (selector.identity_type == internal::IDENTITY_TYPE_UNSPECIFIED || - selector.identity_type == internal::IDENTITY_TYPE_PUBLIC) { - LOG(INFO) << __func__ << ": skip feteching creds for identity type: " - << selector.identity_type; - continue; - } - credential_manager_->GetPublicCredentials( - selector, PublicCredentialType::kRemotePublicCredential, - {.credentials_fetched_cb = - [this, id, identity_type = selector.identity_type]( - absl::StatusOr< - std::vector<::nearby::internal::SharedCredential>> - credentials) { - if (!credentials.ok()) { - LOG(WARNING) - << "Failed to fetch credentials: " << credentials.status(); - return; - } - RunOnServiceControllerThread( - "update-credentials", - [this, id, identity_type, - credentials = std::move(*credentials)]() - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - UpdateCredentials(id, identity_type, - std::move(credentials)); - }); - }}); - } -} - -void ScanManager::UpdateCredentials(ScanSessionId id, - IdentityType identity_type, - std::vector credentials) { - // Credentials should never get fetched for PUBLIC of No-Identity requests - assert(identity_type != internal::IDENTITY_TYPE_UNSPECIFIED); - assert(identity_type != internal::IDENTITY_TYPE_PUBLIC); - - auto it = scan_sessions_.find(id); - - if (it == scan_sessions_.end()) { - return; - } - - ScanSessionState& session = it->second; - session.credentials[identity_type] = std::move(credentials); - session.decoder = AdvertisementDecoderImpl(&session.credentials); -} - -int ScanManager::ScanningCallbacksLengthForTest() { - ::nearby::Future count; - RunOnServiceControllerThread("callbacks-size", - [&]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - count.Set(scan_sessions_.size()); - }); - return count.Get().GetResult(); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/scan_manager.h b/presence/implementation/scan_manager.h deleted file mode 100644 index a174884f..00000000 --- a/presence/implementation/scan_manager.h +++ /dev/null @@ -1,109 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SCAN_MANAGER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SCAN_MANAGER_H_ - -#include -#include -#include -#include - -#include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/mutex.h" -#include "internal/platform/mutex_lock.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_types.h" -#include "presence/implementation/advertisement_filter.h" -#include "presence/implementation/credential_manager.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/scan_request.h" - -#ifdef USE_RUST_DECODER -#include "presence/implementation/advertisement_decoder_rust_impl.h" -#else -#include "presence/implementation/advertisement_decoder_impl.h" -#endif - -namespace nearby { -namespace presence { - -// The instance of ScanManager is owned by `ServiceControllerImpl`. -// Helping service controller to manage scan requests and callbacks. -class ScanManager { - public: - using SingleThreadExecutor = ::nearby::SingleThreadExecutor; - using Mutex = ::nearby::Mutex; - using MutexLock = ::nearby::MutexLock; - using ScanningSession = ::nearby::api::ble::BleMedium::ScanningSession; - using Runnable = ::nearby::Runnable; - using BleAdvertisementData = ::nearby::api::ble::BleAdvertisementData; - using SharedCredential = ::nearby::internal::SharedCredential; - using IdentityType = ::nearby::internal::IdentityType; - - ScanManager(Mediums& mediums, CredentialManager& credential_manager, - SingleThreadExecutor& executor) { - mediums_ = &mediums, credential_manager_ = &credential_manager; - executor_ = &executor; - } - ~ScanManager() = default; - - ScanSessionId StartScan(ScanRequest scan_request, ScanCallback cb); - void StopScan(ScanSessionId session_id); - // Below functions are test only. - // Reference: go/totw/135#augmenting-the-public-api-for-tests - int ScanningCallbacksLengthForTest(); - - private: - struct ScanSessionState { - ScanRequest request; - ScanCallback callback; - absl::flat_hash_map> - credentials; - AdvertisementDecoderImpl decoder; - AdvertisementFilter advertisement_filter; - std::unique_ptr scanning_session; - }; - void NotifyFoundBle(ScanSessionId id, BleAdvertisementData data, - nearby::api::ble::BlePeripheral::UniqueId peripheral_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void NotifyLostBle(ScanSessionId id, - nearby::api::ble::BlePeripheral::UniqueId peripheral_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void FetchCredentials(ScanSessionId id, const ScanRequest& scan_request) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void UpdateCredentials(ScanSessionId id, IdentityType identity_type, - std::vector credentials) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - void RunOnServiceControllerThread(absl::string_view name, Runnable runnable) { - executor_->Execute(std::string(name), std::move(runnable)); - } - Mediums* mediums_; - CredentialManager* credential_manager_; - absl::flat_hash_map scan_sessions_ - ABSL_GUARDED_BY(*executor_); - absl::flat_hash_map - device_unique_id_to_endpoint_id_map_ ABSL_GUARDED_BY(*executor_); - SingleThreadExecutor* executor_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SCAN_MANAGER_H_ diff --git a/presence/implementation/scan_manager_test.cc b/presence/implementation/scan_manager_test.cc deleted file mode 100644 index 4ddee9ee..00000000 --- a/presence/implementation/scan_manager_test.cc +++ /dev/null @@ -1,453 +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 "presence/implementation/scan_manager.h" - -#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 "absl/strings/str_cat.h" -#include "absl/types/variant.h" -#include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/implementation/ble.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/logging.h" -#include "internal/platform/mac_address.h" -#include "internal/platform/medium_environment.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/credential.proto.h" -#include "presence/data_element.h" -#include "presence/data_types.h" -#include "presence/implementation/credential_manager_impl.h" -#include "presence/implementation/mediums/advertisement_data.h" -#include "presence/implementation/mediums/ble.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/implementation/mock_credential_manager.h" -#include "presence/power_mode.h" -#include "presence/presence_action.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -namespace { - -using AdvertisingSession = ::nearby::api::ble::BleMedium::AdvertisingSession; -using AdvertisingCallback = - ::nearby::api::ble::BleMedium::AdvertisingCallback; -using ::nearby::SingleThreadExecutor; - -using CountDownLatch = ::nearby::CountDownLatch; -using ::testing::Contains; - -class ScanManagerTest : public testing::Test { - protected: - void SetUp() override { env_.Start(); } - void TearDown() override { - executor_.Shutdown(); - env_.Stop(); - } - - std::unique_ptr StartAdvertisingOn(Ble& ble) { - auto advertisement = AdvertisementData{ - .is_extended_advertisement = false, - .content = {0x00, 0x26, 0x00, 0x40}, - }; - std::unique_ptr session = ble.StartAdvertising( - advertisement, PowerMode::kLowPower, - AdvertisingCallback{.start_advertising_result = [](absl::Status) {}}); - env_.Sync(); - return session; - } - - ScanRequest MakeDefaultScanRequest() { - std::vector> - filters = {PresenceScanFilter{ - .scan_type = ScanType::kPresenceScan, - .extended_properties = MakeDefaultExtendedProperties(), - }}; - return { - .account_name = "Test account", - .identity_types = MakeDefaultIdentityTypes(), - .scan_filters = filters, - .use_ble = true, - .scan_type = ScanType::kPresenceScan, - .power_mode = PowerMode::kBalanced, - .scan_only_when_screen_on = true, - }; - } - - ScanCallback MakeDefaultScanCallback() { - return { - .start_scan_cb = - [this](absl::Status status) { - if (status.ok()) { - start_latch_.CountDown(); - } - }, - .on_discovered_cb = - [this](PresenceDevice pd) { found_latch_.CountDown(); }, - .on_updated_cb = - [this](PresenceDevice pd) { updated_latch_.CountDown(); }, - .on_lost_cb = [this](PresenceDevice pd) { lost_latch_.CountDown(); }}; - } - - std::vector MakeDefaultIdentityTypes() { - return { - nearby::internal::IdentityType::IDENTITY_TYPE_PUBLIC, - }; - } - std::vector MakeDefaultExtendedProperties() { - return {DataElement(ActionBit::kNearbyShareAction)}; - } - SingleThreadExecutor executor_; - CredentialManagerImpl credential_manager_{&executor_}; - nearby::MediumEnvironment& env_ = {nearby::MediumEnvironment::Instance()}; - CountDownLatch start_latch_{1}; - CountDownLatch found_latch_{1}; - CountDownLatch updated_latch_{1}; - CountDownLatch lost_latch_{1}; -}; - -TEST_F(ScanManagerTest, CanStartThenStopScanning) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - // Start scanning - ScanSessionId scan_session = - manager.StartScan(MakeDefaultScanRequest(), MakeDefaultScanCallback()); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, CannotStopScanTwice) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - - ScanSessionId scan_session = - manager.StartScan(MakeDefaultScanRequest(), MakeDefaultScanCallback()); - - LOG(INFO) << "Start scan"; - EXPECT_TRUE(start_latch_.Await().Ok()); - // Ensure that we have started scanning before we try to stop. - env_.Sync(); - LOG(INFO) << "Stop scan"; - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); - LOG(INFO) << "Stop scan again"; - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, TestNoFilter) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - // Start scanning - ScanRequest scan_request_no_filter = MakeDefaultScanRequest(); - scan_request_no_filter.scan_filters.clear(); - ScanSessionId scan_session = - manager.StartScan(scan_request_no_filter, MakeDefaultScanCallback()); - - ASSERT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - ASSERT_TRUE(mediums.GetBle().IsAvailable()); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, PresenceMetadataIsRetained) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - std::string address = - absl::StrCat(absl::Hex(server_adapter.GetAddress().address())); - ScanCallback callback = { - .start_scan_cb = - [this](absl::Status status) { - if (status.ok()) { - start_latch_.CountDown(); - } - }, - .on_discovered_cb = - [this, &address](PresenceDevice pd) { - if (pd.GetDeviceIdentityMetadata().bluetooth_mac_address() == - address) { - EXPECT_THAT(pd.GetExtendedProperties(), - Contains(DataElement(ActionBit::kNearbyShareAction)) - .Times(1)); - EXPECT_THAT( - pd.GetActions(), - Contains(PresenceAction{(int)ActionBit::kNearbyShareAction}) - .Times(1)); - - found_latch_.CountDown(); - } - }, - .on_updated_cb = - [this, &address](PresenceDevice pd) { - if (pd.GetDeviceIdentityMetadata().bluetooth_mac_address() == - address) { - EXPECT_THAT(pd.GetExtendedProperties(), - Contains(DataElement(ActionBit::kNearbyShareAction)) - .Times(1)); - EXPECT_THAT( - pd.GetActions(), - Contains(PresenceAction{(int)ActionBit::kNearbyShareAction}) - .Times(1)); - - updated_latch_.CountDown(); - } - }}; - // Start scanning - ScanRequest scan_request_no_filter = MakeDefaultScanRequest(); - scan_request_no_filter.scan_filters.clear(); - auto scan_session = - manager.StartScan(scan_request_no_filter, std::move(callback)); - - ASSERT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - ASSERT_TRUE(mediums.GetBle().IsAvailable()); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - - // Advertise again to trigger `on_updated_cb` - advertising_session = StartAdvertisingOn(ble2); - - EXPECT_TRUE(updated_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, DiscoverThenLoseAdvertisement) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - // Start scanning - ScanSessionId scan_session = - manager.StartScan(MakeDefaultScanRequest(), MakeDefaultScanCallback()); - - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - - // Stop advertising to trigger `on_lost_cb` - EXPECT_OK(advertising_session->stop_advertising()); - env_.Sync(); - - EXPECT_TRUE(lost_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -TEST_F(ScanManagerTest, StopOneSessionFromAnotherDeadlock) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - CountDownLatch start_latch2{1}; - CountDownLatch found_latch2{1}; - - // Start scanning - std::vector extended_properties_mismatch = { - DataElement(ActionBit::kInstantTetheringAction)}; - std::vector> - mismatch_filters = {PresenceScanFilter{ - .scan_type = ScanType::kPresenceScan, - .extended_properties = extended_properties_mismatch, - }}; - ScanRequest scan_request_mismatch = { - .account_name = "Test account", - .identity_types = MakeDefaultIdentityTypes(), - .scan_filters = mismatch_filters, - .use_ble = true, - .scan_type = ScanType::kPresenceScan, - .power_mode = PowerMode::kBalanced, - .scan_only_when_screen_on = true, - }; - // we use scan_request_mismatch so this session's discovery doesn't get - // triggered. - ScanSessionId scan_session = - manager.StartScan(scan_request_mismatch, MakeDefaultScanCallback()); - ScanCallback scanning_callback2 = {.start_scan_cb = - [&](absl::Status status) { - if (status.ok()) { - start_latch2.CountDown(); - } - }, - .on_discovered_cb = - [&](PresenceDevice pd) { - LOG(INFO) << "scansession2 found"; - found_latch2.CountDown(); - manager.StopScan(scan_session); - }}; - ScanSessionId scan_session2 = manager.StartScan( - MakeDefaultScanRequest(), std::move(scanning_callback2)); - - ASSERT_EQ(manager.ScanningCallbacksLengthForTest(), 2); - - // Set up advertiser - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - EXPECT_TRUE(found_latch2.Await().Ok()); - // Session was stopped before, this should not be able to stop successfully. - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - ASSERT_TRUE(mediums.GetBle().IsAvailable()); - manager.StopScan(scan_session2); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -// Receive a BLE advertisement after StopScan. `on_discovered_cb` -// must not be called. -TEST_F(ScanManagerTest, NoDeviceFoundAfterStopScan) { - Mediums mediums; - ScanManager manager(mediums, credential_manager_, executor_); - CountDownLatch start_scan_latch{1}; - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::atomic_bool stopped = false; - ScanSessionId scan_session = manager.StartScan( - MakeDefaultScanRequest(), - ScanCallback{.start_scan_cb = - [&start_scan_latch](absl::Status status) { - if (status.ok()) { - start_scan_latch.CountDown(); - } - }, - .on_discovered_cb = - [&](PresenceDevice pd) { EXPECT_FALSE(stopped); }}); - - start_scan_latch.Await(); - manager.StopScan(scan_session); - stopped = true; - std::unique_ptr advertising_session = - StartAdvertisingOn(ble2); - - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); - executor_.Shutdown(); -} - -internal::SharedCredential GetPublicCredential() { - // Values copied from LDT tests - ByteArray seed({ - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - }); - ByteArray known_mac({0x09, 0xFE, 0x9E, 0x81, 0xB7, 0x3E, 0x5E, 0xCC, - 0x76, 0x59, 0x57, 0x71, 0xE0, 0x1F, 0xFB, 0x34, - 0x38, 0xE7, 0x5F, 0x24, 0xA7, 0x69, 0x56, 0xA0, - 0xB8, 0xEA, 0x67, 0xD1, 0x1C, 0x3E, 0x36, 0xFD}); - internal::SharedCredential public_credential; - public_credential.set_key_seed(seed.AsStringView()); - public_credential.set_metadata_encryption_key_tag_v0( - known_mac.AsStringView()); - return public_credential; -} - -std::vector BuildSharedCredentials() { - return {GetPublicCredential()}; -} - -TEST_F(ScanManagerTest, ScanningE2EWithEncryptedAdvertisementAndCredentials) { - Mediums mediums; - auto mock_credential_manager = MockCredentialManager(); - EXPECT_CALL(mock_credential_manager, GetPublicCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - PublicCredentialType public_credential_type, - GetPublicCredentialsResultCallback callback) { - callback.credentials_fetched_cb(BuildSharedCredentials()); - }); - ScanManager manager(mediums, mock_credential_manager, executor_); - - // Set up advertiser to broadcast a private identity adv - nearby::BluetoothAdapter server_adapter; - Ble ble2(server_adapter); - std::string V0AdvEncryptedBytes = "042222D82212EF16DBF872F2A3A7C0FA5248EC"; - std::string payload = absl::HexStringToBytes(V0AdvEncryptedBytes); - auto advertisement = AdvertisementData{ - .is_extended_advertisement = false, - .content = payload, - }; - - std::unique_ptr session = ble2.StartAdvertising( - advertisement, PowerMode::kLowPower, - AdvertisingCallback{.start_advertising_result = [](absl::Status) {}}); - env_.Sync(); - - std::vector< - absl::variant> // NOLINT - filters = {PresenceScanFilter{ - .scan_type = ScanType::kPresenceScan, - .extended_properties = {DataElement(DataElement::kTxPowerFieldType, - 3)}, - }}; - - ScanRequest scan_request = { - .account_name = "Test account", - .identity_types = - {nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP}, - .scan_filters = filters, - .use_ble = true, - .scan_type = ScanType::kPresenceScan, - .power_mode = PowerMode::kBalanced, - .scan_only_when_screen_on = true, - }; - - // Start scanning - ScanSessionId scan_session = - manager.StartScan(scan_request, MakeDefaultScanCallback()); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1); - EXPECT_TRUE(start_latch_.Await().Ok()); - EXPECT_TRUE(found_latch_.Await().Ok()); - manager.StopScan(scan_session); - EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/sensor_fusion.h b/presence/implementation/sensor_fusion.h deleted file mode 100644 index 31639bd7..00000000 --- a/presence/implementation/sensor_fusion.h +++ /dev/null @@ -1,153 +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_PRESENCE_IMPLEMENTATION_SENSOR_FUSION_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SENSOR_FUSION_H_ - -#include -#include -#include -#include - -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "presence/device_motion.h" -#include "presence/presence_zone.h" - -namespace nearby { -namespace presence { - -enum class DataSource { - kUnknown = 0, - kBle = 1, - kUwb = 2, - kNanRtt = 4, -}; - -struct RangingMeasurement { - // [0.0, 1.0], 1.0 is the max confidence. - float confidence_level; - float value; -}; - -struct RangingPosition { - RangingMeasurement distance; - std::optional azimuth; - std::optional elevation; - uint64_t elapsed_realtime_millis; -}; - -struct ZoneTransition { - PresenceZone::DistanceBoundary::RangeType distance_range_type; - float confidence_level; -}; - -struct RangingData { - DataSource data_source; - RangingPosition position; - std::optional zone_transition; - std::vector device_motions; -}; - -struct ZoneTransitionCallback { - absl::AnyInvocable - on_proximity_zone_changed = - [](uint64_t device_id, - PresenceZone::DistanceBoundary::RangeType proximity_zone) {}; - absl::AnyInvocable on_callback_id_generated = - [](uint64_t callback_id) {}; -}; - -class SensorFusion { - public: - virtual ~SensorFusion() = default; - - // Called when a device motion gesture is detected. - typedef std::function - DeviceMotionCallback; - - /** - * Returns a list of data sources would be used by the sensor fusion if they - * are available. - * This is to control what kinds of sources the NP scan engine should use for - * ranging. For instance, if both NAN RTT and UWB are supported, FPP may - * decide NAN RTT isn't useful at a certain moment, so NP scan engine won't - * try to request NAN RTT. - * - * @param elapsed_realtime_millis Elapsed timestamp since boot of the data - * source query. - * @param available_sources A bit mask of data sources that are available. - */ - virtual std::vector GetDataSources( - uint64_t elapsed_realtime_millis, - const std::vector& available_sources) = 0; - - /** - * Updates BLE scanned results to Sensor Fusion. - * - * @param device_id A unique device id of the peer device. - * @param txPower Calibrated TX power of the scan result, {@code - * std::nullopt} if the calibrated TX power is not available. - * @param rssi Received signal strength indicator for the scan result. - * @param elapsed_realtime_millis Elapsed timestamp since boot when the - * scan result is discovered. - */ - virtual absl::Status UpdateBleScanResult( - uint64_t device_id, std::optional txPower, int rssi, - uint64_t elapsed_realtime_millis) = 0; - /** - * Updates UWB ranging results to Sensor Fusion. - * - * @param device_id A unique device id of the peer device. - * @param position UWB ranging result (distance and optionally angle) - */ - virtual void UpdateUwbRangingResult(uint64_t device_id, - RangingPosition position) = 0; - - /** - * Adds callback for updates of proximity zone transitions. - */ - virtual void RequestZoneTransitionUpdates( - ZoneTransitionCallback callback) = 0; - - /** - * Removes callback for updates of proximity zone transitions. - */ - virtual void RemoveZoneTransitionUpdates(uint64_t callback_id) = 0; - - /** - * Adds callback for updates of device motion events. - */ - virtual void RequestDeviceMotionUpdates(DeviceMotionCallback callback) = 0; - - /** - * Remove callback for updates of device motion events. - */ - virtual void RemoveDeviceMotionUpdates(DeviceMotionCallback callback) = 0; - - /** - * Returns the best ranging estimate to a given device. Returns {@code - * std::nullopt} if the sensor fusion cannot produce a ranging estimate. - * - * @param device_id Id of the peer device. - */ - virtual std::optional GetRangingData(uint64_t device_id) = 0; -}; - -} // namespace presence -} // namespace nearby -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SENSOR_FUSION_H_ - diff --git a/presence/implementation/service_controller.h b/presence/implementation/service_controller.h deleted file mode 100644 index 9389741e..00000000 --- a/presence/implementation/service_controller.h +++ /dev/null @@ -1,76 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_H_ - -#include - -#include "absl/status/statusor.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/proto/metadata.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -/* - * This class is owned in {@code PresenceService}. It specifies the function - * signatures. {@code ServiceControllerImpl} and {@code MockServiceController} - * inherit this class and provides real implementation and mock impl for tests. - */ -class ServiceController { - public: - ServiceController() = default; - virtual ~ServiceController() = default; - virtual absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) = 0; - virtual void StopScan(ScanSessionId session_id) = 0; - virtual absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) = 0; - virtual void StopBroadcast(BroadcastSessionId session_id) = 0; - virtual void UpdateLocalDeviceMetadata( - const ::nearby::internal::Metadata& metadata, bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - virtual void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - virtual ::nearby::internal::DeviceIdentityMetaData - GetDeviceIdentityMetaData() = 0; - virtual void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) = 0; - virtual void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) = 0; - virtual void GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_H_ diff --git a/presence/implementation/service_controller_impl.cc b/presence/implementation/service_controller_impl.cc deleted file mode 100644 index 3c158fc6..00000000 --- a/presence/implementation/service_controller_impl.cc +++ /dev/null @@ -1,91 +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. - -#include "presence/implementation/service_controller_impl.h" - -#include -#include - -#include "absl/status/statusor.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "presence/data_types.h" -#include "presence/implementation/credential_manager.h" - -namespace nearby { -namespace presence { - -absl::StatusOr ServiceControllerImpl::StartScan( - ScanRequest scan_request, ScanCallback callback) { - return scan_manager_.StartScan(scan_request, std::move(callback)); -} -void ServiceControllerImpl::StopScan(ScanSessionId id) { - scan_manager_.StopScan(id); -} - -absl::StatusOr ServiceControllerImpl::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - return broadcast_manager_.StartBroadcast(broadcast_request, - std::move(callback)); -} - -void ServiceControllerImpl::StopBroadcast(BroadcastSessionId id) { - broadcast_manager_.StopBroadcast(id); -} - -// TODO(b/327629276): Remove this function. -void ServiceControllerImpl::UpdateLocalDeviceMetadata( - const ::nearby::internal::Metadata& metadata, bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) {} - -void ServiceControllerImpl::UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) { - credential_manager_.SetDeviceIdentityMetaData( - device_identity_metadata, regen_credentials, manager_app_id, - identity_types, credential_life_cycle_days, - contiguous_copy_of_credentials, std::move(credentials_generated_cb)); -} - -void ServiceControllerImpl::GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - credential_manager_.GetPublicCredentials( - credential_selector, PublicCredentialType::kLocalPublicCredential, - std::move(callback)); -} - -void ServiceControllerImpl::UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) { - credential_manager_.UpdateRemotePublicCredentials( - manager_app_id, account_name, remote_public_creds, - std::move(credentials_updated_cb)); -} - -void ServiceControllerImpl::GetLocalCredentials( - const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - credential_manager_.GetLocalCredentials(credential_selector, - std::move(callback)); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/implementation/service_controller_impl.h b/presence/implementation/service_controller_impl.h deleted file mode 100644 index b858b7b3..00000000 --- a/presence/implementation/service_controller_impl.h +++ /dev/null @@ -1,110 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_IMPL_H_ - -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/runnable.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/metadata.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/implementation/broadcast_manager.h" -#include "presence/implementation/credential_manager.h" -#include "presence/implementation/scan_manager.h" -#include "presence/implementation/service_controller.h" -#include "presence/scan_request.h" - -/* - * This class implements {@code ServiceController} functions. Owns mediums and - * other managers instances. - */ -namespace nearby { -namespace presence { - -class ServiceControllerImpl : public ServiceController { - public: - using SingleThreadExecutor = ::nearby::SingleThreadExecutor; - - ServiceControllerImpl(SingleThreadExecutor* executor, - CredentialManager* credential_manager, - ScanManager* scan_manager, - BroadcastManager* broadcast_manager) - : executor_(*executor), - credential_manager_(*credential_manager), - scan_manager_(*scan_manager), - broadcast_manager_(*broadcast_manager) {} - ~ServiceControllerImpl() override { executor_.Shutdown(); } - - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - void StopScan(ScanSessionId session_id) override; - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override; - void StopBroadcast(BroadcastSessionId) override; - void UpdateLocalDeviceMetadata( - const ::nearby::internal::Metadata& metadata, bool regen_credentials, - absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - - ::nearby::internal::DeviceIdentityMetaData GetDeviceIdentityMetaData() - override { - return credential_manager_.GetDeviceIdentityMetaData(); - } - void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) override; - void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) override; - void GetLocalCredentials(const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) override; - - SingleThreadExecutor& GetBackgroundExecutor() { return executor_; } - - private: - void NotifyStartCallbackStatus(BroadcastSessionId id, absl::Status status); - void RunOnServiceControllerThread(absl::string_view name, Runnable runnable) { - executor_.Execute(std::string(name), std::move(runnable)); - } - - SingleThreadExecutor& executor_; - CredentialManager& credential_manager_; - ScanManager& scan_manager_; - BroadcastManager& broadcast_manager_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_SERVICE_CONTROLLER_IMPL_H_ diff --git a/presence/implementation/service_controller_impl_test.cc b/presence/implementation/service_controller_impl_test.cc deleted file mode 100644 index 5d638186..00000000 --- a/presence/implementation/service_controller_impl_test.cc +++ /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. - -#include "presence/implementation/service_controller_impl.h" - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/credential.pb.h" -#include "presence/implementation/broadcast_manager.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/implementation/mock_credential_manager.h" -#include "presence/implementation/scan_manager.h" - -namespace nearby { -namespace presence { -namespace { - -constexpr absl::string_view kManagerAppId = "TEST_MANAGER_APP"; -constexpr absl::string_view kAccountName = "test account"; -constexpr absl::string_view kSecretId1 = "1111111"; -constexpr absl::string_view kSecretId2 = "2222222"; -constexpr absl::string_view kSecretId3 = "3333333"; - -CredentialSelector BuildDefaultCredentialSelector() { - CredentialSelector credential_selector; - credential_selector.manager_app_id = std::string(kManagerAppId); - credential_selector.account_name = std::string(kAccountName); - credential_selector.identity_type = - ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; - return credential_selector; -} - -std::vector BuildLocalCredentials() { - internal::LocalCredential local_credential1; - local_credential1.set_secret_id(kSecretId1); - internal::LocalCredential local_credential2; - local_credential2.set_secret_id(kSecretId2); - internal::LocalCredential local_credential3; - local_credential3.set_secret_id(kSecretId3); - return {local_credential1, local_credential2, local_credential3}; -} - -TEST(ServiceControllerImplTest, GetLocalCredentials) { - auto mock_credential_manager = std::make_unique(); - EXPECT_CALL(*mock_credential_manager.get(), GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - callback.credentials_fetched_cb(BuildLocalCredentials()); - }); - - Mediums mediums; - SingleThreadExecutor executor; - ScanManager scan_manager{mediums, *mock_credential_manager, executor}; - BroadcastManager broadcast_manager{mediums, *mock_credential_manager, - executor}; - - auto service_controller = std::make_unique( - &executor, mock_credential_manager.get(), &scan_manager, - &broadcast_manager); - CredentialSelector credential_selector = BuildDefaultCredentialSelector(); - - absl::StatusOr> - private_credentials; - service_controller->GetLocalCredentials( - credential_selector, - {.credentials_fetched_cb = - [&](absl::StatusOr> - credentials) { - private_credentials = std::move(credentials); - }}); - - EXPECT_OK(private_credentials); - ASSERT_EQ(3u, private_credentials->size()); - ASSERT_EQ(private_credentials->at(0).secret_id(), kSecretId1); - ASSERT_EQ(private_credentials->at(1).secret_id(), kSecretId2); - ASSERT_EQ(private_credentials->at(2).secret_id(), kSecretId3); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/power_mode.h b/presence/power_mode.h deleted file mode 100644 index 229c59fd..00000000 --- a/presence/power_mode.h +++ /dev/null @@ -1,35 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_POWER_MODE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_POWER_MODE_H_ - -namespace nearby { -namespace presence { - -// High level concept of Power mode for Scan and Broadcast. -// More frequent, more power consumption, but less interval and latency. -// Native platforms would decide the specific interval based on their own -// configs. -enum class PowerMode { - kNoPower = 0, - kLowPower = 1, - kBalanced = 2, - kLowLatency = 3, -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_POWER_MODE_H_ diff --git a/presence/presence_action.cc b/presence/presence_action.cc deleted file mode 100644 index 1265eada..00000000 --- a/presence/presence_action.cc +++ /dev/null @@ -1,31 +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. - -#include "presence/presence_action.h" - -#include "internal/platform/logging.h" - -namespace nearby { -namespace presence { - -PresenceAction::PresenceAction(int action_identifier) - : action_identifier_(action_identifier) { - CHECK(kMinActionIdentifierValue <= action_identifier_ && - action_identifier_ <= kMaxActionIdentifierValue); -} - -int PresenceAction::GetActionIdentifier() const { return action_identifier_; } - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_action.h b/presence/presence_action.h deleted file mode 100644 index a073f6b6..00000000 --- a/presence/presence_action.h +++ /dev/null @@ -1,41 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ACTION_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ACTION_H_ - -namespace nearby { -namespace presence { -class PresenceAction { - public: - PresenceAction(int action_identifier = 1); - int GetActionIdentifier() const; - - private: - static constexpr int kMinActionIdentifierValue = 1; - static constexpr int kMaxActionIdentifierValue = 255; - const int action_identifier_; -}; - -inline bool operator==(const PresenceAction& a1, const PresenceAction& a2) { - return a1.GetActionIdentifier() == a2.GetActionIdentifier(); -} - -inline bool operator!=(const PresenceAction& a1, const PresenceAction& a2) { - return !(a1 == a2); -} -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ACTION_H_ diff --git a/presence/presence_action_test.cc b/presence/presence_action_test.cc deleted file mode 100644 index 64b5e78e..00000000 --- a/presence/presence_action_test.cc +++ /dev/null @@ -1,59 +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. - -#include "presence/presence_action.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" - -namespace nearby { -namespace presence { -namespace { -constexpr int kDefaultActionIdentifier = 1; -constexpr int kTestActionIdentifier = 2; -TEST(PresenceActionTest, DefaultConstructorWorks) { - PresenceAction action; - EXPECT_EQ(action.GetActionIdentifier(), kDefaultActionIdentifier); -} - -TEST(PresenceActionTest, DefaultEquals) { - PresenceAction action1; - PresenceAction action2; - EXPECT_EQ(action1, action2); -} - -TEST(PresenceActionTest, ExplicitInitEquals) { - PresenceAction action1 = {kTestActionIdentifier}; - PresenceAction action2 = {kTestActionIdentifier}; - EXPECT_EQ(action1, action2); - EXPECT_EQ(action1.GetActionIdentifier(), kTestActionIdentifier); -} - -TEST(PresenceActionTest, ExplicitInitNotEquals) { - PresenceAction action1 = {kDefaultActionIdentifier}; - PresenceAction action2 = {kTestActionIdentifier}; - EXPECT_NE(action1, action2); -} - -TEST(PresenceActionTest, CopyInitEquals) { - PresenceAction action1 = {kTestActionIdentifier}; - PresenceAction action2 = {action1}; - - EXPECT_EQ(action1, action2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_client.h b/presence/presence_client.h deleted file mode 100644 index 92807d95..00000000 --- a/presence/presence_client.h +++ /dev/null @@ -1,85 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_H_ - -#include - -#include "absl/status/statusor.h" -#include "internal/platform/borrowable.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -class PresenceService; -/** - * Interface for detecting and interacting with nearby devices that are also - * part of the Presence ecosystem. - */ -class PresenceClient { - public: - using BorrowablePresenceService = ::nearby::Borrowable; - - virtual ~PresenceClient() = default; - - // Starts a Nearby Presence scan and registers `ScanCallback` - // which will be invoked when a matching `PresenceDevice` is detected, - // lost, and status changed. - // The session can be terminated with `StopScan()`. - // - // `ScanCallback` is kept in the Nearby Presence service until `StopScan()` is - // called. - // - // `ScanRequest` contains the options like scan power mode - // and type; the filters including credentials, actions and extended - // properties. - virtual absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) = 0; - - // Terminates the scan session. Does nothing if the session is already - // terminated. - virtual void StopScan(ScanSessionId session_id) = 0; - - // Starts a Nearby Presence broadcast and registers `BroadcastCallback` - // which will be invoked after broadcast is started. - // The session can be terminated with `StopBroadcast()`. - // - // `BroadcastCallback` is kept in the Nearby Presence service until - // `StopBroadcast()` is called. - // - // `BroadcastRequest` contains the options like tx_power, - // the credential info like salt and private credential, the actions and - // extended properties. - virtual absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) = 0; - - // Terminates a broadcast session. Does nothing if the session is already - // terminated. - virtual void StopBroadcast(BroadcastSessionId session_id) = 0; - - // Returns the local PresenceDevice describing the current device's actions, - // connectivity info and unique identifier for use in Connections and - // Presence. - virtual std::optional GetLocalDevice() = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_H_ diff --git a/presence/presence_client_impl.cc b/presence/presence_client_impl.cc deleted file mode 100644 index 706e52f2..00000000 --- a/presence/presence_client_impl.cc +++ /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. - -#include "presence/presence_client_impl.h" - -#include -#include -#include - -#include "absl/status/status.h" -#include "internal/platform/borrowable.h" -#include "internal/platform/logging.h" -#include "presence/presence_device.h" -#include "presence/presence_service.h" - -namespace nearby { -namespace presence { - -// static -PresenceClientImpl::Factory* PresenceClientImpl::Factory::g_test_factory_ = - nullptr; - -// static -std::unique_ptr PresenceClientImpl::Factory::Create( - BorrowablePresenceService service) { - if (g_test_factory_) { - return g_test_factory_->CreateInstance(service); - } - return absl::WrapUnique(new PresenceClientImpl(service)); -} - -// static -void PresenceClientImpl::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -PresenceClientImpl::Factory::~Factory() = default; - -absl::StatusOr PresenceClientImpl::StartScan( - ScanRequest scan_request, ScanCallback callback) { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (!borrowed) { - return absl::FailedPreconditionError( - "Can't start scan, presence service is gone"); - } - return (*borrowed)->StartScan(scan_request, std::move(callback)); -} - -void PresenceClientImpl::StopScan(ScanSessionId id) { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (borrowed) { - (*borrowed)->StopScan(id); - } -} - -absl::StatusOr PresenceClientImpl::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (!borrowed) { - return absl::FailedPreconditionError( - "Can't start broadcast, presence service is gone"); - } - return (*borrowed)->StartBroadcast(broadcast_request, std::move(callback)); -} - -void PresenceClientImpl::StopBroadcast(BroadcastSessionId session_id) { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (borrowed) { - (*borrowed)->StopBroadcast(session_id); - } else { - VLOG(1) << "Session already finished, id: " << session_id; - } -} - -std::optional PresenceClientImpl::GetLocalDevice() { - ::nearby::Borrowed borrowed = service_.Borrow(); - if (borrowed) { - const PresenceDevice* device = static_cast( - (*borrowed)->GetLocalDeviceProvider()->GetLocalDevice()); - return PresenceDevice(*device); - } - return std::nullopt; -} - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_client_impl.h b/presence/presence_client_impl.h deleted file mode 100644 index e7f376c8..00000000 --- a/presence/presence_client_impl.h +++ /dev/null @@ -1,75 +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_PRESENCE_PRESENCE_CLIENT_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_IMPL_H_ - -#include -#include - -#include "absl/status/statusor.h" -#include "internal/platform/borrowable.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/presence_client.h" -#include "presence/presence_device.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -class PresenceClientImpl : public PresenceClient{ - public: - using BorrowablePresenceService = ::nearby::Borrowable; - - class Factory { - public: - static std::unique_ptr Create( - BorrowablePresenceService service); - static void SetFactoryForTesting(Factory* test_factory); - - protected: - virtual ~Factory(); - virtual std::unique_ptr CreateInstance( - BorrowablePresenceService service) = 0; - - private: - static Factory* g_test_factory_; - }; - - PresenceClientImpl(const PresenceClientImpl&) = delete; - PresenceClientImpl(PresenceClientImpl&&) = default; - PresenceClientImpl& operator=(const PresenceClientImpl&) = delete; - ~PresenceClientImpl() override = default; - - // PresenceClient: - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - void StopScan(ScanSessionId session_id) override; - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override; - void StopBroadcast(BroadcastSessionId session_id) override; - std::optional GetLocalDevice() override; - - private: - explicit PresenceClientImpl(BorrowablePresenceService service) - : service_(service) {} - - BorrowablePresenceService service_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_IMPL_H_ diff --git a/presence/presence_client_test.cc b/presence/presence_client_test.cc deleted file mode 100644 index 2c43f26f..00000000 --- a/presence/presence_client_test.cc +++ /dev/null @@ -1,151 +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. - -#include "presence/presence_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/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/future.h" -#include "internal/platform/medium_environment.h" -#include "presence/data_types.h" -#include "presence/presence_device.h" -#include "presence/presence_service_impl.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::DeviceIdentityMetaData; -using ::testing::status::StatusIs; - -constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; - -// Creates a PresenceClient and destroys PresenceServiceImpl that was used to -// create it. -std::unique_ptr CreateDefunctPresenceClient() { - PresenceServiceImpl presence_service; - return presence_service.CreatePresenceClient(); -} - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_PHONE); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address(kMacAddr); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} - -class PresenceClientTest : public testing::Test { - protected: - nearby::MediumEnvironment& env_{nearby::MediumEnvironment::Instance()}; -}; - -TEST_F(PresenceClientTest, StartBroadcastWithDefaultConstructor) { - env_.Start(); - absl::Status broadcast_result; - - PresenceServiceImpl presence_service; - std::unique_ptr presence_client = - presence_service.CreatePresenceClient(); - auto unused = presence_client->StartBroadcast( - {}, { - .start_broadcast_cb = - [&](absl::Status status) { broadcast_result = status; }, - }); - - EXPECT_THAT(broadcast_result, StatusIs(absl::StatusCode::kInvalidArgument)); - env_.Stop(); -} - -TEST_F(PresenceClientTest, StartBroadcastFailsWhenPresenceServiceIsGone) { - env_.Start(); - absl::Status broadcast_result = absl::UnknownError(""); - - absl::StatusOr session_id = - CreateDefunctPresenceClient()->StartBroadcast( - {}, { - .start_broadcast_cb = - [&](absl::Status status) { broadcast_result = status; }, - }); - - EXPECT_THAT(session_id, StatusIs(absl::StatusCode::kFailedPrecondition)); - EXPECT_THAT(broadcast_result, StatusIs(absl::StatusCode::kUnknown)); - env_.Stop(); -} - -TEST_F(PresenceClientTest, StartScanWithDefaultConstructor) { - env_.Start(); - ::nearby::Future scan_result; - ScanCallback scan_callback = { - .start_scan_cb = [&](absl::Status status) { scan_result.Set(status); }, - }; - - PresenceServiceImpl presence_service; - std::unique_ptr presence_client = - presence_service.CreatePresenceClient(); - EXPECT_OK(presence_client->StartScan({}, std::move(scan_callback))); - - EXPECT_TRUE(scan_result.Get().ok()); - EXPECT_OK(scan_result.Get().GetResult()); - env_.Stop(); -} - -TEST_F(PresenceClientTest, StartScanFailsWhenPresenceServiceIsGone) { - env_.Start(); - absl::Status scan_result = absl::UnknownError(""); - - absl::StatusOr session_id = - CreateDefunctPresenceClient()->StartScan( - {}, { - .start_scan_cb = - [&](absl::Status status) { scan_result = status; }, - }); - - EXPECT_THAT(session_id, StatusIs(absl::StatusCode::kFailedPrecondition)); - EXPECT_THAT(scan_result, StatusIs(absl::StatusCode::kUnknown)); - env_.Stop(); -} - -TEST_F(PresenceClientTest, GettingDeviceWorks) { - PresenceServiceImpl presence_service; - std::unique_ptr presence_client = - presence_service.CreatePresenceClient(); - presence_service.UpdateDeviceIdentityMetaData( - CreateTestDeviceIdentityMetaData(), false, "", {}, 0, 0, {}); - auto device = presence_client->GetLocalDevice(); - ASSERT_NE(device, std::nullopt); - EXPECT_EQ(device->GetEndpointId().length(), kEndpointIdLength); - EXPECT_EQ(device->GetDeviceIdentityMetadata().SerializeAsString(), - CreateTestDeviceIdentityMetaData().SerializeAsString()); -} - -TEST_F(PresenceClientTest, TestGettingDeviceDefunct) { - std::unique_ptr presence_client = - CreateDefunctPresenceClient(); - auto device = presence_client->GetLocalDevice(); - EXPECT_EQ(device, std::nullopt); -} -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_device.cc b/presence/presence_device.cc deleted file mode 100644 index e2651089..00000000 --- a/presence/presence_device.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 "presence/presence_device.h" - -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/types/variant.h" -#include "connections/implementation/proto/offline_wire_formats.pb.h" -#include "internal/interop/device.h" -#include "internal/platform/ble_connection_info.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/prng.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/device_motion.h" - -namespace nearby { -namespace presence { - -namespace { -constexpr char kEndpointIdChars[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; - -// LINT.IfChange -constexpr int kAndroidIdentityTypeUnknown = -1; -constexpr int kAndroidIdentityTypePrivateGroup = 0; -constexpr int kAndroidIdentityTypeContactsGroup = 1; -constexpr int kAndroidIdentityTypePublic = 2; -// LINT.ThenChange( -// //depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/presence/PresenceIdentity.java -// ) - -std::string GenerateRandomEndpointId() { - std::string result(kEndpointIdLength, 0); - nearby::Prng prng; - for (int i = 0; i < kEndpointIdLength; i++) { - result[i] = kEndpointIdChars[prng.NextUint32() % sizeof(kEndpointIdChars)]; - } - return result; -} - -location::nearby::connections::PresenceDevice::DeviceType -ConvertToConnectionsDeviceType(internal::DeviceType device_type) { - switch (device_type) { - case internal::DEVICE_TYPE_FOLDABLE: - case internal::DEVICE_TYPE_PHONE: - return location::nearby::connections::PresenceDevice::PHONE; - case internal::DEVICE_TYPE_TABLET: - return location::nearby::connections::PresenceDevice::TABLET; - case internal::DEVICE_TYPE_DISPLAY: - return location::nearby::connections::PresenceDevice::DISPLAY; - case internal::DEVICE_TYPE_CHROMEOS: - case internal::DEVICE_TYPE_LAPTOP: - return location::nearby::connections::PresenceDevice::LAPTOP; - case internal::DEVICE_TYPE_TV: - return location::nearby::connections::PresenceDevice::TV; - case internal::DEVICE_TYPE_WATCH: - return location::nearby::connections::PresenceDevice::WATCH; - default: - return location::nearby::connections::PresenceDevice::UNKNOWN; - } -} - -int ConvertToAndroidIdentityType(nearby::internal::IdentityType identity_type) { - switch (identity_type) { - case internal::IDENTITY_TYPE_PRIVATE_GROUP: - return kAndroidIdentityTypePrivateGroup; - case internal::IDENTITY_TYPE_CONTACTS_GROUP: - return kAndroidIdentityTypeContactsGroup; - case internal::IDENTITY_TYPE_PUBLIC: - return kAndroidIdentityTypePublic; - default: - // Unknown identity. - return kAndroidIdentityTypeUnknown; - } -} -} // namespace - -PresenceDevice::PresenceDevice(absl::string_view endpoint_id) noexcept - : endpoint_id_(endpoint_id) {} - -PresenceDevice::PresenceDevice( - DeviceIdentityMetaData device_identity_metadata) noexcept - : discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()), - device_motion_(DeviceMotion()), - device_identity_metadata_(device_identity_metadata) { - endpoint_id_ = GenerateRandomEndpointId(); -} -PresenceDevice::PresenceDevice( - DeviceMotion device_motion, - DeviceIdentityMetaData device_identity_metadata) noexcept - : discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()), - device_motion_(device_motion), - device_identity_metadata_(device_identity_metadata) { - endpoint_id_ = GenerateRandomEndpointId(); -} - -PresenceDevice::PresenceDevice( - DeviceMotion device_motion, DeviceIdentityMetaData device_identity_metadata, - nearby::internal::IdentityType identity_type) noexcept - : discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()), - device_motion_(device_motion), - device_identity_metadata_(device_identity_metadata), - identity_type_(identity_type) { - endpoint_id_ = GenerateRandomEndpointId(); -} - -std::vector PresenceDevice::GetConnectionInfos() - const { - std::vector transformed_actions; - transformed_actions.reserve(actions_.size()); - for (const auto& action : actions_) { - transformed_actions.push_back(action.GetActionIdentifier()); - } - return {nearby::BleConnectionInfo( - device_identity_metadata_.bluetooth_mac_address(), - /*gatt_characteristic=*/"", /*psm=*/"", transformed_actions)}; -} - -std::string PresenceDevice::ToProtoBytes() const { - location::nearby::connections::PresenceDevice device; - device.set_endpoint_id(endpoint_id_); - device.add_identity_type(ConvertToAndroidIdentityType(identity_type_)); - device.set_endpoint_type( - location::nearby::connections::EndpointType::PRESENCE_ENDPOINT); - auto* actions = device.mutable_actions(); - for (const auto& action : actions_) { - actions->Add(action.GetActionIdentifier()); - } - std::string connection_infos = ""; - for (const auto& connection_info : GetConnectionInfos()) { - if (absl::holds_alternative(connection_info)) { - continue; - } - if (absl::holds_alternative(connection_info)) { - connection_infos += - absl::get(connection_info).ToDataElementBytes(); - } - if (absl::holds_alternative(connection_info)) { - connection_infos += absl::get(connection_info) - .ToDataElementBytes(); - } - if (absl::holds_alternative(connection_info)) { - connection_infos += absl::get(connection_info) - .ToDataElementBytes(); - } - } - device.set_device_type( - ConvertToConnectionsDeviceType(device_identity_metadata_.device_type())); - device.set_device_name(device_identity_metadata_.device_name()); - device.set_connectivity_info_list(connection_infos); - device.set_device_image_url("dummy url"); // Not used. - return device.SerializeAsString(); -} -} // namespace presence -} // namespace nearby diff --git a/presence/presence_device.h b/presence/presence_device.h deleted file mode 100644 index 93bac818..00000000 --- a/presence/presence_device.h +++ /dev/null @@ -1,129 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_ - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "internal/interop/device.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/data_element.h" -#include "presence/device_motion.h" -#include "presence/presence_action.h" - -namespace nearby { -namespace presence { - -inline constexpr int kEndpointIdLength = 4; - -class PresenceDevice : public nearby::NearbyDevice { - using Metadata = ::nearby::internal::Metadata; - using DeviceIdentityMetaData = ::nearby::internal::DeviceIdentityMetaData; - - public: - explicit PresenceDevice(absl::string_view endpoint_id) noexcept; - explicit PresenceDevice( - DeviceIdentityMetaData device_identity_metadata) noexcept; - explicit PresenceDevice( - DeviceMotion device_motion, - DeviceIdentityMetaData device_identity_metadata) noexcept; - explicit PresenceDevice( - DeviceMotion device_motion, - DeviceIdentityMetaData device_identity_metadata, - nearby::internal::IdentityType identity_type) noexcept; - std::string GetEndpointId() const override { return endpoint_id_; } - std::vector GetConnectionInfos() - const override; - std::string ToProtoBytes() const override; - void AddExtendedProperty(const DataElement& data_element) { - extended_properties_.push_back(data_element); - } - void AddExtendedProperties(const std::vector& properties) { - extended_properties_.insert(extended_properties_.end(), properties.begin(), - properties.end()); - } - std::vector GetExtendedProperties() const { - return extended_properties_; - } - void AddAction(const PresenceAction& action) { actions_.push_back(action); } - std::vector GetActions() const { return actions_; } - NearbyDevice::Type GetType() const override { - return NearbyDevice::Type::kPresenceDevice; - } - DeviceMotion GetDeviceMotion() const { return device_motion_; } - DeviceIdentityMetaData GetDeviceIdentityMetadata() const { - return device_identity_metadata_; - } - void SetDeviceIdentityMetaData( - const DeviceIdentityMetaData& device_identity_metadata) { - device_identity_metadata_ = device_identity_metadata; - } - void SetDecryptSharedCredential( - const internal::SharedCredential& decrypt_shared_credential) { - decrypt_shared_credential_ = decrypt_shared_credential; - } - const std::optional& GetDecryptSharedCredential() - const { - return decrypt_shared_credential_; - } - absl::Time GetDiscoveryTimestamp() const { return discovery_timestamp_; } - internal::IdentityType GetIdentityType() const { return identity_type_; } - - private: - const absl::Time discovery_timestamp_; - const DeviceMotion device_motion_; - DeviceIdentityMetaData device_identity_metadata_; - std::vector extended_properties_; - std::vector actions_; - std::string endpoint_id_; - internal::IdentityType identity_type_ = internal::IDENTITY_TYPE_UNSPECIFIED; - std::optional decrypt_shared_credential_; -}; - -// Timestamp is not used for equality since if the same device is discovered -// twice, they will have different timestamps and thus will show up as two -// different devices when they are the same device. -inline bool operator==(const PresenceDevice& d1, const PresenceDevice& d2) { - bool shared_credential_equality = true; - shared_credential_equality &= d1.GetDecryptSharedCredential().has_value() == - d2.GetDecryptSharedCredential().has_value(); - if (shared_credential_equality && - d1.GetDecryptSharedCredential().has_value()) { - shared_credential_equality &= - d1.GetDecryptSharedCredential()->SerializeAsString() == - d2.GetDecryptSharedCredential()->SerializeAsString(); - } - return d1.GetDeviceMotion() == d2.GetDeviceMotion() && - d1.GetDeviceIdentityMetadata().SerializeAsString() == - d2.GetDeviceIdentityMetadata().SerializeAsString() && - d1.GetActions() == d2.GetActions() && - d1.GetExtendedProperties() == d2.GetExtendedProperties() && - d1.GetIdentityType() == d2.GetIdentityType() && - shared_credential_equality; -} - -inline bool operator!=(const PresenceDevice& d1, const PresenceDevice& d2) { - return !(d1 == d2); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_ diff --git a/presence/presence_device_provider.cc b/presence/presence_device_provider.cc deleted file mode 100644 index 1b0d4258..00000000 --- a/presence/presence_device_provider.cc +++ /dev/null @@ -1,261 +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 "presence/presence_device_provider.h" - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "absl/types/variant.h" -#include "internal/interop/authentication_status.h" -#include "internal/interop/authentication_transport.h" -#include "internal/interop/device.h" -#include "internal/platform/exception.h" -#include "internal/platform/future.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/platform/logging.h" -#include "presence/implementation/connection_authenticator.h" -#include "presence/implementation/service_controller.h" -#include "presence/presence_device.h" -#include "presence/proto/presence_frame.pb.h" - -namespace nearby { -namespace presence { - -namespace { - -constexpr int kPresenceVersion = 1; - -// TODO(b/317215548): Use Status code rather than custom defined -// authentication status. -std::string AuthenticationErrorToString(AuthenticationStatus status) { - switch (status) { - case AuthenticationStatus::kUnknown: - return "AuthenticationStatus::kUnknown"; - case AuthenticationStatus::kSuccess: - return "AuthenticationStatus::kSuccess"; - case AuthenticationStatus::kFailure: - return "AuthenticationStatus::kFailure"; - } - LOG(ERROR) << "Unexpected value for AuthenticationStatus: " - << static_cast(status); - return "AuthenticationStatus::kUnknown"; -} - -std::optional GetValidCredential( - std::vector local_credentials) { - absl::Time now = SystemClock::ElapsedRealtime(); - for (auto& credential : local_credentials) { - if (absl::FromUnixMillis(credential.start_time_millis()) <= now && - absl::FromUnixMillis(credential.end_time_millis()) > now) { - return credential; - } - } - return std::nullopt; -} - -PresenceAuthenticationFrame BuildInitiatorPresenceAuthenticationFrame( - ConnectionAuthenticator::InitiatorData initiator_data_variant) { - // It is expected that the `PresenceAuthenticationFrame` built for the - // initator role always is `TwoWayInitiatorData`, since the local device is - // always expected to have a valid local credential to be used, and this is - // verified in AuthenticateAsInitiator(), which returns failure if no valid - // local credential is found (which is expected to not happen, since valid - // credentials will be generated if needed before the authentiation is - // called). - // - // Note: std::holds_alternative and std::get cannot be used here because - // they are not supported in Chromium. - DCHECK(absl::holds_alternative( - initiator_data_variant)); - auto two_way_initiator_data = - absl::get( - initiator_data_variant); - - PresenceAuthenticationFrame authentication_frame; - authentication_frame.set_version(kPresenceVersion); - authentication_frame.set_private_key_signature( - two_way_initiator_data.private_key_signature); - authentication_frame.set_shared_credential_id_hash( - two_way_initiator_data.shared_credential_hash); - return authentication_frame; -} - -} // namespace - -PresenceDeviceProvider::PresenceDeviceProvider( - ServiceController* service_controller, - const ConnectionAuthenticator* connection_authenticator) - : service_controller_(*service_controller), - device_(service_controller_.GetDeviceIdentityMetaData()), - connection_authenticator_(*connection_authenticator) { - CHECK(connection_authenticator); -} - -AuthenticationStatus PresenceDeviceProvider::AuthenticateAsInitiator( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const { - Future response; - - // 1. Fetch the local credentials and select the correct one to use - // for authentication by calling `GetValidCredential()`, which - // iterates over the returned list and returns the local credential - // that corresponds with the current time. - // - // TODO(b/304843571): Add support for additional IdentityTypes and for - // AuthenticationStatus::kUnknown. Currently, only `IDENTITY_TYPE_PRIVATE` is - // supported in order to unblock Nearby Presence MVP on CrOS, however in - // order to support future IdentityTypes, there needs to be a way to - // plumb in the requested identity type, as well as report back the - // unknown result to callers in NC. - service_controller_.GetLocalCredentials( - /*credential_selector=*/{.manager_app_id = manager_app_id_, - .account_name = "dummy_account_name", - .identity_type = ::nearby::internal:: - IdentityType::IDENTITY_TYPE_PRIVATE_GROUP}, - /*callback=*/{.credentials_fetched_cb = [this, &response, &remote_device, - &authentication_transport, - &shared_secret]( - auto status_or_credentials) { - if (!status_or_credentials.ok()) { - LOG(INFO) << __func__ << ": failure to fetch local credentials"; - response.Set(AuthenticationStatus::kFailure); - return; - } - - auto credential = GetValidCredential(status_or_credentials.value()); - if (!credential.has_value()) { - LOG(INFO) << __func__ << ": failure to find a valid local credential"; - response.Set(AuthenticationStatus::kFailure); - return; - } - - // 2. Construct the frame and write to the - // |authentication_transport|. - if (!WriteToRemoteDevice( - /*remote_device=*/remote_device, - /*shared_secret=*/shared_secret, - /*authentication_transport=*/authentication_transport, - /*local_credential=*/credential.value(), - /*response=*/response)) { - response.Set(AuthenticationStatus::kFailure); - return; - } - - // 3. Read the message from the remote device via - // |authentication_transport| and verify the response data. - if (!ReadAndVerifyRemoteDeviceData( - /*remote_device=*/remote_device, - /*shared_secret=*/shared_secret, - /*authentication_transport=*/authentication_transport)) { - response.Set(AuthenticationStatus::kFailure); - return; - } - - // 4. Return the status of the authentication to the callers. - response.Set(AuthenticationStatus::kSuccess); - }}); - - LOG(INFO) << __func__ << ": Waiting for future to complete"; - ExceptionOr result = response.Get(); - CHECK(result.ok()); - - LOG(INFO) << "Future:[" << __func__ << "] completed with status:" - << AuthenticationErrorToString(result.result()); - return result.result(); -} - -bool PresenceDeviceProvider::WriteToRemoteDevice( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport, - const internal::LocalCredential& local_credential, - Future& response) const { - // Cast the |remote_device| to a `PresenceDevice` in order to retrieve - // it's shared credentials, which is safe to do since the |remote_device| - // passed to the `PresenceDeviceProvider` will always be a `PresenceDevice`. - const PresenceDevice* remote_presence_device = - static_cast(&remote_device); - auto shared_credential = remote_presence_device->GetDecryptSharedCredential(); - if (!shared_credential.has_value()) { - LOG(INFO) - << __func__ - << ": failure due to no decrypt shared credential from remote device"; - return false; - } - - auto status_or_initiator_data = - connection_authenticator_.BuildSignedMessageAsInitiator( - /*ukey2_secret=*/shared_secret, /*local_credential=*/local_credential, - /*shared_credential=*/shared_credential.value()); - if (!status_or_initiator_data.ok()) { - LOG(INFO) << __func__ << ": failure to build signed message as initiator"; - return false; - } - - // Once the initiator data has been built, construct the Presence frame - // which will be written to the device with the built data. - authentication_transport.WriteMessage( - BuildInitiatorPresenceAuthenticationFrame( - status_or_initiator_data.value()) - .SerializeAsString()); - return true; -} - -bool PresenceDeviceProvider::ReadAndVerifyRemoteDeviceData( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const { - // Fetch the local public credentials to be used to verify the response data. - Future read_and_verify_result; - service_controller_.GetLocalPublicCredentials( - /*credential_selector=*/{.manager_app_id = manager_app_id_, - .account_name = "dummy_account_name", - .identity_type = ::nearby::internal:: - IdentityType::IDENTITY_TYPE_PRIVATE_GROUP}, - /*callback=*/{.credentials_fetched_cb = [this, &read_and_verify_result, - &authentication_transport, - &shared_secret]( - auto status_or_credentials) { - if (!status_or_credentials.ok()) { - LOG(INFO) << __func__ - << ": failure to fetch local public credentials"; - read_and_verify_result.Set(/*success=*/false); - return; - } - - std::string response_data = authentication_transport.ReadMessage(); - auto status = connection_authenticator_.VerifyMessageAsInitiator( - /*authentication_data=*/{.private_key_signature = response_data}, - /*ukey2_secret=*/shared_secret, - /*shared_credential=*/status_or_credentials.value()); - if (!status.ok()) { - LOG(INFO) << __func__ << ": failure to verify remote device"; - read_and_verify_result.Set(/*success=*/false); - return; - } - - read_and_verify_result.Set(/*success=*/true); - }}); - - LOG(INFO) << __func__ << ": Waiting for future to complete"; - ExceptionOr result = read_and_verify_result.Get(); - LOG(INFO) << "Future:[" << __func__ - << "] completed with status:" << result.result(); - return result.result(); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_device_provider.h b/presence/presence_device_provider.h deleted file mode 100644 index afa1df51..00000000 --- a/presence/presence_device_provider.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_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ - -#include -#include - -#include "absl/strings/string_view.h" -#include "internal/interop/authentication_status.h" -#include "internal/interop/authentication_transport.h" -#include "internal/interop/device.h" -#include "internal/interop/device_provider.h" -#include "internal/platform/future.h" -#include "internal/proto/local_credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/implementation/connection_authenticator.h" -#include "presence/presence_device.h" - -namespace nearby { -namespace presence { - -class ServiceController; - -class PresenceDeviceProvider : public NearbyDeviceProvider { - public: - PresenceDeviceProvider( - ServiceController* service_controller, - const ConnectionAuthenticator* connection_authenticator); - - const NearbyDevice* GetLocalDevice() override { return &device_; } - - // To authenticate as an initiator (when the device is in the scanning role), - // the PresenceDeviceProvider will block and: - // 1. Fetch the local credentials and select the correct one to use for - // authentication. - // 2. Construct the frame and write to the |authentication_transport|. - // 3. Read the message from the remote device via |authentication_transport|. - // 4. Return the status of the authentication to the callers. - AuthenticationStatus AuthenticateAsInitiator( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const override; - - AuthenticationStatus AuthenticateAsResponder( - absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const override { - // TODO(b/282027237): Implement. - return AuthenticationStatus::kUnknown; - } - - void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata) { - device_.SetDeviceIdentityMetaData(device_identity_metadata); - } - - void SetManagerAppId(absl::string_view manager_app_id) { - manager_app_id_ = manager_app_id; - } - - std::string GetManagerAppId() { return manager_app_id_; } - - private: - bool WriteToRemoteDevice( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport, - const internal::LocalCredential& local_credential, - Future& response) const; - bool ReadAndVerifyRemoteDeviceData( - const NearbyDevice& remote_device, absl::string_view shared_secret, - const AuthenticationTransport& authentication_transport) const; - - ServiceController& service_controller_; - PresenceDevice device_; - std::string manager_app_id_; - const ConnectionAuthenticator& connection_authenticator_; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ diff --git a/presence/presence_device_provider_test.cc b/presence/presence_device_provider_test.cc deleted file mode 100644 index a8985270..00000000 --- a/presence/presence_device_provider_test.cc +++ /dev/null @@ -1,296 +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 "presence/presence_device_provider.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/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "internal/crypto/ed25519.h" -#include "internal/interop/authentication_status.h" -#include "internal/interop/authentication_transport.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/implementation/system_clock.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/local_credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/implementation/connection_authenticator.h" -#include "presence/implementation/mock_connection_authenticator.h" -#include "presence/implementation/mock_service_controller.h" -#include "presence/presence_device.h" -#include "presence/proto/presence_frame.pb.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::internal::DeviceIdentityMetaData; - -constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; -constexpr absl::string_view kManagerAppId = "test_app_id"; -constexpr char kUkey2Secret[] = {0x34, 0x56, 0x78, 0x90}; -constexpr char kKeySeed[] = {1, 2, 3, 4, 5, 6, 7, 8}; -constexpr int kPresenceVersion = 1; -constexpr absl::string_view kSharedCredentialHash = "shared_cred_hash"; -constexpr absl::string_view kPrivateKeySignature = "private_key_signature"; - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_PHONE); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address(kMacAddr); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} - -nearby::internal::LocalCredential CreateValidLocalCredential( - const crypto::Ed25519KeyPair& key_pair) { - nearby::internal::LocalCredential credential; - absl::Time now = SystemClock::ElapsedRealtime(); - credential.set_start_time_millis(absl::ToUnixMillis(now)); - credential.set_end_time_millis(absl::ToUnixMillis(now + absl::Minutes(10))); - credential.mutable_connection_signing_key()->set_key( - absl::StrCat(key_pair.private_key, key_pair.public_key)); - credential.set_key_seed(kKeySeed); - return credential; -} - -nearby::internal::LocalCredential CreateExpiredLocalCredential() { - nearby::internal::LocalCredential credential; - absl::Time now = SystemClock::ElapsedRealtime(); - credential.set_start_time_millis(absl::ToUnixMillis(now - absl::Minutes(30))); - credential.set_end_time_millis(absl::ToUnixMillis(now - absl::Minutes(10))); - return credential; -} - -internal::SharedCredential BuildSharedCredential( - const crypto::Ed25519KeyPair& key_pair) { - internal::SharedCredential shared_credential; - shared_credential.set_connection_signature_verification_key( - key_pair.public_key); - shared_credential.set_key_seed(kKeySeed); - return shared_credential; -} - -ConnectionAuthenticator::TwoWayInitiatorData BuildDefaultInitiatorData() { - ConnectionAuthenticator::TwoWayInitiatorData data; - data.shared_credential_hash = kSharedCredentialHash; - data.private_key_signature = kPrivateKeySignature; - return data; -} - -class MockAuthenticationTransport : public AuthenticationTransport { - public: - MOCK_METHOD(void, WriteMessage, (absl::string_view), (const, override)); - MOCK_METHOD(std::string, ReadMessage, (), (const, override)); -}; - -class PresenceDeviceProviderTest : public ::testing::Test { - public: - PresenceDeviceProviderTest() { - ON_CALL(mock_service_controller_, GetDeviceIdentityMetaData) - .WillByDefault(testing::Return(CreateTestDeviceIdentityMetaData())); - provider_ = std::make_unique( - &mock_service_controller_, &mock_connection_authenticator_); - } - - void SetUp() override { - auto key_pair_or_status = crypto::Ed25519Signer::CreateNewKeyPair(); - ASSERT_OK_AND_ASSIGN(key_pair_, key_pair_or_status); - } - - protected: - MockServiceController mock_service_controller_; - std::unique_ptr provider_; - crypto::Ed25519KeyPair key_pair_; - MockConnectionAuthenticator mock_connection_authenticator_; -}; - -TEST_F(PresenceDeviceProviderTest, ProviderIsNotTriviallyConstructible) { - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST_F(PresenceDeviceProviderTest, DeviceProviderWorks) { - auto device = provider_->GetLocalDevice(); - ASSERT_EQ(device->GetType(), NearbyDevice::Type::kPresenceDevice); - auto presence_device = static_cast(device); - EXPECT_EQ(presence_device->GetDeviceIdentityMetadata().SerializeAsString(), - CreateTestDeviceIdentityMetaData().SerializeAsString()); -} - -TEST_F(PresenceDeviceProviderTest, DeviceProviderCanUpdateDevice) { - auto device = provider_->GetLocalDevice(); - ASSERT_EQ(device->GetType(), NearbyDevice::Type::kPresenceDevice); - auto presence_device = static_cast(device); - EXPECT_EQ(presence_device->GetDeviceIdentityMetadata().SerializeAsString(), - CreateTestDeviceIdentityMetaData().SerializeAsString()); - auto new_metadata = CreateTestDeviceIdentityMetaData(); - new_metadata.set_device_name("NP interop device"); - provider_->UpdateDeviceIdentityMetaData(new_metadata); - EXPECT_EQ(presence_device->GetDeviceIdentityMetadata().SerializeAsString(), - new_metadata.SerializeAsString()); -} - -TEST_F(PresenceDeviceProviderTest, SetGetManagerAppId) { - provider_->SetManagerAppId(kManagerAppId); - EXPECT_EQ(provider_->GetManagerAppId(), kManagerAppId); -} - -TEST_F(PresenceDeviceProviderTest, - AuthenticateAsInitiatorFails_FailToFetchCredentials) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::move(callback.credentials_fetched_cb)( - absl::Status(absl::StatusCode::kCancelled, /*msg=*/std::string())); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - MockAuthenticationTransport authentication_transport; - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - EXPECT_EQ(AuthenticationStatus::kFailure, status); -} - -TEST_F(PresenceDeviceProviderTest, - AuthenticateAsInitiatorFails_NoValidCredentials) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(CreateExpiredLocalCredential()); - std::move(callback.credentials_fetched_cb)(credentials); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - MockAuthenticationTransport authentication_transport; - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - EXPECT_EQ(AuthenticationStatus::kFailure, status); -} - -TEST_F(PresenceDeviceProviderTest, - AuthenticateAsInitiator_NoRemoteSharedCredential) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(CreateValidLocalCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(credentials); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - MockAuthenticationTransport authentication_transport; - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - - EXPECT_EQ(AuthenticationStatus::kFailure, status); -} - -TEST_F(PresenceDeviceProviderTest, AuthenticateAsInitiator_FailureToVerify) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(CreateValidLocalCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(credentials); - }); - EXPECT_CALL(mock_service_controller_, GetLocalPublicCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(BuildSharedCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(credentials); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - remote_device.SetDecryptSharedCredential(BuildSharedCredential(key_pair_)); - - MockAuthenticationTransport authentication_transport; - EXPECT_CALL(authentication_transport, WriteMessage) - .WillOnce([&](absl::string_view message) { - PresenceAuthenticationFrame authentication_frame; - EXPECT_TRUE(authentication_frame.ParseFromString(message)); - EXPECT_EQ(kPresenceVersion, authentication_frame.version()); - }); - EXPECT_CALL(authentication_transport, ReadMessage).WillOnce([&]() { - PresenceAuthenticationFrame authentication_frame; - return authentication_frame.SerializeAsString(); - }); - - EXPECT_CALL(mock_connection_authenticator_, BuildSignedMessageAsInitiator) - .WillOnce(testing::Return(BuildDefaultInitiatorData())); - EXPECT_CALL(mock_connection_authenticator_, VerifyMessageAsInitiator) - .WillOnce(testing::Return( - absl::Status(absl::StatusCode::kCancelled, /*msg=*/std::string()))); - - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - EXPECT_EQ(AuthenticationStatus::kFailure, status); -} - -TEST_F(PresenceDeviceProviderTest, AuthenticateAsInitiator_Success) { - EXPECT_CALL(mock_service_controller_, GetLocalCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetLocalCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(CreateValidLocalCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(credentials); - }); - EXPECT_CALL(mock_service_controller_, GetLocalPublicCredentials) - .WillOnce([&](const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - std::vector credentials; - credentials.push_back(BuildSharedCredential(key_pair_)); - std::move(callback.credentials_fetched_cb)(std::move(credentials)); - }); - - PresenceDevice remote_device(CreateTestDeviceIdentityMetaData()); - remote_device.SetDecryptSharedCredential(BuildSharedCredential(key_pair_)); - - ON_CALL(mock_connection_authenticator_, BuildSignedMessageAsInitiator) - .WillByDefault(testing::Return(BuildDefaultInitiatorData())); - - MockAuthenticationTransport authentication_transport; - EXPECT_CALL(authentication_transport, WriteMessage) - .WillOnce([&](absl::string_view message) { - PresenceAuthenticationFrame authentication_frame; - EXPECT_TRUE(authentication_frame.ParseFromString(message)); - EXPECT_EQ(kPresenceVersion, authentication_frame.version()); - }); - - auto status = provider_->AuthenticateAsInitiator( - /*remote_device=*/remote_device, /*shared_secret=*/kUkey2Secret, - /*authentication_transport=*/authentication_transport); - - EXPECT_EQ(AuthenticationStatus::kSuccess, status); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_device_test.cc b/presence/presence_device_test.cc deleted file mode 100644 index e567d749..00000000 --- a/presence/presence_device_test.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 "presence/presence_device.h" - -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "connections/implementation/proto/offline_wire_formats.pb.h" -#include "internal/platform/ble_connection_info.h" -#include "internal/proto/credential.pb.h" -#include "internal/proto/metadata.pb.h" -#include "presence/data_element.h" -#include "presence/presence_action.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::DeviceIdentityMetaData; -using ::testing::Contains; - -constexpr DeviceMotion::MotionType kDefaultMotionType = - DeviceMotion::MotionType::kPointAndHold; -constexpr float kDefaultConfidence = 0; -constexpr float kTestConfidence = 0.1; -constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; -constexpr int kDataElementType = DataElement::kBatteryFieldType; -constexpr absl::string_view kDataElementValue = "15"; -constexpr char kEndpointId[] = "endpoint_id"; -constexpr int kTestAction = 3; - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_LAPTOP); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address(kMacAddr); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} -TEST(PresenceDeviceTest, EndpointIdConstructor) { - PresenceDevice device(kEndpointId); - EXPECT_EQ(device.GetEndpointId(), kEndpointId); -} - -TEST(PresenceDeviceTest, DefaultMotionEquals) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device1(device_identity_metadata); - PresenceDevice device2(device_identity_metadata); - EXPECT_EQ(device1, device2); -} - -TEST(PresenceDeviceTest, ExplicitInitEquals) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - internal::SharedCredential shared_credential; - shared_credential.set_credential_type(internal::CREDENTIAL_TYPE_GAIA); - PresenceDevice device1 = - PresenceDevice({kDefaultMotionType, kTestConfidence}, - device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - device1.SetDecryptSharedCredential(shared_credential); - PresenceDevice device2 = - PresenceDevice({kDefaultMotionType, kTestConfidence}, - device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - device2.SetDecryptSharedCredential(shared_credential); - EXPECT_EQ(device1, device2); -} - -TEST(PresenceDeviceTest, ExplicitInitNotEquals) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device1 = - PresenceDevice({kDefaultMotionType}, device_identity_metadata, - internal::IDENTITY_TYPE_PUBLIC); - PresenceDevice device2 = PresenceDevice( - {kDefaultMotionType, kTestConfidence}, device_identity_metadata, - internal::IDENTITY_TYPE_PRIVATE_GROUP); - EXPECT_NE(device1, device2); -} - -TEST(PresenceDeviceTest, TestGetBleConnectionInfo) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - device.AddAction(PresenceAction(kTestAction)); - auto info = (device.GetConnectionInfos().at(0)); - ASSERT_TRUE(std::holds_alternative(info)); - auto ble_info = std::get(info); - EXPECT_EQ(ble_info.GetMacAddress(), kMacAddr); - EXPECT_EQ(ble_info.GetActions(), std::vector{kTestAction}); -} - -TEST(PresenceDeviceTest, TestGetAddExtendedProperties) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - device.AddExtendedProperty({kDataElementType, kDataElementValue}); - ASSERT_EQ(device.GetExtendedProperties().size(), 1); - EXPECT_EQ(device.GetExtendedProperties()[0], - DataElement(kDataElementType, kDataElementValue)); -} - -TEST(PresenceDeviceTest, TestGetAddExtendedPropertiesVector) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - device.AddExtendedProperties( - {DataElement(kDataElementType, kDataElementValue)}); - ASSERT_EQ(device.GetExtendedProperties().size(), 1); - EXPECT_EQ(device.GetExtendedProperties()[0], - DataElement(kDataElementType, kDataElementValue)); -} - -TEST(PresenceDeviceTest, TestAddGetActions) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - device.AddAction({kTestAction}); - ASSERT_EQ(device.GetActions().size(), 1); - EXPECT_EQ(device.GetActions()[0], PresenceAction(kTestAction)); -} - -TEST(PresenceDeviceTest, TestEndpointIdIsCorrectLength) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - EXPECT_EQ(device.GetEndpointId().length(), kEndpointIdLength); -} - -TEST(PresenceDeviceTest, TestEndpointIdIsRandom) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = - PresenceDevice({kDefaultMotionType}, device_identity_metadata); - EXPECT_EQ(device.GetEndpointId().length(), kEndpointIdLength); - EXPECT_NE(device.GetEndpointId(), std::string(kEndpointIdLength, 0)); -} - -TEST(PresenceDeviceTest, TestGetIdentityType) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = PresenceDevice( - DeviceMotion(), device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(device.GetIdentityType(), internal::IDENTITY_TYPE_PUBLIC); -} - -TEST(PresenceDeviceTest, TestGetDecryptSharedCredential) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = PresenceDevice( - DeviceMotion(), device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - EXPECT_EQ(device.GetDecryptSharedCredential(), std::nullopt); - internal::SharedCredential shared_credential; - shared_credential.set_credential_type(internal::CREDENTIAL_TYPE_GAIA); - device.SetDecryptSharedCredential(shared_credential); - EXPECT_EQ(device.GetDecryptSharedCredential()->SerializeAsString(), - shared_credential.SerializeAsString()); -} - -TEST(PresenceDeviceTest, TestToProtoBytes) { - DeviceIdentityMetaData device_identity_metadata = - CreateTestDeviceIdentityMetaData(); - PresenceDevice device = PresenceDevice( - DeviceMotion(), device_identity_metadata, internal::IDENTITY_TYPE_PUBLIC); - std::string proto_bytes = device.ToProtoBytes(); - location::nearby::connections::PresenceDevice device_frame; - ASSERT_TRUE(device_frame.ParseFromString(proto_bytes)); - // Public identity. - EXPECT_THAT(device_frame.identity_type(), Contains(2)); - EXPECT_EQ(device_frame.endpoint_type(), - location::nearby::connections::PRESENCE_ENDPOINT); - EXPECT_EQ(device_frame.endpoint_id(), device.GetEndpointId()); - EXPECT_EQ(device_frame.device_type(), - location::nearby::connections::PresenceDevice::LAPTOP); - EXPECT_EQ(device_frame.device_name(), "NP test device"); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_identity_test.cc b/presence/presence_identity_test.cc deleted file mode 100644 index 5b45704d..00000000 --- a/presence/presence_identity_test.cc +++ /dev/null @@ -1,44 +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. - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "internal/proto/credential.pb.h" - -namespace nearby { -namespace presence { -namespace { -using ::nearby::internal::IdentityType; - -constexpr IdentityType kTestIdentityType = - IdentityType::IDENTITY_TYPE_CONTACTS_GROUP; - -TEST(PresenceIdentityTest, ExplicitInitEquals) { - IdentityType identity1 = {kTestIdentityType}; - IdentityType identity2 = {kTestIdentityType}; - EXPECT_EQ(identity1, identity2); - EXPECT_EQ(identity1, kTestIdentityType); -} - - -TEST(PresenceIdentityTest, CopyInitEquals) { - IdentityType identity1 = {kTestIdentityType}; - IdentityType identity2 = {identity1}; - EXPECT_EQ(identity1, identity2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_service.h b/presence/presence_service.h deleted file mode 100644 index 8fe11637..00000000 --- a/presence/presence_service.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2020-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_PRESENCE_PRESENCE_SERVICE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_SERVICE_H_ - -#include -#include - -#include "internal/interop/device_provider.h" -#include "internal/proto/metadata.pb.h" -#include "presence/data_types.h" -#include "presence/presence_client.h" - -namespace nearby { -namespace presence { - -class PresenceService { - public: - virtual ~PresenceService() = default; - - virtual std::unique_ptr CreatePresenceClient() = 0; - - virtual absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) = 0; - virtual void StopScan(ScanSessionId session_id) = 0; - - virtual absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) = 0; - - virtual void StopBroadcast(BroadcastSessionId session_id) = 0; - - virtual void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) = 0; - - virtual NearbyDeviceProvider* GetLocalDeviceProvider() = 0; - - virtual void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) = 0; - - virtual void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) = 0; - - // Testing only. - virtual ::nearby::internal::DeviceIdentityMetaData - GetDeviceIdentityMetaData() = 0; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_SERVICE_H_ diff --git a/presence/presence_service_impl.cc b/presence/presence_service_impl.cc deleted file mode 100644 index d107e618..00000000 --- a/presence/presence_service_impl.cc +++ /dev/null @@ -1,83 +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. - -#include "presence/presence_service_impl.h" - -#include -#include -#include - -#include "internal/platform/borrowable.h" -#include "presence/data_types.h" -#include "presence/presence_client_impl.h" -#include "presence/presence_device_provider.h" - -namespace nearby { -namespace presence { - -std::unique_ptr PresenceServiceImpl::CreatePresenceClient() { - return PresenceClientImpl::Factory::Create(lender_.GetBorrowable()); -} - -absl::StatusOr PresenceServiceImpl::StartScan( - ScanRequest scan_request, ScanCallback callback) { - return service_controller_.StartScan(scan_request, std::move(callback)); -} - -void PresenceServiceImpl::StopScan(ScanSessionId id) { - service_controller_.StopScan(id); -} - -absl::StatusOr PresenceServiceImpl::StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) { - return service_controller_.StartBroadcast(broadcast_request, - std::move(callback)); -} - -void PresenceServiceImpl::StopBroadcast(BroadcastSessionId session) { - service_controller_.StopBroadcast(session); -} - -void PresenceServiceImpl::UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) { - provider_.UpdateDeviceIdentityMetaData(device_identity_metadata); - provider_.SetManagerAppId(manager_app_id); - service_controller_.UpdateDeviceIdentityMetaData( - device_identity_metadata, regen_credentials, manager_app_id, - identity_types, credential_life_cycle_days, - contiguous_copy_of_credentials, std::move(credentials_generated_cb)); -} - -void PresenceServiceImpl::GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) { - service_controller_.GetLocalPublicCredentials(credential_selector, - std::move(callback)); -} - -void PresenceServiceImpl::UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) { - service_controller_.UpdateRemotePublicCredentials( - manager_app_id, account_name, remote_public_creds, - std::move(credentials_updated_cb)); -} - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_service_impl.h b/presence/presence_service_impl.h deleted file mode 100644 index a8d5a219..00000000 --- a/presence/presence_service_impl.h +++ /dev/null @@ -1,109 +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_PRESENCE_PRESENCE_SERVICE_IMPL_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_SERVICE_IMPL_H_ - -#include -#include - -#include "absl/status/statusor.h" -#include "absl/strings/string_view.h" -#include "internal/platform/borrowable.h" -#include "internal/platform/implementation/credential_callbacks.h" -#include "internal/platform/single_thread_executor.h" -#include "internal/proto/metadata.pb.h" -#include "presence/broadcast_request.h" -#include "presence/data_types.h" -#include "presence/implementation/broadcast_manager.h" -#include "presence/implementation/connection_authenticator_impl.h" -#include "presence/implementation/credential_manager_impl.h" -#include "presence/implementation/mediums/mediums.h" -#include "presence/implementation/scan_manager.h" -#include "presence/implementation/service_controller_impl.h" -#include "presence/presence_client.h" -#include "presence/presence_device_provider.h" -#include "presence/presence_service.h" -#include "presence/scan_request.h" -#include "internal/interop/device_provider.h" - -namespace nearby { -namespace presence { - -/* - * PresenceService hosts presence functions by routing invokes to the unique - * {@code ServiceController}. PresenceService should be initialized once and - * only once in the process that hosting presence functions. - */ -class PresenceServiceImpl : public PresenceService { - public: - PresenceServiceImpl() = default; - ~PresenceServiceImpl() override { lender_.Release(); } - - std::unique_ptr CreatePresenceClient() override; - - absl::StatusOr StartScan(ScanRequest scan_request, - ScanCallback callback) override; - void StopScan(ScanSessionId session_id) override; - - absl::StatusOr StartBroadcast( - BroadcastRequest broadcast_request, BroadcastCallback callback) override; - - void StopBroadcast(BroadcastSessionId session_id) override; - - void UpdateDeviceIdentityMetaData( - const ::nearby::internal::DeviceIdentityMetaData& - device_identity_metadata, - bool regen_credentials, absl::string_view manager_app_id, - const std::vector& identity_types, - int credential_life_cycle_days, int contiguous_copy_of_credentials, - GenerateCredentialsResultCallback credentials_generated_cb) override; - - NearbyDeviceProvider* GetLocalDeviceProvider() override { - return &provider_; - } - - ::nearby::internal::DeviceIdentityMetaData GetDeviceIdentityMetaData() - override { - return service_controller_.GetDeviceIdentityMetaData(); - } - - void GetLocalPublicCredentials( - const CredentialSelector& credential_selector, - GetPublicCredentialsResultCallback callback) override; - - void UpdateRemotePublicCredentials( - absl::string_view manager_app_id, absl::string_view account_name, - const std::vector& - remote_public_creds, - UpdateRemotePublicCredentialsCallback credentials_updated_cb) override; - - private: - SingleThreadExecutor executor_; - Mediums mediums_; - CredentialManagerImpl credential_manager_{&executor_}; - ScanManager scan_manager_{mediums_, credential_manager_, executor_}; - BroadcastManager broadcast_manager_{mediums_, credential_manager_, executor_}; - ServiceControllerImpl service_controller_{ - &executor_, &credential_manager_, &scan_manager_, &broadcast_manager_}; - ConnectionAuthenticatorImpl connection_authenticator_; - ::nearby::Lender lender_{this}; - PresenceDeviceProvider provider_{&service_controller_, - &connection_authenticator_}; -}; - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_SERVICE_IMPL_H_ diff --git a/presence/presence_service_test.cc b/presence/presence_service_test.cc deleted file mode 100644 index 1f24275b..00000000 --- a/presence/presence_service_test.cc +++ /dev/null @@ -1,152 +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. - -#include "presence/presence_service.h" - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" -#include "presence/presence_client.h" -#include "presence/presence_service_impl.h" - -namespace nearby { -namespace presence { -namespace { -using DeviceIdentityMetaData = ::nearby::internal::DeviceIdentityMetaData; - -constexpr absl::string_view kManagerAppId = "TEST_MANAGER_APP"; -constexpr absl::string_view kAccountName = "dummy account"; - -class PresenceServiceTest : public testing::Test { - protected: - nearby::MediumEnvironment& env_{nearby::MediumEnvironment::Instance()}; -}; - -DeviceIdentityMetaData CreateTestDeviceIdentityMetaData() { - DeviceIdentityMetaData device_identity_metadata; - device_identity_metadata.set_device_type( - internal::DeviceType::DEVICE_TYPE_PHONE); - device_identity_metadata.set_device_name("NP test device"); - device_identity_metadata.set_bluetooth_mac_address( - "\xFF\xFF\xFF\xFF\xFF\xFF"); - device_identity_metadata.set_device_id("\x12\xab\xcd"); - return device_identity_metadata; -} - -CredentialSelector BuildDefaultCredentialSelector() { - CredentialSelector credential_selector; - credential_selector.manager_app_id = std::string(kManagerAppId); - credential_selector.account_name = std::string(kAccountName); - credential_selector.identity_type = internal::IDENTITY_TYPE_PRIVATE_GROUP; - return credential_selector; -} - -TEST_F(PresenceServiceTest, DefaultConstructorWorks) { - PresenceServiceImpl presence_service; -} - -TEST_F(PresenceServiceTest, StartThenStopScan) { - env_.Start(); - absl::Status scan_result; - ScanCallback scan_callback = { - .start_scan_cb = [&](absl::Status status) { scan_result = status; }, - }; - PresenceServiceImpl presence_service; - std::unique_ptr client = - presence_service.CreatePresenceClient(); - - absl::StatusOr scan_session = client->StartScan( - {}, - { - .start_scan_cb = [&](absl::Status status) { scan_result = status; }, - }); - absl::StatusOr scan_session_with_default_params = - client->StartScan(ScanRequest(), ScanCallback()); - - ASSERT_OK(scan_session); - ASSERT_OK(scan_session_with_default_params); - EXPECT_NE(*scan_session, *scan_session_with_default_params); - - client->StopScan(*scan_session); - client->StopScan(*scan_session_with_default_params); - env_.Stop(); -} - -TEST_F(PresenceServiceTest, UpdatingDeviceIdentityMetaDataWorks) { - PresenceServiceImpl presence_service; - presence_service.UpdateDeviceIdentityMetaData( - CreateTestDeviceIdentityMetaData(), false, "Test app", {}, 3, 1, {}); - EXPECT_EQ(presence_service.GetDeviceIdentityMetaData().SerializeAsString(), - CreateTestDeviceIdentityMetaData().SerializeAsString()); -} - -TEST_F(PresenceServiceTest, TestGetDeviceProvider) { - PresenceServiceImpl presence_service; - EXPECT_NE(presence_service.GetLocalDeviceProvider(), nullptr); -} - -TEST_F(PresenceServiceTest, TestGetPublicCredentials) { - PresenceServiceImpl presence_service; - CredentialSelector selector = BuildDefaultCredentialSelector(); - absl::Status status; - nearby::CountDownLatch fetched_latch(1); - presence_service.GetLocalPublicCredentials( - selector, - {.credentials_fetched_cb = - [&status, &fetched_latch]( - absl::StatusOr> - result) { - status = result.status(); - fetched_latch.CountDown(); - }}); - EXPECT_TRUE(fetched_latch.Await().Ok()); - EXPECT_THAT(status, testing::status::StatusIs(absl::StatusCode::kNotFound)); -} - -TEST_F(PresenceServiceTest, TestUpdateRemotePublicCredentials) { - PresenceServiceImpl presence_service; - internal::SharedCredential public_credential_for_test; - public_credential_for_test.set_identity_type( - internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP); - std::vector public_credentials{ - {public_credential_for_test}}; - - nearby::CountDownLatch updated_latch(1); - UpdateRemotePublicCredentialsCallback update_credentials_cb{ - .credentials_updated_cb = - [&updated_latch](absl::Status status) { - if (status.ok()) { - updated_latch.CountDown(); - } - }, - }; - - presence_service.UpdateRemotePublicCredentials( - kManagerAppId, kAccountName, public_credentials, - std::move(update_credentials_cb)); - - EXPECT_TRUE(updated_latch.Await().Ok()); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/presence_zone.cc b/presence/presence_zone.cc deleted file mode 100644 index 2fcdad45..00000000 --- a/presence/presence_zone.cc +++ /dev/null @@ -1,82 +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. - -#include "presence/presence_zone.h" - -namespace nearby { -namespace presence { - -PresenceZone::DistanceBoundary::DistanceBoundary(float min_distance_meters, - float max_distance_meters, - RangeType range_type) noexcept - : min_distance_meters_(min_distance_meters), - max_distance_meters_(max_distance_meters), - range_type_(range_type) {} - -float PresenceZone::DistanceBoundary::GetMinDistanceMeters() const { - return min_distance_meters_; -} - -float PresenceZone::DistanceBoundary::GetMaxDistanceMeters() const { - return max_distance_meters_; -} - -PresenceZone::DistanceBoundary::RangeType -PresenceZone::DistanceBoundary::GetRangeType() const { - return range_type_; -} - -PresenceZone::AngleOfArrivalBoundary::AngleOfArrivalBoundary( - float min_angle_degrees, float max_angle_degrees) noexcept - : min_angle_degrees_(min_angle_degrees), - max_angle_degrees_(max_angle_degrees) {} - -float PresenceZone::AngleOfArrivalBoundary::GetMinAngleDegrees() const { - return min_angle_degrees_; -} - -float PresenceZone::AngleOfArrivalBoundary::GetMaxAngleDegrees() const { - return max_angle_degrees_; -} - -PresenceZone::PresenceZone( - const DistanceBoundary& distance_boundary, - const AngleOfArrivalBoundary& azimuth_angle_boundary, - const AngleOfArrivalBoundary& elevation_angle_boundary, - const std::vector& device_motions) - : distance_boundary_(distance_boundary), - azimuth_angle_boundary_(azimuth_angle_boundary), - elevation_angle_boundary_(elevation_angle_boundary), - device_motions_(device_motions) {} - -PresenceZone::DistanceBoundary PresenceZone::GetDistanceBoundary() const { - return distance_boundary_; -} - -PresenceZone::AngleOfArrivalBoundary PresenceZone::GetAzimuthAngleBoundary() - const { - return azimuth_angle_boundary_; -} - -PresenceZone::AngleOfArrivalBoundary PresenceZone::GetElevationAngleBoundary() - const { - return elevation_angle_boundary_; -} - -std::vector PresenceZone::GetLocalDeviceMotions() const { - return device_motions_; -} - -} // namespace presence -} // namespace nearby diff --git a/presence/presence_zone.h b/presence/presence_zone.h deleted file mode 100644 index c2883100..00000000 --- a/presence/presence_zone.h +++ /dev/null @@ -1,108 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ZONE_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ZONE_H_ - -#include - -#include "presence/device_motion.h" -namespace nearby { -namespace presence { -class PresenceZone { - public: - class DistanceBoundary { - public: - enum class RangeType { - kRangeUnknown = 0, - kFar, // Distance is very far away from the peer device. - kWithinReach, // Distance is very close to the peer device, typically - // within one meter or less. - kWithinTap, // Distance is within tap range to the peer device, typically - // within ~0.127 meters. - }; - DistanceBoundary(float min_distance_meters = 0, - float max_distance_meters = 0, - RangeType range_type = RangeType::kRangeUnknown) noexcept; - float GetMinDistanceMeters() const; - float GetMaxDistanceMeters() const; - RangeType GetRangeType() const; - - private: - const float min_distance_meters_; - const float max_distance_meters_; - const RangeType range_type_; - }; - - class AngleOfArrivalBoundary { - public: - AngleOfArrivalBoundary(float min_angle_degrees = 0, - float max_angle_degrees = 0) noexcept; - float GetMinAngleDegrees() const; - float GetMaxAngleDegrees() const; - - private: - const float min_angle_degrees_; - const float max_angle_degrees_; - }; - - PresenceZone(const DistanceBoundary& = {}, const AngleOfArrivalBoundary& = {}, - const AngleOfArrivalBoundary& = {}, - const std::vector& = {}); - DistanceBoundary GetDistanceBoundary() const; - AngleOfArrivalBoundary GetAzimuthAngleBoundary() const; - AngleOfArrivalBoundary GetElevationAngleBoundary() const; - std::vector GetLocalDeviceMotions() const; - - private: - const DistanceBoundary distance_boundary_; - const AngleOfArrivalBoundary azimuth_angle_boundary_; - const AngleOfArrivalBoundary elevation_angle_boundary_; - const std::vector device_motions_; -}; - -inline bool operator==(const PresenceZone::DistanceBoundary& d1, - const PresenceZone::DistanceBoundary& d2) { - return d1.GetMinDistanceMeters() == d2.GetMinDistanceMeters() && - d1.GetMaxDistanceMeters() == d2.GetMaxDistanceMeters() && - d1.GetRangeType() == d2.GetRangeType(); -} -inline bool operator!=(const PresenceZone::DistanceBoundary& d1, - const PresenceZone::DistanceBoundary& d2) { - return !(d1 == d2); -} -inline bool operator==(const PresenceZone::AngleOfArrivalBoundary& a1, - const PresenceZone::AngleOfArrivalBoundary& a2) { - return a1.GetMinAngleDegrees() == a2.GetMinAngleDegrees() && - a1.GetMaxAngleDegrees() == a2.GetMaxAngleDegrees(); -} -inline bool operator!=(const PresenceZone::AngleOfArrivalBoundary& a1, - const PresenceZone::AngleOfArrivalBoundary& a2) { - return !(a1 == a2); -} - -inline bool operator==(const PresenceZone& z1, const PresenceZone& z2) { - return z1.GetDistanceBoundary() == z2.GetDistanceBoundary() && - z1.GetAzimuthAngleBoundary() == z2.GetAzimuthAngleBoundary() && - z1.GetElevationAngleBoundary() == z2.GetElevationAngleBoundary() && - z1.GetLocalDeviceMotions() == z2.GetLocalDeviceMotions(); -} -inline bool operator!=(const PresenceZone& z1, const PresenceZone& z2) { - return !(z1 == z2); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_ZONE_H_ diff --git a/presence/presence_zone_test.cc b/presence/presence_zone_test.cc deleted file mode 100644 index e813bf48..00000000 --- a/presence/presence_zone_test.cc +++ /dev/null @@ -1,221 +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. - -#include "presence/presence_zone.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "presence/device_motion.h" - -namespace nearby { -namespace presence { -namespace { - -using DistanceBoundary = nearby::presence::PresenceZone::DistanceBoundary; -using RangeType = nearby::presence::PresenceZone::DistanceBoundary::RangeType; -using AngleOfArrivalBoundary = - nearby::presence::PresenceZone::AngleOfArrivalBoundary; - -static const float kDefaultDistanceMeters = 0; -static const float kTestMinDistanceMeters = 1; -static const float kTestMaxDistanceMeters = 2; - -static const float kDefaultDegrees = 0; -static const float kTestMinAngleDegrees = 10; -static const float kTestMaxAngleDegrees = 20; - -static const float kTestConfidence = 0.1; - -static const RangeType kDefaultRangeType = RangeType::kRangeUnknown; -static const RangeType kTestRangeType = RangeType::kFar; - -static const DistanceBoundary kDefaultDistanceBoundary; -static const DistanceBoundary kTestDistanceBoundary = { - kTestMinDistanceMeters, kTestMaxDistanceMeters, kTestRangeType}; -static const AngleOfArrivalBoundary kDefaultAngleBoundary; -static const AngleOfArrivalBoundary kTestAzimuthAngleBoundary = { - kTestMinAngleDegrees, kTestMaxAngleDegrees}; -static const AngleOfArrivalBoundary kTestElevationAngleBoundary = { - kTestMinAngleDegrees, kTestMaxAngleDegrees}; -static const DeviceMotion kTestDeviceMotion = { - DeviceMotion::MotionType::kPointAndHold, kTestConfidence}; - -TEST(DistanceBoundaryTest, DefaultConstructorWorks) { - DistanceBoundary boundary; - EXPECT_EQ(boundary.GetMinDistanceMeters(), kDefaultDistanceMeters); - EXPECT_EQ(boundary.GetMaxDistanceMeters(), kDefaultDistanceMeters); - EXPECT_EQ(boundary.GetRangeType(), kDefaultRangeType); -} - -TEST(DistanceBoundaryTest, DefaultEquals) { - DistanceBoundary boundary1; - DistanceBoundary boundary2; - EXPECT_EQ(boundary1, boundary2); -} - -TEST(DistanceBoundaryTest, PartiallyInitializationWorks) { - DistanceBoundary boundary1 = {kTestMinDistanceMeters, kTestMaxDistanceMeters}; - DistanceBoundary boundary2 = {kTestMinDistanceMeters}; - EXPECT_EQ(boundary1.GetMinDistanceMeters(), kTestMinDistanceMeters); - EXPECT_EQ(boundary1.GetMaxDistanceMeters(), kTestMaxDistanceMeters); - EXPECT_EQ(boundary1.GetRangeType(), kDefaultRangeType); - EXPECT_EQ(boundary2.GetMinDistanceMeters(), kTestMinDistanceMeters); - EXPECT_EQ(boundary2.GetMaxDistanceMeters(), kDefaultDistanceMeters); - EXPECT_EQ(boundary2.GetRangeType(), kDefaultRangeType); -} - -TEST(DistanceBoundaryTest, ExplicitInitEquals) { - DistanceBoundary boundary1 = {kTestMinDistanceMeters, kTestMaxDistanceMeters, - kTestRangeType}; - DistanceBoundary boundary2 = {kTestMinDistanceMeters, kTestMaxDistanceMeters, - kTestRangeType}; - EXPECT_EQ(boundary1.GetMinDistanceMeters(), kTestMinDistanceMeters); - EXPECT_EQ(boundary1.GetMaxDistanceMeters(), kTestMaxDistanceMeters); - EXPECT_EQ(boundary1.GetRangeType(), kTestRangeType); - EXPECT_EQ(boundary1, boundary2); -} - -TEST(DistanceBoundaryTest, ExplicitInitNotEquals) { - DistanceBoundary boundary1 = {kTestMinDistanceMeters, kTestMaxDistanceMeters, - kTestRangeType}; - DistanceBoundary boundary2 = {kTestMinDistanceMeters + 0.1f, - kTestMaxDistanceMeters, kTestRangeType}; - EXPECT_NE(boundary1, boundary2); -} - -TEST(DistanceBoundaryTest, CopyInitEquals) { - DistanceBoundary boundary1 = {kTestMinDistanceMeters, kTestMaxDistanceMeters, - kTestRangeType}; - DistanceBoundary boundary2 = {boundary1}; - EXPECT_EQ(boundary1, boundary2); -} - -TEST(AngleOfArrivalBoundaryTest, DefaultConstructorWorks) { - AngleOfArrivalBoundary aoa_boundary; - EXPECT_EQ(aoa_boundary.GetMinAngleDegrees(), kDefaultDegrees); - EXPECT_EQ(aoa_boundary.GetMaxAngleDegrees(), kDefaultDegrees); -} - -TEST(AngleOfArrivalBoundaryTest, DefaultEquals) { - AngleOfArrivalBoundary aoa_boundary1; - AngleOfArrivalBoundary aoa_boundary2; - EXPECT_EQ(aoa_boundary1, aoa_boundary2); -} - -TEST(AngleOfArrivalBoundaryTest, PartiallyInitializationWorks) { - AngleOfArrivalBoundary aoa_boundary = {kTestMinAngleDegrees}; - EXPECT_EQ(aoa_boundary.GetMinAngleDegrees(), kTestMinAngleDegrees); - EXPECT_EQ(aoa_boundary.GetMaxAngleDegrees(), kDefaultDegrees); -} - -TEST(AngleOfArrivalBoundaryTest, ExplicitInitEquals) { - AngleOfArrivalBoundary aoa_boundary1 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees}; - AngleOfArrivalBoundary aoa_boundary2 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees}; - EXPECT_EQ(aoa_boundary1.GetMinAngleDegrees(), kTestMinAngleDegrees); - EXPECT_EQ(aoa_boundary1.GetMaxAngleDegrees(), kTestMaxAngleDegrees); - EXPECT_EQ(aoa_boundary1, aoa_boundary2); -} - -TEST(AngleOfArrivalBoundaryTest, ExplicitInitNotEquals) { - AngleOfArrivalBoundary aoa_boundary1 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees}; - AngleOfArrivalBoundary aoa_boundary2 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees + 0.1f}; - EXPECT_NE(aoa_boundary1, aoa_boundary2); -} - -TEST(AngleOfArrivalBoundaryTest, CopyInitEquals) { - AngleOfArrivalBoundary aoa_boundary1 = {kTestMinAngleDegrees, - kTestMaxAngleDegrees}; - AngleOfArrivalBoundary aoa_boundary2 = {aoa_boundary1}; - EXPECT_EQ(aoa_boundary1, aoa_boundary2); -} - -TEST(PresenceZoneTest, DefaultConstructorWorks) { - PresenceZone zone; - EXPECT_EQ(zone.GetDistanceBoundary(), kDefaultDistanceBoundary); - EXPECT_EQ(zone.GetAzimuthAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone.GetElevationAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone.GetLocalDeviceMotions().capacity(), 0); -} - -TEST(PresenceZoneTest, DefaultEquals) { - PresenceZone zone1; - PresenceZone zone2; - EXPECT_EQ(zone1, zone2); -} - -TEST(PresenceZoneTest, PartiallyInitializationWorks) { - PresenceZone zone1 = {kTestDistanceBoundary, kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary}; - PresenceZone zone2 = {kTestDistanceBoundary, kTestAzimuthAngleBoundary}; - PresenceZone zone3 = {kTestDistanceBoundary}; - EXPECT_EQ(zone1.GetDistanceBoundary(), kTestDistanceBoundary); - EXPECT_EQ(zone1.GetAzimuthAngleBoundary(), kTestAzimuthAngleBoundary); - EXPECT_EQ(zone1.GetElevationAngleBoundary(), kTestElevationAngleBoundary); - EXPECT_EQ(zone1.GetLocalDeviceMotions().capacity(), 0); - EXPECT_EQ(zone2.GetDistanceBoundary(), kTestDistanceBoundary); - EXPECT_EQ(zone2.GetAzimuthAngleBoundary(), kTestAzimuthAngleBoundary); - EXPECT_EQ(zone2.GetElevationAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone2.GetLocalDeviceMotions().capacity(), 0); - EXPECT_EQ(zone3.GetDistanceBoundary(), kTestDistanceBoundary); - EXPECT_EQ(zone3.GetAzimuthAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone3.GetElevationAngleBoundary(), kDefaultAngleBoundary); - EXPECT_EQ(zone3.GetLocalDeviceMotions().capacity(), 0); -} - -TEST(PresenceZoneTest, ExplicitInitEquals) { - PresenceZone zone1 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {kTestDeviceMotion}}; - PresenceZone zone2 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {kTestDeviceMotion}}; - EXPECT_EQ(zone1.GetDistanceBoundary(), kTestDistanceBoundary); - EXPECT_EQ(zone1.GetAzimuthAngleBoundary(), kTestAzimuthAngleBoundary); - EXPECT_EQ(zone1.GetElevationAngleBoundary(), kTestElevationAngleBoundary); - EXPECT_EQ(zone1.GetLocalDeviceMotions().size(), 1); - EXPECT_EQ(zone1.GetLocalDeviceMotions()[0], kTestDeviceMotion); - EXPECT_EQ(zone1, zone2); -} - -TEST(PresenceZoneTest, ExplicitInitNotEquals) { - PresenceZone zone1 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {kTestDeviceMotion}}; - PresenceZone zone2 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {}}; - EXPECT_NE(zone1, zone2); -} - -TEST(PresenceZoneTest, CopyInitEquals) { - PresenceZone zone1 = {kTestDistanceBoundary, - kTestAzimuthAngleBoundary, - kTestElevationAngleBoundary, - {kTestDeviceMotion}}; - PresenceZone zone2 = {zone1}; - EXPECT_EQ(zone1, zone2); -} - -} // namespace -} // namespace presence -} // namespace nearby diff --git a/presence/proto/BUILD b/presence/proto/BUILD deleted file mode 100644 index 6351491c..00000000 --- a/presence/proto/BUILD +++ /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. - -load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") -load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") - -proto_library( - name = "presence_frame_proto", - srcs = ["presence_frame.proto"], -) - -cc_proto_library( - name = "presence_frame_cc_proto", - visibility = [ - "//presence:__subpackages__", - ], - deps = [":presence_frame_proto"], -) diff --git a/presence/proto/presence_frame.proto b/presence/proto/presence_frame.proto deleted file mode 100644 index 1f18cbcd..00000000 --- a/presence/proto/presence_frame.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 = "proto2"; - -package nearby.presence; - -// import "storage/datapol/annotations/proto/semantic_annotations.proto"; - -option optimize_for = LITE_RUNTIME; -option java_package = "com.google.android.gms.nearby.presence"; -option java_outer_classname = "PresenceFrameProtocol"; - -/** - * Nearby Presence’s wire frame format - */ -message PresenceFrame { - /** The version of the frame. */ - enum Version { - UNKNOWN_VERSION = 0; - VERSION_1 = 1; - } - - /** The version 1 frame for Nearby Presence. */ - optional V1Frame v1_frame = 1; -} - -/** - * Nearby Presence’s v1 wire frame format - */ -message V1Frame { - oneof Message { - // Control messages for connection status update. - ControlFrame control_frame = 1; - - // This frame will be shared by public and provisioned identities - DeviceIdentityFrame device_identity_frame = 2; - - // First message from discovery device to broadcaster. - ConnectionInitFrame connection_init_frame = 3; - - // Sent by broadcaster to notify discoverer its UWB capability. - UwbControleeCapabilities uwb_controlee_capabilities_frame = 4; - - // Sent by discoverer to notify broadcaster the UWB ranging parameters. - UwbConnectionInfo uwb_connection_info = 5; - - // Used for identity authentication. - PresenceAuthenticationFrame authentication_frame = 6; - } -} - -/** - * A frame contains the local device’s information, shared by public and - * provisioned identities. - */ -message DeviceIdentityFrame { - optional string device_name = 1; - - // Without this field, the device will not be connectable. - optional bytes bluetooth_mac_address = 2; // deprecated - - optional string device_image_url = 3; - - optional string model_id = 4; - - repeated int32 action = 5 [packed = true]; // deprecated - - optional string device_model_name = 6; - - optional int32 device_type = 7; -} - -/** - * A frame sent from discovery device to broadcast device when connection - * initialized, or when UWB needs to be restarted, or when dedup hint rotates. - */ -message ConnectionInitFrame { - // Discovery-side action list - repeated int32 actions = 1 [packed = true]; - - // Discovery-side identity type - optional int32 identity_type = 2; - - // Should the broadcaster (re)-start UWB OOB process or not. - optional bool uwb_enable = 3; - - // Used for device de-duplicate. Same device ID means the same physical - // device. When dedup hint rotates, this will be updated and send again. - optional int64 device_unique_id = 4; -} - -/** - * A frame that describes the controlee's UWB capabilities. - */ -message UwbControleeCapabilities { - optional bytes controlee_address = 1; - - repeated int32 supported_config_ids = 2 [packed = true]; - - repeated int32 supported_channels = 3 [packed = true]; - - optional int32 min_ranging_interval_ms = 4; - - optional bytes sub_session_id = 5 /* type = ST_SESSION_ID */; - - optional bytes sub_session_key = 6 - /* type = ST_SECURITY_MATERIAL */; - - optional bool ranging_disabled = 7; - - // Used for device de-duplicate. Same device ID means the same physical - // device. - optional int64 device_unique_id = 8; - - optional bool is_distance_supported = 9 [default = true]; - optional bool is_azimuth_supported = 10 [default = true]; - optional bool is_elevation_supported = 11 [default = false]; - optional float min_slot_duration_ms = 12 [default = 2.0]; - repeated int32 supported_ntf_configs = 13 [packed = true]; - optional bool is_ranging_interval_reconfigure_supported = 14 - [default = false]; - repeated int32 supported_slot_durations = 15 [packed = true]; - repeated int32 supported_ranging_update_rates = 16 [packed = true]; - optional int32 chip_count = 17 [default = 1]; - repeated UwbMultiChipInfo multi_chip_info = 18; - optional bool is_background_ranging_supported = 19 [default = false]; -} - -/* A frame containing info needed per chip in a multi-chip environment. */ -message UwbMultiChipInfo { - optional bytes controlee_address = 1; - optional string chip_id = 2; -} - -/** - * A frame that describes the connection info of the UWB ranging session. - */ -message UwbConnectionInfo { - optional bytes controller_address = 1; - - optional int32 channel = 2; - - optional int32 preamble_index = 3; - - optional int32 config_id = 4; - - optional int32 ranging_interval_ms = 5; - - optional int32 session_id = 6 /* type = ST_SESSION_ID */; - - optional bytes vendor_id = 7; - - optional bytes static_sts_iv = 8; - - optional bytes session_key = 9 - /* type = ST_SECURITY_MATERIAL */; - - optional bool ranging_disabled = 10; -} - -/** - * Control frames that used for connection status update. - */ -message ControlFrame { - /** The defined Control type of the frame. */ - enum ControlType { - UNKNOWN_TYPE = 0; - - // Keeps the connection alive. - KEEP_ALIVE = 1; - - // Notifies the peer that the connection will be closed immediately. - DISCONNECT = 2; - } - - optional ControlType type = 1; -} - -message PresenceAuthenticationFrame { - // The version of this frame and protocol. - optional int32 version = 1; - - // A signature signed by the private key in the LocalCredential. - optional bytes private_key_signature = 2; - - // A hash of a shared credential's id. Used to prove ownership of shared - // credentials used in discovery. - optional bytes shared_credential_id_hash = 3; - - // A hash of a local credential's id. Used to expedite local credential - // verification. - optional bytes credential_id_hash = 4 [deprecated = true]; -} diff --git a/presence/rust/README b/presence/rust/README deleted file mode 100644 index 9ca03064..00000000 --- a/presence/rust/README +++ /dev/null @@ -1 +0,0 @@ -This directory contains Rust implementation of Nearby Presence. diff --git a/presence/scan_request.h b/presence/scan_request.h deleted file mode 100644 index 69aaad01..00000000 --- a/presence/scan_request.h +++ /dev/null @@ -1,151 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_H_ - -#include -#include - -#include "absl/types/variant.h" -#include "internal/proto/credential.pb.h" -#include "presence/data_element.h" -#include "presence/power_mode.h" - -namespace nearby { -namespace presence { - -constexpr char kPresenceScanFilterName[] = "PresenceScanFilter"; -constexpr char kLegacyPresenceScanFilterName[] = "LegacyPresenceScanFilter"; - -enum class ScanType { - kUnspecifiedScan = 0, - kFastPairScan = 1, - kPresenceScan = 2, -}; - -/** - * Filter for scanning a nearby presence device. - * Supports Android U and above. - */ -struct PresenceScanFilter { - ScanType scan_type; - // A bundle of extended properties for matching. - std::vector extended_properties; -}; - -/** - * Used to support legacy Android T. Filter for scanning a nearby presence - * device. - */ -struct LegacyPresenceScanFilter { - ScanType scan_type; - // Minimum path loss threshold of the received scan result. - int path_loss_threshold; - - // Android T needs clients to provide remote public credentials in scan - // requests. - std::vector remote_public_credentials; - - // A list of presence actions for matching. Matching condition is met as - // long as there’s one or more equal actions between Scan actions and - // Broadcast actions. - // Considered to use enum, and team agreed to use int to support potential - // un-reserved values. Already existing reserved interger values are defined - // in {@code ActionFactory}. - std::vector actions; - - // A bundle of extended properties for matching. - std::vector extended_properties; -}; - -inline bool operator==(const PresenceScanFilter& a, - const PresenceScanFilter& b) { - return a.scan_type == b.scan_type && - a.extended_properties == b.extended_properties; -} - -inline bool operator!=(const PresenceScanFilter& a, - const PresenceScanFilter& b) { - return !(a == b); -} - -inline bool operator==(const LegacyPresenceScanFilter& a, - const LegacyPresenceScanFilter& b) { - if (a.scan_type != b.scan_type || - a.path_loss_threshold != b.path_loss_threshold || - a.actions != b.actions || - a.remote_public_credentials.size() != - b.remote_public_credentials.size() || - a.extended_properties != b.extended_properties) - return false; - for (size_t i = 0; i < a.remote_public_credentials.size(); ++i) { - if (a.remote_public_credentials[i].SerializeAsString() != - b.remote_public_credentials[i].SerializeAsString()) - return false; - } - return true; -} - -inline bool operator!=(const LegacyPresenceScanFilter& a, - const LegacyPresenceScanFilter& b) { - return !(a == b); -} - -/** - * An encapsulation of various parameters for requesting nearby scans. - */ -struct ScanRequest { - // Same as Metadata.account_name, to fetch private credential - // to broadcast. - std::string account_name; - - // Specifies which manager app to use to get credendentials for scan. - std::string manager_app_id; - - // Used to specify which types of remote SharedCredential to use during the - // scan. If empty, use all available types of remote SharedCredential. - std::vector identity_types; - - // For new Nearby SDK client (like chromeOs and Android U), use - // PresenceScanFilter; for Android T, use LegacyPresenceScanFilter. - std::vector > - scan_filters; - - // Whether to use BLE in the scan. - bool use_ble = false; - - ScanType scan_type = ScanType::kUnspecifiedScan; - PowerMode power_mode = PowerMode::kNoPower; - bool scan_only_when_screen_on = false; -}; - -inline bool operator==(const ScanRequest& a, const ScanRequest& b) { - if (a.identity_types != b.identity_types) return false; - if (a.scan_filters != b.scan_filters) return false; - return a.scan_only_when_screen_on == b.scan_only_when_screen_on && - a.power_mode == b.power_mode && a.scan_type == b.scan_type && - a.use_ble == b.use_ble && a.account_name == b.account_name && - a.identity_types == b.identity_types && - a.manager_app_id == b.manager_app_id; -} - -inline bool operator!=(const ScanRequest& a, const ScanRequest& b) { - return !(a == b); -} - -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_H_ diff --git a/presence/scan_request_builder.cc b/presence/scan_request_builder.cc deleted file mode 100644 index 2d9b5740..00000000 --- a/presence/scan_request_builder.cc +++ /dev/null @@ -1,89 +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. -#include "presence/scan_request_builder.h" - -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/types/variant.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { - -using ::nearby::internal::IdentityType; - -ScanRequestBuilder& ScanRequestBuilder::SetAccountName( - absl::string_view account_name) { - request_.account_name = std::string(account_name); - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetPowerMode(PowerMode power_mode) { - request_.power_mode = power_mode; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetScanType(ScanType scan_type) { - request_.scan_type = scan_type; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::AddIdentityType( - IdentityType identity_type) { - request_.identity_types.push_back(identity_type); - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetIdentityTypes( - std::vector types) { - request_.identity_types = types; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::AddScanFilter( - absl::variant scan_filter) { - request_.scan_filters.push_back(scan_filter); - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetScanFilters( - std::vector> - filters) { - request_.scan_filters = filters; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetUseBle(bool use_ble) { - request_.use_ble = use_ble; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetOnlyScreenOnScan( - bool screen_on_only_scan) { - request_.scan_only_when_screen_on = screen_on_only_scan; - return *this; -} - -ScanRequestBuilder& ScanRequestBuilder::SetManagerAppId( - absl::string_view manager_app_id) { - request_.manager_app_id = std::string(manager_app_id); - return *this; -} - -ScanRequest ScanRequestBuilder::Build() { return this->request_; } - -} // namespace presence -} // namespace nearby diff --git a/presence/scan_request_builder.h b/presence/scan_request_builder.h deleted file mode 100644 index 80bf770d..00000000 --- a/presence/scan_request_builder.h +++ /dev/null @@ -1,56 +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. - -#ifndef THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_BUILDER_H_ -#define THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_BUILDER_H_ - -#include - -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "presence/power_mode.h" -#include "presence/presence_zone.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -class ScanRequestBuilder { - private: - ScanRequest request_; - - public: - ScanRequestBuilder& SetAccountName(absl::string_view account_name); - ScanRequestBuilder& SetPowerMode(PowerMode power_mode); - ScanRequestBuilder& SetScanType(ScanType scan_type); - ScanRequestBuilder& AddIdentityType( - nearby::internal::IdentityType identity_type); - ScanRequestBuilder& SetIdentityTypes( - std::vector types); - ScanRequestBuilder& AddScanFilter( - absl::variant scan_filter); - ScanRequestBuilder& SetScanFilters( - std::vector> - scan_filters); - ScanRequestBuilder& SetUseBle(bool use_ble); - ScanRequestBuilder& SetOnlyScreenOnScan(bool screen_on_only_scan); - ScanRequestBuilder& SetManagerAppId(absl::string_view manager_app_id); - ScanRequest Build(); - inline bool operator==(const ScanRequestBuilder& other) const { - return request_ == other.request_; - } -}; -} // namespace presence -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_PRESENCE_SCAN_REQUEST_BUILDER_H_ diff --git a/presence/scan_request_builder_test.cc b/presence/scan_request_builder_test.cc deleted file mode 100644 index 1d0fd6be..00000000 --- a/presence/scan_request_builder_test.cc +++ /dev/null @@ -1,194 +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. - -#include "presence/scan_request_builder.h" - -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "internal/proto/credential.pb.h" -#include "presence/power_mode.h" -#include "presence/scan_request.h" - -namespace nearby { -namespace presence { -namespace { - -using ::nearby::internal::IdentityType; - -constexpr absl::string_view kAccountName = "Google User"; -constexpr bool kUseBle = true; -constexpr bool kOnlyScreenOnScan = true; -const IdentityType kIdentity = IdentityType::IDENTITY_TYPE_PRIVATE_GROUP; -const ScanType kScanType = ScanType::kPresenceScan; -const PowerMode powerMode = PowerMode::kLowLatency; -constexpr absl::string_view kManagerAppId = "Google App Manager"; -DataElement CreateTestDataElement() { - return {DataElement::kTxPowerFieldType, "1"}; -} -PresenceScanFilter CreateTestPresenceScanFilter() { - return {.scan_type = kScanType, - .extended_properties = {CreateTestDataElement()}}; -} -LegacyPresenceScanFilter CreateTestLegacyPresenceScanFilter() { - return {.scan_type = kScanType}; -} - -TEST(ScanRequestBuilderTest, TestConstructor) { - EXPECT_FALSE(std::is_trivially_constructible::value); -} - -TEST(ScanRequestBuilderTest, TestSetAccountName) { - ScanRequestBuilder builder; - builder.SetAccountName(kAccountName); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.account_name, kAccountName); -} - -TEST(ScanRequestBuilderTest, TestSetPowerMode) { - ScanRequestBuilder builder; - builder.SetPowerMode(powerMode); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.power_mode, powerMode); -} - -TEST(ScanRequestBuilderTest, TestSetScanType) { - ScanRequestBuilder builder; - builder.SetScanType(kScanType); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.scan_type, kScanType); -} - -TEST(ScanRequestBuilderTest, TestAddIdentityType) { - ScanRequestBuilder builder; - builder.AddIdentityType(kIdentity); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.identity_types.size(), 1); - EXPECT_EQ(sr.identity_types[0], kIdentity); -} - -TEST(ScanRequestBuilderTest, TestSetIdentityTypes) { - ScanRequestBuilder builder; - std::vector types = {kIdentity}; - builder.SetIdentityTypes(types); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.identity_types.size(), 1); - EXPECT_EQ(sr.identity_types, types); -} - -TEST(ScanRequestBuilderTest, TestAddScanFilter) { - ScanRequestBuilder builder; - PresenceScanFilter presenceScanFilter = CreateTestPresenceScanFilter(); - LegacyPresenceScanFilter legacyPresenceScanFilter = - CreateTestLegacyPresenceScanFilter(); - builder.AddScanFilter(presenceScanFilter); - builder.AddScanFilter(legacyPresenceScanFilter); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.scan_filters.size(), 2); - EXPECT_TRUE(absl::holds_alternative(sr.scan_filters[0])); - EXPECT_NE(&absl::get(sr.scan_filters[0]), - &presenceScanFilter); - EXPECT_EQ(absl::get(sr.scan_filters[0]), - presenceScanFilter); - EXPECT_TRUE( - absl::holds_alternative(sr.scan_filters[1])); - EXPECT_NE(&absl::get(sr.scan_filters[1]), - &legacyPresenceScanFilter); - EXPECT_EQ(absl::get(sr.scan_filters[1]), - legacyPresenceScanFilter); -} - -TEST(ScanRequestBuilderTest, TestSetScanFilters) { - PresenceScanFilter presenceScanFilter = CreateTestPresenceScanFilter(); - LegacyPresenceScanFilter legacyPresenceScanFilter = - CreateTestLegacyPresenceScanFilter(); - std::vector> - filterList = {presenceScanFilter, legacyPresenceScanFilter}; - ScanRequestBuilder builder; - builder.SetScanFilters(filterList); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.scan_filters.size(), 2); - EXPECT_TRUE(absl::holds_alternative(sr.scan_filters[0])); - EXPECT_NE(&absl::get(sr.scan_filters[0]), - &presenceScanFilter); - EXPECT_EQ(absl::get(sr.scan_filters[0]), - presenceScanFilter); - EXPECT_TRUE( - absl::holds_alternative(sr.scan_filters[1])); - EXPECT_NE(&absl::get(sr.scan_filters[1]), - &legacyPresenceScanFilter); - EXPECT_EQ(absl::get(sr.scan_filters[1]), - legacyPresenceScanFilter); -} - -TEST(ScanRequestBuilderTest, TestNotEqualScanFilter) { - ScanRequestBuilder builderLegacy, builderModern; - ScanRequest legacy = - builderLegacy.AddScanFilter(LegacyPresenceScanFilter{}).Build(); - ScanRequest modern = - builderModern.AddScanFilter(PresenceScanFilter{}).Build(); - EXPECT_NE(legacy, modern); -} - -TEST(ScanRequestBuilderTest, TestSetUseBle) { - ScanRequestBuilder builder; - builder.SetUseBle(kUseBle); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.use_ble, kUseBle); -} - -TEST(ScanRequestBuilderTest, TestSetManagerAppId) { - ScanRequestBuilder builder; - builder.SetManagerAppId(kManagerAppId); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.manager_app_id, kManagerAppId); -} - -TEST(ScanRequestBuilderTest, TestSetOnlyScreenOnScan) { - ScanRequestBuilder builder; - builder.SetOnlyScreenOnScan(kOnlyScreenOnScan); - ScanRequest sr = builder.Build(); - EXPECT_EQ(sr.scan_only_when_screen_on, kOnlyScreenOnScan); -} - -TEST(ScanRequestBuilderTest, TestChainCalls) { - ScanRequestBuilder builder; - ScanRequest sr = builder.SetAccountName(kAccountName) - .SetPowerMode(powerMode) - .SetOnlyScreenOnScan(kOnlyScreenOnScan) - .SetUseBle(kUseBle) - .SetManagerAppId(kManagerAppId) - .Build(); - EXPECT_EQ(sr.account_name, kAccountName); - EXPECT_EQ(sr.scan_only_when_screen_on, kOnlyScreenOnScan); - EXPECT_EQ(sr.power_mode, powerMode); - EXPECT_EQ(sr.use_ble, kUseBle); - EXPECT_EQ(sr.manager_app_id, kManagerAppId); -} - -TEST(ScanRequestBuilderTest, TestCopy) { - ScanRequestBuilder builder1; - builder1.SetOnlyScreenOnScan(kOnlyScreenOnScan).SetUseBle(kUseBle); - ScanRequestBuilder builder2 = {builder1}; - EXPECT_EQ(builder1, builder2); - ScanRequest s1 = builder1.Build(); - ScanRequest s2 = builder2.Build(); - EXPECT_EQ(s1, s2); -} -} // namespace -} // namespace presence -} // namespace nearby