mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
nearby: snapshot of cl/304428753
Signed-off-by: Alexey Polyudov <apolyudov@google.com> Change-Id: I0023ac6e40456fc4a8169c3173bcbff3b5ccc476
This commit is contained in:
+39
-1
@@ -8,7 +8,7 @@ cc_library(
|
||||
"loop_runner.cc",
|
||||
"loop_runner.h",
|
||||
"offline_frames.cc",
|
||||
"offline_frames.h",
|
||||
"wifi_lan_service_info.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"bandwidth_upgrade_handler.h",
|
||||
@@ -40,6 +40,7 @@ cc_library(
|
||||
"internal_payload_factory.h",
|
||||
"medium_manager.cc",
|
||||
"medium_manager.h",
|
||||
"offline_frames.h",
|
||||
"offline_service_controller.cc",
|
||||
"offline_service_controller.h",
|
||||
"p2p_cluster_pcp_handler.cc",
|
||||
@@ -57,6 +58,7 @@ cc_library(
|
||||
"service_controller.h",
|
||||
"service_controller_router.cc",
|
||||
"service_controller_router.h",
|
||||
"wifi_lan_service_info.h",
|
||||
"wifi_lan_upgrade_handler.cc",
|
||||
"wifi_lan_upgrade_handler.h",
|
||||
],
|
||||
@@ -80,6 +82,18 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "base_endpoint_channel_test",
|
||||
srcs = ["base_endpoint_channel_test.cc"],
|
||||
deps = [
|
||||
":internal",
|
||||
"//platform:utils",
|
||||
"//platform/impl/default",
|
||||
"//proto:connections_enums_portable_proto",
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "bluetooth_device_name_test",
|
||||
srcs = ["bluetooth_device_name_test.cc"],
|
||||
@@ -100,3 +114,27 @@ cc_test(
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "wifi_lan_service_info_test",
|
||||
srcs = ["wifi_lan_service_info_test.cc"],
|
||||
deps = [
|
||||
":internal",
|
||||
"//platform:utils",
|
||||
"//platform/port:string",
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "offline_frames_test",
|
||||
srcs = [
|
||||
"offline_frames_test.cc",
|
||||
],
|
||||
deps = [
|
||||
":internal",
|
||||
"//proto/connections:offline_wire_formats_portable_proto",
|
||||
"//platform:types",
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -49,7 +49,7 @@ ExceptionOr<ConstPtr<ByteArray> > readExactly(Ptr<InputStream> reader,
|
||||
ScopedPtr<ConstPtr<ByteArray> > scoped_read_bytes(read_bytes.result());
|
||||
|
||||
// In Java, EOFException is a sub-variant of IOException.
|
||||
if (scoped_read_bytes->size() == 0) {
|
||||
if (scoped_read_bytes.isNull() || scoped_read_bytes->size() == 0) {
|
||||
return ExceptionOr<ConstPtr<ByteArray> >(Exception::IO);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ Exception::Value writeInt(Ptr<OutputStream> writer, std::int32_t value) {
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/150763574): Move implementatiopn to header or .inc file.
|
||||
template <typename Platform>
|
||||
BaseEndpointChannel<Platform>::BaseEndpointChannel(const string& channel_name,
|
||||
Ptr<InputStream> reader,
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "core/internal/base_endpoint_channel.h"
|
||||
|
||||
#include "platform/impl/default/default_platform.h"
|
||||
#include "platform/pipe.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
class TestPlatform : public DefaultPlatform {
|
||||
public:
|
||||
static SystemClock* createSystemClock() { return nullptr; }
|
||||
|
||||
static Ptr<AtomicBoolean> createAtomicBoolean(bool initial_value) {
|
||||
return Ptr<AtomicBoolean>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static Ptr<AtomicReference<T>> createAtomicReference(const T& initial_value) {
|
||||
return Ptr<AtomicReference<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
class TestEndpointChannel : public BaseEndpointChannel<TestPlatform> {
|
||||
public:
|
||||
explicit TestEndpointChannel(Ptr<InputStream> input_stream)
|
||||
: BaseEndpointChannel("channel", input_stream, Ptr<OutputStream>()) {}
|
||||
|
||||
MOCK_METHOD(proto::connections::Medium, getMedium, (), (override));
|
||||
MOCK_METHOD(void, closeImpl, (), (override));
|
||||
};
|
||||
|
||||
using SamplePipe = Pipe<TestPlatform>;
|
||||
|
||||
TEST(BaseEndpointChannelTest, ReadAfterInputStreamClosed) {
|
||||
auto pipe = MakeRefCountedPtr(new SamplePipe());
|
||||
ScopedPtr<Ptr<InputStream>> input_stream(SamplePipe::createInputStream(pipe));
|
||||
ScopedPtr<Ptr<OutputStream>> output_stream(
|
||||
SamplePipe::createOutputStream(pipe));
|
||||
|
||||
TestEndpointChannel test_channel(input_stream.get());
|
||||
|
||||
// Close the output stream before trying to read from the input.
|
||||
output_stream->close();
|
||||
|
||||
// Trying to read should fail gracefully with an IO error.
|
||||
ExceptionOr<ConstPtr<ByteArray>> result = test_channel.read();
|
||||
|
||||
ASSERT_FALSE(result.ok());
|
||||
ASSERT_EQ(Exception::IO, result.exception());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -701,7 +701,10 @@ BasePCPHandler<Platform>::~BasePCPHandler() {
|
||||
|
||||
// Unregister ourselves from the IncomingOfflineFrameProcessors.
|
||||
endpoint_manager_->unregisterIncomingOfflineFrameProcessor(
|
||||
V1Frame::CONNECTION_RESPONSE, MakePtr(this));
|
||||
V1Frame::CONNECTION_RESPONSE,
|
||||
std::static_pointer_cast<
|
||||
typename EndpointManager<Platform>::IncomingOfflineFrameProcessor>(
|
||||
self_));
|
||||
|
||||
encryption_runner_.destroy();
|
||||
|
||||
@@ -747,7 +750,7 @@ Status::Value BasePCPHandler<Platform>::startAdvertising(
|
||||
ScopedPtr<Ptr<Future<Status::Value>>> result(
|
||||
runOnPCPHandlerThread<Status::Value>(
|
||||
MakePtr(new base_pcp_handler::StartAdvertisingCallable<Platform>(
|
||||
MakePtr(this), client_proxy, service_id, local_endpoint_name,
|
||||
self_, client_proxy, service_id, local_endpoint_name,
|
||||
advertising_options, connection_lifecycle_listener))));
|
||||
return waitForResult("startAdvertising(" + local_endpoint_name + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
@@ -759,7 +762,7 @@ void BasePCPHandler<Platform>::stopAdvertising(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::StopAdvertisingRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, latch.get())));
|
||||
self_, client_proxy, latch.get())));
|
||||
waitForLatch("stopAdvertising", latch.get());
|
||||
}
|
||||
|
||||
@@ -771,7 +774,7 @@ Status::Value BasePCPHandler<Platform>::startDiscovery(
|
||||
ScopedPtr<Ptr<Future<Status::Value>>> result(
|
||||
runOnPCPHandlerThread<Status::Value>(
|
||||
MakePtr(new base_pcp_handler::StartDiscoveryCallable<Platform>(
|
||||
MakePtr(this), client_proxy, service_id, discovery_options,
|
||||
self_, client_proxy, service_id, discovery_options,
|
||||
discovery_listener))));
|
||||
return waitForResult("startDiscovery(" + service_id + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
@@ -783,7 +786,7 @@ void BasePCPHandler<Platform>::stopDiscovery(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::StopDiscoveryRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, latch.get())));
|
||||
self_, client_proxy, latch.get())));
|
||||
waitForLatch("stopDiscovery", latch.get());
|
||||
}
|
||||
|
||||
@@ -796,7 +799,7 @@ Status::Value BasePCPHandler<Platform>::requestConnection(
|
||||
Platform::template createSettableFuture<Status::Value>());
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::RequestConnectionRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, local_endpoint_name, endpoint_id,
|
||||
self_, client_proxy, local_endpoint_name, endpoint_id,
|
||||
connection_lifecycle_listener, result.get())));
|
||||
return waitForResult("requestConnection(" + endpoint_id + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
@@ -809,7 +812,7 @@ Status::Value BasePCPHandler<Platform>::acceptConnection(
|
||||
ScopedPtr<Ptr<Future<Status::Value>>> result(
|
||||
runOnPCPHandlerThread<Status::Value>(
|
||||
MakePtr(new base_pcp_handler::AcceptConnectionCallable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, payload_listener))));
|
||||
self_, client_proxy, endpoint_id, payload_listener))));
|
||||
return waitForResult("acceptConnection(" + endpoint_id + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
}
|
||||
@@ -820,7 +823,7 @@ Status::Value BasePCPHandler<Platform>::rejectConnection(
|
||||
ScopedPtr<Ptr<Future<Status::Value>>> result(
|
||||
runOnPCPHandlerThread<Status::Value>(
|
||||
MakePtr(new base_pcp_handler::RejectConnectionCallable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id))));
|
||||
self_, client_proxy, endpoint_id))));
|
||||
return waitForResult("rejectConnection(" + endpoint_id + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
}
|
||||
@@ -845,8 +848,7 @@ void BasePCPHandler<Platform>::processEndpointDisconnection(
|
||||
Ptr<CountDownLatch> process_disconnection_barrier) {
|
||||
runOnPCPHandlerThread(MakePtr(
|
||||
new base_pcp_handler::ProcessEndpointDisconnectionRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id,
|
||||
process_disconnection_barrier)));
|
||||
self_, client_proxy, endpoint_id, process_disconnection_barrier)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -856,7 +858,7 @@ void BasePCPHandler<Platform>::onEncryptionSuccessImpl(
|
||||
ConstPtr<ByteArray> raw_authentication_token) {
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::OnEncryptionSuccessRunnable<Platform>(
|
||||
MakePtr(this), endpoint_id, ukey2_handshake, authentication_token,
|
||||
self_, endpoint_id, ukey2_handshake, authentication_token,
|
||||
raw_authentication_token)));
|
||||
}
|
||||
|
||||
@@ -865,7 +867,7 @@ void BasePCPHandler<Platform>::onEncryptionFailureImpl(
|
||||
const string& endpoint_id, Ptr<EndpointChannel> channel) {
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::OnEncryptionFailureRunnable<Platform>(
|
||||
MakePtr(this), endpoint_id, channel)));
|
||||
self_, endpoint_id, channel)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -1025,8 +1027,8 @@ void BasePCPHandler<Platform>::onConnectionResponse(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::OnConnectionResponseRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id,
|
||||
connection_response_offline_frame, latch.get())));
|
||||
self_, client_proxy, endpoint_id, connection_response_offline_frame,
|
||||
latch.get())));
|
||||
waitForLatch("onConnectionResponse()", latch.get());
|
||||
}
|
||||
|
||||
@@ -1154,8 +1156,8 @@ Exception::Value BasePCPHandler<Platform>::onIncomingConnection(
|
||||
// Next, we'll set up encryption.
|
||||
encryption_runner_->startServer(
|
||||
client_proxy, connection_request.endpoint_id(), endpoint_channel,
|
||||
MakePtr(new typename BasePCPHandler<Platform>::ResultListenerFacade(
|
||||
MakePtr(this))));
|
||||
MakePtr(new
|
||||
typename BasePCPHandler<Platform>::ResultListenerFacade(self_)));
|
||||
return Exception::NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -496,6 +496,7 @@ class BasePCPHandler
|
||||
// This should have been a ScopedPtr, but we are making this a Ptr to manually
|
||||
// control the order of destruction.
|
||||
Ptr<EncryptionRunner<Platform> > encryption_runner_;
|
||||
std::shared_ptr<BasePCPHandler> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -290,9 +290,14 @@ TEST(BLEAdvertisementTest, DeserializationPassesWithLongLength) {
|
||||
endpoint_name, bluetooth_mac_address));
|
||||
|
||||
// Add bytes to the end of the valid BLE advertisement.
|
||||
auto new_array =
|
||||
new ByteArray(BLEAdvertisement::kMinAdvertisementLength + 1000);
|
||||
ASSERT_LE(scoped_ble_advertisement_bytes->size(), new_array->size());
|
||||
memcpy(new_array->getData(),
|
||||
scoped_ble_advertisement_bytes->getData(),
|
||||
scoped_ble_advertisement_bytes->size());
|
||||
ScopedPtr<ConstPtr<ByteArray> > long_ble_advertisement_bytes(MakeConstPtr(
|
||||
new ByteArray(scoped_ble_advertisement_bytes.get()->getData(),
|
||||
BLEAdvertisement::kMinAdvertisementLength + 1000)));
|
||||
new_array));
|
||||
|
||||
// Deserialize the long BLE advertisement.
|
||||
ScopedPtr<Ptr<BLEAdvertisement> > scoped_long_ble_advertisement(
|
||||
@@ -327,9 +332,14 @@ TEST(BLEAdvertisementTest, DeserializationWorksWithLongEndpointName) {
|
||||
corrupt_ble_advertisement_bytes.size())));
|
||||
// Increase the size of the advertisement so that there's enough data for the
|
||||
// now-longer endpoint name.
|
||||
auto new_array =
|
||||
new ByteArray(BLEAdvertisement::kMinAdvertisementLength + 1000);
|
||||
ASSERT_LE(scoped_ble_advertisement_bytes->size(), new_array->size());
|
||||
memcpy(new_array->getData(),
|
||||
scoped_ble_advertisement_bytes->getData(),
|
||||
scoped_ble_advertisement_bytes->size());
|
||||
ScopedPtr<ConstPtr<ByteArray> > long_ble_advertisement_bytes(MakeConstPtr(
|
||||
new ByteArray(scoped_corrupt_ble_advertisement_bytes.get()->getData(),
|
||||
BLEAdvertisement::kMinAdvertisementLength + 1000)));
|
||||
new_array));
|
||||
|
||||
// And deserialize the changed BLE Advertisement.
|
||||
ScopedPtr<Ptr<BLEAdvertisement> > scoped_ble_advertisement(
|
||||
|
||||
@@ -201,10 +201,7 @@ EndpointChannelManager<Platform>::ChannelState::updateChannelForEndpoint(
|
||||
ScopedPtr<Ptr<EndpointChannel> > scoped_previous_endpoint_channel(
|
||||
previous_endpoint_channel);
|
||||
|
||||
// Upgrade endpoint_channel to be reference-counted before starting to track
|
||||
// it (and make it clear that endpoint_channel no longer owns the raw
|
||||
// pointer).
|
||||
endpoint_metadata->endpoint_channel = MakeRefCountedPtr(&(*endpoint_channel));
|
||||
endpoint_metadata->endpoint_channel = endpoint_channel;
|
||||
endpoint_channel.clear();
|
||||
endpoint_id_to_metadata_[endpoint_id] = endpoint_metadata;
|
||||
|
||||
|
||||
@@ -497,7 +497,7 @@ void EndpointManager<Platform>::registerIncomingOfflineFrameProcessor(
|
||||
processor) {
|
||||
runOnEndpointManagerThread(MakePtr(
|
||||
new endpoint_manager::RegisterIncomingOfflineFrameProcessorRunnable<
|
||||
Platform>(MakePtr(this), frame_type, processor)));
|
||||
Platform>(self_, frame_type, processor)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -507,7 +507,7 @@ void EndpointManager<Platform>::unregisterIncomingOfflineFrameProcessor(
|
||||
processor) {
|
||||
runOnEndpointManagerThread(MakePtr(
|
||||
new endpoint_manager::UnregisterIncomingOfflineFrameProcessorRunnable<
|
||||
Platform>(MakePtr(this), frame_type, processor)));
|
||||
Platform>(self_, frame_type, processor)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -521,7 +521,7 @@ EndpointManager<Platform>::getOfflineFrameProcessor(
|
||||
ScopedPtr<ResultType> future_result(
|
||||
runOnEndpointManagerThread<PtrIncomingOfflineFrameProcessor>(MakePtr(
|
||||
new endpoint_manager::GetOfflineFrameProcessorCallable<Platform>(
|
||||
MakePtr(this), frame_type))));
|
||||
self_, frame_type))));
|
||||
|
||||
return waitForResult("getOfflineFrameProcessor", future_result.get());
|
||||
}
|
||||
@@ -536,7 +536,7 @@ void EndpointManager<Platform>::registerEndpoint(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnEndpointManagerThread(
|
||||
MakePtr(new endpoint_manager::RegisterEndpointRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, endpoint_name,
|
||||
self_, client_proxy, endpoint_id, endpoint_name,
|
||||
authentication_token, raw_authentication_token, is_incoming,
|
||||
endpoint_channel, connection_lifecycle_listener, latch.get())));
|
||||
waitForLatch("registerEndpoint", latch.get());
|
||||
@@ -548,7 +548,7 @@ void EndpointManager<Platform>::unregisterEndpoint(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnEndpointManagerThread(
|
||||
MakePtr(new endpoint_manager::UnregisterEndpointRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, latch.get())));
|
||||
self_, client_proxy, endpoint_id, latch.get())));
|
||||
waitForLatch("unregisterEndpoint", latch.get());
|
||||
}
|
||||
|
||||
@@ -557,7 +557,7 @@ void EndpointManager<Platform>::discardEndpoint(
|
||||
Ptr<ClientProxy<Platform>> client_proxy, const string& endpoint_id) {
|
||||
runOnEndpointManagerThread(
|
||||
MakePtr(new endpoint_manager::DiscardEndpointRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id)));
|
||||
self_, client_proxy, endpoint_id)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CORE_INTERNAL_ENDPOINT_MANAGER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "core/internal/client_proxy.h"
|
||||
#include "core/internal/endpoint_channel.h"
|
||||
@@ -221,6 +222,7 @@ class EndpointManager {
|
||||
ScopedPtr<Ptr<typename Platform::MultiThreadExecutorType> >
|
||||
endpoint_readers_thread_pool_;
|
||||
ScopedPtr<Ptr<typename Platform::SingleThreadExecutorType> > serial_executor_;
|
||||
std::shared_ptr<EndpointManager<Platform>> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace nearby {
|
||||
namespace connections {
|
||||
namespace mediums {
|
||||
|
||||
namespace {
|
||||
|
||||
class SampleSystemClock : public SystemClock {
|
||||
public:
|
||||
SampleSystemClock() {}
|
||||
@@ -30,13 +28,24 @@ class SamplePlatform {
|
||||
}
|
||||
};
|
||||
|
||||
// We keep a copy of these constants because this is an old-school test (so we
|
||||
// can't delare it as a friend class of AdvertisementReadResult).
|
||||
constexpr char kAdvertisementBytes[] = {0x0A, 0x0B, 0x0C};
|
||||
|
||||
// Default values may be too big and impractical to wait for in the test.
|
||||
// For the test platform, we redefine them to some reasonable values.
|
||||
const absl::Duration kAdvertisementBaseBackoffDuration =
|
||||
absl::Milliseconds(1000); // 1 second
|
||||
const absl::Duration kAdvertisementMaxBackoffDuration =
|
||||
absl::Milliseconds(6000); // 6 seconds
|
||||
const char kAdvertisementBytes[] = {0x0A, 0x0B, 0x0C};
|
||||
|
||||
template <>
|
||||
const std::int64_t AdvertisementReadResult<
|
||||
SamplePlatform>::kAdvertisementMaxBackoffDurationMillis =
|
||||
ToInt64Milliseconds(kAdvertisementMaxBackoffDuration);
|
||||
template <>
|
||||
const std::int64_t
|
||||
AdvertisementReadResult<
|
||||
SamplePlatform>::kAdvertisementBaseBackoffDurationMillis =
|
||||
ToInt64Milliseconds(kAdvertisementBaseBackoffDuration);
|
||||
|
||||
TEST(AdvertisementReadResultTest, AdvertisementExists) {
|
||||
AdvertisementReadResult<SamplePlatform> advertisement_read_result;
|
||||
@@ -141,7 +150,6 @@ TEST(AdvertisementReadResultTest, GetDurationSinceRead) {
|
||||
ASSERT_GE(advertisement_read_result.getDurationSinceReadMillis(), sleepTime);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mediums
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "core/internal/mediums/ble_advertisement.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
@@ -224,9 +226,10 @@ TEST(BLEAdvertisementTest, DeserializationWorksWithExtraBytes) {
|
||||
|
||||
// Copy the bytes into a new array with extra bytes. We must explicitly
|
||||
// define how long our array is because we can't use variable length arrays.
|
||||
char raw_ble_advertisement_bytes[kLongAdvertisementLength];
|
||||
char raw_ble_advertisement_bytes[kLongAdvertisementLength] {};
|
||||
memcpy(raw_ble_advertisement_bytes, scoped_ble_advertisement_bytes->getData(),
|
||||
kLongAdvertisementLength);
|
||||
std::min(sizeof(raw_ble_advertisement_bytes),
|
||||
scoped_ble_advertisement_bytes->size()));
|
||||
|
||||
// Re-parse the BLE advertisement using our extra long advertisement bytes.
|
||||
ScopedPtr<ConstPtr<ByteArray> > scoped_long_ble_advertisement_bytes(
|
||||
|
||||
@@ -41,6 +41,38 @@ class BLEPacket {
|
||||
ScopedPtr<ConstPtr<ByteArray> > data_;
|
||||
};
|
||||
|
||||
// Represents the format of data sent over BLE sockets.
|
||||
//
|
||||
// [SERVICE_ID_HASH][DATA]
|
||||
//
|
||||
// See go/nearby-ble-design for more information.
|
||||
class BlePacket {
|
||||
public:
|
||||
static BlePacket FromBytes(const ByteArray& bytes);
|
||||
|
||||
static ByteArray ToBytes(const ByteArray& service_id_hash,
|
||||
const ByteArray& data);
|
||||
|
||||
static const uint32_t kServiceIdHashLength;
|
||||
|
||||
~BlePacket();
|
||||
|
||||
ByteArray GetServiceIdHash() const;
|
||||
ByteArray GetData() const;
|
||||
|
||||
private:
|
||||
static size_t ComputeDataSize(const ByteArray& ble_packet_bytes);
|
||||
static size_t ComputePacketLength(const ByteArray& data);
|
||||
|
||||
static const uint32_t kMinPacketLength;
|
||||
static const uint32_t kMaxDataSize;
|
||||
|
||||
BlePacket(const ByteArray& service_id_hash, const ByteArray& data);
|
||||
|
||||
ByteArray service_id_hash_;
|
||||
ByteArray data_;
|
||||
};
|
||||
|
||||
} // namespace mediums
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -22,6 +22,21 @@ class BLEPeripheral {
|
||||
ScopedPtr<ConstPtr<ByteArray>> id_;
|
||||
};
|
||||
|
||||
|
||||
// Represents BLE peripheral for testing.
|
||||
class BlePeripheral {
|
||||
public:
|
||||
explicit BlePeripheral(const ByteArray& id) : id_(id) {}
|
||||
~BlePeripheral() = default;
|
||||
|
||||
const ByteArray& GetId() const { return id_; }
|
||||
|
||||
private:
|
||||
// A unique identifier for this peripheral. It can be the BLE advertisement it
|
||||
// was found on, or even simply the BLE MAC address.
|
||||
const ByteArray id_;
|
||||
};
|
||||
|
||||
} // namespace mediums
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -405,7 +405,7 @@ bool BLEV2<Platform>::startScanning(
|
||||
fast_advertisement_service_uuid);
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<ScanCallbackFacade>> scan_callback_facade(
|
||||
new ScanCallbackFacade(MakePtr(this)));
|
||||
new ScanCallbackFacade(self_));
|
||||
std::set<string> service_uuids;
|
||||
service_uuids.insert(kCopresenceServiceUuid);
|
||||
if (!ble_medium_->startScanning(service_uuids, power_mode,
|
||||
@@ -427,7 +427,7 @@ void BLEV2<Platform>::onAdvertisementFoundImpl(
|
||||
ConstPtr<BLEAdvertisementData> advertisement_data) {
|
||||
offloadFromPlatformThread(
|
||||
MakePtr(new ble_v2::OnAdvertisementFoundRunnable<Platform>(
|
||||
MakePtr(this), ble_peripheral, advertisement_data)));
|
||||
self_, ble_peripheral, advertisement_data)));
|
||||
}
|
||||
|
||||
// This method is synchronized because it affects class state, but is called
|
||||
@@ -461,11 +461,6 @@ void BLEV2<Platform>::stopScanning() {
|
||||
// TODO(b/112199086) Change to RecurringCancelableAlarm
|
||||
template <typename Platform>
|
||||
Ptr<CancelableAlarm<Platform>> BLEV2<Platform>::createOnLostAlarm() {
|
||||
// return MakePtr(new CancelableAlarm<Platform>(
|
||||
// "BluetoothLowEnergy.startScanning() onLost",
|
||||
// MakePtr(new
|
||||
// ble_v2::ProcessOnLostRunnable<Platform>(MakePtr(this))),
|
||||
// kOnLostTimeoutMillis, on_lost_executor_.get()));
|
||||
return Ptr<CancelableAlarm<Platform>>();
|
||||
}
|
||||
|
||||
@@ -606,7 +601,7 @@ bool BLEV2<Platform>::internalStartAdvertisementGattServer(
|
||||
|
||||
ScopedPtr<Ptr<ServerGATTConnectionLifecycleCallbackFacade>>
|
||||
connection_lifecycle_callback(
|
||||
new ServerGATTConnectionLifecycleCallbackFacade(MakePtr(this)));
|
||||
new ServerGATTConnectionLifecycleCallbackFacade(self_));
|
||||
ScopedPtr<Ptr<GATTServer>> gatt_server(
|
||||
ble_medium_->startGATTServer(connection_lifecycle_callback.get()));
|
||||
if (gatt_server.isNull()) {
|
||||
@@ -737,7 +732,7 @@ BLEV2<Platform>::internalReadFromAdvertisementGattServer(
|
||||
|
||||
ScopedPtr<Ptr<ClientGATTConnectionLifecycleCallbackFacade>>
|
||||
connection_lifecycle_callback(
|
||||
new ClientGATTConnectionLifecycleCallbackFacade(MakePtr(this)));
|
||||
new ClientGATTConnectionLifecycleCallbackFacade(self_));
|
||||
ScopedPtr<Ptr<ClientGATTConnection>> gatt_connection(
|
||||
ble_medium_->connectToGATTServer(peripheral, kDefaultMtu,
|
||||
BLEMediumV2::PowerMode::HIGH,
|
||||
|
||||
@@ -300,6 +300,7 @@ class BLEV2 {
|
||||
Ptr<AdvertisingInfo> advertising_info_;
|
||||
Ptr<GATTServerInfo> gatt_server_info_;
|
||||
Ptr<AcceptingConnectionsInfo> accepting_connections_info_;
|
||||
std::shared_ptr<BLEV2> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace mediums
|
||||
|
||||
@@ -71,8 +71,7 @@ TEST(BloomFilterTest, AddMultipleArgsReturnsNonemptyArray) {
|
||||
ScopedPtr<ConstPtr<ByteArray>> scoped_bloom_filter_bytes(
|
||||
scoped_bloom_filter->asBytes());
|
||||
std::string empty_string(kByteArrayLength, '\0');
|
||||
ASSERT_NE(0, memcmp(scoped_bloom_filter_bytes->getData(), empty_string.data(),
|
||||
empty_string.size()));
|
||||
ASSERT_NE(scoped_bloom_filter_bytes->asString(), empty_string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,85 +1,71 @@
|
||||
#include "core/internal/offline_frames.h"
|
||||
|
||||
#include "platform/port/down_cast.h"
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
using ExceptionOrOfflineFrame = ExceptionOr<ConstPtr<OfflineFrame>>;
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
T *downcastToRaw(Ptr<proto_ns::MessageLite> message) {
|
||||
return DOWN_CAST<T *>(message.operator->());
|
||||
}
|
||||
|
||||
// This method takes ownership of the passed-in 'message'.
|
||||
//
|
||||
// This can be implemented more efficiently by taking in a reference to an
|
||||
// OfflineFrame object created on the caller's stack, but we instead create it
|
||||
// on the heap and return a Ptr to it for the sake of consistency.
|
||||
ConstPtr<OfflineFrame> newOfflineFrame(V1Frame::FrameType frame_type,
|
||||
Ptr<proto_ns::MessageLite> message) {
|
||||
std::unique_ptr<OfflineFrame> NewOfflineFrame(
|
||||
V1Frame::FrameType frame_type,
|
||||
std::unique_ptr<proto_ns::MessageLite> message) {
|
||||
V1Frame *v1_frame = new V1Frame();
|
||||
v1_frame->set_type(frame_type);
|
||||
|
||||
switch (frame_type) {
|
||||
case V1Frame::CONNECTION_REQUEST:
|
||||
v1_frame->set_allocated_connection_request(
|
||||
downcastToRaw<ConnectionRequestFrame>(message));
|
||||
static_cast<ConnectionRequestFrame *>(message.release()));
|
||||
break;
|
||||
case V1Frame::CONNECTION_RESPONSE:
|
||||
v1_frame->set_allocated_connection_response(
|
||||
downcastToRaw<ConnectionResponseFrame>(message));
|
||||
static_cast<ConnectionResponseFrame *>(message.release()));
|
||||
break;
|
||||
case V1Frame::PAYLOAD_TRANSFER:
|
||||
v1_frame->set_allocated_payload_transfer(
|
||||
downcastToRaw<PayloadTransferFrame>(message));
|
||||
static_cast<PayloadTransferFrame *>(message.release()));
|
||||
break;
|
||||
case V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION:
|
||||
v1_frame->set_allocated_bandwidth_upgrade_negotiation(
|
||||
downcastToRaw<BandwidthUpgradeNegotiationFrame>(message));
|
||||
static_cast<BandwidthUpgradeNegotiationFrame *>(message.release()));
|
||||
break;
|
||||
case V1Frame::KEEP_ALIVE:
|
||||
v1_frame->set_allocated_keep_alive(
|
||||
downcastToRaw<KeepAliveFrame>(message));
|
||||
static_cast<KeepAliveFrame *>(message.release()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Ptr<OfflineFrame> offline_frame(new OfflineFrame());
|
||||
auto offline_frame = std::make_unique<OfflineFrame>();
|
||||
offline_frame->set_version(OfflineFrame::V1);
|
||||
offline_frame->set_allocated_v1(v1_frame);
|
||||
return ConstifyPtr(offline_frame);
|
||||
return offline_frame;
|
||||
}
|
||||
|
||||
// This method takes ownership of the passed-in 'offline_frame' and destroys it
|
||||
// before returning.
|
||||
ConstPtr<ByteArray> toBytes(ConstPtr<OfflineFrame> offline_frame) {
|
||||
ScopedPtr<ConstPtr<OfflineFrame> > scoped_offline_frame(offline_frame);
|
||||
|
||||
size_t serialized_size = offline_frame->ByteSizeLong();
|
||||
Ptr<ByteArray> bytes{new ByteArray{serialized_size}};
|
||||
|
||||
offline_frame->SerializeToArray(bytes->getData(), serialized_size);
|
||||
return ConstifyPtr(bytes);
|
||||
ConstPtr<ByteArray> toBytes(std::unique_ptr<OfflineFrame> offline_frame) {
|
||||
auto *bytes = new ByteArray{offline_frame->ByteSizeLong()};
|
||||
offline_frame->SerializeToArray(bytes->getData(), bytes->size());
|
||||
return MakeConstPtr(bytes);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ExceptionOr<ConstPtr<OfflineFrame> > OfflineFrames::fromBytes(
|
||||
ExceptionOrOfflineFrame OfflineFrames::fromBytes(
|
||||
ConstPtr<ByteArray> offline_frame_bytes) {
|
||||
ScopedPtr<Ptr<OfflineFrame> > offline_frame(new OfflineFrame());
|
||||
auto offline_frame = std::make_unique<OfflineFrame>();
|
||||
|
||||
if (!offline_frame->ParseFromArray(offline_frame_bytes->getData(),
|
||||
offline_frame_bytes->size())) {
|
||||
return ExceptionOr<ConstPtr<OfflineFrame> >(
|
||||
Exception::INVALID_PROTOCOL_BUFFER);
|
||||
if (!offline_frame->ParseFromString(offline_frame_bytes->asString())) {
|
||||
return ExceptionOrOfflineFrame(Exception::INVALID_PROTOCOL_BUFFER);
|
||||
}
|
||||
|
||||
return ExceptionOr<ConstPtr<OfflineFrame> >(
|
||||
ConstifyPtr(offline_frame.release()));
|
||||
return ExceptionOrOfflineFrame(MakeConstPtr(offline_frame.release()));
|
||||
}
|
||||
|
||||
V1Frame::FrameType OfflineFrames::getFrameType(
|
||||
@@ -96,7 +82,7 @@ ConstPtr<ByteArray> OfflineFrames::forConnectionRequest(
|
||||
const std::string &endpoint_id, const std::string &endpoint_name,
|
||||
std::int32_t nonce,
|
||||
const std::vector<proto::connections::Medium> &mediums) {
|
||||
Ptr<ConnectionRequestFrame> connection_request(new ConnectionRequestFrame());
|
||||
auto connection_request = std::make_unique<ConnectionRequestFrame>();
|
||||
connection_request->set_endpoint_id(endpoint_id);
|
||||
connection_request->set_endpoint_name(endpoint_name);
|
||||
connection_request->set_nonce(nonce);
|
||||
@@ -107,113 +93,113 @@ ConstPtr<ByteArray> OfflineFrames::forConnectionRequest(
|
||||
connection_request->add_mediums(mediumToConnectionRequestMedium(*it));
|
||||
}
|
||||
|
||||
return toBytes(
|
||||
newOfflineFrame(V1Frame::CONNECTION_REQUEST, connection_request));
|
||||
return toBytes(NewOfflineFrame(V1Frame::CONNECTION_REQUEST,
|
||||
std::move(connection_request)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::forConnectionResponse(std::int32_t status) {
|
||||
Ptr<ConnectionResponseFrame> connection_response(
|
||||
new ConnectionResponseFrame());
|
||||
auto connection_response = std::make_unique<ConnectionResponseFrame>();
|
||||
connection_response->set_status(status);
|
||||
|
||||
return toBytes(
|
||||
newOfflineFrame(V1Frame::CONNECTION_RESPONSE, connection_response));
|
||||
return toBytes(NewOfflineFrame(V1Frame::CONNECTION_RESPONSE,
|
||||
std::move(connection_response)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::forDataPayloadTransferFrame(
|
||||
const PayloadTransferFrame::PayloadHeader &header,
|
||||
const PayloadTransferFrame::PayloadChunk &chunk) {
|
||||
Ptr<PayloadTransferFrame> payload_transfer(new PayloadTransferFrame());
|
||||
auto payload_transfer = std::make_unique<PayloadTransferFrame>();
|
||||
payload_transfer->set_packet_type(PayloadTransferFrame::DATA);
|
||||
*payload_transfer->mutable_payload_header() = header;
|
||||
*payload_transfer->mutable_payload_chunk() = chunk;
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::PAYLOAD_TRANSFER, payload_transfer));
|
||||
return toBytes(
|
||||
NewOfflineFrame(V1Frame::PAYLOAD_TRANSFER, std::move(payload_transfer)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::forControlPayloadTransferFrame(
|
||||
const PayloadTransferFrame::PayloadHeader &header,
|
||||
const PayloadTransferFrame::ControlMessage &control) {
|
||||
Ptr<PayloadTransferFrame> payload_transfer(new PayloadTransferFrame());
|
||||
auto payload_transfer = std::make_unique<PayloadTransferFrame>();
|
||||
payload_transfer->set_packet_type(PayloadTransferFrame::CONTROL);
|
||||
*payload_transfer->mutable_payload_header() = header;
|
||||
*payload_transfer->mutable_control_message() = control;
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::PAYLOAD_TRANSFER, payload_transfer));
|
||||
return toBytes(
|
||||
NewOfflineFrame(V1Frame::PAYLOAD_TRANSFER, std::move(payload_transfer)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::
|
||||
forWifiHotspotUpgradePathAvailableBandwidthUpgradeNegotiationEvent(
|
||||
const std::string &ssid, const std::string &password,
|
||||
std::int32_t port) {
|
||||
BandwidthUpgradeNegotiationFrame::UpgradePathInfo::WifiHotspotCredentials
|
||||
*wifi_hotspot_credentials = new BandwidthUpgradeNegotiationFrame::
|
||||
UpgradePathInfo::WifiHotspotCredentials();
|
||||
auto *wifi_hotspot_credentials = new BandwidthUpgradeNegotiationFrame::
|
||||
UpgradePathInfo::WifiHotspotCredentials();
|
||||
wifi_hotspot_credentials->set_ssid(ssid);
|
||||
wifi_hotspot_credentials->set_password(password);
|
||||
wifi_hotspot_credentials->set_port(port);
|
||||
|
||||
BandwidthUpgradeNegotiationFrame::UpgradePathInfo *upgrade_path_info =
|
||||
auto *upgrade_path_info =
|
||||
new BandwidthUpgradeNegotiationFrame::UpgradePathInfo();
|
||||
upgrade_path_info->set_medium(
|
||||
BandwidthUpgradeNegotiationFrame::UpgradePathInfo::WIFI_HOTSPOT);
|
||||
upgrade_path_info->set_allocated_wifi_hotspot_credentials(
|
||||
wifi_hotspot_credentials);
|
||||
|
||||
Ptr<BandwidthUpgradeNegotiationFrame> bandwidth_upgrade_negotiation(
|
||||
new BandwidthUpgradeNegotiationFrame());
|
||||
auto bandwidth_upgrade_negotiation =
|
||||
std::make_unique<BandwidthUpgradeNegotiationFrame>();
|
||||
bandwidth_upgrade_negotiation->set_event_type(
|
||||
BandwidthUpgradeNegotiationFrame::UPGRADE_PATH_AVAILABLE);
|
||||
bandwidth_upgrade_negotiation->set_allocated_upgrade_path_info(
|
||||
upgrade_path_info);
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
bandwidth_upgrade_negotiation));
|
||||
return toBytes(NewOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
std::move(bandwidth_upgrade_negotiation)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray>
|
||||
OfflineFrames::forLastWriteToPriorChannelBandwidthUpgradeNegotiationEvent() {
|
||||
Ptr<BandwidthUpgradeNegotiationFrame> bandwidth_upgrade_negotiation(
|
||||
new BandwidthUpgradeNegotiationFrame());
|
||||
auto bandwidth_upgrade_negotiation =
|
||||
std::make_unique<BandwidthUpgradeNegotiationFrame>();
|
||||
bandwidth_upgrade_negotiation->set_event_type(
|
||||
BandwidthUpgradeNegotiationFrame::LAST_WRITE_TO_PRIOR_CHANNEL);
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
bandwidth_upgrade_negotiation));
|
||||
return toBytes(NewOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
std::move(bandwidth_upgrade_negotiation)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray>
|
||||
OfflineFrames::forSafeToClosePriorChannelBandwidthUpgradeNegotiationEvent() {
|
||||
Ptr<BandwidthUpgradeNegotiationFrame> bandwidth_upgrade_negotiation(
|
||||
new BandwidthUpgradeNegotiationFrame());
|
||||
auto bandwidth_upgrade_negotiation =
|
||||
std::make_unique<BandwidthUpgradeNegotiationFrame>();
|
||||
bandwidth_upgrade_negotiation->set_event_type(
|
||||
BandwidthUpgradeNegotiationFrame::SAFE_TO_CLOSE_PRIOR_CHANNEL);
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
bandwidth_upgrade_negotiation));
|
||||
return toBytes(NewOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
std::move(bandwidth_upgrade_negotiation)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray>
|
||||
OfflineFrames::forClientIntroductionBandwidthUpgradeNegotiationEvent(
|
||||
const std::string &endpoint_id) {
|
||||
BandwidthUpgradeNegotiationFrame::ClientIntroduction *client_introduction =
|
||||
auto *client_introduction =
|
||||
new BandwidthUpgradeNegotiationFrame::ClientIntroduction();
|
||||
client_introduction->set_endpoint_id(endpoint_id);
|
||||
|
||||
Ptr<BandwidthUpgradeNegotiationFrame> bandwidth_upgrade_negotiation(
|
||||
new BandwidthUpgradeNegotiationFrame());
|
||||
auto bandwidth_upgrade_negotiation =
|
||||
std::make_unique<BandwidthUpgradeNegotiationFrame>();
|
||||
bandwidth_upgrade_negotiation->set_event_type(
|
||||
BandwidthUpgradeNegotiationFrame::CLIENT_INTRODUCTION);
|
||||
bandwidth_upgrade_negotiation->set_allocated_client_introduction(
|
||||
client_introduction);
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
bandwidth_upgrade_negotiation));
|
||||
return toBytes(NewOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
std::move(bandwidth_upgrade_negotiation)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::forKeepAlive() {
|
||||
Ptr<KeepAliveFrame> keep_alive_frame(new KeepAliveFrame());
|
||||
return toBytes(newOfflineFrame(V1Frame::KEEP_ALIVE, keep_alive_frame));
|
||||
return toBytes(
|
||||
NewOfflineFrame(V1Frame::KEEP_ALIVE, std::make_unique<KeepAliveFrame>()));
|
||||
}
|
||||
|
||||
ConnectionRequestFrame::Medium OfflineFrames::mediumToConnectionRequestMedium(
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "core/internal/offline_frames.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "proto/connections/offline_wire_formats.pb.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location::nearby::connections {
|
||||
|
||||
namespace {
|
||||
using Medium = proto::connections::Medium;
|
||||
|
||||
std::unique_ptr<OfflineFrame> MakeFrame(V1Frame* sub_frame) {
|
||||
auto frame = std::make_unique<OfflineFrame>();
|
||||
frame->set_version(OfflineFrame::V1);
|
||||
frame->set_allocated_v1(sub_frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
void SetSubframe(V1Frame* frame, ConnectionRequestFrame* sub_frame) {
|
||||
frame->set_type(V1Frame::CONNECTION_REQUEST);
|
||||
frame->set_allocated_connection_request(sub_frame);
|
||||
}
|
||||
|
||||
constexpr ConnectionRequestFrame::Medium ToConnectionRequestMedium(
|
||||
proto::connections::Medium medium) {
|
||||
switch (medium) {
|
||||
case proto::connections::MDNS:
|
||||
return ConnectionRequestFrame::MDNS;
|
||||
case proto::connections::BLUETOOTH:
|
||||
return ConnectionRequestFrame::BLUETOOTH;
|
||||
case proto::connections::WIFI_HOTSPOT:
|
||||
return ConnectionRequestFrame::WIFI_HOTSPOT;
|
||||
case proto::connections::BLE:
|
||||
return ConnectionRequestFrame::BLE;
|
||||
case proto::connections::WIFI_LAN:
|
||||
return ConnectionRequestFrame::WIFI_LAN;
|
||||
default:
|
||||
return ConnectionRequestFrame::UNKNOWN_MEDIUM;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(OfflineFramesTest, CanParseMessageFromBytes) {
|
||||
const string endpoint_id{"ABC"};
|
||||
const string endpoint_name{"XYZ"};
|
||||
const int32 nonce{1234};
|
||||
const std::vector<proto::connections::Medium> mediums{Medium::BLE,
|
||||
Medium::BLUETOOTH};
|
||||
|
||||
auto* v1_frame = new V1Frame{};
|
||||
auto* sub_frame = new ConnectionRequestFrame{};
|
||||
sub_frame->set_endpoint_id(endpoint_id);
|
||||
sub_frame->set_endpoint_name(endpoint_name);
|
||||
sub_frame->set_nonce(nonce);
|
||||
|
||||
for (auto& medium : mediums) {
|
||||
sub_frame->add_mediums(ToConnectionRequestMedium(medium));
|
||||
}
|
||||
|
||||
SetSubframe(v1_frame, sub_frame);
|
||||
auto frame = MakeFrame(v1_frame);
|
||||
|
||||
auto bytes = MakeConstPtr(new ByteArray(frame->SerializeAsString()));
|
||||
|
||||
auto ret_value = OfflineFrames::fromBytes(bytes);
|
||||
ASSERT_TRUE(ret_value.ok());
|
||||
const auto& rx_message = ret_value.result();
|
||||
ASSERT_TRUE(rx_message->has_version());
|
||||
ASSERT_EQ(rx_message->version(), OfflineFrame::V1);
|
||||
ASSERT_TRUE(rx_message->has_v1());
|
||||
const auto& rx_frame = rx_message->v1();
|
||||
ASSERT_EQ(rx_frame.type(), V1Frame::CONNECTION_REQUEST);
|
||||
ASSERT_TRUE(rx_frame.has_connection_request());
|
||||
const auto& req = rx_frame.connection_request();
|
||||
ASSERT_TRUE(req.has_endpoint_id());
|
||||
ASSERT_TRUE(req.has_endpoint_name());
|
||||
ASSERT_TRUE(req.has_nonce());
|
||||
ASSERT_EQ(req.endpoint_id(), endpoint_id);
|
||||
ASSERT_EQ(req.endpoint_name(), endpoint_name);
|
||||
ASSERT_EQ(req.nonce(), nonce);
|
||||
ASSERT_EQ(req.mediums_size(), mediums.size());
|
||||
}
|
||||
|
||||
} // namespace location::nearby::connections
|
||||
@@ -134,14 +134,14 @@ P2PClusterPCPHandler<Platform>::startDiscoveryImpl(
|
||||
|
||||
proto::connections::Medium bluetooth_medium =
|
||||
startBluetoothDiscovery(MakePtr(new FoundBluetoothAdvertisementProcessor(
|
||||
MakePtr(this), client_proxy, service_id)),
|
||||
self_, client_proxy, service_id)),
|
||||
client_proxy, service_id);
|
||||
if (proto::connections::UNKNOWN_MEDIUM != bluetooth_medium) {
|
||||
mediums_started_successfully.push_back(bluetooth_medium);
|
||||
}
|
||||
|
||||
proto::connections::Medium ble_medium = startBleDiscovery(
|
||||
MakePtr(new FoundBleAdvertisementProcessor(MakePtr(this), client_proxy)),
|
||||
MakePtr(new FoundBleAdvertisementProcessor(self_, client_proxy)),
|
||||
client_proxy, service_id);
|
||||
if (proto::connections::UNKNOWN_MEDIUM != ble_medium) {
|
||||
mediums_started_successfully.push_back(ble_medium);
|
||||
@@ -312,7 +312,7 @@ void P2PClusterPCPHandler<Platform>::FoundBluetoothAdvertisementProcessor::
|
||||
onFoundBluetoothDevice(Ptr<BluetoothDevice> bluetooth_device) {
|
||||
pcp_handler_->runOnPCPHandlerThread(
|
||||
MakePtr(new OnFoundBluetoothDeviceRunnable(pcp_handler_, client_proxy_,
|
||||
MakePtr(this), service_id_,
|
||||
self_, service_id_,
|
||||
bluetooth_device)));
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ template <typename Platform>
|
||||
void P2PClusterPCPHandler<Platform>::FoundBluetoothAdvertisementProcessor::
|
||||
onLostBluetoothDevice(Ptr<BluetoothDevice> bluetooth_device) {
|
||||
pcp_handler_->runOnPCPHandlerThread(MakePtr(new OnLostBluetoothDeviceRunnable(
|
||||
pcp_handler_, client_proxy_, MakePtr(this), service_id_,
|
||||
pcp_handler_, client_proxy_, self_, service_id_,
|
||||
bluetooth_device)));
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ void P2PClusterPCPHandler<Platform>::FoundBleAdvertisementProcessor::
|
||||
const string& service_id,
|
||||
ConstPtr<ByteArray> advertisement_bytes) {
|
||||
pcp_handler_->runOnPCPHandlerThread(MakePtr(new OnFoundBlePeripheralRunnable(
|
||||
pcp_handler_, client_proxy_, MakePtr(this), service_id, ble_peripheral,
|
||||
pcp_handler_, client_proxy_, self_, service_id, ble_peripheral,
|
||||
advertisement_bytes)));
|
||||
}
|
||||
|
||||
@@ -532,7 +532,7 @@ void P2PClusterPCPHandler<Platform>::FoundBleAdvertisementProcessor::
|
||||
onLostBlePeripheral(Ptr<BLE_PERIPHERAL> ble_peripheral,
|
||||
const string& service_id) {
|
||||
pcp_handler_->runOnPCPHandlerThread(MakePtr(new OnLostBlePeripheralRunnable(
|
||||
pcp_handler_, client_proxy_, MakePtr(this), service_id, ble_peripheral)));
|
||||
pcp_handler_, client_proxy_, self_, service_id, ble_peripheral)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -597,7 +597,7 @@ P2PClusterPCPHandler<Platform>::startBluetoothAdvertising(
|
||||
if (!medium_manager_->startListeningForIncomingBluetoothConnections(
|
||||
service_id,
|
||||
MakePtr(new IncomingBluetoothConnectionProcessor(
|
||||
MakePtr(this), client_proxy, local_endpoint_name)))) {
|
||||
self_, client_proxy, local_endpoint_name)))) {
|
||||
// TODO(tracyzhou): Add logging.
|
||||
return proto::connections::UNKNOWN_MEDIUM;
|
||||
}
|
||||
@@ -654,7 +654,7 @@ proto::connections::Medium P2PClusterPCPHandler<Platform>::startBleAdvertising(
|
||||
if (!medium_manager_->startListeningForIncomingBleConnections(
|
||||
service_id,
|
||||
MakePtr(new IncomingBleConnectionProcessor(
|
||||
MakePtr(this), client_proxy, local_endpoint_name)))) {
|
||||
self_, client_proxy, local_endpoint_name)))) {
|
||||
// TODO(ahlee): logger.atWarning().log("In startBleAdvertising(%s), client
|
||||
// %d failed to start listening for incoming BLE connections to ServiceId
|
||||
// %s", local_endpoint_name, clientProxy.getClientId(), service_id);
|
||||
|
||||
@@ -208,6 +208,8 @@ class P2PClusterPCPHandler : public BasePCPHandler<Platform> {
|
||||
Ptr<ClientProxy<Platform> > client_proxy_;
|
||||
const string service_id_;
|
||||
ScopedPtr<ConstPtr<ByteArray> > expected_service_id_hash_;
|
||||
std::shared_ptr<FoundBluetoothAdvertisementProcessor> self_{this,
|
||||
[](void*) {}};
|
||||
};
|
||||
|
||||
class FoundBleAdvertisementProcessor
|
||||
@@ -281,6 +283,7 @@ class P2PClusterPCPHandler : public BasePCPHandler<Platform> {
|
||||
// Maps a BLEPeripheral to its corresponding BLEEndpointState.
|
||||
typedef std::map<string, BLEEndpointState> FoundBLEEndpointsMap;
|
||||
FoundBLEEndpointsMap found_ble_endpoints_;
|
||||
std::shared_ptr<FoundBleAdvertisementProcessor> self_{this, [](void*) {}};
|
||||
};
|
||||
|
||||
class BluetoothEndpoint
|
||||
@@ -367,6 +370,7 @@ class P2PClusterPCPHandler : public BasePCPHandler<Platform> {
|
||||
Ptr<ClientProxy<Platform> > client_proxy, Ptr<BLEEndpoint> ble_endpoint);
|
||||
|
||||
Ptr<MediumManager<Platform> > medium_manager_;
|
||||
std::shared_ptr<P2PClusterPCPHandler> self_{this, [](void*) {}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -581,7 +581,9 @@ PayloadManager<Platform>::PayloadManager(
|
||||
payload_status_update_executor_(Platform::createSingleThreadExecutor()),
|
||||
endpoint_manager_(endpoint_manager) {
|
||||
endpoint_manager_->registerIncomingOfflineFrameProcessor(
|
||||
V1Frame::PAYLOAD_TRANSFER, MakePtr(this));
|
||||
V1Frame::PAYLOAD_TRANSFER, std::static_pointer_cast<
|
||||
typename EndpointManager<Platform>::IncomingOfflineFrameProcessor>(
|
||||
self_));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -591,7 +593,9 @@ PayloadManager<Platform>::~PayloadManager() {
|
||||
|
||||
// Unregister ourselves from the IncomingOfflineFrameProcessors.
|
||||
endpoint_manager_->unregisterIncomingOfflineFrameProcessor(
|
||||
V1Frame::CONNECTION_RESPONSE, MakePtr(this));
|
||||
V1Frame::CONNECTION_RESPONSE, std::static_pointer_cast<
|
||||
typename EndpointManager<Platform>::IncomingOfflineFrameProcessor>(
|
||||
self_));
|
||||
|
||||
// Stop all the ongoing Runnables (as gracefully as possible).
|
||||
payload_status_update_executor_->shutdown();
|
||||
@@ -640,7 +644,7 @@ void PayloadManager<Platform>::sendPayload(
|
||||
enqueueOutgoingPayload(
|
||||
send_payload_executor,
|
||||
MakePtr(new payload_manager::SendPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_ids,
|
||||
self_, client_proxy, endpoint_ids,
|
||||
scoped_payload.release())));
|
||||
// TODO(tracyzhou): Add logging.
|
||||
}
|
||||
@@ -694,7 +698,7 @@ void PayloadManager<Platform>::processEndpointDisconnection(
|
||||
Ptr<CountDownLatch> process_disconnection_barrier) {
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::ProcessEndpointDisconnectionRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id,
|
||||
self_, client_proxy, endpoint_id,
|
||||
process_disconnection_barrier)));
|
||||
}
|
||||
|
||||
@@ -830,7 +834,7 @@ void PayloadManager<Platform>::sendClientCallbacksForFinishedOutgoingPayload(
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::
|
||||
SendClientCallbacksForFinishedOutgoingPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, finished_endpoint_ids,
|
||||
self_, client_proxy, finished_endpoint_ids,
|
||||
payload_header, num_bytes_successfully_transferred, status)));
|
||||
}
|
||||
|
||||
@@ -842,7 +846,7 @@ void PayloadManager<Platform>::sendClientCallbacksForFinishedIncomingPayload(
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::
|
||||
SendClientCallbacksForFinishedIncomingPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, payload_header,
|
||||
self_, client_proxy, endpoint_id, payload_header,
|
||||
offset_bytes, status)));
|
||||
}
|
||||
|
||||
@@ -935,7 +939,7 @@ void PayloadManager<Platform>::handleSuccessfulOutgoingChunk(
|
||||
std::int64_t payload_chunk_body_size) {
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::HandleSuccessfulOutgoingChunkRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, payload_header,
|
||||
self_, client_proxy, endpoint_id, payload_header,
|
||||
payload_chunk_flags, payload_chunk_offset, payload_chunk_body_size)));
|
||||
}
|
||||
|
||||
@@ -947,7 +951,7 @@ void PayloadManager<Platform>::handleSuccessfulIncomingChunk(
|
||||
std::int64_t payload_chunk_body_size) {
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::HandleSuccessfulIncomingChunkRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, payload_header,
|
||||
self_, client_proxy, endpoint_id, payload_header,
|
||||
payload_chunk_flags, payload_chunk_offset, payload_chunk_body_size)));
|
||||
}
|
||||
|
||||
|
||||
@@ -277,6 +277,7 @@ class PayloadManager
|
||||
payload_status_update_executor_;
|
||||
|
||||
Ptr<EndpointManager<Platform> > endpoint_manager_;
|
||||
std::shared_ptr<PayloadManager> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -497,7 +497,7 @@ void ServiceControllerRouter<Platform>::startAdvertising(
|
||||
ConstPtr<StartAdvertisingParams> start_advertising_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StartAdvertisingRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, start_advertising_params)));
|
||||
self_, client_proxy, start_advertising_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -506,7 +506,7 @@ void ServiceControllerRouter<Platform>::stopAdvertising(
|
||||
ConstPtr<StopAdvertisingParams> stop_advertising_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StopAdvertisingRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, stop_advertising_params)));
|
||||
self_, client_proxy, stop_advertising_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -515,7 +515,7 @@ void ServiceControllerRouter<Platform>::startDiscovery(
|
||||
ConstPtr<StartDiscoveryParams> start_discovery_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StartDiscoveryRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, start_discovery_params)));
|
||||
self_, client_proxy, start_discovery_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -524,7 +524,7 @@ void ServiceControllerRouter<Platform>::stopDiscovery(
|
||||
ConstPtr<StopDiscoveryParams> stop_discovery_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StopDiscoveryRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, stop_discovery_params)));
|
||||
self_, client_proxy, stop_discovery_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -533,7 +533,7 @@ void ServiceControllerRouter<Platform>::requestConnection(
|
||||
ConstPtr<RequestConnectionParams> request_connection_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::SendConnectionRequestRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, request_connection_params)));
|
||||
self_, client_proxy, request_connection_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -542,7 +542,7 @@ void ServiceControllerRouter<Platform>::acceptConnection(
|
||||
ConstPtr<AcceptConnectionParams> accept_connection_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::AcceptConnectionRequestRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, accept_connection_params)));
|
||||
self_, client_proxy, accept_connection_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -551,7 +551,7 @@ void ServiceControllerRouter<Platform>::rejectConnection(
|
||||
ConstPtr<RejectConnectionParams> reject_connection_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::RejectConnectionRequestRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, reject_connection_params)));
|
||||
self_, client_proxy, reject_connection_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -561,7 +561,7 @@ void ServiceControllerRouter<Platform>::initiateBandwidthUpgrade(
|
||||
initiate_bandwidth_upgrade_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::InitiateBandwidthUpgradeRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, initiate_bandwidth_upgrade_params)));
|
||||
self_, client_proxy, initiate_bandwidth_upgrade_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -570,7 +570,7 @@ void ServiceControllerRouter<Platform>::sendPayload(
|
||||
ConstPtr<SendPayloadParams> send_payload_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::SendPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, send_payload_params)));
|
||||
self_, client_proxy, send_payload_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -579,7 +579,7 @@ void ServiceControllerRouter<Platform>::cancelPayload(
|
||||
ConstPtr<CancelPayloadParams> cancel_payload_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::CancelPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, cancel_payload_params)));
|
||||
self_, client_proxy, cancel_payload_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -588,7 +588,7 @@ void ServiceControllerRouter<Platform>::disconnectFromEndpoint(
|
||||
ConstPtr<DisconnectFromEndpointParams> disconnect_from_endpoint_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::DisconnectFromEndpointRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, disconnect_from_endpoint_params)));
|
||||
self_, client_proxy, disconnect_from_endpoint_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -597,7 +597,7 @@ void ServiceControllerRouter<Platform>::stopAllEndpoints(
|
||||
ConstPtr<StopAllEndpointsParams> stop_all_endpoint_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StopAllEndpointsRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, stop_all_endpoint_params)));
|
||||
self_, client_proxy, stop_all_endpoint_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -605,7 +605,7 @@ void ServiceControllerRouter<Platform>::clientDisconnecting(
|
||||
Ptr<ClientProxy<Platform>> client_proxy) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::ClientDisconnectingRunnable<Platform>(
|
||||
MakePtr(this), client_proxy)));
|
||||
self_, client_proxy)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
|
||||
@@ -140,6 +140,7 @@ class ServiceControllerRouter {
|
||||
Ptr<ServiceController<Platform> > current_service_controller_;
|
||||
Ptr<Strategy> current_strategy_;
|
||||
ScopedPtr<Ptr<typename Platform::SingleThreadExecutorType> > serializer_;
|
||||
std::shared_ptr<ServiceControllerRouter<Platform>> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
#include "core/internal/wifi_lan_service_info.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "platform/base64_utils.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
Ptr<WifiLanServiceInfo> WifiLanServiceInfo::FromString(
|
||||
absl::string_view wifi_lan_service_info_string) {
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_wifi_lan_service_info_name_bytes(
|
||||
Base64Utils::decode(wifi_lan_service_info_string));
|
||||
if (scoped_wifi_lan_service_info_name_bytes.isNull()) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: failed Base64 decoding of %s",
|
||||
// WifiLanServiceInfoString);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
|
||||
if (scoped_wifi_lan_service_info_name_bytes->size() >
|
||||
kMaxLanServiceNameLength) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: expecting max %d raw bytes, got %d",
|
||||
// MAX_WIFILAN_SERVICE_INFO_LENGTH, wifiLanServiceInfoNameBytes.length);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
|
||||
if (scoped_wifi_lan_service_info_name_bytes->size() <
|
||||
kMinLanServiceNameLength) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: expecting min %d raw bytes, got %d",
|
||||
// MIN_WIFILAN_SERVICE_INFO_LENGTH, wifiLanServiceInfoNameBytes.length);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
|
||||
// The upper 3 bits are supposed to be the version.
|
||||
Version version = static_cast<Version>(
|
||||
(scoped_wifi_lan_service_info_name_bytes->getData()[0] &
|
||||
kVersionBitmask) >>
|
||||
kVersionShift);
|
||||
|
||||
switch (version) {
|
||||
case Version::kV1:
|
||||
return CreateV1WifiLanServiceInfo(
|
||||
ConstifyPtr(scoped_wifi_lan_service_info_name_bytes.get()));
|
||||
|
||||
default:
|
||||
// TODO(b/149806065): [ANALYTICIZE] This either represents corruption over
|
||||
// the air, or older versions of GmsCore intermingling with newer ones.
|
||||
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: unsupported Version %d", version);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
std::string WifiLanServiceInfo::AsString(Version version, PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash) {
|
||||
Ptr<ByteArray> wifi_lan_service_info_name_bytes;
|
||||
switch (version) {
|
||||
case Version::kV1:
|
||||
wifi_lan_service_info_name_bytes =
|
||||
CreateV1Bytes(pcp, endpoint_id, service_id_hash);
|
||||
if (wifi_lan_service_info_name_bytes.isNull()) {
|
||||
return "";
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot serialize
|
||||
// WifiLanServiceInfo: unsupported Version %d", version);
|
||||
return "";
|
||||
}
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_wifi_lan_service_info_name_bytes(
|
||||
wifi_lan_service_info_name_bytes);
|
||||
|
||||
// WifiLanServiceInfo needs to be binary safe, so apply a Base64 encoding
|
||||
// over the raw bytes.
|
||||
return Base64Utils::encode(
|
||||
ConstifyPtr(scoped_wifi_lan_service_info_name_bytes.get()));
|
||||
}
|
||||
|
||||
Ptr<WifiLanServiceInfo> WifiLanServiceInfo::CreateV1WifiLanServiceInfo(
|
||||
ConstPtr<ByteArray> wifi_lan_service_info_name_bytes) {
|
||||
const char* wifi_lan_service_info_name_bytes_read_ptr =
|
||||
wifi_lan_service_info_name_bytes->getData();
|
||||
|
||||
// The lower 5 bits of the V1 payload are supposed to be the PCP.
|
||||
PCP::Value pcp = static_cast<PCP::Value>(
|
||||
*wifi_lan_service_info_name_bytes_read_ptr & kPcpBitmask);
|
||||
wifi_lan_service_info_name_bytes_read_ptr++;
|
||||
|
||||
switch (pcp) {
|
||||
case PCP::P2P_CLUSTER: // Fall through
|
||||
case PCP::P2P_STAR: // Fall through
|
||||
case PCP::P2P_POINT_TO_POINT: {
|
||||
// The next 32 bits are supposed to be the endpoint_id.
|
||||
std::string endpoint_id(wifi_lan_service_info_name_bytes_read_ptr,
|
||||
kEndpointIdLength);
|
||||
wifi_lan_service_info_name_bytes_read_ptr += kEndpointIdLength;
|
||||
|
||||
// The next 24 bits are supposed to be the scoped_service_id_hash.
|
||||
ScopedPtr<ConstPtr<ByteArray> > scoped_service_id_hash(
|
||||
MakeConstPtr(new ByteArray(wifi_lan_service_info_name_bytes_read_ptr,
|
||||
kServiceIdHashLength)));
|
||||
wifi_lan_service_info_name_bytes_read_ptr += kServiceIdHashLength;
|
||||
|
||||
// The next bits are supposed to be endpoint_name.
|
||||
// TODO(b/149806065): Implements it. Temp to set "found_device".
|
||||
std::string endpoint_name("found_device");
|
||||
|
||||
return MakePtr(new WifiLanServiceInfo(Version::kV1, pcp, endpoint_id,
|
||||
scoped_service_id_hash.release(),
|
||||
endpoint_name));
|
||||
}
|
||||
default:
|
||||
// TODO(b/149806065): [ANALYTICIZE] This either represents corruption over
|
||||
// the air, or older versions of GmsCore intermingling with newer ones.
|
||||
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: unsupported V1 PCP %d", pcp);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
std::uint32_t WifiLanServiceInfo::ComputeEndpointNameLength(
|
||||
ConstPtr<ByteArray> wifi_lan_service_info_name_bytes) {
|
||||
return kMaxEndpointNameLength -
|
||||
(kMaxLanServiceNameLength - wifi_lan_service_info_name_bytes->size());
|
||||
}
|
||||
|
||||
Ptr<ByteArray> WifiLanServiceInfo::CreateV1Bytes(
|
||||
PCP::Value pcp, absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash) {
|
||||
Ptr<ByteArray> wifi_lan_service_info_name_bytes{
|
||||
new ByteArray{kMinLanServiceNameLength}};
|
||||
|
||||
char* wifi_lan_service_info_name_bytes_write_ptr =
|
||||
wifi_lan_service_info_name_bytes->getData();
|
||||
|
||||
// The upper 3 bits are the Version.
|
||||
char version_and_pcp_byte = static_cast<char>(
|
||||
(static_cast<uint32_t>(Version::kV1) << 5) & kVersionBitmask);
|
||||
// The lower 5 bits are the PCP.
|
||||
version_and_pcp_byte |= static_cast<char>(pcp & kPcpBitmask);
|
||||
*wifi_lan_service_info_name_bytes_write_ptr = version_and_pcp_byte;
|
||||
wifi_lan_service_info_name_bytes_write_ptr++;
|
||||
|
||||
switch (pcp) {
|
||||
case PCP::P2P_CLUSTER: // Fall through
|
||||
case PCP::P2P_STAR: // Fall through
|
||||
case PCP::P2P_POINT_TO_POINT:
|
||||
// The next 32 bits are the endpoint_id.
|
||||
if (endpoint_id.size() != kEndpointIdLength) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot serialize
|
||||
// WifiLanServiceInfo: V1 Endpoint ID %s (%d bytes) should be exactly
|
||||
// %d bytes", endpointId, endpointId.length(), ENDPOINT_ID_LENGTH);
|
||||
return Ptr<ByteArray>();
|
||||
}
|
||||
memcpy(wifi_lan_service_info_name_bytes_write_ptr, endpoint_id.data(),
|
||||
kEndpointIdLength);
|
||||
wifi_lan_service_info_name_bytes_write_ptr += kEndpointIdLength;
|
||||
|
||||
// The next 24 bits are the service_id_hash.
|
||||
if (service_id_hash->size() != kServiceIdHashLength) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot serialize
|
||||
// WifiLanServiceInfo: V1 ServiceID hash (%d bytes) should be exactly
|
||||
// %d bytes", serviceIdHash.length, SERVICE_ID_HASH_LENGTH);
|
||||
return Ptr<ByteArray>();
|
||||
}
|
||||
memcpy(wifi_lan_service_info_name_bytes_write_ptr,
|
||||
service_id_hash->getData(), kServiceIdHashLength);
|
||||
wifi_lan_service_info_name_bytes_write_ptr += kServiceIdHashLength;
|
||||
|
||||
// The next bits are the endpoint_name.
|
||||
// TODO(b/149806065): Implements to parse endpoint_name.
|
||||
break;
|
||||
default:
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot serialize
|
||||
// WifiLanServiceInfo: unsupported V1 PCP %d", pcp);
|
||||
return Ptr<ByteArray>();
|
||||
}
|
||||
|
||||
return wifi_lan_service_info_name_bytes;
|
||||
}
|
||||
|
||||
WifiLanServiceInfo::WifiLanServiceInfo(Version version, PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash,
|
||||
absl::string_view endpoint_name)
|
||||
: version_(version),
|
||||
pcp_(pcp),
|
||||
endpoint_id_(endpoint_id),
|
||||
service_id_hash_(service_id_hash),
|
||||
endpoint_name_(endpoint_name) {}
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,96 @@
|
||||
#ifndef CORE_INTERNAL_WIFI_LAN_SERVICE_INFO_H_
|
||||
#define CORE_INTERNAL_WIFI_LAN_SERVICE_INFO_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "core/internal/pcp.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/port/string.h"
|
||||
#include "platform/ptr.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
// Represents the format of the WifiLan service info used in Advertising +
|
||||
// Discovery.
|
||||
//
|
||||
// See go/nearby-offline-data-interchange-formats for the specification.
|
||||
class WifiLanServiceInfo {
|
||||
public:
|
||||
// Versions of the WifiLanServiceInfo.
|
||||
enum class Version {
|
||||
kV1 = 1,
|
||||
};
|
||||
|
||||
// Static method to deserialize from the encrypted string to
|
||||
// WifiLanServiceInfo object.
|
||||
// TODO(b/149762166): Ptr is deprectaed. Uses shrared_ptr<T> or unique_ptr<T>.
|
||||
static Ptr<WifiLanServiceInfo> FromString(
|
||||
absl::string_view wifi_lan_service_info_string);
|
||||
|
||||
// Static method to serialize to encrypted string from WifiLanServiceInfo
|
||||
// object.
|
||||
static std::string AsString(Version version, PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash);
|
||||
|
||||
static constexpr std::uint32_t kServiceIdHashLength = 3;
|
||||
|
||||
~WifiLanServiceInfo() = default;
|
||||
|
||||
inline Version GetVersion() const { return version_; }
|
||||
inline PCP::Value GetPcp() const { return pcp_; }
|
||||
inline std::string GetEndpointId() const { return endpoint_id_; }
|
||||
inline ConstPtr<ByteArray> GetServiceIdHash() const {
|
||||
return service_id_hash_.get();
|
||||
}
|
||||
inline std::string GetEndpointName() const { return endpoint_name_; }
|
||||
|
||||
private:
|
||||
static Ptr<WifiLanServiceInfo> CreateV1WifiLanServiceInfo(
|
||||
ConstPtr<ByteArray> wifi_lan_service_info_name_bytes);
|
||||
static std::uint32_t ComputeEndpointNameLength(
|
||||
ConstPtr<ByteArray> wifi_lan_service_info_name_bytes);
|
||||
static Ptr<ByteArray> CreateV1Bytes(PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash);
|
||||
|
||||
// The maximum length of encrypted WifiLanServiceInfo string.
|
||||
static constexpr int kMaxLanServiceNameLength = 47;
|
||||
// The minimum length of encrypted WifiLanServiceInfo string.
|
||||
static constexpr int kMinLanServiceNameLength = 9;
|
||||
// The length for endpoint id in encrypted WifiLanServiceInfo string.
|
||||
static constexpr int kEndpointIdLength = 4;
|
||||
// The maximum length for endpoint id in encrypted WifiLanServiceInfo string.
|
||||
static constexpr int kMaxEndpointNameLength = 131;
|
||||
|
||||
static constexpr uint16 kVersionBitmask = 0x0E0;
|
||||
static constexpr uint16 kPcpBitmask = 0x01F;
|
||||
static constexpr uint16 kVersionShift = 5;
|
||||
|
||||
WifiLanServiceInfo(Version version, PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash,
|
||||
absl::string_view endpoint_name);
|
||||
|
||||
// WifiLanServiceInfo version.
|
||||
const Version version_;
|
||||
// Pre-Connection Protocols version.
|
||||
const PCP::Value pcp_;
|
||||
// Connected endpoint id.
|
||||
const std::string endpoint_id_;
|
||||
// Connected hash service id.
|
||||
ScopedPtr<ConstPtr<ByteArray> > service_id_hash_;
|
||||
// TODO(b/149806065): Replaces endpointName as endPointInfo eventually;
|
||||
// it is not in this version yet for endpointName.
|
||||
// Connected endpoint name.
|
||||
const std::string endpoint_name_;
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // CORE_INTERNAL_WIFI_LAN_SERVICE_INFO_H_
|
||||
@@ -0,0 +1,151 @@
|
||||
#include "core/internal/wifi_lan_service_info.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "platform/base64_utils.h"
|
||||
#include "platform/port/string.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
const WifiLanServiceInfo::Version kVersion = WifiLanServiceInfo::Version::kV1;
|
||||
const PCP::Value kPcp = PCP::P2P_CLUSTER;
|
||||
const char kEndPointID[] = "AB12";
|
||||
const char kServiceIDHashBytes[] = {0x0A, 0x0B, 0x0C};
|
||||
// TODO(b/149806065): Implements test endpoint_name.
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationDeserializationWorks) {
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string = WifiLanServiceInfo::AsString(
|
||||
kVersion, kPcp, kEndPointID, ConstifyPtr(scoped_service_id_hash.get()));
|
||||
ScopedPtr<Ptr<WifiLanServiceInfo> > scoped_wifi_lan_service_info(
|
||||
WifiLanServiceInfo::FromString(wifi_lan_service_info_string));
|
||||
|
||||
EXPECT_EQ(kPcp, scoped_wifi_lan_service_info->GetPcp());
|
||||
EXPECT_EQ(kVersion, scoped_wifi_lan_service_info->GetVersion());
|
||||
EXPECT_EQ(kEndPointID, scoped_wifi_lan_service_info->GetEndpointId());
|
||||
EXPECT_EQ(*scoped_service_id_hash,
|
||||
*(scoped_wifi_lan_service_info->GetServiceIdHash()));
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest,
|
||||
SerializationDeserializationWorksWithEmptyEndpointName) {
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string = WifiLanServiceInfo::AsString(
|
||||
kVersion, kPcp, kEndPointID, ConstifyPtr(scoped_service_id_hash.get()));
|
||||
ScopedPtr<Ptr<WifiLanServiceInfo> > scoped_wifi_lan_service_info(
|
||||
WifiLanServiceInfo::FromString(wifi_lan_service_info_string));
|
||||
|
||||
EXPECT_EQ(kPcp, scoped_wifi_lan_service_info->GetPcp());
|
||||
EXPECT_EQ(kVersion, scoped_wifi_lan_service_info->GetVersion());
|
||||
EXPECT_EQ(kEndPointID, scoped_wifi_lan_service_info->GetEndpointId());
|
||||
EXPECT_EQ(*scoped_service_id_hash,
|
||||
*(scoped_wifi_lan_service_info->GetServiceIdHash()));
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithBadVersion) {
|
||||
WifiLanServiceInfo::Version bad_version =
|
||||
static_cast<WifiLanServiceInfo::Version>(666);
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string =
|
||||
WifiLanServiceInfo::AsString(bad_version, kPcp, kEndPointID,
|
||||
ConstifyPtr(scoped_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithBadPCP) {
|
||||
PCP::Value bad_pcp = static_cast<PCP::Value>(666);
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string =
|
||||
WifiLanServiceInfo::AsString(kVersion, bad_pcp, kEndPointID,
|
||||
ConstifyPtr(scoped_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithShortEndpointId) {
|
||||
std::string short_endpoint_id("AB1");
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string =
|
||||
WifiLanServiceInfo::AsString(kVersion, kPcp, short_endpoint_id,
|
||||
ConstifyPtr(scoped_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithLongEndpointId) {
|
||||
std::string long_endpoint_id("AB12X");
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string =
|
||||
WifiLanServiceInfo::AsString(kVersion, kPcp, long_endpoint_id,
|
||||
ConstifyPtr(scoped_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithShortServiceIdHash) {
|
||||
char short_service_id_hash_bytes[] = {0x0A, 0x0B};
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_short_service_id_hash(
|
||||
new ByteArray(short_service_id_hash_bytes,
|
||||
sizeof(short_service_id_hash_bytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string = WifiLanServiceInfo::AsString(
|
||||
kVersion, kPcp, kEndPointID,
|
||||
ConstifyPtr(scoped_short_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithLongServiceIdHash) {
|
||||
char long_service_id_hash_bytes[] = {0x0A, 0x0B, 0x0C, 0x0D};
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_long_service_id_hash(
|
||||
new ByteArray(long_service_id_hash_bytes,
|
||||
sizeof(long_service_id_hash_bytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string = WifiLanServiceInfo::AsString(
|
||||
kVersion, kPcp, kEndPointID,
|
||||
ConstifyPtr(scoped_long_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, DeserializationFailsWithShortLength) {
|
||||
char wifi_lan_service_info_bytes[] = {'X'};
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_wifi_lan_service_info_bytes(
|
||||
new ByteArray(wifi_lan_service_info_bytes,
|
||||
sizeof(wifi_lan_service_info_bytes) / sizeof(char)));
|
||||
|
||||
ScopedPtr<Ptr<WifiLanServiceInfo> > scoped_wifi_lan_service_info(
|
||||
WifiLanServiceInfo::FromString(Base64Utils::encode(
|
||||
ConstifyPtr(scoped_wifi_lan_service_info_bytes.get()))));
|
||||
|
||||
EXPECT_TRUE(scoped_wifi_lan_service_info.isNull());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
+9
-5
@@ -26,7 +26,6 @@ cc_library(
|
||||
":types",
|
||||
"//platform/api",
|
||||
"//platform/port:string",
|
||||
"//strings",
|
||||
"//absl/strings",
|
||||
"//absl/time",
|
||||
],
|
||||
@@ -34,15 +33,11 @@ cc_library(
|
||||
|
||||
cc_library(
|
||||
name = "types",
|
||||
srcs = [
|
||||
"ptr.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"byte_array.h",
|
||||
"callable.h",
|
||||
"cancelable.h",
|
||||
"container_of.h",
|
||||
"exception.cc",
|
||||
"exception.h",
|
||||
"ptr.h",
|
||||
"runnable.h",
|
||||
@@ -113,6 +108,15 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "exception_test",
|
||||
srcs = ["exception_test.cc"],
|
||||
deps = [
|
||||
":types",
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "pipe_test",
|
||||
timeout = "short",
|
||||
|
||||
@@ -20,23 +20,28 @@ cc_library(
|
||||
"hash_utils.h",
|
||||
"input_file.h",
|
||||
"input_stream.h",
|
||||
"listenable_future.h",
|
||||
"lock.h",
|
||||
"multi_thread_executor.h",
|
||||
"output_file.h",
|
||||
"output_stream.h",
|
||||
"scheduled_executor.h",
|
||||
"server_sync.h",
|
||||
"settable_future.h",
|
||||
"single_thread_executor.h",
|
||||
"socket.h",
|
||||
"submittable_executor.h",
|
||||
"system_clock.h",
|
||||
"thread_utils.h",
|
||||
"webrtc.h",
|
||||
"wifi.h",
|
||||
"wifi_lan.h",
|
||||
],
|
||||
deps = [
|
||||
"//platform:types",
|
||||
"//platform/port:down_cast",
|
||||
"//platform/port:string",
|
||||
"//webrtc/files/stable/webrtc/api:libjingle_peerconnection_api",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ struct BLEAdvertisementData {
|
||||
std::set<std::string> service_uuids;
|
||||
// Maps service UUIDs to their service data.
|
||||
// Ownership of the map values is tied to ownership of BLEAdvertisementData.
|
||||
std::map<std::string, ConstPtr<ByteArray> > service_data;
|
||||
std::map<std::string, ConstPtr<ByteArray>> service_data;
|
||||
};
|
||||
|
||||
// Opaque wrapper over a BLE peripheral. Must be able to uniquely identify a
|
||||
@@ -217,7 +217,8 @@ class GATTServer {
|
||||
// about this descriptor, please go to:
|
||||
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
|
||||
virtual Ptr<GATTCharacteristic> createCharacteristic(
|
||||
const std::string& service_uuid, const std::string& characteristic_uuid,
|
||||
const std::string& service_uuid,
|
||||
const std::string& characteristic_uuid,
|
||||
const std::set<GATTCharacteristic::Permission::Value>& permissions,
|
||||
const std::set<GATTCharacteristic::Property::Value>& properties) = 0;
|
||||
|
||||
@@ -384,7 +385,9 @@ class BLEMediumV2 {
|
||||
// HIGH:
|
||||
// - Connection interval = ~100ms - 125ms
|
||||
virtual Ptr<ClientGATTConnection> connectToGATTServer(
|
||||
Ptr<BLEPeripheralV2> peripheral, MTU mtu, PowerMode::Value power_mode,
|
||||
Ptr<BLEPeripheralV2> peripheral,
|
||||
MTU mtu,
|
||||
PowerMode::Value power_mode,
|
||||
Ptr<ClientGATTConnectionLifecycleCallback>
|
||||
connection_lifecycle_callback) = 0;
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class BluetoothServerSocket {
|
||||
//
|
||||
// The returned Ptr will be owned (and destroyed) by the caller. Returns
|
||||
// Exception::IO on error.
|
||||
virtual ExceptionOr<Ptr<BluetoothSocket> > accept() = 0;
|
||||
virtual ExceptionOr<Ptr<BluetoothSocket>> accept() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close()
|
||||
//
|
||||
@@ -116,8 +116,9 @@ class BluetoothClassicMedium {
|
||||
//
|
||||
// The returned Ptr will be owned (and destroyed) by the caller. Returns
|
||||
// Exception::IO on error.
|
||||
virtual ExceptionOr<Ptr<BluetoothSocket> > connectToService(
|
||||
Ptr<BluetoothDevice> remote_device, const std::string& service_uuid) = 0;
|
||||
virtual ExceptionOr<Ptr<BluetoothSocket>> connectToService(
|
||||
Ptr<BluetoothDevice> remote_device,
|
||||
const std::string& service_uuid) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord
|
||||
//
|
||||
@@ -129,8 +130,9 @@ class BluetoothClassicMedium {
|
||||
//
|
||||
// The returned Ptr will be owned (and destroyed) by the caller. Returns
|
||||
// Exception::IO on error.
|
||||
virtual ExceptionOr<Ptr<BluetoothServerSocket> > listenForService(
|
||||
const std::string& service_name, const std::string& service_uuid) = 0;
|
||||
virtual ExceptionOr<Ptr<BluetoothServerSocket>> listenForService(
|
||||
const std::string& service_name,
|
||||
const std::string& service_uuid) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef PLATFORM_API_EXECUTOR_H_
|
||||
#define PLATFORM_API_EXECUTOR_H_
|
||||
|
||||
#include "platform/ptr.h"
|
||||
#include "platform/runnable.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
@@ -12,6 +15,9 @@ class Executor {
|
||||
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--
|
||||
virtual void shutdown() = 0;
|
||||
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-
|
||||
virtual void execute(Ptr<Runnable> runnable) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef PLATFORM_API_FUTURE_H_
|
||||
#define PLATFORM_API_FUTURE_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "platform/exception.h"
|
||||
|
||||
namespace location {
|
||||
@@ -16,6 +18,11 @@ class Future {
|
||||
|
||||
virtual ExceptionOr<T>
|
||||
get() = 0; // throws Exception::INTERRUPTED, Exception::EXECUTION
|
||||
|
||||
// throws Exception::INTERRUPTED, Exception::EXECUTION
|
||||
// throws Exception::TIMEOUT if |timeout_ms| is exceeded while waiting for
|
||||
// result.
|
||||
virtual ExceptionOr<T> get(std::int64_t timeout_ms) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -16,7 +16,7 @@ class InputFile {
|
||||
// The returned ConstPtr will be owned (and destroyed) by the caller.
|
||||
// When we have exhausted reading the file and no bytes remain, read will
|
||||
// always return an empty ConstPtr for which isNull() is true.
|
||||
virtual ExceptionOr<ConstPtr<ByteArray> > read(
|
||||
virtual ExceptionOr<ConstPtr<ByteArray>> read(
|
||||
std::int64_t size) = 0; // throws Exception::IO when the file cannot be
|
||||
// opened or read.
|
||||
virtual std::string getFilePath() const = 0;
|
||||
|
||||
@@ -18,9 +18,9 @@ class InputStream {
|
||||
virtual ~InputStream() {}
|
||||
|
||||
// The returned ConstPtr will be owned (and destroyed) by the caller.
|
||||
virtual ExceptionOr<ConstPtr<ByteArray> > read() = 0; // throws Exception::IO
|
||||
virtual ExceptionOr<ConstPtr<ByteArray>> read() = 0; // throws Exception::IO
|
||||
// The returned ConstPtr will be owned (and destroyed) by the caller.
|
||||
virtual ExceptionOr<ConstPtr<ByteArray> > read(
|
||||
virtual ExceptionOr<ConstPtr<ByteArray>> read(
|
||||
std::int64_t size) = 0; // throws Exception::IO
|
||||
virtual Exception::Value close() = 0; // throws Exception::IO
|
||||
};
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef PLATFORM_API_LISTENABLE_FUTURE_H_
|
||||
#define PLATFORM_API_LISTENABLE_FUTURE_H_
|
||||
|
||||
#include "platform/api/executor.h"
|
||||
#include "platform/api/future.h"
|
||||
#include "platform/exception.h"
|
||||
#include "platform/ptr.h"
|
||||
#include "platform/runnable.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A Future that accepts completion listeners.
|
||||
//
|
||||
// https://guava.dev/releases/20.0/api/docs/com/google/common/util/concurrent/ListenableFuture.html
|
||||
template <typename T>
|
||||
class ListenableFuture : public Future<T> {
|
||||
public:
|
||||
~ListenableFuture() override {}
|
||||
|
||||
// Executor is shared among multiple runnables. It is not owned by any future.
|
||||
virtual void addListener(Ptr<Runnable> runnable, Executor* executor) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API_LISTENABLE_FUTURE_H_
|
||||
@@ -11,8 +11,8 @@ namespace nearby {
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-
|
||||
template <typename ConcreteSubmittableExecutor>
|
||||
class MultiThreadExecutor :
|
||||
public SubmittableExecutor<ConcreteSubmittableExecutor> {
|
||||
class MultiThreadExecutor
|
||||
: public SubmittableExecutor<ConcreteSubmittableExecutor> {
|
||||
public:
|
||||
~MultiThreadExecutor() override {}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#ifndef PLATFORM_API_SERVER_SYNC_H_
|
||||
#define PLATFORM_API_SERVER_SYNC_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/ptr.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// Abstraction that represents a Nearby endpoint exchanging data through
|
||||
// ServerSync Medium.
|
||||
class ServerSyncDevice {
|
||||
public:
|
||||
virtual ~ServerSyncDevice() {}
|
||||
|
||||
virtual std::string getName() = 0;
|
||||
|
||||
virtual std::string getGuid() = 0;
|
||||
|
||||
virtual std::string getOwnGuid() = 0;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the Chrome Sync medium.
|
||||
class ServerSyncMedium {
|
||||
public:
|
||||
virtual ~ServerSyncMedium() {}
|
||||
|
||||
// Takes ownership of (and is responsible for destroying) the passed-in
|
||||
// 'endpoint_info'.
|
||||
virtual bool startAdvertising(const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
ConstPtr<ByteArray> endpoint_info) = 0;
|
||||
virtual void stopAdvertising(const std::string& service_id) = 0;
|
||||
|
||||
class DiscoveredDeviceCallback {
|
||||
public:
|
||||
virtual ~DiscoveredDeviceCallback() {}
|
||||
|
||||
// Called on a new ServerSyncDevice discovery.
|
||||
virtual void onDeviceDiscovered(Ptr<ServerSyncDevice> device,
|
||||
const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
ConstPtr<ByteArray> endpoint_info) = 0;
|
||||
// Called when ServerSyncDevice is no longer reachable.
|
||||
virtual void onDeviceLost(Ptr<ServerSyncDevice> device,
|
||||
const std::string& service_id) = 0;
|
||||
};
|
||||
|
||||
// Returns true once the Chrome Sync scan has been initiated.
|
||||
virtual bool startDiscovery(
|
||||
const std::string& service_id,
|
||||
Ptr<DiscoveredDeviceCallback> discovered_device_callback) = 0;
|
||||
// Returns true once Chrome Sync scan for service_id is well and truly
|
||||
// stopped; after this returns, there must be no more invocations of the
|
||||
// DiscoveredDeviceCallback passed in to startScanning() for service_id.
|
||||
virtual void stopDiscovery(const std::string& service_id) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API_SERVER_SYNC_H_
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef PLATFORM_API_SETTABLE_FUTURE_H_
|
||||
#define PLATFORM_API_SETTABLE_FUTURE_H_
|
||||
|
||||
#include "platform/api/future.h"
|
||||
#include "platform/api/listenable_future.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
@@ -10,11 +10,13 @@ namespace nearby {
|
||||
//
|
||||
// https://google.github.io/guava/releases/20.0/api/docs/com/google/common/util/concurrent/SettableFuture.html
|
||||
template <typename T>
|
||||
class SettableFuture : public Future<T> {
|
||||
class SettableFuture : public ListenableFuture<T> {
|
||||
public:
|
||||
~SettableFuture() override {}
|
||||
|
||||
virtual bool set(T value) = 0;
|
||||
|
||||
virtual bool setException(Exception exception) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -11,8 +11,8 @@ namespace nearby {
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor--
|
||||
template <typename ConcreteSubmittableExecutor>
|
||||
class SingleThreadExecutor :
|
||||
public SubmittableExecutor<ConcreteSubmittableExecutor> {
|
||||
class SingleThreadExecutor
|
||||
: public SubmittableExecutor<ConcreteSubmittableExecutor> {
|
||||
public:
|
||||
~SingleThreadExecutor() override {}
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "platform/callable.h"
|
||||
#include "platform/port/down_cast.h"
|
||||
#include "platform/ptr.h"
|
||||
#include "platform/runnable.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
@@ -29,12 +28,9 @@ class SubmittableExecutor : public Executor {
|
||||
~SubmittableExecutor() override {}
|
||||
|
||||
template <typename T>
|
||||
Ptr<Future<T> > submit(Ptr<Callable<T> > callable) {
|
||||
Ptr<Future<T>> submit(Ptr<Callable<T>> callable) {
|
||||
return DOWN_CAST<ConcreteSubmittableExecutor*>(this)->submit(callable);
|
||||
}
|
||||
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-
|
||||
virtual void execute(Ptr<Runnable> runnable) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef PLATFORM_API_WEBRTC_H_
|
||||
#define PLATFORM_API_WEBRTC_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/ptr.h"
|
||||
#include "webrtc/files/stable/webrtc/api/peer_connection_interface.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
class WebRtcSignalingMessenger {
|
||||
public:
|
||||
virtual ~WebRtcSignalingMessenger() = default;
|
||||
|
||||
/** Called whenever we receive an inbox message from tachyon. */
|
||||
class SignalingMessageListener {
|
||||
public:
|
||||
virtual ~SignalingMessageListener() = default;
|
||||
|
||||
virtual void onSignalingMessage(ConstPtr<ByteArray> message) = 0;
|
||||
};
|
||||
|
||||
class IceServersListener {
|
||||
public:
|
||||
virtual ~IceServersListener() = default;
|
||||
|
||||
virtual void OnIceServersFetched(
|
||||
std::vector<Ptr<webrtc::PeerConnectionInterface::IceServer>>
|
||||
ice_servers) = 0;
|
||||
};
|
||||
|
||||
virtual bool registerSignaling() = 0;
|
||||
virtual bool unregisterSignaling() = 0;
|
||||
virtual bool sendMessage(const string& peer_id,
|
||||
ConstPtr<ByteArray> message) = 0;
|
||||
virtual bool startReceivingMessages(
|
||||
Ptr<SignalingMessageListener> listener) = 0;
|
||||
virtual void getIceServers(Ptr<IceServersListener> ice_servers_listener) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API_WEBRTC_H_
|
||||
@@ -58,7 +58,7 @@ class WifiMedium {
|
||||
// owned (and destroyed) by the recipient of the callback methods (i.e. the
|
||||
// creator of the concrete ScanResultCallback object).
|
||||
virtual void onScanResults(
|
||||
const std::vector<ConstPtr<WifiScanResult> >& scan_results) = 0;
|
||||
const std::vector<ConstPtr<WifiScanResult>>& scan_results) = 0;
|
||||
};
|
||||
|
||||
// Does not take ownership of the passed-in scan_result_callback -- destroying
|
||||
@@ -69,7 +69,8 @@ class WifiMedium {
|
||||
// WifiConnectionStatus::CONNECTED on success, or the appropriate failure code
|
||||
// otherwise.
|
||||
virtual WifiConnectionStatus::Value connectToNetwork(
|
||||
const std::string& ssid, const std::string& password,
|
||||
const std::string& ssid,
|
||||
const std::string& password,
|
||||
WifiAuthType::Value auth_type) = 0;
|
||||
|
||||
// Blocks until it's certain of there being a connection to the internet, or
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
#ifndef PLATFORM_API_WIFI_LAN_H_
|
||||
#define PLATFORM_API_WIFI_LAN_H_
|
||||
|
||||
#include "platform/api/input_stream.h"
|
||||
#include "platform/api/output_stream.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/exception.h"
|
||||
#include "platform/port/string.h"
|
||||
#include "platform/ptr.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// Opaque wrapper over a WifiLan service which contains encoded service name.
|
||||
class WifiLanService {
|
||||
public:
|
||||
virtual ~WifiLanService() = default;
|
||||
|
||||
virtual std::string GetName() = 0;
|
||||
};
|
||||
|
||||
class WifiLanSocket {
|
||||
public:
|
||||
virtual ~WifiLanSocket() = default;
|
||||
|
||||
// Returns the InputStream of the WifiLanSocket, or a null Ptr<InputStream>
|
||||
// on error.
|
||||
//
|
||||
// The returned Ptr is not owned by the caller, and can be invalidated once
|
||||
// the WifiLanSocket object is destroyed.
|
||||
virtual Ptr<InputStream> GetInputStream() = 0;
|
||||
|
||||
// Returns the OutputStream of the WifiLanSocket, or a null
|
||||
// Ptr<OutputStream> on error.
|
||||
//
|
||||
// The returned Ptr is not owned by the caller, and can be invalidated once
|
||||
// the WifiLanSocket object is destroyed.
|
||||
virtual Ptr<OutputStream> GetOutputStream() = 0;
|
||||
|
||||
// Returns Exception::IO on error, Exception::NONE otherwise.
|
||||
virtual Exception::Value Close() = 0;
|
||||
|
||||
// The returned Ptr is not owned by the caller, and can be invalidated once
|
||||
// the WifiLanSocket object is destroyed.
|
||||
virtual Ptr<WifiLanService> GetRemoteWifiLanService() = 0;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the WifiLan medium.
|
||||
class WifiLanMedium {
|
||||
public:
|
||||
virtual ~WifiLanMedium() = default;
|
||||
|
||||
virtual bool StartAdvertising(const std::string& service_id,
|
||||
const string& wifi_lan_service_info_name) = 0;
|
||||
virtual void StopAdvertising(const std::string& service_id) = 0;
|
||||
|
||||
// Callback for WifiLan discover results.
|
||||
class DiscoveredServiceCallback {
|
||||
public:
|
||||
virtual ~DiscoveredServiceCallback() = default;
|
||||
|
||||
virtual void OnServiceDiscovered(Ptr<WifiLanService> wifi_lan_service) = 0;
|
||||
virtual void OnServiceLost(Ptr<WifiLanService> wifi_lan_service) = 0;
|
||||
};
|
||||
|
||||
virtual bool StartDiscovery(
|
||||
const std::string& service_id,
|
||||
Ptr<DiscoveredServiceCallback> discovered_service_callback) = 0;
|
||||
virtual void StopDiscovery(const std::string& service_id) = 0;
|
||||
|
||||
class AcceptedConnectionCallback {
|
||||
public:
|
||||
virtual ~AcceptedConnectionCallback() = default;
|
||||
|
||||
// The Ptr provided in this callback method will be owned (and
|
||||
// destroyed) by the recipient of the callback methods (i.e. the creator of
|
||||
// the concrete AcceptedConnectionCallback object).
|
||||
virtual void OnConnectionAccepted(Ptr<WifiLanSocket> socket,
|
||||
const string& service_id) = 0;
|
||||
};
|
||||
|
||||
virtual bool StartAcceptingConnections(
|
||||
const std::string& service_id,
|
||||
Ptr<AcceptedConnectionCallback> accepted_connection_callback) = 0;
|
||||
virtual void StopAcceptingConnections(const std::string& service_id) = 0;
|
||||
|
||||
virtual Ptr<WifiLanSocket> Connect(Ptr<WifiLanService> wifi_lan_service,
|
||||
const std::string& service_id) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API_WIFI_LAN_H_
|
||||
@@ -0,0 +1,65 @@
|
||||
package(default_visibility = [
|
||||
"//core:__subpackages__",
|
||||
"//platform:__subpackages__",
|
||||
"//location/nearby/setup/core:__subpackages__",
|
||||
])
|
||||
|
||||
cc_library(
|
||||
name = "api2",
|
||||
hdrs = [
|
||||
"atomic_boolean.h",
|
||||
"atomic_reference.h",
|
||||
"ble.h",
|
||||
"ble_v2.h",
|
||||
"bluetooth_adapter.h",
|
||||
"bluetooth_classic.h",
|
||||
"condition_variable.h",
|
||||
"count_down_latch.h",
|
||||
"executor.h",
|
||||
"future.h",
|
||||
"hash_utils.h",
|
||||
"input_file.h",
|
||||
"input_stream.h",
|
||||
"listenable_future.h",
|
||||
"multi_thread_executor.h",
|
||||
"mutex.h",
|
||||
"output_file.h",
|
||||
"output_stream.h",
|
||||
"scheduled_executor.h",
|
||||
"server_sync.h",
|
||||
"settable_future.h",
|
||||
"single_thread_executor.h",
|
||||
"socket.h",
|
||||
"submittable_executor.h",
|
||||
"system_clock.h",
|
||||
"thread_utils.h",
|
||||
"webrtc.h",
|
||||
"wifi.h",
|
||||
],
|
||||
deps = [
|
||||
"//platform:types",
|
||||
"//absl/strings",
|
||||
"//absl/time",
|
||||
"//webrtc/files/stable/webrtc/api:libjingle_peerconnection_api",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "mutex",
|
||||
hdrs = ["mutex.h"],
|
||||
visibility = [
|
||||
"//platform:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "condition_variable",
|
||||
hdrs = ["condition_variable.h"],
|
||||
visibility = [
|
||||
"//platform:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//platform:types",
|
||||
"//absl/time",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef PLATFORM_API2_ATOMIC_BOOLEAN_H_
|
||||
#define PLATFORM_API2_ATOMIC_BOOLEAN_H_
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A boolean value that may be updated atomically.
|
||||
//
|
||||
// https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html
|
||||
class AtomicBoolean {
|
||||
public:
|
||||
virtual ~AtomicBoolean() {}
|
||||
|
||||
virtual bool Get() = 0;
|
||||
virtual void Set(bool value) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_ATOMIC_BOOLEAN_H_
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PLATFORM_API2_ATOMIC_REFERENCE_H_
|
||||
#define PLATFORM_API2_ATOMIC_REFERENCE_H_
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// An object reference that may be updated atomically.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html
|
||||
template <typename T>
|
||||
class AtomicReference {
|
||||
public:
|
||||
virtual ~AtomicReference() {}
|
||||
|
||||
virtual T Get() = 0;
|
||||
virtual void Set(const T& value) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_ATOMIC_REFERENCE_H_
|
||||
@@ -0,0 +1,111 @@
|
||||
#ifndef PLATFORM_API2_BLE_H_
|
||||
#define PLATFORM_API2_BLE_H_
|
||||
|
||||
#include "platform/api2/bluetooth_classic.h"
|
||||
#include "platform/api2/input_stream.h"
|
||||
#include "platform/api2/output_stream.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// Opaque wrapper over a BLE peripheral. Must contain enough data about a
|
||||
// particular BLE device to connect to its GATT server.
|
||||
class BlePeripheral {
|
||||
public:
|
||||
virtual ~BlePeripheral() {}
|
||||
|
||||
// The returned Ptr is not owned by the caller, and can be invalidated once
|
||||
// the corresponding BLEPeripheral object is destroyed.
|
||||
virtual BluetoothDevice& GetBluetoothDevice() = 0;
|
||||
};
|
||||
|
||||
class BleSocket {
|
||||
public:
|
||||
virtual ~BleSocket() {}
|
||||
|
||||
// Returns the InputStream of the BleSocket.
|
||||
// On error, returned stream will report Exception::kIo on any operation.
|
||||
//
|
||||
// The returned object is not owned by the caller, and can be invalidated once
|
||||
// the BleSocket object is destroyed.
|
||||
virtual InputStream& GetInputStream() = 0;
|
||||
|
||||
// Returns the OutputStream of the BleSocket.
|
||||
// On error, returned stream will report Exception::kIo on any operation.
|
||||
//
|
||||
// The returned object is not owned by the caller, and can be invalidated once
|
||||
// the BleSocket object is destroyed.
|
||||
virtual OutputStream& GetOutputStream() = 0;
|
||||
|
||||
// Conforms to the same contract as
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#close().
|
||||
//
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
virtual Exception Close() = 0;
|
||||
|
||||
// The returned object is not owned by the caller, and can be invalidated once
|
||||
// the BleSocket object is destroyed.
|
||||
virtual BlePeripheral& GetRemotePeripheral() = 0;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the BLE medium.
|
||||
class BleMedium {
|
||||
public:
|
||||
virtual ~BleMedium() {}
|
||||
|
||||
virtual bool StartAdvertising(absl::string_view service_id,
|
||||
const ByteArray& advertisement) = 0;
|
||||
virtual void StopAdvertising(absl::string_view service_id) = 0;
|
||||
|
||||
class DiscoveredPeripheralCallback {
|
||||
public:
|
||||
virtual ~DiscoveredPeripheralCallback() {}
|
||||
|
||||
// The BlePeripheral* is not owned by callbacks.
|
||||
// It is passed to give access to its non-const methods.
|
||||
// It is guaranteed to be valid for the duration of call.
|
||||
virtual void OnPeripheralDiscovered(BlePeripheral* ble_peripheral,
|
||||
absl::string_view service_id,
|
||||
const ByteArray& advertisement) = 0;
|
||||
virtual void OnPeripheralLost(BlePeripheral* ble_peripheral,
|
||||
absl::string_view service_id) = 0;
|
||||
};
|
||||
|
||||
// Returns true once the BLE scan has been initiated.
|
||||
virtual bool StartScanning(
|
||||
absl::string_view service_id,
|
||||
const DiscoveredPeripheralCallback& discovered_peripheral_callback) = 0;
|
||||
|
||||
// Returns true once BLE scanning for service_id is well and truly stopped;
|
||||
// after this returns, there must be no more invocations of the
|
||||
// DiscoveredPeripheralCallback passed in to StartScanning() for service_id.
|
||||
virtual void StopScanning(absl::string_view service_id) = 0;
|
||||
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
class AcceptedConnectionCallback {
|
||||
public:
|
||||
virtual ~AcceptedConnectionCallback() {}
|
||||
|
||||
virtual void OnConnectionAccepted(std::unique_ptr<BleSocket> socket,
|
||||
absl::string_view service_id) = 0;
|
||||
};
|
||||
|
||||
// Returns true once BLE socket connection requests to service_id can be
|
||||
// accepted.
|
||||
virtual bool StartAcceptingConnections(
|
||||
absl::string_view service_id,
|
||||
const AcceptedConnectionCallback& accepted_connection_callback) = 0;
|
||||
virtual void StopAcceptingConnections(const std::string& service_id) = 0;
|
||||
|
||||
// BlePeripheral* is not owned by this call;
|
||||
// it must remain valid for the duration of a call.
|
||||
virtual std::unique_ptr<BleSocket> Connect(BlePeripheral* ble_peripheral,
|
||||
absl::string_view service_id) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_BLE_H_
|
||||
@@ -0,0 +1,390 @@
|
||||
#ifndef PLATFORM_API2_BLE_V2_H_
|
||||
#define PLATFORM_API2_BLE_V2_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/exception.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace v2 {
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/le/AdvertiseData
|
||||
//
|
||||
// Bundle of data found in a BLE advertisement.
|
||||
//
|
||||
// All service UUIDs will conform to the 16-bit Bluetooth base UUID,
|
||||
// 0000xxxx-0000-1000-8000-00805F9B34FB. This makes it possible to store two
|
||||
// byte service UUIDs in the advertisement.
|
||||
struct BleAdvertisementData {
|
||||
using TxPowerLevel = int8_t;
|
||||
|
||||
static const TxPowerLevel kUnspecifiedTxPowerLevel =
|
||||
std::numeric_limits<TxPowerLevel>::min();
|
||||
|
||||
bool is_connectable;
|
||||
// When set to kUnspecifiedTxPowerLevel, TX power should not be included in
|
||||
// the advertisement data.
|
||||
TxPowerLevel tx_power_level;
|
||||
// When set to an empty string, local name should not be included in the
|
||||
// advertisement data.
|
||||
std::string local_name;
|
||||
// When set to an empty vector, the set of 16-bit service class UUIDs should
|
||||
// not be included in the advertisement data.
|
||||
std::set<std::string> service_uuids;
|
||||
// Maps service UUIDs to their service data.
|
||||
std::map<std::string, ByteArray> service_data;
|
||||
};
|
||||
|
||||
// Opaque wrapper over a BLE peripheral. Must be able to uniquely identify a
|
||||
// peripheral so that we can connect to its GATT server.
|
||||
class BlePeripheral {
|
||||
public:
|
||||
virtual ~BlePeripheral() {}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice#getAddress()
|
||||
//
|
||||
// This should be the MAC address when possible. If the implementation is
|
||||
// unable to retrieve that, any unique identifier should suffice.
|
||||
virtual std::string GetId() const = 0;
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic
|
||||
//
|
||||
// Representation of a GATT characteristic.
|
||||
class GattCharacteristic {
|
||||
public:
|
||||
virtual ~GattCharacteristic() {}
|
||||
|
||||
// Possible permissions of a GATT characteristic.
|
||||
enum class Permission {
|
||||
kUnknown = 0,
|
||||
kRead = 1,
|
||||
kWrite = 2,
|
||||
kLast,
|
||||
};
|
||||
|
||||
// Possible properties of a GATT characteristic.
|
||||
enum class Property {
|
||||
kUnknown = 0,
|
||||
kRead = 1,
|
||||
kWrite = 2,
|
||||
kIndicate = 3,
|
||||
kLast,
|
||||
};
|
||||
|
||||
// Returns the UUID of this characteristic.
|
||||
virtual std::string GetUuid() = 0;
|
||||
|
||||
// Returns the UUID of the containing GATT service.
|
||||
virtual std::string GetServiceUuid() = 0;
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt
|
||||
//
|
||||
// Representation of a client GATT connection to a remote GATT server.
|
||||
class ClientGattConnection {
|
||||
public:
|
||||
virtual ~ClientGattConnection() {}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#getDevice()
|
||||
//
|
||||
// Retrieves the BLE peripheral that this connection is tied to.
|
||||
virtual BlePeripheral& GetPeripheral() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#discoverServices()
|
||||
//
|
||||
// Discovers all available services and characteristics on this connection.
|
||||
// Returns whether or not discovery finished successfully.
|
||||
//
|
||||
// This function should block until discovery has finished.
|
||||
virtual bool DiscoverServices() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#getService(java.util.UUID)
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattService.html#getCharacteristic(java.util.UUID)
|
||||
//
|
||||
// Retrieves a GATT characteristic. On error, does not return a value.
|
||||
//
|
||||
// DiscoverServices() should be called before this method to fetch all
|
||||
// available services and characteristics first.
|
||||
//
|
||||
// It is okay for duplicate services to exist, as long as the specified
|
||||
// characteristic UUID is unique among all services of the same UUID.
|
||||
virtual std::optional<GattCharacteristic> GetCharacteristic(
|
||||
absl::string_view service_uuid,
|
||||
absl::string_view characteristic_uuid) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#readCharacteristic(android.bluetooth.BluetoothGattCharacteristic)
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html#getValue()
|
||||
//
|
||||
// Reads a GATT characteristic. No value is returned upon error.
|
||||
virtual std::optional<ByteArray> ReadCharacteristic(
|
||||
const GattCharacteristic& characteristic) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html#setValue(byte[])
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic)
|
||||
//
|
||||
// Sends a remote characteristic write request to the server and returns
|
||||
// whether or not it was successful.
|
||||
virtual bool WriteCharacteristic(const GattCharacteristic& characteristic,
|
||||
const ByteArray& value) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#disconnect()
|
||||
//
|
||||
// Disconnects a GATT connection.
|
||||
virtual void Disconnect() = 0;
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattServer
|
||||
//
|
||||
// Representation of a server GATT connection to a remote GATT client.
|
||||
class ServerGattConnection {
|
||||
public:
|
||||
virtual ~ServerGattConnection() {}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html#setValue(byte[])
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattServer.html#notifyCharacteristicChanged(android.bluetooth.BluetoothDevice,%20android.bluetooth.BluetoothGattCharacteristic,%20boolean)
|
||||
//
|
||||
// Sends a notification (via indication) to the client that a characteristic
|
||||
// has changed with the given value. Returns whether or not it was successful.
|
||||
//
|
||||
// The value sent does not have to reflect the locally stored characteristic
|
||||
// value. To update the local value, call GattServer::UpdateCharacteristic.
|
||||
virtual bool SendCharacteristic(const GattCharacteristic& characteristic,
|
||||
const ByteArray& value) = 0;
|
||||
};
|
||||
|
||||
// Callback for asynchronous events on the client side of a GATT connection.
|
||||
class ClientGattConnectionLifeCycleCallback {
|
||||
public:
|
||||
virtual ~ClientGattConnectionLifeCycleCallback() {}
|
||||
|
||||
// Called when the client is disconnected from the GATT server.
|
||||
virtual void OnDisconnected(ClientGattConnection* connection) = 0;
|
||||
};
|
||||
|
||||
// Callback for asynchronous events on the server side of a GATT connection.
|
||||
class ServerGattConnectionLifeCycleCallback {
|
||||
public:
|
||||
virtual ~ServerGattConnectionLifeCycleCallback() {}
|
||||
|
||||
// Called when a remote peripheral connected to us and subscribed to one of
|
||||
// our characteristics.
|
||||
virtual void OnCharacteristicSubscription(
|
||||
ServerGattConnection* connection,
|
||||
const GattCharacteristic& characteristic) = 0;
|
||||
|
||||
// Called when a remote peripheral unsubscribed from one of our
|
||||
// characteristics.
|
||||
virtual void OnCharacteristicUnsubscription(
|
||||
ServerGattConnection* connection,
|
||||
const GattCharacteristic& characteristic) = 0;
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattServer
|
||||
//
|
||||
// Representation of a BLE GATT server.
|
||||
class GattServer {
|
||||
public:
|
||||
virtual ~GattServer() {}
|
||||
|
||||
// Creates a characteristic and adds it to the GATT server under the given
|
||||
// characteristic and service UUIDs. Returns no value upon error.
|
||||
//
|
||||
// Characteristics of the same service UUID should be put under one
|
||||
// service rather than many services with the same UUID.
|
||||
//
|
||||
// If the INDICATE property is included, the characteristic should include the
|
||||
// official Bluetooth Client Characteristic Configuration descriptor with UUID
|
||||
// 0x2902 and a WRITE permission. This allows remote clients to write to this
|
||||
// descriptor and subscribe for characteristic changes. For more information
|
||||
// about this descriptor, please go to:
|
||||
// https://www.bluetooth.com/specifications/Gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.Gatt.client_characteristic_configuration.xml
|
||||
virtual std::optional<GattCharacteristic> CreateCharacteristic(
|
||||
absl::string_view service_uuid, absl::string_view characteristic_uuid,
|
||||
const std::set<GattCharacteristic::Permission>& permissions,
|
||||
const std::set<GattCharacteristic::Property>& properties) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html#setValue(byte[])
|
||||
//
|
||||
// Locally updates the value of a characteristic and returns whether or not it
|
||||
// was successful.
|
||||
// Takes ownership of (and is responsible for destroying) the passed-in
|
||||
// 'value'.
|
||||
virtual bool UpdateCharacteristic(const GattCharacteristic& characteristic,
|
||||
const ByteArray& value) = 0;
|
||||
|
||||
// Stops a GATT server.
|
||||
virtual void Stop() = 0;
|
||||
};
|
||||
|
||||
// A BLE socket representation.
|
||||
class BleSocket {
|
||||
public:
|
||||
virtual ~BleSocket() {}
|
||||
|
||||
// Returns the remote BLE peripheral tied to this socket.
|
||||
virtual BlePeripheral& GetRemotePeripheral() = 0;
|
||||
|
||||
// Writes a message on the socket and blocks until finished. Returns
|
||||
// Exception::kIo upon error, and Exception::kSuccess otherwise.
|
||||
virtual Exception Write(const ByteArray& message) = 0;
|
||||
|
||||
// Closes the socket and blocks until finished. Returns Exception::kIo upon
|
||||
// error, and Exception::kSuccess otherwise.
|
||||
virtual Exception Close() = 0;
|
||||
};
|
||||
|
||||
// Callback for asynchronous events on a BleSocket object.
|
||||
class BleSocketLifeCycleCallback {
|
||||
public:
|
||||
virtual ~BleSocketLifeCycleCallback() {}
|
||||
|
||||
// Called when a message arrives on a socket.
|
||||
virtual void OnMessageReceived(BleSocket* socket,
|
||||
const ByteArray& message) = 0;
|
||||
|
||||
// Called when a socket gets disconnected.
|
||||
virtual void OnDisconnected(BleSocket* socket) = 0;
|
||||
};
|
||||
|
||||
// Callback for asynchronous events on the server side of a BleSocket object.
|
||||
class ServerBleSocketLifeCycleCallback : public BleSocketLifeCycleCallback {
|
||||
public:
|
||||
~ServerBleSocketLifeCycleCallback() override {}
|
||||
|
||||
// Called when a new incoming socket has been established.
|
||||
virtual void OnSocketEstablished(BleSocket* socket) = 0;
|
||||
};
|
||||
|
||||
// The main BLE medium used inside of Nearby. This serves as the entry point for
|
||||
// all BLE and GATT related operations.
|
||||
class BleMedium {
|
||||
public:
|
||||
using Mtu = uint32_t;
|
||||
|
||||
virtual ~BleMedium() {}
|
||||
|
||||
// Coarse representation of power settings throughout all BLE operations.
|
||||
enum class PowerMode {
|
||||
kUnknown = 0,
|
||||
kLow = 1,
|
||||
kHigh = 2,
|
||||
kLast,
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser.html#startAdvertising(android.bluetooth.le.AdvertiseSettings,%20android.bluetooth.le.AdvertiseData,%20android.bluetooth.le.AdvertiseData,%20android.bluetooth.le.AdvertiseCallback)
|
||||
//
|
||||
// Starts BLE advertising and returns whether or not it was successful.
|
||||
//
|
||||
// Power mode should be interpreted in the following way:
|
||||
// LOW:
|
||||
// - Advertising interval = ~1000ms
|
||||
// - TX power = low
|
||||
// HIGH:
|
||||
// - Advertising interval = ~100ms
|
||||
// - TX power = high
|
||||
virtual bool StartAdvertising(const BleAdvertisementData& advertisement_data,
|
||||
const BleAdvertisementData& scan_response,
|
||||
PowerMode power_mode) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser.html#stopAdvertising(android.bluetooth.le.AdvertiseCallback)
|
||||
//
|
||||
// Stops advertising.
|
||||
virtual void StopAdvertising() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/le/ScanCallback
|
||||
//
|
||||
// Callback for BLE scan results.
|
||||
class ScanCallback {
|
||||
public:
|
||||
virtual ~ScanCallback() {}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/le/ScanCallback.html#onScanResult(int,%20android.bluetooth.le.ScanResult)
|
||||
//
|
||||
// Called when a BLE advertisement is discovered.
|
||||
//
|
||||
// The passed in advertisement_data is the merged combination of both
|
||||
// advertisement data and scan response.
|
||||
//
|
||||
// Every discovery of an advertisement should be reported, even if the
|
||||
// advertisement was discovered before.
|
||||
//
|
||||
// Ownership of the BleAdvertisementData transfers to the caller at this
|
||||
// point.
|
||||
virtual void OnAdvertisementFound(
|
||||
BlePeripheral* peripheral,
|
||||
const BleAdvertisementData& advertisement_data) = 0;
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html#startScan(java.util.List%3Candroid.bluetooth.le.ScanFilter%3E,%20android.bluetooth.le.ScanSettings,%20android.bluetooth.le.ScanCallback)
|
||||
//
|
||||
// Starts scanning and returns whether or not it was successful.
|
||||
//
|
||||
// Power mode should be interpreted in the following way:
|
||||
// LOW:
|
||||
// - Scan window = ~512ms
|
||||
// - Scan interval = ~5120ms
|
||||
// HIGH:
|
||||
// - Scan window = ~4096ms
|
||||
// - Scan interval = ~4096ms
|
||||
virtual bool StartScanning(const std::set<std::string>& service_uuids,
|
||||
PowerMode power_mode,
|
||||
const ScanCallback& scan_callback) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html#stopScan(android.bluetooth.le.ScanCallback)
|
||||
//
|
||||
// Stops scanning.
|
||||
virtual void StopScanning() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothManager#openGattServer(android.content.Context,%20android.bluetooth.BluetoothGattServerCallback)
|
||||
//
|
||||
// Starts a GATT server. Returns a nullptr upon error.
|
||||
virtual std::unique_ptr<GattServer> StartGattServer(
|
||||
const ServerGattConnectionLifeCycleCallback& callback) = 0;
|
||||
|
||||
// Starts listening for incoming BLE sockets and returns false upon error.
|
||||
virtual bool StartListeningForIncomingBleSockets(
|
||||
const ServerBleSocketLifeCycleCallback& callback) = 0;
|
||||
|
||||
// Stops listening for incoming BLE sockets.
|
||||
virtual void StopListeningForIncomingBleSockets() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#connectGatt(android.content.Context,%20boolean,%20android.bluetooth.BluetoothGattCallback)
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#requestConnectionPriority(int)
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#requestMtu(int)
|
||||
//
|
||||
// Connects to a GATT server and negotiates the specified connection
|
||||
// parameters. Returns nullptr upon error.
|
||||
//
|
||||
// Both connection interval and MTU can be negotiated on a best-effort basis.
|
||||
//
|
||||
// Power mode should be interpreted in the following way:
|
||||
// LOW:
|
||||
// - Connection interval = ~11.25ms - 15ms
|
||||
// HIGH:
|
||||
// - Connection interval = ~100ms - 125ms
|
||||
virtual std::unique_ptr<ClientGattConnection> ConnectToGattServer(
|
||||
BlePeripheral* peripheral, Mtu mtu, PowerMode power_mode,
|
||||
const ClientGattConnectionLifeCycleCallback& callback) = 0;
|
||||
|
||||
// Establishes a BLE socket to the specified remote peripheral. Returns
|
||||
// nullptr on error.
|
||||
virtual std::unique_ptr<BleSocket> EstablishBleSocket(
|
||||
BlePeripheral* peripheral,
|
||||
const BleSocketLifeCycleCallback& callback) = 0;
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_BLE_V2_H_
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef PLATFORM_API2_BLUETOOTH_ADAPTER_H_
|
||||
#define PLATFORM_API2_BLUETOOTH_ADAPTER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html
|
||||
class BluetoothAdapter {
|
||||
public:
|
||||
virtual ~BluetoothAdapter() {}
|
||||
|
||||
// Eligible statuses of the BluetoothAdapter.
|
||||
enum class Status {
|
||||
kDisabled,
|
||||
kEnabled,
|
||||
};
|
||||
|
||||
// Synchronously sets the status of the BluetoothAdapter to 'status', and
|
||||
// returns true if the operation was a success.
|
||||
virtual bool SetStatus(Status status) = 0;
|
||||
// Returns true if the BluetoothAdapter's current status is
|
||||
// Status::Value::kEnabled.
|
||||
virtual bool IsEnabled() = 0;
|
||||
|
||||
// Scan modes of a BluetoothAdapter, as described at
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getScanMode().
|
||||
enum class ScanMode {
|
||||
kUnknown,
|
||||
kConnectableDiscoverable,
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getScanMode()
|
||||
//
|
||||
// Returns ScanMode::kUnknown on error.
|
||||
virtual ScanMode GetScanMode() = 0;
|
||||
// Synchronously sets the scan mode of the adapter, and returns true if the
|
||||
// operation was a success.
|
||||
virtual bool SetScanMode(ScanMode scan_mode) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getName()
|
||||
// Returns an empty string on error
|
||||
virtual std::string GetName() const = 0;
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#setName(java.lang.String)
|
||||
virtual bool SetName(absl::string_view name) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_BLUETOOTH_ADAPTER_H_
|
||||
@@ -0,0 +1,124 @@
|
||||
#ifndef PLATFORM_API2_BLUETOOTH_CLASSIC_H_
|
||||
#define PLATFORM_API2_BLUETOOTH_CLASSIC_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "platform/api2/input_stream.h"
|
||||
#include "platform/api2/output_stream.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/exception.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
|
||||
class BluetoothDevice {
|
||||
public:
|
||||
virtual ~BluetoothDevice() {}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getName()
|
||||
virtual std::string GetName() = 0;
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html.
|
||||
class BluetoothSocket {
|
||||
public:
|
||||
virtual ~BluetoothSocket() {}
|
||||
|
||||
// Returns the InputStream of the BluetoothSocket.
|
||||
virtual InputStream& GetInputStream() = 0;
|
||||
|
||||
// Returns the OutputStream of the BluetoothSocket.
|
||||
virtual OutputStream& GetOutputStream() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#close()
|
||||
//
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
virtual Exception Close() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#getRemoteDevice()
|
||||
virtual BluetoothDevice& GetRemoteDevice() = 0;
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html.
|
||||
class BluetoothServerSocket {
|
||||
public:
|
||||
virtual ~BluetoothServerSocket() {}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#accept()
|
||||
//
|
||||
// returns Exception::kIo on error.
|
||||
virtual ExceptionOr<std::unique_ptr<BluetoothSocket>> Accept() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close()
|
||||
//
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
virtual Exception Close() = 0;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the Bluetooth Classic
|
||||
// medium.
|
||||
class BluetoothClassicMedium {
|
||||
public:
|
||||
virtual ~BluetoothClassicMedium() {}
|
||||
|
||||
class DiscoveryCallback {
|
||||
public:
|
||||
virtual ~DiscoveryCallback() {}
|
||||
|
||||
// BluetoothDevice* is not owned by callbacks.
|
||||
// Pointer is guaranteed to remain valid for the duration of a call.
|
||||
virtual void OnDeviceDiscovered(BluetoothDevice* device) = 0;
|
||||
virtual void OnDeviceNameChanged(BluetoothDevice* device) = 0;
|
||||
virtual void OnDeviceLost(BluetoothDevice* device) = 0;
|
||||
};
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery()
|
||||
//
|
||||
// Returns true once the process of discovery has been initiated.
|
||||
//
|
||||
// Does not take ownership of the passed-in discovery_callback -- destroying
|
||||
// that is up to the caller.
|
||||
virtual bool StartDiscovery(const DiscoveryCallback& discovery_callback) = 0;
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#cancelDiscovery()
|
||||
//
|
||||
// Returns true once discovery is well and truly stopped; after this returns,
|
||||
// there must be no more invocations of the DiscoveryCallback passed in to
|
||||
// startDiscovery().
|
||||
virtual bool StopDiscovery() = 0;
|
||||
|
||||
// A combination of
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord
|
||||
// followed by
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#connect().
|
||||
//
|
||||
// service_uuid is the canonical textual representation
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a
|
||||
// type 3 name-based
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
|
||||
// UUID.
|
||||
//
|
||||
// On success, returns a new BluetoothSocket, wrapped in a ExceptionOr object.
|
||||
// On error, returns Exception object.
|
||||
virtual ExceptionOr<std::unique_ptr<BluetoothSocket>> ConnectToService(
|
||||
BluetoothDevice* remote_device, absl::string_view service_uuid) = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord
|
||||
//
|
||||
// service_uuid is the canonical textual representation
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a
|
||||
// type 3 name-based
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
|
||||
// UUID.
|
||||
//
|
||||
// Returns Exception::kIo on error.
|
||||
virtual ExceptionOr<std::unique_ptr<BluetoothServerSocket>> ListenForService(
|
||||
absl::string_view service_name, absl::string_view service_uuid) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_BLUETOOTH_CLASSIC_H_
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef PLATFORM_API2_CONDITION_VARIABLE_H_
|
||||
#define PLATFORM_API2_CONDITION_VARIABLE_H_
|
||||
|
||||
#include "platform/exception.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// The ConditionVariable class is a synchronization primitive that can be used
|
||||
// to block a thread, or multiple threads at the same time, until another thread
|
||||
// both modifies a shared variable (the condition), and notifies the
|
||||
// ConditionVariable.
|
||||
class ConditionVariable {
|
||||
public:
|
||||
virtual ~ConditionVariable() {}
|
||||
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#notify--
|
||||
virtual void Notify() = 0;
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait--
|
||||
virtual Exception Wait() = 0; // throws Exception::kInterrupted
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_CONDITION_VARIABLE_H_
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef PLATFORM_API2_COUNT_DOWN_LATCH_H_
|
||||
#define PLATFORM_API2_COUNT_DOWN_LATCH_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "platform/exception.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A synchronization aid that allows one or more threads to wait until a set of
|
||||
// operations being performed in other threads completes.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html
|
||||
class CountDownLatch {
|
||||
public:
|
||||
virtual ~CountDownLatch() {}
|
||||
|
||||
virtual Exception Await() = 0; // throws Exception::kInterrupted
|
||||
virtual ExceptionOr<bool> Await(
|
||||
absl::Duration timeout) = 0; // throws Exception::kInterrupted
|
||||
virtual void CountDown() = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_COUNT_DOWN_LATCH_H_
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef PLATFORM_API2_EXECUTOR_H_
|
||||
#define PLATFORM_API2_EXECUTOR_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "platform/runnable.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// This abstract class is the superclass of all classes representing an
|
||||
// Executor.
|
||||
class Executor {
|
||||
public:
|
||||
virtual ~Executor() = default;
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-
|
||||
virtual void Execute(std::unique_ptr<Runnable> runnable) = 0;
|
||||
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--
|
||||
virtual void Shutdown() = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_EXECUTOR_H_
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef PLATFORM_API2_FUTURE_H_
|
||||
#define PLATFORM_API2_FUTURE_H_
|
||||
|
||||
#include "platform/exception.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A Future represents the result of an asynchronous computation.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html
|
||||
template <typename T>
|
||||
class Future {
|
||||
public:
|
||||
virtual ~Future() = default;
|
||||
|
||||
// throws Exception::kInterrupted, Exception::kExecution
|
||||
virtual ExceptionOr<T> Get() = 0;
|
||||
|
||||
// throws Exception::kInterrupted, Exception::kExecution
|
||||
// throws Exception::kTimeout if timeout is exceeded while waiting for
|
||||
// result.
|
||||
virtual ExceptionOr<T> Get(absl::Duration timeout) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_FUTURE_H_
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef PLATFORM_API2_HASH_UTILS_H_
|
||||
#define PLATFORM_API2_HASH_UTILS_H_
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A provider of standard hashing algorithms.
|
||||
class HashUtils {
|
||||
public:
|
||||
static ByteArray Md5(absl::string_view input);
|
||||
static ByteArray Sha256(absl::string_view input);
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_HASH_UTILS_H_
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef PLATFORM_API2_INPUT_FILE_H_
|
||||
#define PLATFORM_API2_INPUT_FILE_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "platform/api2/input_stream.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/exception.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// An InputFile represents a readable file on the system.
|
||||
class InputFile : public InputStream {
|
||||
public:
|
||||
~InputFile() override = default;
|
||||
virtual std::string GetFilePath() const = 0;
|
||||
virtual size_t GetTotalSize() const = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_INPUT_FILE_H_
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef PLATFORM_API2_INPUT_STREAM_H_
|
||||
#define PLATFORM_API2_INPUT_STREAM_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/exception.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// An InputStream represents an input stream of bytes.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html
|
||||
class InputStream {
|
||||
public:
|
||||
virtual ~InputStream() {}
|
||||
|
||||
virtual ExceptionOr<ByteArray> Read(
|
||||
size_t size) = 0; // throws Exception::kIo
|
||||
virtual Exception Close() = 0; // throws Exception::kIo
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_INPUT_STREAM_H_
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef PLATFORM_API2_LISTENABLE_FUTURE_H_
|
||||
#define PLATFORM_API2_LISTENABLE_FUTURE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "platform/api2/executor.h"
|
||||
#include "platform/api2/future.h"
|
||||
#include "platform/exception.h"
|
||||
#include "platform/runnable.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A Future that accepts completion listeners.
|
||||
//
|
||||
// https://guava.dev/releases/20.0/api/docs/com/google/common/util/concurrent/ListenableFuture.html
|
||||
template <typename T>
|
||||
class ListenableFuture : public Future<T> {
|
||||
public:
|
||||
~ListenableFuture() override = default;
|
||||
|
||||
virtual void AddListener(std::unique_ptr<Runnable> runnable,
|
||||
Executor* executor) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_LISTENABLE_FUTURE_H_
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef PLATFORM_API2_MULTI_THREAD_EXECUTOR_H_
|
||||
#define PLATFORM_API2_MULTI_THREAD_EXECUTOR_H_
|
||||
|
||||
#include "platform/api2/submittable_executor.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// An Executor that reuses a fixed number of threads operating off a shared
|
||||
// unbounded queue.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-
|
||||
template <typename ConcreteSubmittableExecutor>
|
||||
class MultiThreadExecutor
|
||||
: public SubmittableExecutor<ConcreteSubmittableExecutor> {
|
||||
public:
|
||||
~MultiThreadExecutor() override {}
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_MULTI_THREAD_EXECUTOR_H_
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PLATFORM_API2_MUTEX_H_
|
||||
#define PLATFORM_API2_MUTEX_H_
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A lock is a tool for controlling access to a shared resource by multiple
|
||||
// threads.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.html
|
||||
class Mutex {
|
||||
public:
|
||||
virtual ~Mutex() {}
|
||||
|
||||
virtual void Lock() = 0;
|
||||
virtual void Unlock() = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_MUTEX_H_
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef PLATFORM_API2_OUTPUT_FILE_H_
|
||||
#define PLATFORM_API2_OUTPUT_FILE_H_
|
||||
|
||||
#include "platform/api2/output_stream.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/exception.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// An OutputFile represents a writable file on the system.
|
||||
class OutputFile : public OutputStream {
|
||||
public:
|
||||
~OutputFile() override = default;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_OUTPUT_FILE_H_
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef PLATFORM_API2_OUTPUT_STREAM_H_
|
||||
#define PLATFORM_API2_OUTPUT_STREAM_H_
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/exception.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// An OutputStream represents an output stream of bytes.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html
|
||||
class OutputStream {
|
||||
public:
|
||||
virtual ~OutputStream() {}
|
||||
|
||||
virtual Exception Write(const ByteArray& data) = 0; // throws Exception::kIo
|
||||
virtual Exception Flush() = 0; // throws Exception::kIo
|
||||
virtual Exception Close() = 0; // throws Exception::kIo
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_OUTPUT_STREAM_H_
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef PLATFORM_API2_SCHEDULED_EXECUTOR_H_
|
||||
#define PLATFORM_API2_SCHEDULED_EXECUTOR_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "platform/api2/executor.h"
|
||||
#include "platform/cancelable.h"
|
||||
#include "platform/runnable.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// An Executor that can schedule commands to run after a given delay, or to
|
||||
// execute periodically.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html
|
||||
class ScheduledExecutor : public Executor {
|
||||
public:
|
||||
~ScheduledExecutor() override = default;
|
||||
virtual std::unique_ptr<Cancelable> Schedule(
|
||||
std::unique_ptr<Runnable> runnable, absl::Duration duration) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_SCHEDULED_EXECUTOR_H_
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef PLATFORM_API2_SERVER_SYNC_H_
|
||||
#define PLATFORM_API2_SERVER_SYNC_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// Abstraction that represents a Nearby endpoint exchanging data through
|
||||
// ServerSync Medium.
|
||||
class ServerSyncDevice {
|
||||
public:
|
||||
virtual ~ServerSyncDevice() = default;
|
||||
|
||||
virtual std::string GetName() const = 0;
|
||||
virtual std::string GetGuid() const = 0;
|
||||
virtual std::string GetOwnGuid() const = 0;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the Chrome Sync medium.
|
||||
class ServerSyncMedium {
|
||||
public:
|
||||
virtual ~ServerSyncMedium() = default;
|
||||
|
||||
virtual bool StartAdvertising(absl::string_view service_id,
|
||||
absl::string_view endpoint_id,
|
||||
const ByteArray& endpoint_info) = 0;
|
||||
virtual void StopAdvertising(absl::string_view service_id) = 0;
|
||||
|
||||
class DiscoveredDeviceCallback {
|
||||
public:
|
||||
virtual ~DiscoveredDeviceCallback() = default;
|
||||
|
||||
// Called on a new ServerSyncDevice discovery.
|
||||
virtual void OnDeviceDiscovered(ServerSyncDevice* device,
|
||||
absl::string_view service_id,
|
||||
absl::string_view endpoint_id,
|
||||
const ByteArray& endpoint_info) = 0;
|
||||
// Called when ServerSyncDevice is no longer reachable.
|
||||
virtual void OnDeviceLost(ServerSyncDevice* device,
|
||||
absl::string_view service_id) = 0;
|
||||
};
|
||||
|
||||
// Returns true once the Chrome Sync scan has been initiated.
|
||||
virtual bool StartDiscovery(
|
||||
absl::string_view service_id,
|
||||
const DiscoveredDeviceCallback& discovered_device_callback) = 0;
|
||||
// Returns true once Chrome Sync scan for service_id is well and truly
|
||||
// stopped; after this returns, there must be no more invocations of the
|
||||
// DiscoveredDeviceCallback passed in to startScanning() for service_id.
|
||||
virtual void StopDiscovery(absl::string_view service_id) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_SERVER_SYNC_H_
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef PLATFORM_API2_SETTABLE_FUTURE_H_
|
||||
#define PLATFORM_API2_SETTABLE_FUTURE_H_
|
||||
|
||||
#include "platform/api2/listenable_future.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A SettableFuture is a type of Future whose result can be set.
|
||||
//
|
||||
// https://google.github.io/guava/releases/20.0/api/docs/com/google/common/util/concurrent/SettableFuture.html
|
||||
template <typename T>
|
||||
class SettableFuture : public ListenableFuture<T> {
|
||||
public:
|
||||
~SettableFuture() override = default;
|
||||
|
||||
virtual bool Set(const T& value) = 0;
|
||||
virtual bool SetException(Exception exception) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_SETTABLE_FUTURE_H_
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef PLATFORM_API2_SINGLE_THREAD_EXECUTOR_H_
|
||||
#define PLATFORM_API2_SINGLE_THREAD_EXECUTOR_H_
|
||||
|
||||
#include "platform/api2/submittable_executor.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// An Executor that uses a single worker thread operating off an unbounded
|
||||
// queue.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor--
|
||||
template <typename ConcreteSubmittableExecutor>
|
||||
class SingleThreadExecutor
|
||||
: public SubmittableExecutor<ConcreteSubmittableExecutor> {
|
||||
public:
|
||||
~SingleThreadExecutor() override {}
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_SINGLE_THREAD_EXECUTOR_H_
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef PLATFORM_API2_SOCKET_H_
|
||||
#define PLATFORM_API2_SOCKET_H_
|
||||
|
||||
#include "platform/api2/input_stream.h"
|
||||
#include "platform/api2/output_stream.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// A socket is an endpoint for communication between two machines.
|
||||
//
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html
|
||||
class Socket {
|
||||
public:
|
||||
virtual ~Socket() {}
|
||||
|
||||
virtual InputStream& GetInputStream() = 0;
|
||||
virtual OutputStream& GetOutputStream() = 0;
|
||||
virtual void Close() = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_SOCKET_H_
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef PLATFORM_API2_SUBMITTABLE_EXECUTOR_H_
|
||||
#define PLATFORM_API2_SUBMITTABLE_EXECUTOR_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "platform/api2/executor.h"
|
||||
#include "platform/api2/future.h"
|
||||
#include "platform/callable.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// Each per-platform concrete implementation is expected to extend from
|
||||
// SubmittableExecutor and provide an override of its submit() method.
|
||||
//
|
||||
// e.g.
|
||||
// class XyzSubmittableExecutor
|
||||
// : public SubmittableExecutor<XyzSubmittableExecutor> {
|
||||
// public:
|
||||
// template <typename T>
|
||||
// std::unique_ptr<Future<T>> submit(std::unique_ptr<Callable<T>> callable) {
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
template <typename ConcreteSubmittableExecutor>
|
||||
class SubmittableExecutor : public Executor {
|
||||
public:
|
||||
~SubmittableExecutor() override {}
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<Future<T>> Submit(std::unique_ptr<Callable<T>> callable) {
|
||||
static_assert(
|
||||
std::is_base_of_v<SubmittableExecutor, ConcreteSubmittableExecutor>,
|
||||
"Class template type is not derived from SubmittableExecutor");
|
||||
return static_cast<ConcreteSubmittableExecutor*>(this)->submit(callable);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_SUBMITTABLE_EXECUTOR_H_
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PLATFORM_API2_SYSTEM_CLOCK_H_
|
||||
#define PLATFORM_API2_SYSTEM_CLOCK_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
class SystemClock final {
|
||||
public:
|
||||
// Returns the time (in milliseconds) since the system was booted, and
|
||||
// includes deep sleep. This clock should be guaranteed to be monotonic, and
|
||||
// should continue to tick even when the CPU is in power saving modes.
|
||||
static absl::Time ElapsedRealtime();
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_SYSTEM_CLOCK_H_
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PLATFORM_API2_THREAD_UTILS_H_
|
||||
#define PLATFORM_API2_THREAD_UTILS_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "platform/exception.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
class ThreadUtils final {
|
||||
public:
|
||||
// https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#sleep(long)
|
||||
// throws Exception::kInterrupted
|
||||
static Exception Sleep(absl::Duration timeout);
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_THREAD_UTILS_H_
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef PLATFORM_API2_WEBRTC_H_
|
||||
#define PLATFORM_API2_WEBRTC_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
#include "webrtc/files/stable/webrtc/api/peer_connection_interface.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
class WebRtcSignalingMessenger {
|
||||
public:
|
||||
virtual ~WebRtcSignalingMessenger() = default;
|
||||
|
||||
/** Called whenever we receive an inbox message from tachyon. */
|
||||
class SignalingMessageListener {
|
||||
public:
|
||||
virtual ~SignalingMessageListener() = default;
|
||||
|
||||
virtual void OnSignalingMessage(const ByteArray& message) = 0;
|
||||
};
|
||||
|
||||
class IceServersListener {
|
||||
public:
|
||||
virtual ~IceServersListener() = default;
|
||||
|
||||
virtual void OnIceServersFetched(
|
||||
std::vector<webrtc::PeerConnectionInterface::IceServer>
|
||||
ice_servers) = 0;
|
||||
};
|
||||
|
||||
virtual bool RegisterSignaling() = 0;
|
||||
virtual bool UnregisterSignaling() = 0;
|
||||
virtual bool SendMessage(std::string_view peer_id,
|
||||
const ByteArray& message) = 0;
|
||||
virtual bool StartReceivingMessages(
|
||||
const SignalingMessageListener& listener) = 0;
|
||||
virtual void GetIceServers(
|
||||
const IceServersListener& ice_servers_listener) = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_WEBRTC_H_
|
||||
@@ -0,0 +1,88 @@
|
||||
#ifndef PLATFORM_API2_WIFI_H_
|
||||
#define PLATFORM_API2_WIFI_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// Possible authentication types for a WiFi network.
|
||||
enum class WifiAuthType {
|
||||
// WiFi Authentication type; either none (non-secured a.k.a. open) link, or
|
||||
// WPA PSK (WiFi Protected Access PreShared Key), or
|
||||
// see https://en.wikipedia.org/wiki/Wi-Fi_Protected_Access
|
||||
// WEP (Wired Equivalent Privacy);
|
||||
// see https://en.wikipedia.org/wiki/Wired_Equivalent_Privacy
|
||||
kUnknown = 0,
|
||||
kOpen = 1,
|
||||
kWpaPsk = 2,
|
||||
kWep = 3,
|
||||
};
|
||||
|
||||
// Possible statuses of a device's connection to a WiFi network.
|
||||
enum class WifiConnectionStatus {
|
||||
kUnknown = 0,
|
||||
kConnected = 1,
|
||||
kConnectionFailure = 2,
|
||||
kAuthFailure = 3,
|
||||
};
|
||||
|
||||
// Represents a WiFi network found during a call to WifiMedium#scan().
|
||||
class WifiScanResult {
|
||||
public:
|
||||
virtual ~WifiScanResult() {}
|
||||
|
||||
// Gets the SSID of this WiFi network.
|
||||
virtual std::string GetSsid() const = 0;
|
||||
// Gets the signal strength of this WiFi network in dBm.
|
||||
virtual std::int32_t GetSignalStrengthDbm() const = 0;
|
||||
// Gets the frequency band of this WiFi network in MHz.
|
||||
virtual std::int32_t GetFrequencyMhz() const = 0;
|
||||
// Gets the authentication type of this WiFi network.
|
||||
virtual WifiAuthType GetAuthType() const = 0;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the WiFi medium.
|
||||
class WifiMedium {
|
||||
public:
|
||||
virtual ~WifiMedium() {}
|
||||
|
||||
class ScanResultCallback {
|
||||
public:
|
||||
virtual ~ScanResultCallback() {}
|
||||
|
||||
virtual void OnScanResults(
|
||||
const std::vector<WifiScanResult>& scan_results) = 0;
|
||||
};
|
||||
|
||||
// Does not take ownership of the passed-in scan_result_callback -- destroying
|
||||
// that is up to the caller.
|
||||
virtual bool Scan(const ScanResultCallback& scan_result_callback) = 0;
|
||||
|
||||
// If 'password' is an empty string, none has been provided. Returns
|
||||
// WifiConnectionStatus::CONNECTED on success, or the appropriate failure code
|
||||
// otherwise.
|
||||
virtual WifiConnectionStatus ConnectToNetwork(absl::string_view ssid,
|
||||
absl::string_view password,
|
||||
WifiAuthType auth_type) = 0;
|
||||
|
||||
// Blocks until it's certain of there being a connection to the internet, or
|
||||
// returns false if it fails to do so.
|
||||
//
|
||||
// How this method wants to verify said connection is totally up to it (so it
|
||||
// can feel free to ping whatever server, download whatever resource, etc.
|
||||
// that it needs to gain confidence that the internet is reachable hereon in).
|
||||
virtual bool VerifyInternetConnectivity() = 0;
|
||||
|
||||
// Returns the local device's IP address in the IPv4 dotted-quad format.
|
||||
virtual std::string GetIpAddress() = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_API2_WIFI_H_
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "platform/base64_utils.h"
|
||||
|
||||
#include "strings/escaping.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
|
||||
namespace location {
|
||||
@@ -25,7 +24,7 @@ std::string Base64Utils::encode(const ByteArray& bytes) {
|
||||
return base64_string;
|
||||
}
|
||||
|
||||
std::string Base64Utils::encode(const std::string& input) {
|
||||
std::string Base64Utils::encode(absl::string_view input) {
|
||||
std::string base64_string;
|
||||
absl::WebSafeBase64Escape(input, &base64_string);
|
||||
|
||||
@@ -33,7 +32,7 @@ std::string Base64Utils::encode(const std::string& input) {
|
||||
}
|
||||
|
||||
template<>
|
||||
Ptr<ByteArray> Base64Utils::decode(const std::string& base64_string) {
|
||||
Ptr<ByteArray> Base64Utils::decode(absl::string_view base64_string) {
|
||||
std::string decoded_string;
|
||||
if (!absl::WebSafeBase64Unescape(base64_string, &decoded_string)) {
|
||||
return Ptr<ByteArray>();
|
||||
@@ -43,7 +42,7 @@ Ptr<ByteArray> Base64Utils::decode(const std::string& base64_string) {
|
||||
}
|
||||
|
||||
template<>
|
||||
ByteArray Base64Utils::decode(const std::string& base64_string) {
|
||||
ByteArray Base64Utils::decode(absl::string_view base64_string) {
|
||||
std::string decoded_string;
|
||||
if (!absl::WebSafeBase64Unescape(base64_string, &decoded_string)) {
|
||||
return ByteArray();
|
||||
|
||||
@@ -4,23 +4,24 @@
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/port/string.h"
|
||||
#include "platform/ptr.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
class Base64Utils {
|
||||
public:
|
||||
static std::string encode(const std::string& input);
|
||||
static std::string encode(absl::string_view input);
|
||||
static std::string encode(const ByteArray& bytes);
|
||||
static std::string encode(ConstPtr<ByteArray> bytes);
|
||||
|
||||
template <typename T>
|
||||
static T decode(const std::string& base64_string);
|
||||
static T decode(absl::string_view base64_string);
|
||||
template <>
|
||||
Ptr<ByteArray> decode(const std::string& base64_string);
|
||||
Ptr<ByteArray> decode(absl::string_view base64_string);
|
||||
template <>
|
||||
ByteArray decode(const std::string& base64_string);
|
||||
static Ptr<ByteArray> decode(const std::string& base64_string) {
|
||||
ByteArray decode(absl::string_view base64_string);
|
||||
static Ptr<ByteArray> decode(absl::string_view base64_string) {
|
||||
return decode<Ptr<ByteArray>>(base64_string);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#include "platform/exception.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
template <typename T>
|
||||
ExceptionOr<T>::ExceptionOr(T result)
|
||||
: result_(result), exception_(Exception::NONE) {}
|
||||
|
||||
template <typename T>
|
||||
ExceptionOr<T>::ExceptionOr(Exception::Value exception)
|
||||
: result_(), exception_(exception) {}
|
||||
|
||||
template <typename T>
|
||||
bool ExceptionOr<T>::ok() const {
|
||||
return Exception::NONE == exception_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ExceptionOr<T>::result() const {
|
||||
return result_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Exception::Value ExceptionOr<T>::exception() const {
|
||||
return exception_;
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
+33
-11
@@ -1,21 +1,34 @@
|
||||
#ifndef PLATFORM_EXCEPTION_H_
|
||||
#define PLATFORM_EXCEPTION_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
struct Exception {
|
||||
enum Value {
|
||||
enum Value : int {
|
||||
NONE,
|
||||
IO,
|
||||
INTERRUPTED,
|
||||
INVALID_PROTOCOL_BUFFER,
|
||||
EXECUTION,
|
||||
// New code should use the kConstants.
|
||||
// Old CONSTANTS are deprecated, and should not be used.
|
||||
kFailed = -1, // Initial value of Exception; any unknown error.
|
||||
kSuccess = NONE, // No exception.
|
||||
kIo = IO, // IO Error happened.
|
||||
kInterrupted = INTERRUPTED, // Operation was interrupted.
|
||||
kInvalidProtocolBuffer = INVALID_PROTOCOL_BUFFER, // Couldn't parse.
|
||||
kExecution = EXECUTION, // Couldn't execute.
|
||||
kTimeout, // Operarion did not finish within specified time.
|
||||
};
|
||||
Value value {kFailed};
|
||||
};
|
||||
|
||||
// ExceptionOr models the concept of the return value of a function that might
|
||||
// throw an exception.
|
||||
// ExceptionOr provides experience similar to StatusOr<T> used in
|
||||
// Google Cloud API, see:
|
||||
// https://googleapis.github.io/google-cloud-cpp/0.7.0/common/status__or_8h_source.html
|
||||
//
|
||||
// If ok() returns true, result() is a usable return value. Otherwise,
|
||||
// exception() explains why such a value is not present.
|
||||
@@ -36,22 +49,31 @@ struct Exception {
|
||||
template <typename T>
|
||||
class ExceptionOr {
|
||||
public:
|
||||
explicit ExceptionOr(T result);
|
||||
explicit ExceptionOr(Exception::Value exception);
|
||||
ExceptionOr() = default;
|
||||
ExceptionOr(T&& result) : result_{std::move(result)}, // NOLINT
|
||||
exception_{Exception::kSuccess} {}
|
||||
ExceptionOr(const T& result) : result_{result}, // NOLINT
|
||||
exception_{Exception::kSuccess} {}
|
||||
ExceptionOr(Exception::Value exception) : exception_{exception} {} // NOLINT
|
||||
|
||||
bool ok() const;
|
||||
bool ok() const { return exception_.value == Exception::kSuccess; }
|
||||
|
||||
T result() const;
|
||||
Exception::Value exception() const;
|
||||
T& result() & { return result_; }
|
||||
const T& result() const & { return result_; }
|
||||
T&& result() && { return std::move(result_); }
|
||||
const T&& result() const && { return std::move(result_); }
|
||||
|
||||
Exception::Value exception() const { return exception_.value; }
|
||||
|
||||
T GetResult() const;
|
||||
Exception GetException() const;
|
||||
|
||||
private:
|
||||
T result_;
|
||||
Exception::Value exception_;
|
||||
Exception exception_ {Exception::kFailed};
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#include "platform/exception.cc"
|
||||
|
||||
#endif // PLATFORM_EXCEPTION_H_
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "platform/exception.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location::nearby {
|
||||
|
||||
TEST(ExceptionOr, Result_Copy_NonConst) {
|
||||
ExceptionOr<std::vector<int>> exception_or_vector({1, 2, 3});
|
||||
EXPECT_FALSE(exception_or_vector.result().empty());
|
||||
|
||||
// Expect a copy when not explicitly moving the result.
|
||||
std::vector<int> copy = exception_or_vector.result();
|
||||
EXPECT_FALSE(copy.empty());
|
||||
EXPECT_FALSE(exception_or_vector.result().empty());
|
||||
|
||||
// Modifying |exception_or_vector| should not affect the copy.
|
||||
exception_or_vector.result().clear();
|
||||
EXPECT_FALSE(copy.empty());
|
||||
}
|
||||
|
||||
TEST(ExceptionOr, Result_Copy_Const) {
|
||||
const ExceptionOr<std::vector<int>> exception_or_vector({1, 2, 3});
|
||||
EXPECT_FALSE(exception_or_vector.result().empty());
|
||||
|
||||
// Expect a copy when not explicitly moving the result.
|
||||
std::vector<int> copy = exception_or_vector.result();
|
||||
EXPECT_FALSE(copy.empty());
|
||||
EXPECT_FALSE(exception_or_vector.result().empty());
|
||||
}
|
||||
|
||||
TEST(ExceptionOr, Result_Reference_NonConst) {
|
||||
ExceptionOr<std::vector<int>> exception_or_vector({1, 2, 3});
|
||||
EXPECT_FALSE(exception_or_vector.result().empty());
|
||||
|
||||
// Getting a reference should not modify the source.
|
||||
std::vector<int>& reference = exception_or_vector.result();
|
||||
EXPECT_FALSE(reference.empty());
|
||||
EXPECT_FALSE(exception_or_vector.result().empty());
|
||||
|
||||
// Modifying |exception_or_vector| should reflect in the reference.
|
||||
exception_or_vector.result().clear();
|
||||
EXPECT_TRUE(reference.empty());
|
||||
}
|
||||
|
||||
TEST(ExceptionOr, Result_Reference_Const) {
|
||||
const ExceptionOr<std::vector<int>> exception_or_vector({1, 2, 3});
|
||||
EXPECT_FALSE(exception_or_vector.result().empty());
|
||||
|
||||
// Getting a reference should not modify the source.
|
||||
const std::vector<int>& reference = exception_or_vector.result();
|
||||
EXPECT_FALSE(reference.empty());
|
||||
EXPECT_FALSE(exception_or_vector.result().empty());
|
||||
}
|
||||
|
||||
TEST(ExceptionOr, Result_Move_NonConst) {
|
||||
ExceptionOr<std::vector<int>> exception_or_vector({1, 2, 3});
|
||||
ASSERT_FALSE(exception_or_vector.result().empty());
|
||||
|
||||
// Moving the result should clear the source.
|
||||
std::vector<int> moved = std::move(exception_or_vector).result();
|
||||
ASSERT_FALSE(moved.empty());
|
||||
}
|
||||
|
||||
TEST(ExceptionOr, Result_Move_Const) {
|
||||
const ExceptionOr<std::vector<int>> exception_or_vector({1, 2, 3});
|
||||
ASSERT_FALSE(exception_or_vector.result().empty());
|
||||
|
||||
// Moving const rvalue reference will result in a copy.
|
||||
std::vector<int> moved = std::move(exception_or_vector).result();
|
||||
ASSERT_FALSE(moved.empty());
|
||||
}
|
||||
|
||||
} // namespace location::nearby
|
||||
@@ -1,8 +1,6 @@
|
||||
cc_library(
|
||||
name = "default",
|
||||
srcs = [
|
||||
"default_condition_variable.cc",
|
||||
"default_lock.cc",
|
||||
"default_platform.cc",
|
||||
],
|
||||
hdrs = [
|
||||
@@ -15,6 +13,8 @@ cc_library(
|
||||
"//core:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":condition_variable",
|
||||
":lock",
|
||||
"//platform:types",
|
||||
"//platform/api",
|
||||
],
|
||||
@@ -38,7 +38,7 @@ cc_library(
|
||||
"//platform:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":default",
|
||||
":lock",
|
||||
"//platform:types",
|
||||
"//platform/api:condition_variable",
|
||||
],
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#include "platform/ptr.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
namespace ptr_impl {
|
||||
|
||||
const std::int32_t RefCount::kInitialCount = 0;
|
||||
|
||||
} // namespace ptr_impl
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
+64
-194
@@ -4,78 +4,15 @@
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include "platform/impl/default/default_lock.h"
|
||||
#include "platform/logging.h"
|
||||
#include "platform/port/down_cast.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
namespace ptr_impl {
|
||||
|
||||
class RefCount {
|
||||
public:
|
||||
RefCount() : lock_(), count_(kInitialCount) {}
|
||||
|
||||
// Returns false if this operation doesn't make conceptual sense any more
|
||||
// (for example, if it leads to bringing count_ back from the dead).
|
||||
bool increment() {
|
||||
bool result;
|
||||
|
||||
lock_.lock();
|
||||
{
|
||||
// Avoid coming back from the dead.
|
||||
if (count_ < kInitialCount) {
|
||||
result = false;
|
||||
} else {
|
||||
count_++;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
lock_.unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns true if after this operation, count_ is 0.
|
||||
bool decrement() {
|
||||
bool result;
|
||||
|
||||
lock_.lock();
|
||||
{
|
||||
// It's alright for count_ to go negative because it will only be exactly
|
||||
// 0 once (since increment() makes sure that once you go negative, you
|
||||
// can't come back from the dead).
|
||||
count_--;
|
||||
result = (count_ == 0);
|
||||
}
|
||||
lock_.unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static const std::int32_t kInitialCount;
|
||||
|
||||
DefaultLock lock_;
|
||||
std::int32_t count_;
|
||||
};
|
||||
|
||||
} // namespace ptr_impl
|
||||
|
||||
template <typename T>
|
||||
class ObjectDestroyer {
|
||||
public:
|
||||
static void destroy(T* t) { delete t; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ArrayDestroyer {
|
||||
public:
|
||||
static void destroy(T* t) { delete[] t; }
|
||||
};
|
||||
|
||||
// Forward declarations to make it possible for Ptr (a class template) to
|
||||
// declare ConstifyPtr, DowncastPtr, and DowncastConstPtr (function templates)
|
||||
// as friends.
|
||||
@@ -85,7 +22,7 @@ class ArrayDestroyer {
|
||||
// Ptr (which is what one might reasonably expect).
|
||||
//
|
||||
// See https://isocpp.org/wiki/faq/templates#template-friends for more.
|
||||
template <typename T, template <typename> class Destroyer = ObjectDestroyer>
|
||||
template <typename T>
|
||||
class Ptr;
|
||||
template <typename T>
|
||||
class ConstPtr;
|
||||
@@ -96,128 +33,74 @@ Ptr<ChildT> DowncastPtr(Ptr<BaseT> base_ptr);
|
||||
template <typename ChildT, typename BaseT>
|
||||
ConstPtr<ChildT> DowncastConstPtr(ConstPtr<BaseT> base_ptr);
|
||||
|
||||
// A layer of indirection over a raw pointer, to buy flexibility in the
|
||||
// future to use, for instance:
|
||||
//
|
||||
// a) the in-built shared_ptr in modern implementations of C++,
|
||||
// b) a custom reference-counting mechanism, etc.
|
||||
//
|
||||
// , all without having to touch every line of our codebase that uses
|
||||
// pointers.
|
||||
//
|
||||
// Destroyer defines how the owned pointee should be destroyed, and is
|
||||
// expected to be a class template that provides at least a destroy()
|
||||
// method, like so:
|
||||
//
|
||||
// template <typename T>
|
||||
// class MyDestroyer {
|
||||
// public:
|
||||
// static void destroy(T* t);
|
||||
// };
|
||||
//
|
||||
// It defaults to ObjectDestroyer<T>.
|
||||
template <typename T, template <typename> class Destroyer>
|
||||
// A layer of indirection over a raw pointer.
|
||||
// It is being deprecated in favor of standard c++ smart pointers.
|
||||
// For transion period, Ptr<T> will behave similar to shared_ptr<T>.
|
||||
// New code should use shrared_ptr<T> or unique_ptr<T> and not Ptr<T>.
|
||||
template <typename T>
|
||||
class Ptr {
|
||||
public:
|
||||
// Provide an alias for use as a dependent name.
|
||||
typedef T PointeeType;
|
||||
|
||||
Ptr() : pointee_(nullptr), ref_count_(nullptr) {}
|
||||
explicit Ptr(T* pointee, bool is_ref_counted = false,
|
||||
ptr_impl::RefCount* ref_count = nullptr)
|
||||
: pointee_(pointee),
|
||||
ref_count_(
|
||||
is_ref_counted
|
||||
? (ref_count != nullptr ? ref_count : new ptr_impl::RefCount())
|
||||
: nullptr) {
|
||||
init();
|
||||
}
|
||||
Ptr(const Ptr& that) : pointee_(that.pointee_), ref_count_(that.ref_count_) {
|
||||
init();
|
||||
}
|
||||
Ptr() = default;
|
||||
explicit Ptr(T* pointee) : ptr_(pointee) {}
|
||||
Ptr(const Ptr& that) = default;
|
||||
|
||||
Ptr& operator=(const Ptr& other) {
|
||||
if (pointee_ != other.pointee_) {
|
||||
// If we're not currently ref-counted, then an assignment shouldn't lead
|
||||
// to any destruction of our past state -- that's the responsibility of
|
||||
// whichever instance of Ptr believes it owns pointee_.
|
||||
destroy(false);
|
||||
Ptr(std::shared_ptr<T> ptr) : ptr_(ptr) {} // NOLINT
|
||||
|
||||
pointee_ = other.pointee_;
|
||||
ref_count_ = other.ref_count_;
|
||||
|
||||
init();
|
||||
}
|
||||
template <typename T2>
|
||||
Ptr<T>& operator=(T2* ptr) {
|
||||
Ptr<T> tmp(ptr);
|
||||
this->ptr_.swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ptr& operator=(const Ptr& other) = default;
|
||||
|
||||
// Conversion to Ptr<T2>, where T is trivially convertible to T2. E.g.
|
||||
// conversion from derived to base class.
|
||||
template <typename T2>
|
||||
operator Ptr<T2>() {
|
||||
return Ptr<T2>(pointee_, isRefCounted(), ref_count_);
|
||||
operator Ptr<T2>() { // NOLINT
|
||||
return Ptr<T2>(std::static_pointer_cast<T2>(this->ptr_));
|
||||
}
|
||||
operator Ptr() { // NOLINT
|
||||
return Ptr(*this);
|
||||
}
|
||||
|
||||
~Ptr() {
|
||||
if (isRefCounted()) {
|
||||
destroy();
|
||||
} else {
|
||||
// Left empty on purpose.
|
||||
}
|
||||
}
|
||||
explicit operator std::shared_ptr<T>() { return this->ptr_; }
|
||||
|
||||
~Ptr() = default;
|
||||
|
||||
bool operator==(const Ptr& other) const {
|
||||
assert(!(this->isNull()));
|
||||
assert(!(other.isNull()));
|
||||
|
||||
return ((*(this->pointee_) == *(other.pointee_)) &&
|
||||
(this->isRefCounted() == other.isRefCounted()));
|
||||
return *(this->ptr_) == *(other.ptr_);
|
||||
}
|
||||
|
||||
bool operator!=(const Ptr& other) const { return !(*this == other); }
|
||||
|
||||
bool operator<(const Ptr& other) const {
|
||||
assert(!(this->isNull()));
|
||||
assert(!(other.isNull()));
|
||||
|
||||
return *(this->pointee_) < *(other.pointee_);
|
||||
return *(this->ptr_) < *(other.ptr_);
|
||||
}
|
||||
|
||||
// Calls Destroyer::destroy() to perform deallocation of pointee_.
|
||||
void destroy(bool should_destroy_if_not_ref_counted = true) {
|
||||
bool need_to_destroy = isRefCounted() ? ref_count_->decrement()
|
||||
: should_destroy_if_not_ref_counted;
|
||||
if (need_to_destroy) {
|
||||
delete ref_count_;
|
||||
Destroyer<T>::destroy(pointee_);
|
||||
}
|
||||
// No-op: refcounted objects will be destroyed correctly
|
||||
ABSL_DEPRECATED("Use c++ smart pointers directly instead of Ptr<T>")
|
||||
void destroy(bool = true) {}
|
||||
|
||||
ref_count_ = NULL; // NOLINT
|
||||
pointee_ = NULL; // NOLINT
|
||||
}
|
||||
// No-op: refcounted objects will be destroyed correctly
|
||||
ABSL_DEPRECATED("Use c++ smart pointers directly instead of Ptr<T>")
|
||||
void clear() {}
|
||||
|
||||
// Use this function only when the ownership is held by someone else, and this
|
||||
// Ptr object has no responsibility to destroy it.
|
||||
void clear() {
|
||||
if (isRefCounted()) {
|
||||
NEARBY_LOG(FATAL, "Attempting to invoke clear() on a RefCounted Ptr.");
|
||||
}
|
||||
T& operator*() const { return *ptr_; }
|
||||
|
||||
pointee_ = NULL; // NOLINT
|
||||
}
|
||||
T* operator->() const { return ptr_.get(); }
|
||||
T* get() { return ptr_.get(); }
|
||||
void reset() { return ptr_.reset(); }
|
||||
|
||||
T& operator*() const {
|
||||
assert(pointee_ != NULL); // NOLINT
|
||||
return *pointee_;
|
||||
}
|
||||
ABSL_DEPRECATED("Use c++ smart pointers directly instead of Ptr<T>")
|
||||
bool isNull() const { return !this->ptr_; }
|
||||
|
||||
T* operator->() const {
|
||||
assert(pointee_ != NULL); // NOLINT
|
||||
return pointee_;
|
||||
}
|
||||
|
||||
bool isNull() const { return pointee_ == nullptr; }
|
||||
bool isRefCounted() const { return ref_count_ != nullptr; }
|
||||
// used by pipe.cc; introduced by cr/295271652
|
||||
ABSL_DEPRECATED("Use c++ smart pointers directly instead of Ptr<T>")
|
||||
bool isRefCounted() const { return true; }
|
||||
|
||||
private:
|
||||
template <typename PointeeT>
|
||||
@@ -227,16 +110,7 @@ class Ptr {
|
||||
template <typename ChildT, typename BaseT>
|
||||
friend ConstPtr<ChildT> DowncastConstPtr(ConstPtr<BaseT> base_ptr);
|
||||
|
||||
void init() {
|
||||
if (isRefCounted()) {
|
||||
if (!ref_count_->increment()) {
|
||||
NEARBY_LOG(FATAL, "Failed to increment RefCount.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
T* pointee_;
|
||||
ptr_impl::RefCount* ref_count_;
|
||||
std::shared_ptr<T> ptr_;
|
||||
};
|
||||
|
||||
// Convenience wrapper for a read-only version of Ptr (in which the pointee
|
||||
@@ -259,9 +133,9 @@ template <typename T>
|
||||
class ConstPtr : public Ptr<T const> {
|
||||
public:
|
||||
ConstPtr() {}
|
||||
explicit ConstPtr(T* pointee, bool is_ref_counted = false,
|
||||
ptr_impl::RefCount* ref_count = nullptr)
|
||||
: Ptr<T const>(pointee, is_ref_counted, ref_count) {}
|
||||
explicit ConstPtr(const T* pointee) : Ptr<T const>(pointee) {}
|
||||
explicit ConstPtr(T* pointee) : Ptr<T const>(pointee) {}
|
||||
explicit ConstPtr(Ptr<T> ptr) : Ptr<T const>(ptr) {}
|
||||
};
|
||||
|
||||
// RAII wrapper over Ptr and ConstPtr (hereon referred to by the PtrType
|
||||
@@ -291,33 +165,29 @@ class ScopedPtr {
|
||||
public:
|
||||
explicit ScopedPtr(typename PtrType::PointeeType* pointee) : ptr_(pointee) {}
|
||||
explicit ScopedPtr(PtrType ptr) : ptr_(ptr) {}
|
||||
~ScopedPtr() { ptr_.destroy(); }
|
||||
ScopedPtr(const ScopedPtr&) = delete;
|
||||
~ScopedPtr() = default;
|
||||
|
||||
ScopedPtr& operator=(const ScopedPtr&) = delete;
|
||||
|
||||
// Shadow methods for the underlying Ptr.
|
||||
typename PtrType::PointeeType& operator*() const { return ptr_.operator*(); }
|
||||
typename PtrType::PointeeType& operator*() const { return *ptr_; }
|
||||
typename PtrType::PointeeType* operator->() const {
|
||||
return ptr_.operator->();
|
||||
}
|
||||
bool isNull() const { return ptr_.isNull(); }
|
||||
|
||||
// Accessor for the underlying Ptr.
|
||||
PtrType get() const { return ptr_; }
|
||||
PtrType get() const { return this->ptr_; }
|
||||
|
||||
// Releases the underlying Ptr from the clutches of this ScopedPtr,
|
||||
// effectively resetting this ScopedPtr (and making its destructor be a no-op)
|
||||
// -- useful for transfer of ownership from one ScopedPtr to another across
|
||||
// scopes.
|
||||
// Does nothing;
|
||||
// this is to avoid unintended destruction of a managed pointer.
|
||||
// TODO(b/149938110): remove this completely.
|
||||
PtrType release() {
|
||||
PtrType released = ptr_;
|
||||
ptr_ = PtrType();
|
||||
return released;
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copy and assignment.
|
||||
ScopedPtr(const ScopedPtr&);
|
||||
ScopedPtr& operator=(const ScopedPtr&);
|
||||
|
||||
PtrType ptr_;
|
||||
};
|
||||
|
||||
@@ -358,19 +228,19 @@ ConstPtr<T> MakeConstPtr(T* raw_ptr) {
|
||||
// reference).
|
||||
template <typename T>
|
||||
Ptr<T> MakeRefCountedPtr(T* raw_ptr) {
|
||||
return Ptr<T>(raw_ptr, true);
|
||||
return Ptr<T>(raw_ptr);
|
||||
}
|
||||
|
||||
// ConstPtr counterpart to MakeRefCountedPtr().
|
||||
template <typename T>
|
||||
ConstPtr<T> MakeRefCountedConstPtr(T* raw_ptr) {
|
||||
return ConstPtr<T>(raw_ptr, true);
|
||||
return ConstPtr<T>(raw_ptr);
|
||||
}
|
||||
|
||||
// Use this function to convert a Ptr object to a ConstPtr object.
|
||||
template <typename T>
|
||||
ConstPtr<T> ConstifyPtr(Ptr<T> ptr) {
|
||||
return ConstPtr<T>(ptr.pointee_, ptr.isRefCounted(), ptr.ref_count_);
|
||||
return ConstPtr<T>(ptr);
|
||||
}
|
||||
|
||||
// Use this function to downcast from a Ptr<BaseT> to a Ptr<ChildT>.
|
||||
@@ -382,16 +252,16 @@ ConstPtr<T> ConstifyPtr(Ptr<T> ptr) {
|
||||
// Ptr<MyChild> my_child_ptr = DowncastPtr<MyChild>(my_base_ptr);
|
||||
template <typename ChildT, typename BaseT>
|
||||
Ptr<ChildT> DowncastPtr(Ptr<BaseT> base_ptr) {
|
||||
return Ptr<ChildT>(DOWN_CAST<ChildT*>(base_ptr.pointee_),
|
||||
base_ptr.isRefCounted(), base_ptr.ref_count_);
|
||||
static_assert(std::is_base_of_v<BaseT, ChildT>);
|
||||
return Ptr<ChildT>(std::static_pointer_cast<ChildT>(base_ptr.ptr_));
|
||||
}
|
||||
|
||||
// ConstPtr counterpart to DowncastPtr().
|
||||
template <typename ChildT, typename BaseT>
|
||||
ConstPtr<ChildT> DowncastConstPtr(ConstPtr<BaseT> base_ptr) {
|
||||
static_assert(std::is_base_of_v<BaseT, ChildT>);
|
||||
return ConstPtr<ChildT>(
|
||||
const_cast<ChildT*>(DOWN_CAST<const ChildT*>(base_ptr.pointee_)),
|
||||
base_ptr.isRefCounted(), base_ptr.ref_count_);
|
||||
std::static_pointer_cast<const ChildT>(base_ptr.ptr_));
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
+19
-128
@@ -22,15 +22,6 @@ TEST(PtrTest, RefCountedPtr_MultipleReferences) {
|
||||
SUCCEED();
|
||||
}
|
||||
|
||||
TEST(PtrTest, RefCountedPtr_IsRefCounted_Works) {
|
||||
Ptr<int> ref_counted = MakeRefCountedPtr(new int(1234));
|
||||
Ptr<int> manually_counted = MakePtr(new int(1234));
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted(manually_counted);
|
||||
|
||||
ASSERT_TRUE(ref_counted.isRefCounted());
|
||||
ASSERT_FALSE(manually_counted.isRefCounted());
|
||||
}
|
||||
|
||||
TEST(PtrTest, RefCountedPtr_MultipleReferencesWithScoped) {
|
||||
Ptr<int> ref_counted = MakeRefCountedPtr(new int(1234));
|
||||
ScopedPtr<Ptr<int> > scoped_ref_counted_1(ref_counted);
|
||||
@@ -51,60 +42,6 @@ TEST(PtrTest, AssignmentOperator_RefCountedToRefCounted) {
|
||||
ASSERT_EQ(1234, *ref_counted_2);
|
||||
}
|
||||
|
||||
TEST(PtrTest, AssignmentOperator_ManuallyCountedToManuallyCounted) {
|
||||
Ptr<int> manually_counted_1 = MakePtr(new int(1234));
|
||||
Ptr<int> manually_counted_2 = MakePtr(new int(5678));
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted_1(manually_counted_1);
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted_2(manually_counted_2);
|
||||
|
||||
manually_counted_2 = manually_counted_1;
|
||||
|
||||
ASSERT_EQ(1234, *manually_counted_1);
|
||||
ASSERT_EQ(1234, *manually_counted_2);
|
||||
ASSERT_EQ(1234, *scoped_manually_counted_1);
|
||||
ASSERT_EQ(5678, *scoped_manually_counted_2);
|
||||
}
|
||||
|
||||
TEST(PtrTest, AssignmentOperator_RefCountedToManuallyCounted) {
|
||||
Ptr<int> ref_counted = MakeRefCountedPtr(new int(1234));
|
||||
Ptr<int> manually_counted = MakePtr(new int(5678));
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted(manually_counted);
|
||||
|
||||
manually_counted = ref_counted;
|
||||
|
||||
ASSERT_EQ(1234, *ref_counted);
|
||||
ASSERT_EQ(1234, *manually_counted);
|
||||
ASSERT_EQ(5678, *scoped_manually_counted);
|
||||
}
|
||||
|
||||
TEST(PtrTest, AssignmentOperator_ManuallyCountedToRefCounted) {
|
||||
Ptr<int> manually_counted = MakePtr(new int(1234));
|
||||
Ptr<int> ref_counted = MakeRefCountedPtr(new int(5678));
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted(manually_counted);
|
||||
|
||||
ref_counted = manually_counted;
|
||||
|
||||
ASSERT_EQ(1234, *ref_counted);
|
||||
ASSERT_EQ(1234, *manually_counted);
|
||||
ASSERT_EQ(1234, *scoped_manually_counted);
|
||||
}
|
||||
|
||||
TEST(PtrTest, AssignmentOperator_SelfAssignment_ManuallyCounted) {
|
||||
Ptr<int> manually_counted_1 = MakePtr(new int(1234));
|
||||
Ptr<int> manually_counted_2(manually_counted_1);
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted_1(manually_counted_1);
|
||||
|
||||
manually_counted_1 = manually_counted_2;
|
||||
|
||||
ASSERT_EQ(1234, *manually_counted_1);
|
||||
ASSERT_EQ(1234, *manually_counted_2);
|
||||
ASSERT_EQ(1234, *scoped_manually_counted_1);
|
||||
}
|
||||
|
||||
TEST(PtrTest, AssignmentOperator_SelfAssignment_RefCounted) {
|
||||
Ptr<int> ref_counted_1 = MakeRefCountedPtr(new int(1234));
|
||||
Ptr<int> ref_counted_2(ref_counted_1);
|
||||
@@ -115,19 +52,6 @@ TEST(PtrTest, AssignmentOperator_SelfAssignment_RefCounted) {
|
||||
ASSERT_EQ(1234, *ref_counted_2);
|
||||
}
|
||||
|
||||
TEST(PtrTest, EqualityOperator_ManuallyCounted) {
|
||||
Ptr<int> manually_counted_1 = MakePtr(new int(1234));
|
||||
Ptr<int> manually_counted_2(manually_counted_1);
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted_1(manually_counted_1);
|
||||
|
||||
ASSERT_TRUE(manually_counted_1 == manually_counted_2);
|
||||
|
||||
manually_counted_1 = manually_counted_2;
|
||||
|
||||
ASSERT_TRUE(manually_counted_1 == manually_counted_2);
|
||||
}
|
||||
|
||||
TEST(PtrTest, EqualityOperator_RefCounted) {
|
||||
Ptr<int> ref_counted_1 = MakeRefCountedPtr(new int(1234));
|
||||
Ptr<int> ref_counted_2(ref_counted_1);
|
||||
@@ -139,16 +63,6 @@ TEST(PtrTest, EqualityOperator_RefCounted) {
|
||||
ASSERT_TRUE(ref_counted_1 == ref_counted_2);
|
||||
}
|
||||
|
||||
TEST(PtrTest, EqualityOperator_ManuallyAndRefCounted) {
|
||||
int* raw = new int(1234);
|
||||
Ptr<int> manually_counted = MakePtr(raw);
|
||||
Ptr<int> ref_counted = MakeRefCountedPtr(raw);
|
||||
// No need for a ScopedPtr for manually_counted here because we know that
|
||||
// ref_counted will take care of deallocating 'raw'.
|
||||
|
||||
ASSERT_FALSE(manually_counted == ref_counted);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class Base {
|
||||
@@ -171,17 +85,6 @@ class Derived : public Base {
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(PtrTest, DerivedToBaseConversion_ManuallyCounted) {
|
||||
Ptr<Derived> derived = MakePtr(new Derived(1234));
|
||||
Ptr<Base> base = derived;
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<Derived> > scoped_derived(derived);
|
||||
|
||||
ASSERT_EQ(1234, base->getInt());
|
||||
ASSERT_EQ(1234, derived->getInt());
|
||||
ASSERT_EQ(1234, scoped_derived->getInt());
|
||||
}
|
||||
|
||||
TEST(PtrTest, DerivedToBaseConversion_RefCounted) {
|
||||
Ptr<Derived> derived = MakeRefCountedPtr(new Derived(1234));
|
||||
Ptr<Base> base = derived;
|
||||
@@ -193,17 +96,18 @@ TEST(PtrTest, DerivedToBaseConversion_RefCounted) {
|
||||
ASSERT_EQ(1234, base->getInt());
|
||||
}
|
||||
|
||||
TEST(PtrTest, ScopedPtr_Release_ManuallyCounted) {
|
||||
Ptr<int> manually_counted_1 = MakePtr(new int(1234));
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted_1(manually_counted_1);
|
||||
TEST(PtrTest, DistinctValuesAreNotEqual) {
|
||||
Ptr<int> value1 = MakePtr(new int(5));
|
||||
Ptr<int> value2 = MakePtr(new int(6));
|
||||
|
||||
Ptr<int> manually_counted_2 = scoped_manually_counted_1.release();
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted_2(manually_counted_2);
|
||||
ASSERT_NE(value1, value2);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(scoped_manually_counted_1.isNull());
|
||||
ASSERT_EQ(1234, *manually_counted_2);
|
||||
ASSERT_EQ(1234, *scoped_manually_counted_2);
|
||||
TEST(PtrTest, SameValuesAreEqual) {
|
||||
Ptr<int> value1 = MakePtr(new int(5));
|
||||
Ptr<int> value2 = MakePtr(new int(5));
|
||||
|
||||
ASSERT_EQ(value1, value2);
|
||||
}
|
||||
|
||||
TEST(PtrTest, ScopedPtr_Release_RefCounted) {
|
||||
@@ -212,20 +116,20 @@ TEST(PtrTest, ScopedPtr_Release_RefCounted) {
|
||||
|
||||
Ptr<int> ref_counted_2 = scoped_ref_counted_1.release();
|
||||
|
||||
ASSERT_TRUE(scoped_ref_counted_1.isNull());
|
||||
ASSERT_EQ(*scoped_ref_counted_1, *ref_counted_2);
|
||||
ASSERT_EQ(1234, *ref_counted_2);
|
||||
}
|
||||
|
||||
TEST(PtrTest, ConstifyPtr_ManuallyCounted) {
|
||||
Ptr<int> manually_counted = MakePtr(new int(1234));
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<int> > scoped_manually_counted(manually_counted);
|
||||
TEST(PtrTest, ScopedPtr_Release_RefCounted_Stay_Valid) {
|
||||
Ptr<int> ref_counted_1 = MakeRefCountedPtr(new int(1234));
|
||||
Ptr<int> ref_counted_2 = ref_counted_1;
|
||||
ScopedPtr<Ptr<int> > scoped_ref_counted_1(ref_counted_1);
|
||||
|
||||
ConstPtr<int> const_manually_counted = ConstifyPtr(manually_counted);
|
||||
Ptr<int> ref_counted_3 = scoped_ref_counted_1.release();
|
||||
|
||||
ASSERT_EQ(1234, *const_manually_counted);
|
||||
ASSERT_EQ(1234, *manually_counted);
|
||||
ASSERT_EQ(1234, *scoped_manually_counted);
|
||||
ASSERT_EQ(*scoped_ref_counted_1, *ref_counted_3);
|
||||
ASSERT_EQ(1234, *ref_counted_2);
|
||||
ASSERT_EQ(1234, *ref_counted_3);
|
||||
}
|
||||
|
||||
TEST(PtrTest, ConstifyPtr_RefCounted) {
|
||||
@@ -240,19 +144,6 @@ TEST(PtrTest, ConstifyPtr_RefCounted) {
|
||||
ASSERT_EQ(1234, *const_ref_counted);
|
||||
}
|
||||
|
||||
TEST(PtrTest, DowncastPtr_ManuallyCounted) {
|
||||
Ptr<Derived> derived = MakePtr(new Derived(1234));
|
||||
Ptr<Base> base = derived;
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<Derived> > scoped_derived(derived);
|
||||
|
||||
Ptr<Derived> derived_from_downcast = DowncastPtr<Derived>(base);
|
||||
|
||||
ASSERT_EQ(1234, base->getInt());
|
||||
ASSERT_EQ(1234, derived->getInt());
|
||||
ASSERT_EQ(1234, derived_from_downcast->getInt());
|
||||
}
|
||||
|
||||
TEST(PtrTest, DowncastPtr_RefCounted) {
|
||||
Ptr<Derived> derived = MakeRefCountedPtr(new Derived(1234));
|
||||
Ptr<Base> base = derived;
|
||||
|
||||
Reference in New Issue
Block a user