mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Migrate fast pair from location/nearby/cpp/fastpair to third_party/nearby/fastpair
PiperOrigin-RevId: 495726740
This commit is contained in:
committed by
Copybara-Service
parent
682813388f
commit
fe26466278
@@ -0,0 +1,12 @@
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "platform",
|
||||
textual_hdrs = glob(["**/*.h"]),
|
||||
visibility = [
|
||||
"//fastpair:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_API_DEVICE_INFO_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_API_DEVICE_INFO_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
|
||||
class DeviceInfo {
|
||||
public:
|
||||
enum class ScreenStatus {
|
||||
kUndetermined = 0,
|
||||
kLocked = 1,
|
||||
kUnlocked = 2,
|
||||
};
|
||||
|
||||
enum class OsType {
|
||||
kUnknown = 0,
|
||||
kAndroid = 1,
|
||||
kChromeOs = 2,
|
||||
kIos = 3,
|
||||
kWindows = 4,
|
||||
};
|
||||
|
||||
virtual ~DeviceInfo() = default;
|
||||
|
||||
virtual OsType GetOsType() const = 0;
|
||||
|
||||
// Monitor screen status
|
||||
virtual bool IsScreenLocked() const = 0;
|
||||
virtual void RegisterScreenLockedListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(ScreenStatus)> callback) = 0;
|
||||
virtual void UnregisterScreenLockedListener(
|
||||
absl::string_view listener_name) = 0;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_API_DEVICE_INFO_H_
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_API_FAST_PAIR_PLATFORM_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_API_FAST_PAIR_PLATFORM_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/internal/api/device_info.h"
|
||||
#include "fastpair/internal/api/timer.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
|
||||
class ImplementationFastPairPlatform {
|
||||
public:
|
||||
static std::unique_ptr<DeviceInfo> CreateDeviceInfo();
|
||||
|
||||
// Timer API
|
||||
static std::unique_ptr<Timer> CreateTimer();
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_API_FAST_PAIR_PLATFORM_H_
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef LOCATION_NEARBY_CPP_FASTPAIR_INTERNAL_API_TIMER_H_
|
||||
#define LOCATION_NEARBY_CPP_FASTPAIR_INTERNAL_API_TIMER_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
|
||||
class Timer {
|
||||
public:
|
||||
virtual ~Timer() = default;
|
||||
|
||||
// Creates a timer based on interval.
|
||||
//
|
||||
// @param delay
|
||||
// The amount of time in milliseconds relative to the current
|
||||
// time that must elapse before the timer is signaled for the first
|
||||
// time.
|
||||
// @param interval
|
||||
// The period of the timer, in milliseconds. If this parameter
|
||||
// is zero, the timer is signaled once.
|
||||
// @param callback
|
||||
// It will be called when timer signaled.
|
||||
// @return
|
||||
// return true if success, otherwise false
|
||||
virtual bool Create(int delay, int interval,
|
||||
std::function<void()> callback) = 0;
|
||||
|
||||
// Stops timer. No timer signal is sent after the call.
|
||||
virtual bool Stop() = 0;
|
||||
virtual bool FireNow() = 0;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // LOCATION_NEARBY_CPP_FASTPAIR_INTERNAL_API_TIMER_H_
|
||||
@@ -0,0 +1,48 @@
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "bluetooth_address",
|
||||
srcs = [
|
||||
"bluetooth_address.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"bluetooth_address.h",
|
||||
],
|
||||
visibility = [
|
||||
"//fastpair:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_absl//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "base",
|
||||
srcs = [
|
||||
],
|
||||
hdrs = [
|
||||
"observer_list.h",
|
||||
],
|
||||
visibility = [
|
||||
"//fastpair:__subpackages__",
|
||||
],
|
||||
deps = ["@com_google_absl//absl/container:flat_hash_set"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "base_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"bluetooth_address_test.cc",
|
||||
],
|
||||
shard_count = 8,
|
||||
deps = [
|
||||
":bluetooth_address",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,124 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/base/bluetooth_address.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
namespace {
|
||||
|
||||
// Utility to convert a character to a digit in a given base
|
||||
template <int BASE, typename CHAR>
|
||||
std::optional<uint8_t> CharToDigit(CHAR c) {
|
||||
static_assert(1 <= BASE && BASE <= 36, "BASE needs to be in [1, 36]");
|
||||
if (c >= '0' && c < '0' + std::min(BASE, 10)) return c - '0';
|
||||
|
||||
if (c >= 'a' && c < 'a' + BASE - 10) return c - 'a' + 10;
|
||||
|
||||
if (c >= 'A' && c < 'A' + BASE - 10) return c - 'A' + 10;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Convert a string of hex digits into an equivalent byte array
|
||||
template <typename OutIter>
|
||||
static bool HexStringToByteContainer(absl::string_view input, OutIter output) {
|
||||
size_t count = input.size();
|
||||
if (count == 0 || (count % 2) != 0) return false;
|
||||
for (uintptr_t i = 0; i < count / 2; ++i) {
|
||||
std::optional<uint8_t> upper = CharToDigit<16>(input[i * 2]);
|
||||
std::optional<uint8_t> lower = CharToDigit<16>(input[i * 2 + 1]);
|
||||
if (!upper.has_value() || !lower.has_value()) {
|
||||
return false;
|
||||
}
|
||||
*(output++) = (*upper << 4) | *lower;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexStringToSpan(absl::string_view input, absl::Span<uint8_t> output) {
|
||||
if (input.size() / 2 != output.size()) return false;
|
||||
|
||||
return HexStringToByteContainer(input, output.begin());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ParseBluetoothAddress(absl::string_view input,
|
||||
absl::Span<uint8_t> output) {
|
||||
if (output.size() != 6) return false;
|
||||
|
||||
// Try parsing addresses that lack separators, like "1A2B3C4D5E6F".
|
||||
if (input.size() == 12) return HexStringToSpan(input, output);
|
||||
|
||||
// Try parsing MAC address with separators like: "00:11:22:33:44:55" or
|
||||
// "00-11-22-33-44-55". Separator can be either '-' or ':', but must use the
|
||||
// same style throughout.
|
||||
if (input.size() == 17) {
|
||||
const char separator = input[2];
|
||||
if (separator != '-' && separator != ':') return false;
|
||||
return (input[2] == separator) && (input[5] == separator) &&
|
||||
(input[8] == separator) && (input[11] == separator) &&
|
||||
(input[14] == separator) &&
|
||||
HexStringToSpan(input.substr(0, 2), output.subspan(0, 1)) &&
|
||||
HexStringToSpan(input.substr(3, 2), output.subspan(1, 1)) &&
|
||||
HexStringToSpan(input.substr(6, 2), output.subspan(2, 1)) &&
|
||||
HexStringToSpan(input.substr(9, 2), output.subspan(3, 1)) &&
|
||||
HexStringToSpan(input.substr(12, 2), output.subspan(4, 1)) &&
|
||||
HexStringToSpan(input.substr(15, 2), output.subspan(5, 1));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ConvertBluetoothAddressUIntToString(uint64_t address) {
|
||||
std::string mac_address = absl::StrFormat(
|
||||
"%02llX:%02llX:%02llX:%02llX:%02llX:%02llX", address >> 40,
|
||||
(address >> 32) & 0xff, (address >> 24) & 0xff, (address >> 16) & 0xff,
|
||||
(address >> 8) & 0xff, address & 0xff);
|
||||
return CanonicalizeBluetoothAddress(mac_address);
|
||||
}
|
||||
|
||||
std::string CanonicalizeBluetoothAddress(absl::string_view address) {
|
||||
std::array<uint8_t, 6> bytes;
|
||||
|
||||
if (!ParseBluetoothAddress(address, absl::MakeSpan(bytes.data(), 6)))
|
||||
return std::string();
|
||||
|
||||
return CanonicalizeBluetoothAddress(bytes);
|
||||
}
|
||||
|
||||
std::string CanonicalizeBluetoothAddress(
|
||||
const std::array<uint8_t, 6>& address_bytes) {
|
||||
return absl::StrFormat("%02X:%02X:%02X:%02X:%02X:%02X", address_bytes[0],
|
||||
address_bytes[1], address_bytes[2], address_bytes[3],
|
||||
address_bytes[4], address_bytes[5]);
|
||||
}
|
||||
|
||||
std::string CanonicalizeBluetoothAddress(uint64_t address) {
|
||||
return ConvertBluetoothAddressUIntToString(address);
|
||||
}
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BASE_BLUETOOTH_ADDRESS_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BASE_BLUETOOTH_ADDRESS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
// Parses a Bluetooth address to an output buffer. The output buffer must be
|
||||
// exactly 6 bytes in size.
|
||||
// The address can be formatted in one of three ways:
|
||||
// · 1A:2B:3C:4D:5E:6F
|
||||
// · 1A-2B-3C-4D-5E-6F
|
||||
// · 1A2B3C4D5E6F
|
||||
bool ParseBluetoothAddress(absl::string_view input, absl::Span<uint8_t> output);
|
||||
|
||||
// Converts a uint64_t Bluetooth address to string.
|
||||
std::string ConvertBluetoothAddressUIntToString(uint64_t address);
|
||||
|
||||
// Returns |address| in the canonical format: XX:XX:XX:XX:XX:XX, where each 'X'
|
||||
// is a hex digit. If the input |address| is invalid, returns an empty string.
|
||||
std::string CanonicalizeBluetoothAddress(absl::string_view address);
|
||||
std::string CanonicalizeBluetoothAddress(
|
||||
const std::array<uint8_t, 6>& address_bytes);
|
||||
std::string CanonicalizeBluetoothAddress(uint64_t address);
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BASE_BLUETOOTH_ADDRESS_H_
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/base/bluetooth_address.h"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
namespace {
|
||||
|
||||
TEST(BluetoothUtil, ParseBluetoothAddress) {
|
||||
std::array<uint8_t, 6> output;
|
||||
std::array<uint8_t, 6> expected_output{{26, 43, 60, 77, 94, 111}};
|
||||
EXPECT_TRUE(ParseBluetoothAddress(
|
||||
"1A:2B:3C:4D:5E:6F", absl::MakeSpan(output.data(), output.size())));
|
||||
EXPECT_EQ(output, expected_output);
|
||||
}
|
||||
|
||||
TEST(BluetoothUtil, ConvertBluetoothAddressUIntToString) {
|
||||
const uint64_t input = 0x00001A2B3C4D5E6F;
|
||||
std::string expected_output = "1A:2B:3C:4D:5E:6F";
|
||||
std::string output = ConvertBluetoothAddressUIntToString(input);
|
||||
EXPECT_EQ(output, expected_output);
|
||||
}
|
||||
|
||||
TEST(BluetoothUtil, CanonicalizeBluetoothAddress) {
|
||||
std::array<uint8_t, 6> address{{26, 43, 60, 77, 94, 111}};
|
||||
EXPECT_EQ(CanonicalizeBluetoothAddress(address), "1A:2B:3C:4D:5E:6F");
|
||||
EXPECT_EQ(CanonicalizeBluetoothAddress("1A-2B-3C-4D-5E-6F"),
|
||||
"1A:2B:3C:4D:5E:6F");
|
||||
EXPECT_EQ(CanonicalizeBluetoothAddress(0x00001A2B3C4D5E6F),
|
||||
"1A:2B:3C:4D:5E:6F");
|
||||
|
||||
// Canonicalizes invalid address
|
||||
EXPECT_EQ(CanonicalizeBluetoothAddress("1A-2B-3C-4D-5E-6F-89"), "");
|
||||
EXPECT_EQ(CanonicalizeBluetoothAddress("nearby"), "");
|
||||
EXPECT_EQ(CanonicalizeBluetoothAddress("MA-2M-3C-4D-5E-6F"), "");
|
||||
EXPECT_EQ(CanonicalizeBluetoothAddress(0x001A2B3C4D5E6F89), "");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BASE_OBSERVER_LIST_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BASE_OBSERVER_LIST_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
template <class ObserverType>
|
||||
class ObserverList {
|
||||
public:
|
||||
using iterator = typename absl::flat_hash_set<ObserverType*>::iterator;
|
||||
using const_iterator =
|
||||
typename absl::flat_hash_set<ObserverType*>::const_iterator;
|
||||
|
||||
void AddObserver(ObserverType* observer) { observers_.emplace(observer); }
|
||||
|
||||
void RemoveObserver(ObserverType* observer) { observers_.erase(observer); }
|
||||
|
||||
bool HasObserver(ObserverType* observer) {
|
||||
return observers_.contains(observer);
|
||||
}
|
||||
|
||||
void Clear() { observers_.clear(); }
|
||||
|
||||
bool empty() const { return observers_.empty(); }
|
||||
|
||||
int size() const { return observers_.size(); }
|
||||
|
||||
// Supports iterators
|
||||
iterator begin() { return observers_.begin(); }
|
||||
iterator end() { return observers_.end(); }
|
||||
const_iterator begin() const { return observers_.begin(); }
|
||||
const_iterator end() const { return observers_.end(); }
|
||||
|
||||
private:
|
||||
absl::flat_hash_set<ObserverType*> observers_;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BASE_OBSERVER_LIST_H_
|
||||
@@ -0,0 +1,37 @@
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "platform_g3",
|
||||
srcs = [
|
||||
"fast_pair_platform.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"device_info.h",
|
||||
"timer.h",
|
||||
],
|
||||
visibility = [
|
||||
"//fastpair:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//fastpair/internal/api:platform",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "g3_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"device_info_test.cc",
|
||||
],
|
||||
shard_count = 8,
|
||||
deps = [
|
||||
":platform_g3",
|
||||
"//fastpair/internal/api:platform",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_G3_DEVICE_INFO_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_G3_DEVICE_INFO_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/internal/api/device_info.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
|
||||
class DeviceInfo : public api::DeviceInfo {
|
||||
public:
|
||||
api::DeviceInfo::OsType GetOsType() const override {
|
||||
return api::DeviceInfo::OsType::kChromeOs;
|
||||
}
|
||||
|
||||
bool IsScreenLocked() const override { return false; }
|
||||
|
||||
void RegisterScreenLockedListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> callback) override {
|
||||
screen_locked_listeners_.emplace(listener_name, std::move(callback));
|
||||
}
|
||||
|
||||
void UnregisterScreenLockedListener(
|
||||
absl::string_view listener_name) override {
|
||||
screen_locked_listeners_.erase(listener_name);
|
||||
}
|
||||
|
||||
absl::flat_hash_map<std::string,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)>>
|
||||
screen_locked_listeners_;
|
||||
};
|
||||
|
||||
} // namespace g3
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_G3_DEVICE_INFO_H_
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/impl/g3/device_info.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "fastpair/internal/api/device_info.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
namespace {
|
||||
|
||||
TEST(DeviceInfo, GetOsType) {
|
||||
EXPECT_EQ(DeviceInfo().GetOsType(), api::DeviceInfo::OsType::kChromeOs);
|
||||
}
|
||||
|
||||
TEST(DeviceInfo, IsScreenLocked) {
|
||||
EXPECT_FALSE(DeviceInfo().IsScreenLocked());
|
||||
}
|
||||
|
||||
TEST(DeviceInfo, RegisterScreenLockedListener) {
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
|
||||
DeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_1", listener_1);
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 1);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_2", listener_2);
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 2);
|
||||
}
|
||||
|
||||
TEST(DeviceInfo, UnregisterScreenLockedListener) {
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
|
||||
DeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_1", listener_1);
|
||||
device_info.RegisterScreenLockedListener("listener_2", listener_2);
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 2);
|
||||
|
||||
device_info.UnregisterScreenLockedListener("listener_1");
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 1);
|
||||
|
||||
device_info.UnregisterScreenLockedListener("listener_2");
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace g3
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/api/fast_pair_platform.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "fastpair/internal/impl/g3/device_info.h"
|
||||
#include "fastpair/internal/impl/g3/timer.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
|
||||
std::unique_ptr<api::DeviceInfo>
|
||||
ImplementationFastPairPlatform::CreateDeviceInfo() {
|
||||
return std::make_unique<g3::DeviceInfo>();
|
||||
}
|
||||
|
||||
std::unique_ptr<api::Timer> ImplementationFastPairPlatform::CreateTimer() {
|
||||
return std::make_unique<g3::Timer>();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_G3_TIMER_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_G3_TIMER_H_
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
#include "fastpair/internal/api/timer.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
|
||||
class Timer : public api::Timer {
|
||||
public:
|
||||
Timer() = default;
|
||||
~Timer() override = default;
|
||||
|
||||
bool Create(int delay, int interval,
|
||||
std::function<void()> callback) override {
|
||||
if (delay < 0 || interval < 0) {
|
||||
return false;
|
||||
}
|
||||
callback_ = std::move(callback);
|
||||
is_stopped_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Stop() override {
|
||||
is_stopped_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FireNow() override {
|
||||
if (is_stopped_ || !callback_) {
|
||||
return false;
|
||||
}
|
||||
callback_();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mocked methods for test only
|
||||
void TriggerCallback() {
|
||||
if (is_stopped_ || callback_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback_();
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> callback_;
|
||||
bool is_stopped_ = false;
|
||||
};
|
||||
|
||||
} // namespace g3
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_G3_TIMER_H_
|
||||
@@ -27,23 +27,62 @@ cc_library(
|
||||
name = "platform_windows",
|
||||
srcs = [
|
||||
"ble_gatt_client.cc",
|
||||
"device_info.cc",
|
||||
"fast_pair_platform.cc",
|
||||
"timer.cc",
|
||||
"utils.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"ble_gatt_client.h",
|
||||
"device_info.h",
|
||||
"timer.h",
|
||||
"utils.h",
|
||||
],
|
||||
copts = [
|
||||
"-Ithird_party",
|
||||
"-Ithird_party/nearby/internal/platform/implementation/windows/generated",
|
||||
],
|
||||
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
|
||||
visibility = ["//fastpair:__subpackages__"],
|
||||
deps = [
|
||||
"//fastpair/internal/api:platform",
|
||||
"//fastpair/internal/base",
|
||||
"//fastpair/internal/base:bluetooth_address",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform/implementation/windows",
|
||||
"//internal/platform/implementation/windows/generated:types",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "platform_windows_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"device_info_test.cc",
|
||||
"timer_test.cc",
|
||||
],
|
||||
copts = [
|
||||
"-Ithird_party/nearby/internal/platform/implementation/windows/generated",
|
||||
],
|
||||
shard_count = 1,
|
||||
deps = [
|
||||
":platform_windows",
|
||||
":platform_windows_libs",
|
||||
"//fastpair/internal/api:platform",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform/implementation/windows",
|
||||
"//internal/platform/implementation/windows/generated:types",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/impl/windows/device_info.h"
|
||||
|
||||
#include <shlobj_core.h>
|
||||
#include <windows.h>
|
||||
#include <wtsapi32.h>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/internal/api/device_info.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "winrt/Windows.Foundation.Collections.h"
|
||||
#include "winrt/Windows.Foundation.h"
|
||||
#include "winrt/Windows.System.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
constexpr char window_class_name[] = "FastPairDLL_MessageWindowClass";
|
||||
constexpr char window_name[] = "FastPairDLL_MessageWindow";
|
||||
|
||||
namespace {
|
||||
// This WindowProc method must be static for the successful initialization of
|
||||
// WNDCLASS
|
||||
// window_class.lpfnWndProc = (WNDPROC) &DeviceInfo::WindowProc;
|
||||
// where a WNDPROC typed function pointer is expected
|
||||
// typedef LRESULT (CALLBACK* WNDPROC)(HWND,UINT,WPARAM,LPARAM)
|
||||
// the calling convention used here CALLBACK is a macro defined as
|
||||
// #define CALLBACK __stdcall
|
||||
//
|
||||
// If WindProc is not static and defined as a member function, it uses the
|
||||
// __thiscall calling convention instead
|
||||
// https://docs.microsoft.com/en-us/cpp/cpp/thiscall?view=msvc-170
|
||||
// https://isocpp.org/wiki/faq/pointers-to-members
|
||||
// https://en.cppreference.com/w/cpp/language/pointer
|
||||
//
|
||||
// This is problematic because the function pointer now looks like this
|
||||
// typedef LRESULT (CALLBACK* DeviceInfo_WNDPROC)(DeviceInfo*
|
||||
// this,HWND,UINT,WPARAM,LPARAM)
|
||||
// which causes casting errors
|
||||
LRESULT CALLBACK WindowProc(HWND window_handle, UINT message, WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
DeviceInfo* self = reinterpret_cast<DeviceInfo*>(
|
||||
GetWindowLongPtr(window_handle, GWLP_USERDATA));
|
||||
CREATESTRUCT* create_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
|
||||
LONG_PTR result = 0L;
|
||||
switch (message) {
|
||||
case WM_CREATE:
|
||||
self = reinterpret_cast<DeviceInfo*>(create_struct->lpCreateParams);
|
||||
self->message_window_handle_ = window_handle;
|
||||
|
||||
// Store pointer to the self to the window's user data.
|
||||
SetLastError(0);
|
||||
result = SetWindowLongPtr(window_handle, GWLP_USERDATA,
|
||||
reinterpret_cast<LONG_PTR>(self));
|
||||
if (result == 0 && GetLastError() != 0) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Error connecting message window to Fast Pair DLL.";
|
||||
}
|
||||
break;
|
||||
case WM_WTSSESSION_CHANGE:
|
||||
if (self) {
|
||||
switch (wparam) {
|
||||
case WTS_SESSION_LOCK:
|
||||
for (auto& listener : self->screen_locked_listeners_) {
|
||||
listener.second(api::DeviceInfo::ScreenStatus::
|
||||
kLocked); // Trigger registered callbacks
|
||||
}
|
||||
break;
|
||||
case WTS_SESSION_UNLOCK:
|
||||
for (auto& listener : self->screen_locked_listeners_) {
|
||||
listener.second(api::DeviceInfo::ScreenStatus::
|
||||
kUnlocked); // Trigger registered callbacks
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
SetLastError(0);
|
||||
result = SetWindowLongPtr(window_handle, GWLP_USERDATA, NULL);
|
||||
if (result == 0 && GetLastError() != 0) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Error disconnecting message window to Fast Pair DLL.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(window_handle, message, wparam, lparam);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
DeviceInfo::~DeviceInfo() {
|
||||
UnregisterClass(MAKEINTATOM(registered_class_), instance_);
|
||||
}
|
||||
|
||||
api::DeviceInfo::OsType DeviceInfo::GetOsType() const {
|
||||
return api::DeviceInfo::OsType::kWindows;
|
||||
}
|
||||
|
||||
bool DeviceInfo::IsScreenLocked() const {
|
||||
DWORD session_id = WTSGetActiveConsoleSessionId();
|
||||
WTS_INFO_CLASS wts_info_class = WTSSessionInfoEx;
|
||||
LPTSTR session_info_buffer = nullptr;
|
||||
DWORD session_info_buffer_size_bytes = 0;
|
||||
|
||||
WTSINFOEXW* wts_info = nullptr;
|
||||
LONG session_state = WTS_SESSIONSTATE_UNKNOWN;
|
||||
|
||||
if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id,
|
||||
wts_info_class, &session_info_buffer,
|
||||
&session_info_buffer_size_bytes)) {
|
||||
if (session_info_buffer_size_bytes > 0) {
|
||||
wts_info = (WTSINFOEXW*)session_info_buffer;
|
||||
if (wts_info->Level == 1) {
|
||||
session_state = wts_info->Data.WTSInfoExLevel1.SessionFlags;
|
||||
}
|
||||
}
|
||||
WTSFreeMemory(session_info_buffer);
|
||||
session_info_buffer = nullptr;
|
||||
}
|
||||
bool isScreenLocked = session_state == WTS_SESSIONSTATE_LOCK;
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__ << "ScreenStatus: "
|
||||
<< (isScreenLocked ? "Locked" : "NotLocked");
|
||||
|
||||
return isScreenLocked;
|
||||
}
|
||||
|
||||
void DeviceInfo::RegisterScreenLockedListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> callback) {
|
||||
if (message_window_handle_ == nullptr) {
|
||||
instance_ = (HINSTANCE)GetModuleHandle(NULL);
|
||||
|
||||
WNDCLASS window_class;
|
||||
window_class.style = 0;
|
||||
window_class.lpfnWndProc = (WNDPROC)&WindowProc;
|
||||
window_class.cbClsExtra = 0;
|
||||
window_class.cbWndExtra = 0;
|
||||
window_class.hInstance = instance_;
|
||||
window_class.hIcon = nullptr;
|
||||
window_class.hCursor = nullptr;
|
||||
window_class.hbrBackground = nullptr;
|
||||
window_class.lpszMenuName = nullptr;
|
||||
window_class.lpszClassName = window_class_name;
|
||||
|
||||
registered_class_ = RegisterClass(&window_class);
|
||||
|
||||
message_window_handle_ = CreateWindow(
|
||||
MAKEINTATOM(registered_class_), // class atom from RegisterClass
|
||||
window_name, // window name
|
||||
0, // window style
|
||||
0, // initial x position of window
|
||||
0, // initial y position of window
|
||||
0, // width
|
||||
0, // height
|
||||
HWND_MESSAGE, // handle to the parent of window
|
||||
// (message-only window in this case)
|
||||
nullptr, // handle to a menu
|
||||
instance_, // handle to the instance of the module
|
||||
// associated to the window
|
||||
this); // pointer to be passed to the window for additional data
|
||||
|
||||
if (!message_window_handle_) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << ": Failed to create message window for Fast Pair DLL.";
|
||||
}
|
||||
}
|
||||
|
||||
screen_locked_listeners_.emplace(listener_name, callback);
|
||||
}
|
||||
|
||||
void DeviceInfo::UnregisterScreenLockedListener(
|
||||
absl::string_view listener_name) {
|
||||
screen_locked_listeners_.erase(listener_name);
|
||||
}
|
||||
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_DEVICE_INFO_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_DEVICE_INFO_H_
|
||||
|
||||
#include <guiddef.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/internal/api/device_info.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
class DeviceInfo : public api::DeviceInfo {
|
||||
public:
|
||||
~DeviceInfo() override;
|
||||
|
||||
api::DeviceInfo::OsType GetOsType() const override;
|
||||
|
||||
bool IsScreenLocked() const override;
|
||||
void RegisterScreenLockedListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> callback) override;
|
||||
void UnregisterScreenLockedListener(absl::string_view listener_name) override;
|
||||
absl::flat_hash_map<std::string,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)>>
|
||||
screen_locked_listeners_;
|
||||
|
||||
HINSTANCE instance_ = nullptr;
|
||||
ATOM registered_class_ = NULL;
|
||||
HWND message_window_handle_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_DEVICE_INFO_H_
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/impl/windows/device_info.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "fastpair/internal/api/device_info.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
|
||||
TEST(DeviceInfo, DISABLED_GetOsType) {
|
||||
EXPECT_EQ(DeviceInfo().GetOsType(), api::DeviceInfo::OsType::kWindows);
|
||||
}
|
||||
|
||||
TEST(DeviceInfo, DISABLED_IsScreenLocked) {
|
||||
EXPECT_TRUE(DeviceInfo().IsScreenLocked());
|
||||
}
|
||||
|
||||
TEST(DeviceInfo, DISABLED_RegisterScreenLockedListener) {
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
|
||||
DeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_1", listener_1);
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 1);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_2", listener_2);
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 2);
|
||||
}
|
||||
|
||||
TEST(DeviceInfo, DISABLED_UnregisterScreenLockedListener) {
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
|
||||
DeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_1", listener_1);
|
||||
device_info.RegisterScreenLockedListener("listener_2", listener_2);
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 2);
|
||||
|
||||
device_info.UnregisterScreenLockedListener("listener_1");
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 1);
|
||||
|
||||
device_info.UnregisterScreenLockedListener("listener_2");
|
||||
EXPECT_EQ(device_info.screen_locked_listeners_.size(), 0);
|
||||
}
|
||||
|
||||
TEST(DeviceInfo, DISABLED_UpdateScreenLockedListener) {
|
||||
absl::Notification notification;
|
||||
|
||||
api::DeviceInfo::ScreenStatus screen_locked_tracker =
|
||||
api::DeviceInfo::ScreenStatus::kUndetermined;
|
||||
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener =
|
||||
[&screen_locked_tracker,
|
||||
¬ification](api::DeviceInfo::ScreenStatus status) {
|
||||
screen_locked_tracker = api::DeviceInfo::ScreenStatus::kLocked;
|
||||
notification.Notify();
|
||||
};
|
||||
|
||||
DeviceInfo device_info;
|
||||
device_info.RegisterScreenLockedListener("listener", listener);
|
||||
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(absl::Seconds(5)));
|
||||
EXPECT_EQ(screen_locked_tracker, api::DeviceInfo::ScreenStatus::kLocked);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/api/fast_pair_platform.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/internal/impl/windows/device_info.h"
|
||||
#include "fastpair/internal/impl/windows/timer.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace api {
|
||||
|
||||
std::unique_ptr<api::DeviceInfo>
|
||||
ImplementationFastPairPlatform::CreateDeviceInfo() {
|
||||
return std::make_unique<windows::DeviceInfo>();
|
||||
}
|
||||
|
||||
std::unique_ptr<api::Timer> ImplementationFastPairPlatform::CreateTimer() {
|
||||
return std::make_unique<windows::Timer>();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,114 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/impl/windows/timer.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
Timer::~Timer() { Stop(); }
|
||||
|
||||
bool Timer::Create(int delay, int interval, std::function<void()> callback) {
|
||||
if ((delay < 0) || (interval < 0)) {
|
||||
NEARBY_LOGS(WARNING) << "Delay and interval shouldn\'t be negative value.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timer_queue_handle_ != nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Creates a queue for timers.
|
||||
// If succeeds, return a handle to the timer queue.
|
||||
// If fails, the return value is NULL.
|
||||
timer_queue_handle_ = CreateTimerQueue();
|
||||
if (timer_queue_handle_ == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << "Failed to create timer queue.";
|
||||
return false;
|
||||
}
|
||||
|
||||
delay_ = delay;
|
||||
interval_ = interval;
|
||||
callback_ = std::move(callback);
|
||||
|
||||
// Creates a timer-queue timer. This timer expires at the specified due time,
|
||||
// then after every specified period. When the timer expires,
|
||||
// the callback function is called.
|
||||
if (!CreateTimerQueueTimer(&handle_, timer_queue_handle_,
|
||||
static_cast<WAITORTIMERCALLBACK>(TimerRoutine),
|
||||
&callback_, delay, interval, WT_EXECUTEDEFAULT)) {
|
||||
// Deletes a timer queue.
|
||||
// Any pending timers in the queue are canceled and deleted.
|
||||
if (!DeleteTimerQueueEx(timer_queue_handle_, nullptr)) {
|
||||
NEARBY_LOGS(ERROR) << "Failed to create timer in timer queue.";
|
||||
}
|
||||
timer_queue_handle_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Timer::Stop() {
|
||||
if (timer_queue_handle_ == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Deletes a timer queue.
|
||||
// Any pending timers in the queue are canceled and deleted.
|
||||
if (!DeleteTimerQueueTimer(timer_queue_handle_, handle_, nullptr)) {
|
||||
if (GetLastError() != ERROR_IO_PENDING) {
|
||||
NEARBY_LOGS(ERROR) << "Failed to delete timer from timer queue.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
handle_ = nullptr;
|
||||
|
||||
if (!DeleteTimerQueueEx(timer_queue_handle_, nullptr)) {
|
||||
NEARBY_LOGS(ERROR) << "Failed to delete timer queue.";
|
||||
return false;
|
||||
}
|
||||
|
||||
timer_queue_handle_ = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Timer::FireNow() {
|
||||
if (!timer_queue_handle_ || !callback_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
callback_();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CALLBACK Timer::TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired) {
|
||||
std::function<void()>* callback =
|
||||
reinterpret_cast<std::function<void()>*>(lpParam);
|
||||
if (*callback != NULL) {
|
||||
(*callback)();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_TIMER_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_TIMER_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "fastpair/internal/api/timer.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
class Timer : public api::Timer {
|
||||
public:
|
||||
Timer() = default;
|
||||
~Timer() override;
|
||||
|
||||
bool Create(int delay, int interval, std::function<void()> callback) override;
|
||||
bool Stop() override;
|
||||
bool FireNow() override;
|
||||
|
||||
private:
|
||||
static void CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired);
|
||||
|
||||
int delay_;
|
||||
int interval_;
|
||||
std::function<void()> callback_;
|
||||
HANDLE handle_ = NULL;
|
||||
HANDLE timer_queue_handle_ = NULL;
|
||||
};
|
||||
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_TIMER_H_
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <chrono> // NOLINT
|
||||
#include <functional> // NOLINT
|
||||
#include <memory>
|
||||
#include <thread> // NOLINT
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "fastpair/internal/api/fast_pair_platform.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
|
||||
TEST(Timer, TestCreateTimer) {
|
||||
int count = 0;
|
||||
std::function<void()> callback = [&count]() { ++count; };
|
||||
|
||||
std::unique_ptr<api::Timer> timer =
|
||||
api::ImplementationFastPairPlatform::CreateTimer();
|
||||
|
||||
ASSERT_TRUE(timer != nullptr);
|
||||
EXPECT_FALSE(timer->Create(-100, 0, callback));
|
||||
EXPECT_TRUE(timer->Stop());
|
||||
}
|
||||
|
||||
// This test case cannot run on Google3
|
||||
TEST(Timer, DISABLED_TestRepeatTimer) {
|
||||
int count = 0;
|
||||
std::function<void()> callback = [&count]() { count++; };
|
||||
|
||||
std::unique_ptr<api::Timer> timer =
|
||||
api::ImplementationFastPairPlatform::CreateTimer();
|
||||
|
||||
ASSERT_TRUE(timer != nullptr);
|
||||
EXPECT_TRUE(timer->Create(300, 300, callback));
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
EXPECT_TRUE(timer->Stop());
|
||||
EXPECT_EQ(count, 3);
|
||||
}
|
||||
|
||||
TEST(Timer, DISABLED_TestFireNow) {
|
||||
int count = 0;
|
||||
std::function<void()> callback = [&count]() { ++count; };
|
||||
auto timer = api::ImplementationFastPairPlatform::CreateTimer();
|
||||
EXPECT_TRUE(timer != nullptr);
|
||||
EXPECT_TRUE(timer->Create(3000, 3000, callback));
|
||||
EXPECT_TRUE(timer->FireNow());
|
||||
EXPECT_TRUE(timer->Stop());
|
||||
EXPECT_EQ(count, 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/impl/windows/utils.h"
|
||||
|
||||
// Standard C/C++ headers
|
||||
#include <string>
|
||||
|
||||
// Third party headers
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
// Nearby connections headers
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/bluetooth_utils.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
std::string uint64_to_mac_address_string(uint64_t bluetoothAddress) {
|
||||
std::string buffer = absl::StrFormat(
|
||||
"%2llx:%2llx:%2llx:%2llx:%2llx:%2llx", bluetoothAddress >> 40,
|
||||
(bluetoothAddress >> 32) & 0xff, (bluetoothAddress >> 24) & 0xff,
|
||||
(bluetoothAddress >> 16) & 0xff, (bluetoothAddress >> 8) & 0xff,
|
||||
bluetoothAddress & 0xff);
|
||||
|
||||
return absl::AsciiStrToUpper(buffer);
|
||||
}
|
||||
|
||||
uint64_t mac_address_string_to_uint64(absl::string_view mac_address) {
|
||||
location::nearby::ByteArray mac_address_array =
|
||||
location::nearby::BluetoothUtils::FromString(mac_address);
|
||||
uint64_t mac_address_uint64 = 0;
|
||||
for (int i = 0; i < mac_address_array.size(); i++) {
|
||||
mac_address_uint64 <<= 8;
|
||||
mac_address_uint64 |= static_cast<uint8_t>(
|
||||
static_cast<unsigned char>(*(mac_address_array.data() + i)));
|
||||
}
|
||||
return mac_address_uint64;
|
||||
}
|
||||
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_UTILS_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_UTILS_H_
|
||||
|
||||
#include <guiddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "winrt/Windows.Foundation.h"
|
||||
#include "winrt/base.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
std::string uint64_to_mac_address_string(uint64_t bluetoothAddress);
|
||||
uint64_t mac_address_string_to_uint64(absl::string_view mac_address);
|
||||
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_IMPL_WINDOWS_UTILS_H_
|
||||
@@ -0,0 +1,87 @@
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "types",
|
||||
hdrs = [
|
||||
"device_info.h",
|
||||
"task_runner.h",
|
||||
"timer.h",
|
||||
],
|
||||
visibility = ["//fastpair:__subpackages__"],
|
||||
deps = [
|
||||
"//fastpair/internal/api:platform",
|
||||
"//fastpair/internal/impl/g3:platform_g3",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/time",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "fastpair_context",
|
||||
srcs = [
|
||||
"task_runner_impl.cc",
|
||||
"timer_impl.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"task_runner_impl.h",
|
||||
"timer_impl.h",
|
||||
],
|
||||
visibility = ["//fastpair:__subpackages__"],
|
||||
deps = [
|
||||
":device_info",
|
||||
":types",
|
||||
"//fastpair/internal/api:platform",
|
||||
"//fastpair/internal/base", # fixdeps: keep
|
||||
"//fastpair/internal/impl/g3:platform_g3",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/random",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "device_info",
|
||||
srcs = [
|
||||
"device_info_impl.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"device_info_impl.h",
|
||||
],
|
||||
visibility = ["//fastpair:__subpackages__"],
|
||||
deps = [
|
||||
":types",
|
||||
"//fastpair/internal/api:platform",
|
||||
"//fastpair/internal/impl/g3:platform_g3",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "fastpair_context_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"task_runner_impl_test.cc",
|
||||
"timer_impl_test.cc",
|
||||
],
|
||||
shard_count = 8,
|
||||
deps = [
|
||||
"device_info",
|
||||
":fastpair_context",
|
||||
":types",
|
||||
"//fastpair/internal/api:platform",
|
||||
"//fastpair/internal/impl/g3:platform_g3",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation/g3",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_DEVICE_INFO_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_DEVICE_INFO_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/internal/api/device_info.h"
|
||||
#include "fastpair/internal/api/fast_pair_platform.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
class DeviceInfo {
|
||||
public:
|
||||
virtual ~DeviceInfo() = default;
|
||||
|
||||
virtual api::DeviceInfo::OsType GetOsType() const = 0;
|
||||
|
||||
virtual bool IsScreenLocked() const = 0;
|
||||
virtual void RegisterScreenLockedListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> callback) = 0;
|
||||
virtual void UnregisterScreenLockedListener(
|
||||
absl::string_view listener_name) = 0;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_DEVICE_INFO_H_
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/public/device_info_impl.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
api::DeviceInfo::OsType DeviceInfoImpl::GetOsType() const {
|
||||
return device_info_impl_->GetOsType();
|
||||
}
|
||||
|
||||
bool DeviceInfoImpl::IsScreenLocked() const {
|
||||
return device_info_impl_->IsScreenLocked();
|
||||
}
|
||||
|
||||
void DeviceInfoImpl::RegisterScreenLockedListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> callback) {
|
||||
device_info_impl_->RegisterScreenLockedListener(listener_name, callback);
|
||||
}
|
||||
|
||||
void DeviceInfoImpl::UnregisterScreenLockedListener(
|
||||
absl::string_view listener_name) {
|
||||
device_info_impl_->UnregisterScreenLockedListener(listener_name);
|
||||
}
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_DEVICE_INFO_IMPL_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_DEVICE_INFO_IMPL_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "fastpair/internal/api/fast_pair_platform.h"
|
||||
#include "fastpair/internal/public/device_info.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
class DeviceInfoImpl : public DeviceInfo {
|
||||
public:
|
||||
DeviceInfoImpl()
|
||||
: device_info_impl_(
|
||||
api::ImplementationFastPairPlatform::CreateDeviceInfo()) {}
|
||||
|
||||
api::DeviceInfo::OsType GetOsType() const override;
|
||||
|
||||
bool IsScreenLocked() const override;
|
||||
void RegisterScreenLockedListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> callback) override;
|
||||
void UnregisterScreenLockedListener(absl::string_view listener_name) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<api::DeviceInfo> device_info_impl_;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_DEVICE_INFO_IMPL_H_
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TASK_RUNNER_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TASK_RUNNER_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
// Task runner is an implementation to run tasks immediately or with a delay.
|
||||
// The current implementation does not allow running nested tasks.
|
||||
class TaskRunner {
|
||||
public:
|
||||
virtual ~TaskRunner() = default;
|
||||
|
||||
// Posts a task to task runner. The task runs immediately or not depends on
|
||||
// the implementation of class. If the implementation supports multiple
|
||||
// threads, posted tasks could run concurrently.
|
||||
virtual bool PostTask(std::function<void()> task) = 0;
|
||||
|
||||
// Posts a task to run with delay. Multiple tasks can be scheduled. Tasks will
|
||||
// execute in the order of their delay expiring, not in the order they were
|
||||
// posted.
|
||||
virtual bool PostDelayedTask(absl::Duration delay,
|
||||
std::function<void()> task) = 0;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TASK_RUNNER_H_
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/public/task_runner_impl.h"
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/random/random.h"
|
||||
#include "fastpair/internal/public/timer_impl.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
TaskRunnerImpl::TaskRunnerImpl(uint32_t runner_count) {
|
||||
executor_ =
|
||||
std::make_unique<::location::nearby::MultiThreadExecutor>(runner_count);
|
||||
}
|
||||
|
||||
TaskRunnerImpl::~TaskRunnerImpl() = default;
|
||||
|
||||
bool TaskRunnerImpl::PostTask(std::function<void()> task) {
|
||||
if (!task) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Because of cannot get the executor status from platform API, just returns
|
||||
// true after calling the Execute method.
|
||||
executor_->Execute(std::move(task));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TaskRunnerImpl::PostDelayedTask(absl::Duration delay,
|
||||
std::function<void()> task) {
|
||||
if (!task) {
|
||||
return true;
|
||||
}
|
||||
|
||||
absl::MutexLock lock(&mutex_);
|
||||
uint64_t id = GenerateId();
|
||||
|
||||
std::unique_ptr<Timer> timer = std::make_unique<TimerImpl>();
|
||||
if (timer->Start(delay / absl::Milliseconds(1), 0,
|
||||
[this, id, task = std::move(task)]() {
|
||||
if (task) {
|
||||
PostTask(std::move(task));
|
||||
}
|
||||
{
|
||||
absl::MutexLock lock(&mutex_);
|
||||
timers_map_.erase(id);
|
||||
}
|
||||
})) {
|
||||
timers_map_.emplace(id, std::move(timer));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t TaskRunnerImpl::GenerateId() {
|
||||
absl::BitGen bitgen;
|
||||
return absl::Uniform(bitgen, 0u, std::numeric_limits<uint64_t>::max());
|
||||
}
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TASK_RUNNER_IMPL_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TASK_RUNNER_IMPL_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "fastpair/internal/public/task_runner.h"
|
||||
#include "fastpair/internal/public/timer.h"
|
||||
#include "internal/platform/multi_thread_executor.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
class TaskRunnerImpl : public TaskRunner {
|
||||
public:
|
||||
explicit TaskRunnerImpl(uint32_t runner_count);
|
||||
~TaskRunnerImpl() override;
|
||||
|
||||
bool PostTask(std::function<void()> task) override;
|
||||
bool PostDelayedTask(absl::Duration delay,
|
||||
std::function<void()> task) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
uint64_t GenerateId();
|
||||
|
||||
mutable absl::Mutex mutex_;
|
||||
std::unique_ptr<::location::nearby::MultiThreadExecutor> executor_;
|
||||
absl::flat_hash_map<uint64_t, std::unique_ptr<Timer>> timers_map_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TASK_RUNNER_IMPL_H_
|
||||
@@ -0,0 +1,166 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/public/task_runner_impl.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "absl/time/clock.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
namespace {
|
||||
|
||||
TEST(TaskRunnerImpl, PostTask) {
|
||||
TaskRunnerImpl task_runner{1};
|
||||
absl::Notification notification;
|
||||
bool called = false;
|
||||
|
||||
task_runner.PostTask([&called, ¬ification]() {
|
||||
called = true;
|
||||
notification.Notify();
|
||||
});
|
||||
notification.WaitForNotificationWithTimeout(absl::Milliseconds(100));
|
||||
EXPECT_TRUE(called);
|
||||
}
|
||||
|
||||
TEST(TaskRunnerImpl, PostSequenceTasks) {
|
||||
TaskRunnerImpl task_runner{1};
|
||||
std::vector<std::string> completed_tasks;
|
||||
absl::Notification notification;
|
||||
|
||||
// Run the first task
|
||||
task_runner.PostTask([&completed_tasks, ¬ification]() {
|
||||
completed_tasks.push_back("task1");
|
||||
if (completed_tasks.size() == 2) {
|
||||
absl::SleepFor(absl::Milliseconds(100));
|
||||
notification.Notify();
|
||||
}
|
||||
});
|
||||
|
||||
// Run the second task
|
||||
task_runner.PostTask([&completed_tasks, ¬ification]() {
|
||||
completed_tasks.push_back("task2");
|
||||
if (completed_tasks.size() == 2) {
|
||||
notification.Notify();
|
||||
}
|
||||
});
|
||||
|
||||
notification.WaitForNotificationWithTimeout(absl::Milliseconds(200));
|
||||
ASSERT_EQ(completed_tasks.size(), 2u);
|
||||
EXPECT_EQ(completed_tasks[0], "task1");
|
||||
EXPECT_EQ(completed_tasks[1], "task2");
|
||||
}
|
||||
|
||||
TEST(TaskRunnerImpl, DISABLED_PostDelayedTask) {
|
||||
TaskRunnerImpl task_runner{1};
|
||||
std::vector<std::string> completed_tasks;
|
||||
absl::Notification notification;
|
||||
|
||||
// Run the first task
|
||||
task_runner.PostDelayedTask(absl::Milliseconds(50),
|
||||
[&completed_tasks, ¬ification]() {
|
||||
completed_tasks.push_back("task1");
|
||||
if (completed_tasks.size() == 2) {
|
||||
notification.Notify();
|
||||
}
|
||||
});
|
||||
|
||||
// Run the second task
|
||||
task_runner.PostTask([&completed_tasks, ¬ification]() {
|
||||
completed_tasks.push_back("task2");
|
||||
if (completed_tasks.size() == 2) {
|
||||
notification.Notify();
|
||||
}
|
||||
});
|
||||
|
||||
notification.WaitForNotificationWithTimeout(absl::Milliseconds(200));
|
||||
ASSERT_EQ(completed_tasks.size(), 2u);
|
||||
EXPECT_EQ(completed_tasks[0], "task2");
|
||||
EXPECT_EQ(completed_tasks[1], "task1");
|
||||
}
|
||||
|
||||
TEST(TaskRunnerImpl, DISABLED_PostTwoDelayedTask) {
|
||||
TaskRunnerImpl task_runner{1};
|
||||
std::vector<std::string> completed_tasks;
|
||||
absl::Notification notification;
|
||||
|
||||
// Run the first task
|
||||
task_runner.PostDelayedTask(absl::Milliseconds(100),
|
||||
[&completed_tasks, ¬ification]() {
|
||||
completed_tasks.push_back("task1");
|
||||
if (completed_tasks.size() == 2) {
|
||||
notification.Notify();
|
||||
}
|
||||
});
|
||||
|
||||
// Run the second task
|
||||
task_runner.PostDelayedTask(absl::Milliseconds(50),
|
||||
[&completed_tasks, ¬ification]() {
|
||||
completed_tasks.push_back("task2");
|
||||
if (completed_tasks.size() == 2) {
|
||||
notification.Notify();
|
||||
}
|
||||
});
|
||||
|
||||
notification.WaitForNotificationWithTimeout(absl::Milliseconds(150));
|
||||
ASSERT_EQ(completed_tasks.size(), 2u);
|
||||
EXPECT_EQ(completed_tasks[0], "task2");
|
||||
EXPECT_EQ(completed_tasks[1], "task1");
|
||||
|
||||
absl::Notification notification2;
|
||||
task_runner.PostDelayedTask(absl::Milliseconds(100),
|
||||
[&completed_tasks, ¬ification2]() {
|
||||
completed_tasks.push_back("task3");
|
||||
notification2.Notify();
|
||||
});
|
||||
notification2.WaitForNotificationWithTimeout(absl::Milliseconds(150));
|
||||
ASSERT_EQ(completed_tasks.size(), 3u);
|
||||
EXPECT_EQ(completed_tasks[2], "task3");
|
||||
}
|
||||
|
||||
TEST(TaskRunnerImpl, PostTasksOnRunnerWithMultipleThreads) {
|
||||
TaskRunnerImpl task_runner{10};
|
||||
std::atomic_int count = 0;
|
||||
absl::Notification notification;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
task_runner.PostTask([&count, ¬ification]() {
|
||||
absl::SleepFor(absl::Milliseconds(100));
|
||||
count++;
|
||||
if (count == 10) {
|
||||
notification.Notify();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
notification.WaitForNotificationWithTimeout(absl::Milliseconds(190));
|
||||
EXPECT_EQ(count, 10);
|
||||
}
|
||||
|
||||
TEST(TaskRunnerImpl, PostEmptyTask) {
|
||||
TaskRunnerImpl task_runner{1};
|
||||
EXPECT_TRUE(task_runner.PostTask(nullptr));
|
||||
EXPECT_TRUE(task_runner.PostDelayedTask(absl::Milliseconds(100), nullptr));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TIMER_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TIMER_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
class Timer {
|
||||
public:
|
||||
virtual ~Timer() = default;
|
||||
|
||||
// Starts the timer.
|
||||
//
|
||||
// @param delay
|
||||
// The amount of time in milliseconds relative to the current time that must
|
||||
// elapse before the timer is signaled for the first time.
|
||||
// @param period
|
||||
// The period of the timer, in milliseconds.
|
||||
// If this parameter is zero, the timer is signaled once.
|
||||
// If this parameter is greater than zero, the timer is periodic.
|
||||
// @param callback
|
||||
// The callback is called when timer is signaled
|
||||
// @return
|
||||
// Returns true if succeed, otherwise false is returned.
|
||||
virtual bool Start(int delay, int period, std::function<void()> callback) = 0;
|
||||
virtual bool Stop() = 0;
|
||||
virtual bool IsRunning() = 0;
|
||||
virtual bool FireNow() = 0;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TIMER_H_
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/public/timer_impl.h"
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/time/clock.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
bool TimerImpl::Start(int delay, int period, std::function<void()> callback) {
|
||||
if (internal_timer_ != nullptr) {
|
||||
NEARBY_LOGS(INFO) << "The timer is already running.";
|
||||
return false;
|
||||
}
|
||||
|
||||
delay_ = delay;
|
||||
period_ = period;
|
||||
callback_ = std::move(callback);
|
||||
internal_timer_ = api::ImplementationFastPairPlatform::CreateTimer();
|
||||
if (!internal_timer_->Create(delay, period, callback_)) {
|
||||
NEARBY_LOGS(INFO) << "Failed to create timer.";
|
||||
internal_timer_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TimerImpl::Stop() {
|
||||
if (internal_timer_ == nullptr) {
|
||||
return true;
|
||||
}
|
||||
if (internal_timer_->Stop()) {
|
||||
internal_timer_ = nullptr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TimerImpl::IsRunning() { return (internal_timer_ != nullptr); }
|
||||
|
||||
bool TimerImpl::FireNow() {
|
||||
if (IsRunning()) {
|
||||
return internal_timer_->FireNow();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TIMER_IMPL_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TIMER_IMPL_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "fastpair/internal/api/fast_pair_platform.h"
|
||||
#include "fastpair/internal/public/timer.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
class TimerImpl : public Timer {
|
||||
public:
|
||||
~TimerImpl() override { Stop(); }
|
||||
|
||||
bool Start(int delay, int period, std::function<void()> callback) override;
|
||||
bool Stop() override;
|
||||
bool IsRunning() override;
|
||||
bool FireNow() override;
|
||||
|
||||
private:
|
||||
int delay_ = 0;
|
||||
int period_ = 0;
|
||||
std::function<void()> callback_ = nullptr;
|
||||
std::unique_ptr<api::Timer> internal_timer_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_PUBLIC_TIMER_IMPL_H_
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/internal/public/timer_impl.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
namespace {
|
||||
|
||||
TEST(TimerImpl, TestCreateTimer) {
|
||||
TimerImpl timer;
|
||||
|
||||
EXPECT_FALSE(timer.Start(-100, 0, nullptr));
|
||||
EXPECT_TRUE(timer.Start(100, 100, []() {}));
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
}
|
||||
|
||||
TEST(TimerImpl, TestRunningStatus) {
|
||||
TimerImpl timer;
|
||||
|
||||
EXPECT_TRUE(timer.Start(100, 100, []() {}));
|
||||
EXPECT_TRUE(timer.IsRunning());
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
EXPECT_FALSE(timer.IsRunning());
|
||||
}
|
||||
|
||||
TEST(TimerImpl, TestStartRunningTimer) {
|
||||
TimerImpl timer;
|
||||
|
||||
EXPECT_TRUE(timer.Start(100, 100, []() {}));
|
||||
EXPECT_FALSE(timer.Start(100, 100, []() {}));
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
}
|
||||
|
||||
TEST(TimerImpl, TestFireNow) {
|
||||
TimerImpl timer;
|
||||
int count = 0;
|
||||
|
||||
EXPECT_TRUE(timer.Start(100, 100, [&count]() { ++count; }));
|
||||
EXPECT_TRUE(timer.FireNow());
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
EXPECT_EQ(count, 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -148,6 +148,7 @@ cc_library(
|
||||
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
|
||||
visibility = [
|
||||
"//connections/clients/windows:__subpackages__",
|
||||
"//fastpair/internal/impl/windows:__subpackages__",
|
||||
"//location/nearby:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
|
||||
Reference in New Issue
Block a user