Add FastPairService adapter.

Add an adapter and windows plugin for scalable seeker,

PiperOrigin-RevId: 545920541
This commit is contained in:
Janusz Sobczak
2023-07-06 02:18:02 -07:00
committed by Copybara-Service
parent 08d157399c
commit d516e52204
11 changed files with 290 additions and 42 deletions
+4
View File
@@ -35,8 +35,10 @@ lexan.cc_windows_dll(
"//location/nearby/apps/better_together/windows/fast_pair:__subpackages__",
],
deps = [
"//fastpair:fast_pair_service",
"//fastpair/dart/proto:fastpair_cc_proto",
"//fastpair/keyed_service",
"//fastpair/plugins:windows_admin_plugin",
"//fastpair/ui:fast_pair_ui",
"//internal/platform:logging",
"//internal/platform/implementation/windows",
@@ -69,9 +71,11 @@ lexan.cc_windows_dll(
"//location/nearby/apps/better_together/windows/fast_pair:__subpackages__",
],
deps = [
"//fastpair:fast_pair_service",
"//fastpair/common",
"//fastpair/dart/proto:fastpair_cc_proto",
"//fastpair/keyed_service",
"//fastpair/plugins:windows_admin_plugin",
"//fastpair/ui:fast_pair_ui",
"//internal/platform:logging",
"//internal/platform/implementation/windows",
@@ -17,8 +17,11 @@
#include <memory>
#include <string>
#include "fastpair/fast_pair_service.h"
#include "fastpair/internal/fast_pair_seeker_impl.h"
#include "fastpair/keyed_service/fast_pair_mediator.h"
#include "fastpair/keyed_service/fast_pair_mediator_factory.h"
#include "fastpair/plugins/windows_admin_plugin.h"
#include "fastpair/ui/actions.h"
#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h"
#include "internal/platform/logging.h"
@@ -27,69 +30,138 @@ namespace nearby {
namespace fastpair {
namespace windows {
static Mediator *pMediator_ = nullptr;
// Set to 1 to use Mediator. Set to 0 to use scalable seeker.
#define USE_MEDIATOR 0
namespace {
#if USE_MEDIATOR
Mediator *pMediator_ = nullptr;
#else
WindowsAdminPlugin::PluginState *plugin_state = nullptr;
#endif /* USE_MEDIATOR */
WindowsAdminPlugin::PluginState *InitFastPairService() {
NEARBY_LOGS(INFO) << "[[ Init Fast Pair Service. ]]";
plugin_state = new WindowsAdminPlugin::PluginState();
plugin_state->fast_pair_service = std::make_unique<FastPairService>();
plugin_state->fast_pair_service->RegisterPluginProvider(
"admin", std::make_unique<WindowsAdminPlugin::Provider>(plugin_state));
return plugin_state;
}
void CloseFastPairService(void *instance) {
NEARBY_LOGS(INFO) << "[[ Closing Fast Pair Service. ]]";
CHECK_EQ(plugin_state, instance);
delete plugin_state;
plugin_state = nullptr;
NEARBY_LOGS(INFO) << "[[ Successfully closed Fast Pair Service. ]]";
}
void StartFastPairServiceScan(void *instance) {
CHECK_EQ(plugin_state, instance);
FastPairSeekerExt *seeker = static_cast<FastPairSeekerExt *>(
plugin_state->fast_pair_service->GetSeeker());
absl::Status status = seeker->StartFastPairScan();
NEARBY_LOGS(INFO) << "Start FP scan result: " << status;
}
} // namespace
void *InitMediator() {
#if defined(NEARBY_LOG_SEVERITY)
// Direct override of logging level.
NEARBY_LOG_SET_SEVERITY(NEARBY_LOG_SEVERITY);
#endif // LOG_SEVERITY_VERBOSE;
Mediator *pMediator = MediatorFactory::GetInstance()->CreateMediator();
pMediator_ = pMediator;
#if USE_MEDIATOR
pMediator_ = MediatorFactory::GetInstance()->CreateMediator();
return pMediator_;
#else
return InitFastPairService();
#endif /* USE_MEDIATOR */
}
void CloseMediator(Mediator *pMediator) {
void CloseMediator(void *instance) {
#if USE_MEDIATOR
NEARBY_LOGS(INFO) << "[[ Closing Fast Pair Mediator. ]]";
if (pMediator_ != nullptr) delete pMediator_;
NEARBY_LOGS(INFO) << "[[ Successfully closed Fast Pair Mediator. ]]";
#else
CloseFastPairService(instance);
#endif /* USE_MEDIATOR */
}
void __stdcall StartScan(Mediator *pMediator) {
void __stdcall StartScan(void *instance) {
NEARBY_LOGS(INFO) << "StartScan is called";
#if USE_MEDIATOR
if (pMediator_ == nullptr) {
NEARBY_LOGS(VERBOSE) << "The pMediator is a null pointer.";
return;
}
pMediator_->StartScanning();
Mediator *mediator = static_cast<Mediator *>(instance);
mediator->StartScanning();
#else
StartFastPairServiceScan(instance);
#endif /* USE_MEDIATOR */
}
void __stdcall AddNotificationControllerObserver(
Mediator *pMediator, FastPairNotificationController::Observer *observer) {
void *instance, FastPairNotificationController::Observer *observer) {
NEARBY_LOGS(INFO) << "AddNotificationControllerObserver is called";
#if USE_MEDIATOR
if (pMediator_ == nullptr) {
NEARBY_LOGS(VERBOSE) << "The pMediator is a null pointer.";
return;
}
static_cast<Mediator *>(pMediator)->GetNotificationController()->AddObserver(
observer);
Mediator *mediator = static_cast<Mediator *>(instance);
mediator->GetNotificationController()->AddObserver(observer);
#else
CHECK_EQ(plugin_state, instance);
plugin_state->observers.AddObserver(observer);
#endif /* USE_MEDIATOR */
}
void __stdcall RemoveNotificationControllerObserver(
Mediator *pMediator, FastPairNotificationController::Observer *observer) {
void *instance, FastPairNotificationController::Observer *observer) {
#if USE_MEDIATOR
if (pMediator_ == nullptr) {
NEARBY_LOGS(VERBOSE) << "The pMediator is a null pointer.";
return;
}
static_cast<Mediator *>(pMediator)
->GetNotificationController()
->RemoveObserver(observer);
Mediator *mediator = static_cast<Mediator *>(instance);
mediator->GetNotificationController()->RemoveObserver(observer);
#else
CHECK_EQ(plugin_state, instance);
plugin_state->observers.RemoveObserver(observer);
#endif /* USE_MEDIATOR */
}
void __stdcall DiscoveryClicked(Mediator *pMediator, DiscoveryAction action) {
static_cast<Mediator *>(pMediator)
->GetNotificationController()
->OnDiscoveryClicked(action);
void __stdcall DiscoveryClicked(void *instance, DiscoveryAction action) {
#if USE_MEDIATOR
Mediator *mediator = static_cast<Mediator *>(instance);
mediator->GetNotificationController()->OnDiscoveryClicked(action);
#else
CHECK_EQ(plugin_state, instance);
plugin_state->DiscoveryClicked(action);
#endif /* USE_MEDIATOR */
}
void __stdcall SetIsScreenLocked(bool is_locked) {
#if USE_MEDIATOR
if (pMediator_ == nullptr) {
NEARBY_LOGS(INFO) << "The pMediator is a null pointer.";
return;
}
NEARBY_LOGS(INFO) << "SetIsScreenLocked :" << is_locked;
pMediator_->SetIsScreenLocked(is_locked);
#else
if (plugin_state == nullptr) {
NEARBY_LOGS(INFO) << "Plugin not initialized";
return;
}
plugin_state->SetIsScreenLocked(is_locked);
#endif /* USE_MEDIATOR */
}
} // namespace windows
} // namespace fastpair
} // namespace nearby
@@ -31,18 +31,18 @@ namespace windows {
DLL_EXPORT void *__stdcall InitMediator();
// Starts scanning service
DLL_EXPORT void __stdcall StartScan(Mediator *pMediator);
DLL_EXPORT void __stdcall StartScan(void *instance);
// Adds a notification controller observer to the service.
DLL_EXPORT void __stdcall AddNotificationControllerObserver(
Mediator *pMediator, FastPairNotificationController::Observer *observer);
void *instance, FastPairNotificationController::Observer *observer);
// Removes a notification controller observer to the service.
DLL_EXPORT void __stdcall RemoveNotificationControllerObserver(
Mediator *pMediator, FastPairNotificationController::Observer *observer);
void *instance, FastPairNotificationController::Observer *observer);
// Triggers discovery click action
DLL_EXPORT void DiscoveryClicked(Mediator *pMediator, DiscoveryAction action);
DLL_EXPORT void DiscoveryClicked(void *instance, DiscoveryAction action);
// Sends screen locked event.
DLL_EXPORT void __stdcall SetIsScreenLocked(bool is_locked);
@@ -68,40 +68,38 @@ class NotificationControllerObserver
};
} // namespace
void InitMediatorDart() { InitMediator(); }
void *InitMediatorDart() { return InitMediator(); }
void StartScanDart(Mediator *pMediator) { StartScan(pMediator); }
void StartScanDart(void *instance) { StartScan(instance); }
static absl::flat_hash_map<Dart_Port,
std::unique_ptr<NotificationControllerObserver>>
*notification_controller_observer_map_ = new absl::flat_hash_map<
Dart_Port, std::unique_ptr<NotificationControllerObserver>>();
void AddNotificationControllerObserverDart(Mediator *pMediator,
Dart_Port port) {
void AddNotificationControllerObserverDart(void *instance, Dart_Port port) {
auto observer = std::make_unique<NotificationControllerObserver>(port);
AddNotificationControllerObserver(pMediator, observer.get());
AddNotificationControllerObserver(instance, observer.get());
notification_controller_observer_map_->insert({port, std::move(observer)});
CHECK(notification_controller_observer_map_->contains(port));
}
void RemoveNotificationControllerObserverDart(Mediator *pMediator,
Dart_Port port) {
void RemoveNotificationControllerObserverDart(void *instance, Dart_Port port) {
auto it = notification_controller_observer_map_->find(port);
if (it != notification_controller_observer_map_->end()) {
RemoveNotificationControllerObserver(pMediator, it->second.get());
RemoveNotificationControllerObserver(instance, it->second.get());
notification_controller_observer_map_->erase(it);
}
}
void DiscoveryClickedDart(Mediator *pMediator, int action) {
void DiscoveryClickedDart(void *instance, int action) {
switch (action) {
case ::nearby::fastpair::dart::proto::DISCOVERY_ACTION_PAIR_TO_DEVICE:
DiscoveryClicked(pMediator,
DiscoveryClicked(instance,
::nearby::fastpair::DiscoveryAction::kPairToDevice);
break;
case ::nearby::fastpair::dart::proto::DISCOVERY_ACTION_LEARN_MORE:
DiscoveryClicked(pMediator,
DiscoveryClicked(instance,
::nearby::fastpair::DiscoveryAction::kLearnMore);
break;
}
@@ -25,21 +25,21 @@ namespace fastpair {
namespace windows {
// Initiates a default Mediator instance.
DLL_EXPORT void __stdcall InitMediatorDart();
DLL_EXPORT void* __stdcall InitMediatorDart();
// Starts scanning service
DLL_EXPORT void __stdcall StartScanDart(Mediator* pMediator);
DLL_EXPORT void __stdcall StartScanDart(void* instance);
// Adds a notification controller observer to the service.
DLL_EXPORT void __stdcall AddNotificationControllerObserverDart(
Mediator* pMediator, Dart_Port port);
DLL_EXPORT void __stdcall AddNotificationControllerObserverDart(void* instance,
Dart_Port port);
// Removes a notification controller observer to the service.
DLL_EXPORT void __stdcall RemoveNotificationControllerObserverDart(
Mediator* pMediator, Dart_Port port);
void* instance, Dart_Port port);
// Triggers discovery click action
DLL_EXPORT void __stdcall DiscoveryClickedDart(Mediator* pMediator, int action);
DLL_EXPORT void __stdcall DiscoveryClickedDart(void* instance, int action);
} // namespace windows
} // namespace fastpair
+3 -1
View File
@@ -26,7 +26,9 @@ struct InitialDiscoveryEvent {};
struct SubsequentDiscoveryEvent {};
struct PairEvent {};
struct PairEvent {
bool is_paired;
};
struct ScreenEvent {
std::optional<bool> is_locked;
+13 -2
View File
@@ -45,7 +45,7 @@ constexpr FeatureFlags::Flags fast_pair_feature_flags = FeatureFlags::Flags{
.enable_scan_for_fast_pair_advertisement = true,
};
constexpr absl::Duration kTimeout = absl::Seconds(3);
}
} // namespace
FastPairService::FastPairService()
: FastPairService(std::make_unique<auth::AuthenticationManagerImpl>(),
@@ -159,8 +159,19 @@ void FastPairService::OnInitialDiscoveryEvent(const FastPairDevice& device,
void FastPairService::OnSubsequentDiscoveryEvent(
const FastPairDevice& device, SubsequentDiscoveryEvent event) {}
void FastPairService::OnPairEvent(const FastPairDevice& device,
PairEvent event) {}
PairEvent event) {
executor_.Execute(
"on-pair-event", [this, device = &device, event = std::move(event)]() {
NEARBY_LOGS(INFO) << "OnPairEvent " << *device;
for (auto& entry : plugin_states_) {
auto plugin = entry.second.GetPlugin(seeker_.get(), device);
plugin->OnPairEvent(event);
}
});
}
void FastPairService::OnScreenEvent(ScreenEvent event) {
executor_.Execute("on-screen-event", [this, event = std::move(event)]() {
NEARBY_LOGS(INFO) << "OnScreenEvent ";
+5 -1
View File
@@ -221,6 +221,10 @@ void FastPairSeekerImpl::DevicePairedChanged(BluetoothDevice& device,
bool new_paired_status) {
NEARBY_LOGS(VERBOSE) << __func__ << "(" << device.GetMacAddress() << ", "
<< new_paired_status << ")";
// Note, the FP service will be notified about paired events from the
// retroactive pairing path if `device` is an FP device.
// TODO(jsobczak): Notify service about unpair events if `device` is a known
// FP device.
}
void FastPairSeekerImpl::DeviceConnectedStateChanged(BluetoothDevice& device,
@@ -231,7 +235,7 @@ void FastPairSeekerImpl::DeviceConnectedStateChanged(BluetoothDevice& device,
void FastPairSeekerImpl::OnRetroactivePairFound(FastPairDevice& device) {
NEARBY_LOGS(VERBOSE) << __func__ << ": " << device;
callbacks_.on_pair_event(device, PairEvent{});
callbacks_.on_pair_event(device, PairEvent{.is_paired = true});
}
} // namespace fastpair
+17
View File
@@ -33,6 +33,23 @@ cc_library(
],
)
cc_library(
name = "windows_admin_plugin",
srcs = ["windows_admin_plugin.cc"],
hdrs = ["windows_admin_plugin.h"],
compatible_with = ["//buildenv/target:non_prod"],
visibility = ["//:__subpackages__"],
deps = [
"//fastpair:fast_pair_events",
"//fastpair:fast_pair_plugin",
"//fastpair:fast_pair_seeker",
"//fastpair:fast_pair_service",
"//fastpair/common",
"//fastpair/ui:fast_pair_ui",
"//internal/platform:types",
],
)
cc_test(
name = "fake_initial_pair_plugin_test",
size = "small",
+71
View File
@@ -0,0 +1,71 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastpair/plugins/windows_admin_plugin.h"
#include "fastpair/internal/fast_pair_seeker_impl.h"
namespace nearby {
namespace fastpair {
void WindowsAdminPlugin::PluginState::DiscoveryClicked(DiscoveryAction action) {
NEARBY_LOGS(INFO) << __func__;
if (device == nullptr || fast_pair_service == nullptr) return;
absl::Status status = fast_pair_service->GetSeeker()->StartInitialPairing(
*device, InitialPairingParam{},
{.on_pairing_result = [](const FastPairDevice& device,
absl::Status status) {
NEARBY_LOGS(INFO) << "Pairing result: " << status;
}});
NEARBY_LOGS(INFO) << "StartInitialPairing: " << status;
}
void WindowsAdminPlugin::PluginState::SetIsScreenLocked(bool is_locked) {
NEARBY_LOGS(INFO) << __func__;
if (device == nullptr || fast_pair_service == nullptr) return;
FastPairSeekerExt* seeker =
static_cast<FastPairSeekerExt*>(fast_pair_service->GetSeeker());
seeker->SetIsScreenLocked(is_locked);
}
void WindowsAdminPlugin::OnInitialDiscoveryEvent(
const InitialDiscoveryEvent& event) {
NEARBY_LOGS(INFO) << "Received on initial discovery event";
auto metadata = device_->GetMetadata();
if (!metadata) {
NEARBY_LOGS(INFO)
<< "Ignoring initial discovery event because metadata is missing";
return;
}
state_->device = device_;
for (auto* observer : state_->observers.GetObservers()) {
observer->OnUpdateDevice(*metadata);
}
}
void WindowsAdminPlugin::OnPairEvent(const PairEvent& event) {
NEARBY_LOGS(INFO) << "Received on pair event";
absl::Status status = seeker_->StartRetroactivePairing(
*device_, RetroactivePairingParam{},
{.on_pairing_result = [](const FastPairDevice& device,
absl::Status status) {
NEARBY_LOGS(INFO) << "Pairing result: " << status;
// TODO(jsobczak): Ask for user constent and save the Account Key to
// user's account.
}});
NEARBY_LOGS(INFO) << "StartRetroactivePairing: " << status;
}
} // namespace fastpair
} // namespace nearby
+69
View File
@@ -0,0 +1,69 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_WINDOWS_ADMIN_PLUGIN_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_WINDOWS_ADMIN_PLUGIN_H_
#include <memory>
#include "fastpair/common/fast_pair_device.h"
#include "fastpair/fast_pair_events.h"
#include "fastpair/fast_pair_plugin.h"
#include "fastpair/fast_pair_seeker.h"
#include "fastpair/fast_pair_service.h"
#include "fastpair/ui/actions.h"
#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace fastpair {
class WindowsAdminPlugin : public FastPairPlugin {
public:
struct PluginState {
void DiscoveryClicked(DiscoveryAction action);
void SetIsScreenLocked(bool is_locked);
ObserverList<FastPairNotificationController::Observer> observers;
const FastPairDevice* device = nullptr;
std::unique_ptr<FastPairService> fast_pair_service;
};
class Provider : public FastPairPluginProvider {
public:
explicit Provider(PluginState* state) : state_(state) {}
std::unique_ptr<FastPairPlugin> GetPlugin(
FastPairSeeker* seeker, const FastPairDevice* device) override {
return std::make_unique<WindowsAdminPlugin>(seeker, device, state_);
}
private:
PluginState* state_;
};
WindowsAdminPlugin(FastPairSeeker* seeker, const FastPairDevice* device,
PluginState* state)
: seeker_(seeker), device_(device), state_(state) {}
void OnInitialDiscoveryEvent(const InitialDiscoveryEvent& event) override;
void OnPairEvent(const PairEvent& event) override;
private:
FastPairSeeker* seeker_;
const FastPairDevice* device_;
PluginState* state_;
};
} // namespace fastpair
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_FASTPAIR_PLUGINS_WINDOWS_ADMIN_PLUGIN_H_