mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Merge remote-tracking branch 'upstream/main' into fix-clang15-gcc13-headers
Brings changes in upstream that fix compilation issues documented in
This commit is contained in:
+4
-4
@@ -3,10 +3,10 @@
|
||||
"pins": [
|
||||
{
|
||||
"package": "abseil",
|
||||
"repositoryURL": "https://github.com/firebase/abseil-cpp-SwiftPM.git",
|
||||
"repositoryURL": "https://github.com/bourdakos1/abseil-cpp-SwiftPM.git",
|
||||
"state": {
|
||||
"branch": "main",
|
||||
"revision": "06e7506b74bfc47c70f3353e2927ea3e2275230c",
|
||||
"branch": "cxx17",
|
||||
"revision": "a7042563d167160f56e614cd1e2a32616510d9ec",
|
||||
"version": null
|
||||
}
|
||||
},
|
||||
@@ -22,4 +22,4 @@
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
|
||||
+7
-42
@@ -168,78 +168,40 @@ let package = Package(
|
||||
.headerSearchPath("smhasher/src/")
|
||||
]
|
||||
),
|
||||
.target(
|
||||
name: "securemessage",
|
||||
dependencies: [
|
||||
"protobuf",
|
||||
.product(name: "openssl_grpc", package: "BoringSSL-GRPC"),
|
||||
],
|
||||
path: "third_party/securemessage",
|
||||
exclude: [
|
||||
"securemessage/cmake",
|
||||
"securemessage/cpp/src/securemessage/CMakeLists.txt",
|
||||
"securemessage/cpp/test",
|
||||
"securemessage/cpp/CMakeLists.txt",
|
||||
"securemessage/cpp/Makefile",
|
||||
"securemessage/cpp/README.md",
|
||||
"securemessage/java",
|
||||
"securemessage/js",
|
||||
"securemessage/proto",
|
||||
"securemessage/third_party",
|
||||
"securemessage/CMakeLists.txt",
|
||||
"securemessage/CONTRIBUTORS",
|
||||
"securemessage/CONTRIBUTING.md",
|
||||
"securemessage/LICENSE",
|
||||
"securemessage/README.md",
|
||||
],
|
||||
sources: [
|
||||
"securemessage/cpp/src/securemessage",
|
||||
"compiled_proto",
|
||||
],
|
||||
publicHeadersPath: "include",
|
||||
cSettings: [
|
||||
.headerSearchPath("securemessage/cpp/include/"),
|
||||
.headerSearchPath("compiled_proto/"),
|
||||
]
|
||||
),
|
||||
.target(
|
||||
name: "ukey2",
|
||||
dependencies: [
|
||||
"securemessage",
|
||||
"protobuf",
|
||||
.product(name: "abseil", package: "abseil"),
|
||||
.product(name: "openssl_grpc", package: "BoringSSL-GRPC"),
|
||||
],
|
||||
path: "third_party/ukey2",
|
||||
exclude: [
|
||||
"ukey2/cmake",
|
||||
"ukey2/src/main/cpp/src/securegcm/CMakeLists.txt",
|
||||
"ukey2/src/main/cpp/src/securegcm/ukey2_shell.cc",
|
||||
"ukey2/src/main/cpp/test",
|
||||
"ukey2/src/main/cpp/CMakeLists.txt",
|
||||
"ukey2/src/main/java",
|
||||
"ukey2/src/main/javatest",
|
||||
"ukey2/src/main/proto",
|
||||
"ukey2/src/main/CMakeLists.txt",
|
||||
"ukey2/third_party",
|
||||
"ukey2/Android.bp",
|
||||
"ukey2/build.gradle",
|
||||
"ukey2/CMakeLists.txt",
|
||||
"ukey2/CONTRIBUTING.md",
|
||||
"ukey2/LICENSE",
|
||||
"ukey2/MODULE_LICENSE_APACHE2",
|
||||
"ukey2/NOTICE",
|
||||
"ukey2/README",
|
||||
"ukey2/README.md",
|
||||
"compiled_proto/proto/securemessage.pb.cc",
|
||||
],
|
||||
sources: [
|
||||
"ukey2/src/securemessage/src/securemessage",
|
||||
"ukey2/src/main/cpp/src/securegcm",
|
||||
"compiled_proto",
|
||||
],
|
||||
publicHeadersPath: "include",
|
||||
cSettings: [
|
||||
.headerSearchPath("ukey2/src/main/cpp/include/"),
|
||||
.headerSearchPath("ukey2/"),
|
||||
.headerSearchPath("compiled_proto/"),
|
||||
.headerSearchPath("compiled_proto/src/main/"),
|
||||
]
|
||||
),
|
||||
.target(
|
||||
@@ -569,6 +531,7 @@ let package = Package(
|
||||
"internal/network/http_request_test.cc",
|
||||
"internal/network/http_client_impl_test.cc",
|
||||
"internal/network/http_status_code_test.cc",
|
||||
"internal/test/google3_only/fake_authentication_manager_test.cc",
|
||||
"internal/test/fake_clock_test.cc",
|
||||
"internal/test/fake_timer_test.cc",
|
||||
"internal/test/fake_device_info_test.cc",
|
||||
@@ -604,6 +567,8 @@ let package = Package(
|
||||
cSettings: [
|
||||
.headerSearchPath("./"),
|
||||
.headerSearchPath("compiled_proto/"),
|
||||
.headerSearchPath("third_party/ukey2/ukey2/"),
|
||||
.headerSearchPath("third_party/ukey2/compiled_proto/"),
|
||||
.define("NO_WEBRTC"),
|
||||
.define("NEARBY_SWIFTPM"),
|
||||
]
|
||||
|
||||
@@ -59,10 +59,10 @@ http_archive(
|
||||
urls = ["https://github.com/google/glog/archive/v0.4.0.tar.gz"],
|
||||
)
|
||||
|
||||
new_local_repository(
|
||||
http_archive(
|
||||
name = "com_google_ukey2",
|
||||
path = "./third_party/ukey2/ukey2",
|
||||
build_file_content = _ALL_CONTENT,
|
||||
strip_prefix = "ukey2-master",
|
||||
urls = ["https://github.com/google/ukey2/archive/master.zip"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")
|
||||
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -15,28 +13,6 @@ load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")
|
||||
# limitations under the License.
|
||||
licenses(["notice"])
|
||||
|
||||
cmake(
|
||||
name = "ukey2",
|
||||
env = {
|
||||
"CC": "clang",
|
||||
"CXX": "clang++",
|
||||
},
|
||||
generate_args = [
|
||||
"-DBYPASS_TESTING=ON", # Set the flags in CMakeLists.txt (ukey2 & its dependencies) here.
|
||||
"-Dukey2_USE_LOCAL_ABSL=ON",
|
||||
"-Dukey2_USE_LOCAL_PROTOBUF=ON", # Add -DCMAKE_BUILD_TYPE=Debug for debugger & Valgrind
|
||||
],
|
||||
lib_source = "@com_google_ukey2//:all_srcs",
|
||||
out_static_libs = [
|
||||
"libproto_device_to_device_messages_cc_proto.a",
|
||||
"libproto_securegcm_cc_proto.a",
|
||||
"libproto_securemessage_cc_proto.a",
|
||||
"libproto_ukey_cc_proto.a",
|
||||
"libsecuremessage.a",
|
||||
"libukey2.a",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "internal",
|
||||
srcs = [
|
||||
@@ -131,15 +107,13 @@ cc_library(
|
||||
"//location/nearby/cpp/sharing/implementation:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":message_lite",
|
||||
":ukey2",
|
||||
"//connections:core_types",
|
||||
"//connections/implementation/analytics",
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//connections/implementation/mediums",
|
||||
"//connections/implementation/mediums:utils",
|
||||
"//connections/implementation/mediums/webrtc",
|
||||
"//connections/implementation/proto:offline_wire_formats_cc_proto",
|
||||
"//connections/v3:v3_types",
|
||||
"//internal/analytics:event_logger",
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/interop:device",
|
||||
@@ -164,6 +138,7 @@ cc_library(
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@com_google_ukey2//:ukey2",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -242,11 +217,11 @@ cc_test(
|
||||
deps = [
|
||||
":internal",
|
||||
":internal_test",
|
||||
":ukey2",
|
||||
"//connections:core_types",
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//connections/implementation/mediums",
|
||||
"//connections/implementation/proto:offline_wire_formats_cc_proto",
|
||||
"//connections/v3:v3_types",
|
||||
"//internal/analytics:event_logger",
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/platform:base",
|
||||
@@ -255,6 +230,7 @@ cc_test(
|
||||
"//internal/platform:test_util",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"//internal/test",
|
||||
"//proto:connections_enums_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
@@ -265,5 +241,6 @@ cc_test(
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
"@com_google_ukey2//:ukey2",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "connections/v3/connections_device_provider.h"
|
||||
#include "internal/analytics/event_logger.h"
|
||||
#include "internal/platform/error_code_recorder.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
@@ -70,11 +71,13 @@ std::int64_t ClientProxy::GetClientId() const { return client_id_; }
|
||||
|
||||
std::string ClientProxy::GetLocalEndpointId() {
|
||||
MutexLock lock(&mutex_);
|
||||
if (local_endpoint_id_.empty()) {
|
||||
if (!local_endpoint_id_.empty()) {
|
||||
return local_endpoint_id_;
|
||||
}
|
||||
if (device_provider_ == nullptr) {
|
||||
local_endpoint_id_ = GenerateLocalEndpointId();
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [Local Endpoint Generated]: client="
|
||||
<< GetClientId()
|
||||
<< "; endpoint_id=" << local_endpoint_id_;
|
||||
} else {
|
||||
local_endpoint_id_ = device_provider_->GetLocalDevice()->GetEndpointId();
|
||||
}
|
||||
return local_endpoint_id_;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "connections/advertising_options.h"
|
||||
@@ -31,6 +32,7 @@
|
||||
#include "connections/strategy.h"
|
||||
#include "internal/analytics/event_logger.h"
|
||||
#include "internal/interop/device.h"
|
||||
#include "internal/interop/device_provider.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancelable_alarm.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
@@ -206,6 +208,10 @@ class ClientProxy final {
|
||||
absl::string_view endpoint_id,
|
||||
const location::nearby::connections::OsInfo& remote_os_info);
|
||||
|
||||
void RegisterDeviceProvider(std::unique_ptr<NearbyDeviceProvider> provider) {
|
||||
device_provider_ = std::move(provider);
|
||||
}
|
||||
|
||||
private:
|
||||
struct Connection {
|
||||
// Status: may be either:
|
||||
@@ -282,7 +288,7 @@ class ClientProxy final {
|
||||
// Bluetooth Classic enabled. When high_visibility_mode_ is true, the endpoint
|
||||
// id is stable for 30s. When high_visibility_mode_ is false, the endpoint id
|
||||
// always rotates.
|
||||
bool high_vis_mode_{false};
|
||||
bool high_vis_mode_ = false;
|
||||
// Caches the endpoint id when it is in high visibility mode advertisement for
|
||||
// 30s. Currently, Nearby Connections keeps rotating endpoint id. The client
|
||||
// (Nearby Share) treats different endpoints as different receivers, duplicate
|
||||
@@ -339,6 +345,7 @@ class ClientProxy final {
|
||||
std::unique_ptr<ErrorCodeRecorder> error_code_recorder_;
|
||||
// Local device OS information.
|
||||
location::nearby::connections::OsInfo local_os_info_;
|
||||
std::unique_ptr<NearbyDeviceProvider> device_provider_;
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
@@ -28,6 +29,7 @@
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "connections/v3/connections_device_provider.h"
|
||||
#include "internal/analytics/event_logger.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
@@ -427,6 +429,16 @@ TEST_F(ClientProxyTest, GeneratedEndpointIdIsUnique) {
|
||||
EXPECT_NE(client1_.GetLocalEndpointId(), client2_.GetLocalEndpointId());
|
||||
}
|
||||
|
||||
TEST_F(ClientProxyTest, GeneratedEndpointIdIsUniqueWithDeviceProvider) {
|
||||
client1_.RegisterDeviceProvider(
|
||||
std::make_unique<v3::ConnectionsDeviceProvider>(
|
||||
v3::ConnectionsDeviceProvider("", {})));
|
||||
client2_.RegisterDeviceProvider(
|
||||
std::make_unique<v3::ConnectionsDeviceProvider>(
|
||||
v3::ConnectionsDeviceProvider("", {})));
|
||||
EXPECT_NE(client1_.GetLocalEndpointId(), client2_.GetLocalEndpointId());
|
||||
}
|
||||
|
||||
TEST_F(ClientProxyTest, ResetClearsState) {
|
||||
client1_.Reset();
|
||||
EXPECT_FALSE(client1_.IsAdvertising());
|
||||
|
||||
@@ -287,10 +287,16 @@ bool operator<(const EndpointManager::FrameProcessor& lhs,
|
||||
}
|
||||
|
||||
EndpointManager::EndpointManager(EndpointChannelManager* manager)
|
||||
: channel_manager_(manager) {}
|
||||
: EndpointManager(manager, std::make_unique<SingleThreadExecutor>()) {}
|
||||
|
||||
EndpointManager::EndpointManager(
|
||||
EndpointChannelManager* manager,
|
||||
std::unique_ptr<SingleThreadExecutor> serial_executor)
|
||||
: channel_manager_(manager), serial_executor_(std::move(serial_executor)) {}
|
||||
|
||||
EndpointManager::~EndpointManager() {
|
||||
NEARBY_LOG(INFO, "Initiating shutdown of EndpointManager.");
|
||||
is_shutdown_ = true;
|
||||
analytics::ThroughputRecorderContainer::GetInstance().Shutdown();
|
||||
CountDownLatch latch(1);
|
||||
RunOnEndpointManagerThread("bring-down-endpoints", [this, &latch]() {
|
||||
@@ -301,7 +307,7 @@ EndpointManager::~EndpointManager() {
|
||||
latch.Await();
|
||||
|
||||
NEARBY_LOG(INFO, "Bringing down control thread");
|
||||
serial_executor_.Shutdown();
|
||||
serial_executor_->Shutdown();
|
||||
NEARBY_LOG(INFO, "EndpointManager is down");
|
||||
}
|
||||
|
||||
@@ -524,10 +530,48 @@ std::vector<std::string> EndpointManager::SendPayloadChunk(
|
||||
void EndpointManager::DiscardEndpoint(ClientProxy* client,
|
||||
const std::string& endpoint_id) {
|
||||
NEARBY_LOGS(VERBOSE) << "DiscardEndpoint for endpoint " << endpoint_id;
|
||||
RunOnEndpointManagerThread("discard-endpoint", [this, client, endpoint_id]() {
|
||||
RemoveEndpoint(client, endpoint_id,
|
||||
/*notify=*/client->IsConnectedToEndpoint(endpoint_id));
|
||||
});
|
||||
RunOnEndpointManagerThread(
|
||||
"discard-endpoint", [this, client, endpoint_id]() {
|
||||
// `ClientProxy` is destroyed before `EndpointManager` in
|
||||
// `~NearbyConnections`, which means "discard-endpoint" needs to check
|
||||
// if this task is being executing during `~EndpointManager` to
|
||||
// prevent accessing an invalid `ClientProxy` pointer. There are two
|
||||
// cases where "discard-endpoint" can be executed during destruction,
|
||||
// both of which can safely use `is_shutdown_` to check if this is being
|
||||
// executed during the destruction of the object:
|
||||
//
|
||||
// Case 1: "discard-endpoints" is posted to the thread before
|
||||
// destruction, but not executed yet: `~EndpointManager` blocks on
|
||||
// "bring-down-endpoints" and because the executor is a single thread
|
||||
// executor, tasks are guaranteed to execute sequentially
|
||||
// (see
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor--)
|
||||
// and this means that the "discard-endpoints" will be executed before
|
||||
// "bring-down-endpoints", blocking the destruction of `is_shutdown_`
|
||||
// and therefore `is_shutdown_` is not garbage memory.
|
||||
//
|
||||
// Case 2: "discard-endpoints" is posted to the thread during
|
||||
// destruction, after "bring-down-endpoints" is called: the executor
|
||||
// will be destructed before `is_shutdown_` because of the ordering of
|
||||
// `EndpointManager`'s member variables, and the executor's destructor
|
||||
// blocks on running all pending tasks
|
||||
// (see
|
||||
// https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:chrome/services/sharing/nearby/platform/scheduled_executor.cc;l=67;drc=e0e0d24aaa54727dc0a8bc4b159ccdf80d3f5d8d),
|
||||
// which means that "discard-endpoints" will run during the destruction
|
||||
// of `serial_executor_` and will still have access to a valid
|
||||
// `is_shutdown_`.
|
||||
//
|
||||
// TODO(b/280653613): Develop a more robost solution to prevent
|
||||
// accessing an already destroyed `ClientProxy` during destruction.
|
||||
if (is_shutdown_) {
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< "DiscardEndpoint called during destruction, returning early.";
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveEndpoint(client, endpoint_id,
|
||||
/*notify=*/client->IsConnectedToEndpoint(endpoint_id));
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::string> EndpointManager::SendControlMessage(
|
||||
@@ -698,7 +742,7 @@ void EndpointManager::EndpointState::StartEndpointKeepAliveManager(
|
||||
|
||||
void EndpointManager::RunOnEndpointManagerThread(const std::string& name,
|
||||
Runnable runnable) {
|
||||
serial_executor_.Execute(name, std::move(runnable));
|
||||
serial_executor_->Execute(name, std::move(runnable));
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -153,6 +153,11 @@ class EndpointManager {
|
||||
// blocked here.
|
||||
void DiscardEndpoint(ClientProxy* client, const std::string& endpoint_id);
|
||||
|
||||
protected:
|
||||
// For unit tests only to control executing tasks on the executor.
|
||||
EndpointManager(EndpointChannelManager* manager,
|
||||
std::unique_ptr<SingleThreadExecutor> serial_executor);
|
||||
|
||||
private:
|
||||
class EndpointState {
|
||||
public:
|
||||
@@ -288,7 +293,18 @@ class EndpointManager {
|
||||
// We keep track of all registered channel endpoints here.
|
||||
absl::flat_hash_map<std::string, EndpointState> endpoints_;
|
||||
|
||||
SingleThreadExecutor serial_executor_;
|
||||
// Indicates whether the destructor has been called yet. If `is_shutdown_`
|
||||
// is true, assume any `ClientProxy` pointers are invalid, and should not
|
||||
// be used.
|
||||
//
|
||||
// The ordering of these objects is important: `serial_executor_` must be
|
||||
// destroyed before `is_shutdown_` because `serial_executor_` runs all
|
||||
// pending tasks during it's destruction, and the "discard-endpoints"
|
||||
// task checks `is_shutdown_` to prevent accessing an invalid `ClientProxy`
|
||||
// pointer.
|
||||
bool is_shutdown_ = false;
|
||||
|
||||
std::unique_ptr<SingleThreadExecutor> serial_executor_;
|
||||
};
|
||||
|
||||
// Operator overloads when comparing FrameProcessor*.
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/test/fake_single_thread_executor.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -111,6 +112,13 @@ class MockFrameProcessor : public EndpointManager::FrameProcessor {
|
||||
(override));
|
||||
};
|
||||
|
||||
class TestEndpointManager : public EndpointManager {
|
||||
public:
|
||||
TestEndpointManager(EndpointChannelManager* manager,
|
||||
std::unique_ptr<SingleThreadExecutor> serial_executor)
|
||||
: EndpointManager(manager, std::move(serial_executor)) {}
|
||||
};
|
||||
|
||||
class EndpointManagerTest : public ::testing::Test {
|
||||
protected:
|
||||
void RegisterEndpoint(std::unique_ptr<MockEndpointChannel> channel,
|
||||
@@ -127,14 +135,15 @@ class EndpointManagerTest : public ::testing::Test {
|
||||
EXPECT_CALL(*channel, GetLastWriteTimestamp())
|
||||
.WillRepeatedly(Return(start_time_));
|
||||
EXPECT_CALL(mock_listener_.initiated_cb, Call).Times(1);
|
||||
em_.RegisterEndpoint(&client_, endpoint_id_, info_, connection_options_,
|
||||
std::move(channel), listener_, connection_token);
|
||||
em_.RegisterEndpoint(client_.get(), endpoint_id_, info_,
|
||||
connection_options_, std::move(channel), listener_,
|
||||
connection_token);
|
||||
if (should_close) {
|
||||
EXPECT_TRUE(done.Await(absl::Milliseconds(1000)).result());
|
||||
}
|
||||
}
|
||||
|
||||
ClientProxy client_;
|
||||
std::unique_ptr<ClientProxy> client_ = std::make_unique<ClientProxy>();
|
||||
ConnectionOptions connection_options_{
|
||||
.keep_alive_interval_millis = 5000,
|
||||
.keep_alive_timeout_millis = 30000,
|
||||
@@ -195,7 +204,7 @@ TEST_F(EndpointManagerTest, UnregisterEndpointCallsOnDisconnected) {
|
||||
// (IMO, it should be called as long as any connection callback was called
|
||||
// before. (in this case initiated_cb is called)).
|
||||
// Test captures current protocol behavior.
|
||||
em_.UnregisterEndpoint(&client_, endpoint_id_);
|
||||
em_.UnregisterEndpoint(client_.get(), endpoint_id_);
|
||||
}
|
||||
|
||||
TEST_F(EndpointManagerTest, RegisterFrameProcessorWorks) {
|
||||
@@ -250,7 +259,7 @@ TEST_F(EndpointManagerTest, UnregisterFrameProcessorWorks) {
|
||||
processors_.emplace_back(std::move(connect_request));
|
||||
// Endpoint will not send OnDisconnect notification to frame processor.
|
||||
RegisterEndpoint(std::move(endpoint_channel), false);
|
||||
em_.UnregisterEndpoint(&client_, endpoint_id_);
|
||||
em_.UnregisterEndpoint(client_.get(), endpoint_id_);
|
||||
}
|
||||
|
||||
TEST_F(EndpointManagerTest, SendControlMessageWorks) {
|
||||
@@ -286,7 +295,7 @@ TEST_F(EndpointManagerTest, SendControlMessageWorks) {
|
||||
em_.SendControlMessage(header, control, std::vector{endpoint_id_});
|
||||
EXPECT_EQ(failed_ids, std::vector<std::string>{});
|
||||
NEARBY_LOG(INFO, "Will unregister endpoint now");
|
||||
em_.UnregisterEndpoint(&client_, endpoint_id_);
|
||||
em_.UnregisterEndpoint(client_.get(), endpoint_id_);
|
||||
NEARBY_LOG(INFO, "Will call destructors now");
|
||||
}
|
||||
|
||||
@@ -301,6 +310,48 @@ TEST_F(EndpointManagerTest, SingleReadOnInvalidPayload) {
|
||||
RegisterEndpoint(std::move(endpoint_channel));
|
||||
}
|
||||
|
||||
// Regression test for b/278729669.
|
||||
//
|
||||
// During the destruction of NearbyConnections, Core (which owns ClientProxy)
|
||||
// is destructed before ServiceController (which owns EndpointManager), which
|
||||
// means any pending tasks on the EndpointManager than use ClientProxy will
|
||||
// be using garbage memory, and cause crashes. This test enforces the fix.
|
||||
TEST_F(EndpointManagerTest, DisconnectEndpointDuringDestruction) {
|
||||
// This test uses a `FakeSingleThreadExecutor` in order to control when
|
||||
// tasks are executed in order to simulate the scenario where
|
||||
// `DiscardEndpoint` is posted to the executor before the EndpointManager
|
||||
// is destructed, and executed during it's destruction.
|
||||
std::unique_ptr<SingleThreadExecutor> serial_executor =
|
||||
std::make_unique<FakeSingleThreadExecutor>();
|
||||
FakeSingleThreadExecutor* fake_serial_executor =
|
||||
static_cast<FakeSingleThreadExecutor*>(serial_executor.get());
|
||||
std::unique_ptr<EndpointManager> endpoint_manager =
|
||||
std::make_unique<TestEndpointManager>(&ecm_, std::move(serial_executor));
|
||||
|
||||
// DiscardEndpoint posts a task to the executor to run "discard-endpoint",
|
||||
// however the `FakeSingleThreadExecutor` will not run this task
|
||||
// immediately.
|
||||
fake_serial_executor->SetRunExecutablesImmediately(
|
||||
/*run_executables_immediately=*/false);
|
||||
endpoint_manager->DiscardEndpoint(client_.get(), endpoint_id_);
|
||||
|
||||
// Simulate Core destruction of ClientProxy by destroying `client_`.
|
||||
client_.reset();
|
||||
|
||||
// Simulate ServiceController destruction of EndpointManager by destroying
|
||||
// `endpoint_manager`, and set the `FakeSingleThreadExecutor` to run
|
||||
// executables on calls `Execute`. When `endpoint_manager` is destructed, it
|
||||
// will block on calls to `Execute` to run all pending executables, notably
|
||||
// "discard-endpoint" from above. However, "discard-endpoint" will have a
|
||||
// reference to a destroyed ClientProxy.
|
||||
//
|
||||
// Expect no crash when "discard-endpoints" is executed during the
|
||||
// destruction.
|
||||
fake_serial_executor->SetRunExecutablesImmediately(
|
||||
/*run_executables_immediately=*/true);
|
||||
endpoint_manager.reset();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -37,8 +37,8 @@ constexpr auto kBlePeripheralLostTimeoutMillis =
|
||||
flags::Flag<int64_t>(kConfigPackage, "45411439", 12000);
|
||||
|
||||
// LINT.ThenChange(
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/windows/nearby_sharing_service_adapter_dart.h,
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/windows/nearby_sharing_service_adapter_dart.cc,
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/cpp/nearby_sharing_service_adapter_dart.h,
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/cpp/nearby_sharing_service_adapter_dart.cc,
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/dart/platform/lib/ffi_types.dart,
|
||||
// //depot/google3/location/nearby/cpp/sharing/clients/dart/platform/lib/types/models.dart
|
||||
// )
|
||||
|
||||
@@ -3,6 +3,7 @@ licenses(["notice"])
|
||||
cc_library(
|
||||
name = "common",
|
||||
srcs = [
|
||||
"battery_notification.cc",
|
||||
"fast_pair_device.cc",
|
||||
"fast_pair_http_result.cc",
|
||||
"pair_failure.cc",
|
||||
@@ -10,9 +11,11 @@ cc_library(
|
||||
],
|
||||
hdrs = [
|
||||
"account_key.h",
|
||||
"battery_notification.h",
|
||||
"constant.h",
|
||||
"fast_pair_device.h",
|
||||
"fast_pair_http_result.h",
|
||||
"non_discoverable_advertisement.h",
|
||||
"pair_failure.h",
|
||||
"protocol.h",
|
||||
],
|
||||
@@ -21,6 +24,7 @@ cc_library(
|
||||
],
|
||||
deps = [
|
||||
"//internal/crypto",
|
||||
"//internal/platform:logging",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
@@ -36,6 +40,7 @@ cc_test(
|
||||
shard_count = 16,
|
||||
deps = [
|
||||
":common",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
@@ -51,6 +56,22 @@ cc_test(
|
||||
shard_count = 16,
|
||||
deps = [
|
||||
":common",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "battery_notification_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"battery_notification_test.cc",
|
||||
],
|
||||
shard_count = 16,
|
||||
deps = [
|
||||
":common",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/common/battery_notification.h"
|
||||
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fastpair/common/constant.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
BatteryInfo::BatteryInfo(bool is_charging)
|
||||
: is_charging(is_charging), percentage(std::nullopt) {}
|
||||
|
||||
BatteryInfo::BatteryInfo(bool is_charging, int8_t percentage)
|
||||
: is_charging(is_charging), percentage(percentage) {}
|
||||
|
||||
// static
|
||||
BatteryInfo BatteryInfo::FromByte(uint8_t byte) {
|
||||
// Battery value is in the form 0bSVVVVVVV.
|
||||
// S = charging (0b1) or not (0b0).
|
||||
// V = value, Ranges from 0-100, or 0bS1111111 if unknown.
|
||||
bool is_charging = byte & kBatteryChargingMask;
|
||||
uint8_t percentage = byte & kBatteryPercentageMask;
|
||||
int8_t percentage_signed = static_cast<int8_t>(percentage);
|
||||
if (percentage_signed < 0 || percentage_signed > 100) {
|
||||
NEARBY_LOGS(INFO) << __func__ << "Invalid battery percentage.";
|
||||
return BatteryInfo(is_charging);
|
||||
}
|
||||
return BatteryInfo(is_charging, percentage_signed);
|
||||
}
|
||||
|
||||
uint8_t BatteryInfo::ToByte() const {
|
||||
// Battery value is in the form 0bSVVVVVVV.
|
||||
// S = charging (0b1) or not (0b0).
|
||||
// V = value, Ranges from 0-100, or 1111111 if unknown.
|
||||
if (!percentage) {
|
||||
return is_charging ? kBatteryIsChargingByte : kBatteryNotChargingByte;
|
||||
} else {
|
||||
return percentage.value() | (is_charging ? kBatteryChargingMask : 0);
|
||||
}
|
||||
}
|
||||
|
||||
BatteryNotification::BatteryNotification(
|
||||
Type type, const std::vector<BatteryInfo>& battery_infos)
|
||||
: type(type), battery_infos(battery_infos) {}
|
||||
|
||||
// static
|
||||
std::optional<BatteryNotification> BatteryNotification::FromBytes(
|
||||
const std::vector<uint8_t>& bytes, Type type) {
|
||||
if (bytes.size() == 1) {
|
||||
// Single component device.
|
||||
NEARBY_LOGS(INFO) << __func__ << " : Single component device.";
|
||||
std::vector<BatteryInfo> battery_infos = {BatteryInfo::FromByte(bytes[0])};
|
||||
return std::make_optional<BatteryNotification>(type, battery_infos);
|
||||
} else if (bytes.size() == 3) {
|
||||
// True wireless headset expecting 3 bytes - Left bud, Right bud and case.
|
||||
NEARBY_LOGS(INFO) << __func__ << " : True wireless headset.";
|
||||
std::vector<BatteryInfo> battery_infos = {
|
||||
/* left bud info */ BatteryInfo::FromByte(bytes[0]),
|
||||
/* right bud info */ BatteryInfo::FromByte(bytes[1]),
|
||||
/* case info */ BatteryInfo::FromByte(bytes[2])};
|
||||
return std::make_optional<BatteryNotification>(type, battery_infos);
|
||||
}
|
||||
NEARBY_LOGS(WARNING) << __func__
|
||||
<< " : Unexpected battery notification length :"
|
||||
<< bytes.size();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_BATTERY_NOTIFICATION_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_BATTERY_NOTIFICATION_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
// Fast Pair battery information from notification. See
|
||||
// https://developers.google.com/nearby/fast-pair/spec#BatteryNotification
|
||||
struct BatteryInfo {
|
||||
BatteryInfo() = default;
|
||||
explicit BatteryInfo(bool is_charging);
|
||||
BatteryInfo(bool is_charging, int8_t percentage);
|
||||
~BatteryInfo() = default;
|
||||
|
||||
static BatteryInfo FromByte(uint8_t byte);
|
||||
|
||||
uint8_t ToByte() const;
|
||||
|
||||
bool is_charging = false;
|
||||
std::optional<int8_t> percentage;
|
||||
};
|
||||
|
||||
// Fast Pair battery notification. See
|
||||
// https://developers.google.com/nearby/fast-pair/spec#BatteryNotification
|
||||
struct BatteryNotification {
|
||||
// Represents if the provider wants to show an indication
|
||||
// of the battery values
|
||||
enum class Type {
|
||||
kNone = 0,
|
||||
kShowUi = 3, /* Show UI indication: 0b0011 */
|
||||
kHideUi = 4, /* Hide UI indication: 0b0100 */
|
||||
};
|
||||
|
||||
BatteryNotification() = default;
|
||||
BatteryNotification(Type type, const std::vector<BatteryInfo>& battery_infos);
|
||||
~BatteryNotification() = default;
|
||||
|
||||
static std::optional<BatteryNotification> FromBytes(
|
||||
const std::vector<uint8_t>& bytes, Type type);
|
||||
|
||||
Type type = Type::kNone;
|
||||
std::vector<BatteryInfo> battery_infos;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_BATTERY_NOTIFICATION_H_
|
||||
@@ -0,0 +1,152 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/common/battery_notification.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
namespace {
|
||||
// Test data comes from:
|
||||
// https://developers.google.com/nearby/fast-pair/specifications/appendix/testcases#test_cases
|
||||
|
||||
TEST(BatteryNotificationTest, TestBatteryInfo) {
|
||||
// Tests default constructor
|
||||
BatteryInfo battery_info_1;
|
||||
EXPECT_FALSE(battery_info_1.is_charging);
|
||||
|
||||
// Tests Constructor with is_charging
|
||||
BatteryInfo battery_info_2(true);
|
||||
EXPECT_TRUE(battery_info_2.is_charging);
|
||||
// Tests ToByte and FromByte
|
||||
BatteryInfo battery_info_3 = BatteryInfo::FromByte(battery_info_2.ToByte());
|
||||
EXPECT_TRUE(battery_info_3.is_charging);
|
||||
EXPECT_FALSE(battery_info_3.percentage.has_value());
|
||||
|
||||
// Tests Constructor with is_charging and percentage value
|
||||
BatteryInfo battery_info_4(true, 80);
|
||||
EXPECT_TRUE(battery_info_4.is_charging);
|
||||
EXPECT_EQ(battery_info_4.percentage.value(), 80);
|
||||
// Tests ToByte and FromByte
|
||||
BatteryInfo battery_info_5 = BatteryInfo::FromByte(battery_info_4.ToByte());
|
||||
EXPECT_TRUE(battery_info_5.is_charging);
|
||||
EXPECT_EQ(battery_info_5.percentage.value(), 80);
|
||||
|
||||
// Tests Constructor with is_charging and wrong percentage value
|
||||
BatteryInfo battery_info_6(true, 110);
|
||||
// Tests ToByte and FromByte
|
||||
BatteryInfo battery_info_7 = BatteryInfo::FromByte(battery_info_6.ToByte());
|
||||
EXPECT_TRUE(battery_info_7.is_charging);
|
||||
EXPECT_FALSE(battery_info_7.percentage.has_value());
|
||||
|
||||
// Tests FromByte with battery percentage = 0
|
||||
BatteryInfo battery_info_8 = BatteryInfo::FromByte(0);
|
||||
EXPECT_FALSE(battery_info_8.is_charging);
|
||||
EXPECT_EQ(battery_info_8.percentage.value(), 0);
|
||||
|
||||
BatteryInfo battery_info_10 = BatteryInfo::FromByte(0x80);
|
||||
EXPECT_TRUE(battery_info_10.is_charging);
|
||||
EXPECT_EQ(battery_info_10.percentage.value(), 0);
|
||||
|
||||
// Tests FromByte with battery percentage = 100
|
||||
BatteryInfo battery_info_9 = BatteryInfo::FromByte(100);
|
||||
EXPECT_FALSE(battery_info_9.is_charging);
|
||||
EXPECT_EQ(battery_info_9.percentage.value(), 100);
|
||||
|
||||
BatteryInfo battery_info_11 = BatteryInfo::FromByte(0x80 | 100);
|
||||
EXPECT_TRUE(battery_info_11.is_charging);
|
||||
EXPECT_EQ(battery_info_11.percentage.value(), 100);
|
||||
|
||||
// Test battery with invalid battery percentage
|
||||
BatteryInfo battery_info_12 = BatteryInfo::FromByte(0x7F);
|
||||
EXPECT_FALSE(battery_info_12.is_charging);
|
||||
EXPECT_FALSE(battery_info_12.percentage.has_value());
|
||||
|
||||
BatteryInfo battery_info_13 = BatteryInfo::FromByte(0xFF);
|
||||
EXPECT_TRUE(battery_info_13.is_charging);
|
||||
EXPECT_FALSE(battery_info_13.percentage.has_value());
|
||||
}
|
||||
|
||||
TEST(BatteryNotificationTest, TestBatteryNotificationDefaultConstructor) {
|
||||
// Tests default constructor
|
||||
BatteryNotification battery_notification;
|
||||
EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kNone);
|
||||
EXPECT_EQ(battery_notification.battery_infos.size(), 0);
|
||||
}
|
||||
|
||||
TEST(BatteryNotificationTest, TestBatteryNotificationForSingleComponentDevice) {
|
||||
std::vector<BatteryInfo> battery_infos = {BatteryInfo(false, 70)};
|
||||
BatteryNotification battery_notification(BatteryNotification::Type::kShowUi,
|
||||
battery_infos);
|
||||
EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kShowUi);
|
||||
EXPECT_FALSE(battery_notification.battery_infos.at(0).is_charging);
|
||||
EXPECT_EQ(battery_notification.battery_infos.at(0).percentage.value(), 70);
|
||||
}
|
||||
|
||||
TEST(BatteryNotificationTest, TestBatteryNotificationForTrueWirelessHeadset) {
|
||||
std::vector<BatteryInfo> battery_infos = {
|
||||
BatteryInfo(false, 70), BatteryInfo(false, 80), BatteryInfo(true, 90)};
|
||||
BatteryNotification battery_notification(BatteryNotification::Type::kShowUi,
|
||||
battery_infos);
|
||||
EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kShowUi);
|
||||
// Left bud
|
||||
EXPECT_FALSE(battery_notification.battery_infos.at(0).is_charging);
|
||||
EXPECT_EQ(battery_notification.battery_infos.at(0).percentage.value(), 70);
|
||||
// Right bud
|
||||
EXPECT_FALSE(battery_notification.battery_infos.at(1).is_charging);
|
||||
EXPECT_EQ(battery_notification.battery_infos.at(1).percentage.value(), 80);
|
||||
// Case
|
||||
EXPECT_TRUE(battery_notification.battery_infos.at(2).is_charging);
|
||||
EXPECT_EQ(battery_notification.battery_infos.at(2).percentage.value(), 90);
|
||||
}
|
||||
|
||||
TEST(BatteryNotificationTest,
|
||||
TestBatteryNotificationFromBytesForSingleComponentDevice) {
|
||||
const std::vector<uint8_t> batteryData{0b01000000};
|
||||
BatteryNotification battery_notification =
|
||||
BatteryNotification::FromBytes(batteryData,
|
||||
BatteryNotification::Type::kShowUi)
|
||||
.value();
|
||||
EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kShowUi);
|
||||
EXPECT_EQ(battery_notification.battery_infos.at(0).percentage.value(), 64);
|
||||
}
|
||||
|
||||
TEST(BatteryNotificationTest,
|
||||
TestBatteryNotificationFromBytesForTrueWirelessHeadset) {
|
||||
const std::vector<uint8_t> batteryData{0b01000000, 0b01000000, 0b01000000};
|
||||
BatteryNotification battery_notification =
|
||||
BatteryNotification::FromBytes(batteryData,
|
||||
BatteryNotification::Type::kShowUi)
|
||||
.value();
|
||||
EXPECT_EQ(battery_notification.type, BatteryNotification::Type::kShowUi);
|
||||
EXPECT_EQ(battery_notification.battery_infos.at(0).percentage.value(), 64);
|
||||
EXPECT_EQ(battery_notification.battery_infos.at(1).percentage.value(), 64);
|
||||
EXPECT_EQ(battery_notification.battery_infos.at(2).percentage.value(), 64);
|
||||
}
|
||||
|
||||
TEST(BatteryNotificationTest, TestBatteryNotificationFromWrongBytes) {
|
||||
const std::vector<uint8_t> batteryDataWithWrongLenth{0b01000000, 0b01000000};
|
||||
EXPECT_FALSE(
|
||||
BatteryNotification::FromBytes(batteryDataWithWrongLenth,
|
||||
BatteryNotification::Type::kShowUi)
|
||||
.has_value());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
@@ -24,7 +24,6 @@ namespace fastpair {
|
||||
constexpr char kServiceId[] = "Fast Pair";
|
||||
|
||||
constexpr char kRfcommUuid[] = "df21fe2c-2515-4fdb-8886-f12c4d67927c";
|
||||
|
||||
constexpr int kAccountKeySize = 16;
|
||||
|
||||
// Key pair
|
||||
@@ -60,6 +59,13 @@ constexpr uint8_t kAccountKeyStartByte = 0x04;
|
||||
constexpr uint8_t kKeyBasedPairingType = 0x00;
|
||||
constexpr uint8_t kInitialOrSubsequentFlags = 0x00;
|
||||
constexpr uint8_t kRetroactiveFlags = 0x10;
|
||||
|
||||
// Battery Info
|
||||
constexpr int kBatteryChargingMask = 0b10000000;
|
||||
constexpr int kBatteryPercentageMask = 0b01111111;
|
||||
constexpr int kBatteryIsChargingByte = 0b11111111;
|
||||
constexpr int kBatteryNotChargingByte = 0b01111111;
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_COMMON_NON_DISCOVERABLE_ADVERTISEMENT_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_COMMON_NON_DISCOVERABLE_ADVERTISEMENT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fastpair/common/battery_notification.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
// Fast Pair 'Not Discoverable' advertisement. See
|
||||
// https://developers.google.com/nearby/fast-pair/specifications/service/provider#AdvertisingWhenNotDiscoverable
|
||||
struct NonDiscoverableAdvertisement {
|
||||
// Represents showing UI indication
|
||||
enum class Type {
|
||||
kShowUi = 0, /* Show UI indication: 0b0000*/
|
||||
kNone = 1,
|
||||
kHideUi = 2, /* Hide UI indication: 0b0010*/
|
||||
};
|
||||
|
||||
NonDiscoverableAdvertisement() = default;
|
||||
NonDiscoverableAdvertisement(
|
||||
std::vector<uint8_t> account_key_filter, Type type,
|
||||
std::vector<uint8_t> salt,
|
||||
std::optional<BatteryNotification> battery_notification)
|
||||
: account_key_filter(std::move(account_key_filter)),
|
||||
type(type),
|
||||
salt(std::move(salt)),
|
||||
battery_notification(std::move(battery_notification)) {}
|
||||
|
||||
~NonDiscoverableAdvertisement() = default;
|
||||
|
||||
std::vector<uint8_t> account_key_filter;
|
||||
Type type = Type::kNone;
|
||||
std::vector<uint8_t> salt;
|
||||
std::optional<BatteryNotification> battery_notification;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_COMMON_NON_DISCOVERABLE_ADVERTISEMENT_H_
|
||||
@@ -38,7 +38,7 @@ void NearbyHttpClient::StartRequest(
|
||||
CleanThreads();
|
||||
|
||||
std::future<void> http_thread = std::async(
|
||||
std::launch::async, [&, request, callback = std::move(callback)]() {
|
||||
std::launch::async, [=]() {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Start async request to url="
|
||||
<< request.GetUrl().GetUrlPath();
|
||||
absl::StatusOr<HttpResponse> response = InternalGetResponse(request);
|
||||
|
||||
@@ -36,7 +36,10 @@ cc_library(
|
||||
"single_thread_executor.h",
|
||||
"timer.h",
|
||||
],
|
||||
visibility = ["//location/nearby/cpp:__subpackages__"],
|
||||
visibility = [
|
||||
"//internal/test:__subpackages__",
|
||||
"//location/nearby/cpp:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":preferences_repository",
|
||||
"//internal/platform:base",
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace nearby {
|
||||
// queue.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor--
|
||||
class ABSL_LOCKABLE SingleThreadExecutor final : public SubmittableExecutor {
|
||||
class ABSL_LOCKABLE SingleThreadExecutor : public SubmittableExecutor {
|
||||
public:
|
||||
using Platform = api::ImplementationPlatform;
|
||||
SingleThreadExecutor()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
@@ -53,7 +54,7 @@ class ABSL_LOCKABLE SubmittableExecutor : public api::SubmittableExecutor,
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
void Execute(const std::string& name, Runnable&& runnable)
|
||||
virtual void Execute(const std::string& name, Runnable&& runnable)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_) {
|
||||
MutexLock lock(&mutex_);
|
||||
if (impl_)
|
||||
|
||||
@@ -18,12 +18,14 @@ cc_library(
|
||||
name = "test",
|
||||
srcs = [
|
||||
"fake_clock.cc",
|
||||
"fake_single_thread_executor.cc",
|
||||
"fake_task_runner.cc",
|
||||
"fake_timer.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"fake_clock.h",
|
||||
"fake_device_info.h",
|
||||
"fake_single_thread_executor.h",
|
||||
"fake_task_runner.h",
|
||||
"fake_timer.h",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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 "internal/test/fake_single_thread_executor.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace nearby {
|
||||
|
||||
FakeSingleThreadExecutor::FakeSingleThreadExecutor() = default;
|
||||
|
||||
FakeSingleThreadExecutor::~FakeSingleThreadExecutor() { DoShutdown(); }
|
||||
|
||||
void FakeSingleThreadExecutor::Execute(const std::string& name,
|
||||
Runnable&& runnable) {
|
||||
runnables_.push_back(std::make_pair(name, std::move(runnable)));
|
||||
|
||||
if (!run_executables_immediately_) return;
|
||||
|
||||
RunAllExecutables();
|
||||
}
|
||||
|
||||
void FakeSingleThreadExecutor::RunAllExecutables() {
|
||||
// Because `SingleThreadExecutor` ensures sequencing, run all pending
|
||||
// executables in order they were added to the vector.
|
||||
for (auto& runnable_pair : runnables_) {
|
||||
runnable_pair.second();
|
||||
}
|
||||
|
||||
runnables_.clear();
|
||||
}
|
||||
|
||||
void FakeSingleThreadExecutor::DoShutdown() { RunAllExecutables(); }
|
||||
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,52 @@
|
||||
// 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 PLATFORM_PUBLIC_FAKE_SINGLE_THREAD_EXECUTOR_H_
|
||||
#define PLATFORM_PUBLIC_FAKE_SINGLE_THREAD_EXECUTOR_H_
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "internal/platform/single_thread_executor.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
class ABSL_LOCKABLE FakeSingleThreadExecutor final
|
||||
: public SingleThreadExecutor {
|
||||
public:
|
||||
FakeSingleThreadExecutor();
|
||||
~FakeSingleThreadExecutor() override;
|
||||
FakeSingleThreadExecutor(FakeSingleThreadExecutor&&) = default;
|
||||
FakeSingleThreadExecutor& operator=(FakeSingleThreadExecutor&&) = default;
|
||||
|
||||
void Execute(const std::string& name, Runnable&& runnable) override;
|
||||
|
||||
void SetRunExecutablesImmediately(bool run_executables_immediately) {
|
||||
run_executables_immediately_ = run_executables_immediately;
|
||||
}
|
||||
|
||||
void RunAllExecutables();
|
||||
|
||||
private:
|
||||
void DoShutdown();
|
||||
|
||||
bool run_executables_immediately_ = false;
|
||||
std::vector<std::pair<std::string, Runnable>> runnables_;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
#endif // PLATFORM_PUBLIC_FAKE_SINGLE_THREAD_EXECUTOR_H_
|
||||
@@ -58,7 +58,6 @@ ScanSessionId ScanManager::StartScan(ScanRequest scan_request,
|
||||
absl::Status ble_status) mutable {
|
||||
start_scan_client(ble_status);
|
||||
},
|
||||
// TODO(b/256686710): Track known devices
|
||||
.advertisement_found_cb =
|
||||
[this, id](BlePeripheral& peripheral,
|
||||
BleAdvertisementData data) {
|
||||
|
||||
Vendored
+1
-1
Submodule third_party/absl updated: b957f0ccd0...abe63eb9bd
Vendored
+1
-1
Submodule third_party/depot_tools updated: e1197f06a8...6316ac234e
+1
-1
Submodule third_party/google-toolbox-for-mac/google-toolbox-for-mac updated: 3394150480...1b2da5e6e6
Vendored
+1
-1
Submodule third_party/gtest updated: d61d4d8e64...d6fb5e3bf7
Vendored
+1
-1
Submodule third_party/json/json updated: 6af826d0bd...bc889afb4c
Vendored
+1
-1
Submodule third_party/mbedtls updated: 3e0418fe50...ff7a346201
Vendored
+1
-1
Submodule third_party/protobuf updated: 4812107b9d...12f743d4e7
Vendored
+1
-1
Submodule third_party/ukey2/ukey2 updated: c2436e5511...03290b58d9
Reference in New Issue
Block a user