Initial impl for PresenceClient

PiperOrigin-RevId: 437370707
This commit is contained in:
hais
2022-03-25 17:37:25 -07:00
committed by Copybara-Service
parent c9bb09ce6e
commit c1e898bcf1
14 changed files with 642 additions and 3 deletions
+1
View File
@@ -53,6 +53,7 @@ cc_library(
"//internal/proto/analytics:__subpackages__",
"//location/nearby/cpp/sharing:__subpackages__",
"//third_party/nearby/cpp/cal:__subpackages__",
"//third_party/nearby/presence:__subpackages__",
],
deps = [
"@com_google_absl//absl/container:flat_hash_map",
+41
View File
@@ -13,27 +13,51 @@
# limitations under the License.
licenses(["notice"])
cc_library(
name = "presence",
srcs = [
"presence_client.cc",
],
hdrs = [
"presence_client.h",
],
visibility = [
"//third_party/nearby:__subpackages__",
],
deps = [
":types",
],
)
cc_library(
name = "types",
srcs = [
"device_motion.cc",
"discovery_filter.cc",
"presence_action.cc",
"presence_client.cc",
"presence_device.cc",
"presence_identity.cc",
"presence_zone.cc",
],
hdrs = [
"broadcast_options.h",
"device_motion.h",
"discovery_filter.h",
"discovery_options.h",
"listeners.h",
"presence_action.h",
"presence_client.h",
"presence_device.h",
"presence_identity.h",
"presence_zone.h",
"status.h",
],
visibility = [
"//third_party/nearby/presence:__subpackages__",
],
deps = [
"//internal/platform:base",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:variant",
"@com_google_glog//:glog",
@@ -44,12 +68,15 @@ cc_test(
name = "types_test",
size = "small",
srcs = [
"broadcast_options_test.cc",
"device_motion_test.cc",
"discovery_filter_test.cc",
"discovery_options_test.cc",
"presence_action_test.cc",
"presence_device_test.cc",
"presence_identity_test.cc",
"presence_zone_test.cc",
"status_test.cc",
],
shard_count = 6,
deps = [
@@ -58,3 +85,17 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "presence_test",
size = "small",
srcs = [
"presence_client_test.cc",
],
shard_count = 6,
deps = [
":presence",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_googletest//:gtest_main",
],
)
+36
View File
@@ -0,0 +1,36 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_OPTIONS_H_
#define THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_OPTIONS_H_
#include <cstdint>
namespace nearby {
namespace presence {
struct BroadcastOptions {
const std::int64_t reporting_interval_millis;
};
inline bool operator==(const BroadcastOptions& o1, const BroadcastOptions& o2) {
return o1.reporting_interval_millis == o2.reporting_interval_millis;
}
inline bool operator!=(const BroadcastOptions& o1, const BroadcastOptions& o2) {
return !(o1 == o2);
}
} // namespace presence
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_OPTIONS_H_
+53
View File
@@ -0,0 +1,53 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "third_party/nearby/presence/broadcast_options.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
namespace nearby {
namespace presence {
namespace {
constexpr std::int64_t kReportingIntervalMillis1 = 1000;
constexpr std::int64_t kReportingIntervalMillis2 = 2000;
TEST(BroadcastOptionsTest, NoDefaultConstructor) {
EXPECT_FALSE(std::is_trivially_constructible<BroadcastOptions>::value);
}
TEST(BroadcastOptionsTest, ExplicitInitEquals) {
BroadcastOptions option1 = {kReportingIntervalMillis1};
BroadcastOptions option2 = {kReportingIntervalMillis1};
EXPECT_EQ(option1, option2);
EXPECT_EQ(option1.reporting_interval_millis, kReportingIntervalMillis1);
}
TEST(BroadcastOptionsTest, ExplicitInitNotEquals) {
BroadcastOptions option1 = {kReportingIntervalMillis1};
BroadcastOptions option2 = {kReportingIntervalMillis2};
EXPECT_NE(option1, option2);
}
TEST(BroadcastOptionsTest, CopyInitEquals) {
BroadcastOptions option1 = {kReportingIntervalMillis1};
BroadcastOptions option2 = {option1};
EXPECT_EQ(option1, option2);
}
} // namespace
} // namespace presence
} // namespace nearby
+37
View File
@@ -0,0 +1,37 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_PRESENCE_LISTENERS_H_
#define THIRD_PARTY_NEARBY_PRESENCE_LISTENERS_H_
#include "internal/platform/listeners.h"
#include "third_party/nearby/presence/status.h"
namespace nearby {
namespace presence {
// Common callback for asynchronously invoked methods.
// Called after a job scheduled for execution is completed.
struct ResultCallback {
// Callback to access the status of the operation when available.
// status - result of job execution;
// Status::kSuccess, if successful; anything else indicates failure.
std::function<void(Status)> result_cb =
location::nearby::DefaultCallback<Status>();
};
} // namespace presence
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_PRESENCE_LISTENERS_H_
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "third_party/nearby/presence/presence_client.h"
#include "third_party/nearby/presence/presence_device.h"
namespace nearby {
namespace presence {
void PresenceClient::StartDiscovery(const DiscoveryFilter& filter,
const DiscoveryOptions& options,
ResultCallback callback) {}
void PresenceClient::UpdateDiscoveryFilter(const DiscoveryFilter& filter,
ResultCallback callback) {}
void PresenceClient::StopDiscovery(ResultCallback callback) {}
std::vector<PresenceDevice> PresenceClient::GetCachedDevices(
const DiscoveryFilter& filter) {
return std::vector<PresenceDevice>{};
}
void PresenceClient::StartBroadcast(const PresenceIdentity& identity,
const std::vector<PresenceAction>& actions,
const BroadcastOptions& options,
ResultCallback callback) {}
void PresenceClient::UpdateBroadcastActions(
const PresenceIdentity& identity,
const std::vector<PresenceAction>& actions, ResultCallback callback) {}
void PresenceClient::StopBroadcast(const PresenceIdentity& identity,
ResultCallback callback) {}
} // namespace presence
} // namespace nearby
+149
View File
@@ -0,0 +1,149 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_H_
#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_H_
#include <vector>
#include "third_party/nearby/presence/broadcast_options.h"
#include "third_party/nearby/presence/discovery_filter.h"
#include "third_party/nearby/presence/discovery_options.h"
#include "third_party/nearby/presence/listeners.h"
#include "third_party/nearby/presence/presence_device.h"
namespace nearby {
namespace presence {
/**
* Interface for detecting and interacting with nearby devices that are also
* part of the Presence ecosystem.
*/
class PresenceClient {
public:
/**
* Discovery APIs.
*/
/**
* Starts a Nearby Presence discovery and registers {@link ResultCallback}
* which will be invoked when a matching {@link PresenceDevice} is detected
* by the service.
*
* <p>The {@link ResultCallback} is registered at the Nearby Presence service.
* And a same callback can only be registered once.
*
* <p>The returned {@link Task} may contain the value {@link
* PresenceStatusCodes#RESOLUTION_REQUIRED}. If that is the case, client
* should call {@link Status#startResolutionForResult} to get the users
* consents/permissions before retrying the request.
*/
void StartDiscovery(const DiscoveryFilter& filter,
const DiscoveryOptions& options, ResultCallback callback);
/**
* Update the discovery filter for an ongoing discovery.
*
* <p>The returned {@link Task} may contain the value
* {@link PresenceStatusCodes#RESOLUTION_REQUIRED}. If that is the case,
* client should call {@link Status#startResolutionForResult} to get the users
* consents/permissions before retrying the request.
*/
void UpdateDiscoveryFilter(const DiscoveryFilter& filter,
ResultCallback callback);
/**
* Stops a Nearby Presence discovery and unregisters a {@link
* DiscoveryCallback} which was previously registered with {@link
* #startDiscovery}.
*
* <p>If the callback wasn't previously registered, then this will be silently
* ignored. Presence stops discovery, if no client is requesting discovery.
*/
void StopDiscovery(ResultCallback callback);
/**
* Gets all devices which Presence has recently detected to be within range
* and matching a given {@link DiscoveryFilter}.
*
* <p>There may be devices within proximity which are not returned as part of
* this method because they haven't yet been discovered by Presence's
* scanning. Apps can call this method multiple times to get the most
* up-to-date information about what is around, however calling it does not
* initiate any scans to find more devices, scanning is handled out-of-band
* from this API.
*
* <p>Alternatively, clients can use {@link #startDiscovery} to be notified
* when a device is discovered nearby, if the client would like to retrieve
* live devices and their ranging data.
*/
std::vector<PresenceDevice> GetCachedDevices(const DiscoveryFilter& filter);
/**
* Advertising APIs.
*/
/**
* Requests that an {@link PresenceIdentity} and associated {@link
* PresenceAction}s be broadcast to other devices nearby.
*
* <p>These actions can then be detected by those devices and trigger a
* callback to a client which as invoked {@link #startDiscovery} for the same
* action.
*
* <p>Clients set a {@link PresenceIdentity} to determine who should be able
* to resolve their advertisements.
*
* <p>One client can advertise up to one advertisement per identity. Due to
* hardware capabilities, Presence needs to rotate advertisement or release
* resources. Frequent callers might be throttled based on resource
* limitations.
*
* <p>The returned {@link Task} may contain the value {@link
* PresenceStatusCodes#RESOLUTION_REQUIRED}. If that is the case, client
* should call {@linkStatus#startResolutionForResult} to get the users
* consents/permissions before retrying the request.
*/
void StartBroadcast(const PresenceIdentity& identity,
const std::vector<PresenceAction>& actions,
const BroadcastOptions& options, ResultCallback callback);
/**
* Updates {@link PresenceAction}s of an ongoing advertising for a
* {@link PresenceIdentity}.
*
* <p>The returned {@link Task} may contain the value {@link
* PresenceStatusCodes#RESOLUTION_REQUIRED}. If that is the case, client
* should call {@link Status#startResolutionForResult} to get the users
* consents/permissions before retrying the request.
*/
void UpdateBroadcastActions(const PresenceIdentity& identity,
const std::vector<PresenceAction>& actions,
ResultCallback callback);
/**
* Removes an identity broadcast that was currently requested via
* {@link #startBroadcast}.
*
* <p>This should be invoked after the use case has been fulfilled and the
* device no longer needs remote devices to know that it is nearby.
*/
void StopBroadcast(const PresenceIdentity& identity, ResultCallback callback);
};
} // namespace presence
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_H_
+32
View File
@@ -0,0 +1,32 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "third_party/nearby/presence/presence_client.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
namespace nearby {
namespace presence {
namespace {
TEST(PresenceClientTest, DefaultConstructorWorks) {
PresenceClient presence_client;
presence_client.StartBroadcast({}, {}, {}, {});
}
} // namespace
} // namespace presence
} // namespace nearby
+31
View File
@@ -0,0 +1,31 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "third_party/nearby/presence/presence_device.h"
namespace nearby {
namespace presence {
PresenceDevice::PresenceDevice(PresenceDevice::MotionType type,
float confidence) noexcept
: motion_type_(type), confidence_(confidence) {}
PresenceDevice::MotionType PresenceDevice::GetMotionType() const {
return motion_type_;
}
float PresenceDevice::GetConfidence() const { return confidence_; }
} // namespace presence
} // namespace nearby
+47
View File
@@ -0,0 +1,47 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_
#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_
namespace nearby {
namespace presence {
class PresenceDevice {
public:
enum class MotionType {
kPointAndHold = 0,
};
PresenceDevice(MotionType type = MotionType::kPointAndHold,
float confidence = 0) noexcept;
MotionType GetMotionType() const;
float GetConfidence() const;
private:
const MotionType motion_type_;
const float confidence_;
};
inline bool operator==(const PresenceDevice& d1, const PresenceDevice& d2) {
return d1.GetMotionType() == d2.GetMotionType() &&
d1.GetConfidence() == d2.GetConfidence();
}
inline bool operator!=(const PresenceDevice& d1, const PresenceDevice& d2) {
return !(d1 == d2);
}
} // namespace presence
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_
+60
View File
@@ -0,0 +1,60 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "third_party/nearby/presence/presence_device.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
namespace nearby {
namespace presence {
namespace {
constexpr PresenceDevice::MotionType kDefaultMotionType =
PresenceDevice::MotionType::kPointAndHold;
constexpr float kDefaultConfidence = 0;
constexpr float kTestConfidence = 0.1;
TEST(PresenceDeviceTest, DefaultConstructorWorks) {
PresenceDevice device;
EXPECT_EQ(device.GetMotionType(), kDefaultMotionType);
EXPECT_EQ(device.GetConfidence(), kDefaultConfidence);
}
TEST(PresenceDeviceTest, DefaultEquals) {
PresenceDevice device1;
PresenceDevice device2;
EXPECT_EQ(device1, device2);
}
TEST(PresenceDeviceTest, ExplicitInitEquals) {
PresenceDevice device1 = {kDefaultMotionType, kTestConfidence};
PresenceDevice device2 = {kDefaultMotionType, kTestConfidence};
EXPECT_EQ(device1, device2);
}
TEST(PresenceDeviceTest, ExplicitInitNotEquals) {
PresenceDevice device1 = {kDefaultMotionType};
PresenceDevice device2 = {kDefaultMotionType, kTestConfidence};
EXPECT_NE(device1, device2);
}
TEST(PresenceDeviceTest, CopyInitEquals) {
PresenceDevice device1 = {kDefaultMotionType, kTestConfidence};
PresenceDevice device2 = {device1};
EXPECT_EQ(device1, device2);
}
} // namespace
} // namespace presence
} // namespace nearby
+5 -3
View File
@@ -36,8 +36,9 @@ class PresenceZone {
kWithinTap, // Distance is within tap range to the peer device, typically
// within ~0.127 meters.
};
DistanceBoundary(float = 0, float = 0,
RangeType = RangeType::kRangeUnknown) noexcept;
DistanceBoundary(float min_distance_meters = 0,
float max_distance_meters = 0,
RangeType range_type = RangeType::kRangeUnknown) noexcept;
float GetMinDistanceMeters() const;
float GetMaxDistanceMeters() const;
RangeType GetRangeType() const;
@@ -50,7 +51,8 @@ class PresenceZone {
class AngleOfArrivalBoundary {
public:
AngleOfArrivalBoundary(float = 0, float = 0) noexcept;
AngleOfArrivalBoundary(float min_angle_degrees = 0,
float max_angle_degrees = 0) noexcept;
float GetMinAngleDegrees() const;
float GetMaxAngleDegrees() const;
+43
View File
@@ -0,0 +1,43 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_PRESENCE_STATUS_H_
#define THIRD_PARTY_NEARBY_PRESENCE_STATUS_H_
namespace nearby {
namespace presence {
// Protocol operation result: kSuccess, if operation was successful;
// descriptive error code otherwise.
struct Status {
// Status is a struct, so it is possible to pass some context about failure,
// by adding extra fields to it when necessary, and not change any of the
// method signatures.
enum class Value {
kError = 0,
kSuccess,
};
Value value{Value::kError};
bool Ok() const { return value == Value::kSuccess; }
};
inline bool operator==(const Status& a, const Status& b) {
return a.value == b.value;
}
inline bool operator!=(const Status& a, const Status& b) { return !(a == b); }
} // namespace presence
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_PRESENCE_STATUS_H_
+58
View File
@@ -0,0 +1,58 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "third_party/nearby/presence/status.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
namespace nearby {
namespace presence {
namespace {
TEST(StatusTest, DefaultIsError) {
Status status;
EXPECT_FALSE(status.Ok());
EXPECT_EQ(status, Status{Status::Value::kError});
}
TEST(StatusTest, DefaultEquals) {
Status status1;
Status status2;
EXPECT_EQ(status1, status2);
}
TEST(StatusTest, ExplicitInitEquals) {
Status status1 = {Status::Value::kSuccess};
Status status2 = {Status::Value::kSuccess};
EXPECT_EQ(status1, status2);
EXPECT_TRUE(status1.Ok());
}
TEST(StatusTest, ExplicitInitNotEquals) {
Status status1 = {Status::Value::kSuccess};
Status status2 = {Status::Value::kError};
EXPECT_NE(status1, status2);
}
TEST(StatusTest, CopyInitEquals) {
Status status1 = {Status::Value::kSuccess};
Status status2 = {status1};
EXPECT_EQ(status1, status2);
}
} // namespace
} // namespace presence
} // namespace nearby