Commit b20a4341 authored by Justin Carlson's avatar Justin Carlson Committed by Commit Bot

Refactor ServiceDiscoveryDeviceLister.

This change does two things.  First, it splits out the implementation
of ServiceDiscoveryDeviceLister from the interface, which will allow
users of the API to mock/fake it for testing.

Second, it adds a service_type parameter to
ServiceDiscoveryDeviceLister::Delegate::OnDeviceCacheFlushed.  This
allows users of the class that want to manage multiple service types
with a single Delegate to disambiguate which service is being flushed.
The other Delegate functions already pass in the service description
so don't need any additional information for this use.

Also fixup callsites for all users of this API.

Bug: 808157
Change-Id: I9cf4b23692f54c66e0224e06df1769f750f846b3
Reviewed-on: https://chromium-review.googlesource.com/898184
Commit-Queue: Justin Carlson <justincarlson@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarGene Gutnik <gene@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Reviewed-by: default avatarSean Kau <skau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534146}
parent 6ff23b06
......@@ -226,9 +226,8 @@ class ZeroconfPrinterDetectorImpl
// Since we start the discoverers immediately, this must come last in the
// constructor.
for (const char* service : services) {
device_listers_.emplace_back(
std::make_unique<ServiceDiscoveryDeviceLister>(
this, discovery_client_.get(), service));
device_listers_.emplace_back(ServiceDiscoveryDeviceLister::Create(
this, discovery_client_.get(), service));
device_listers_.back()->Start();
device_listers_.back()->DiscoverNewDevices();
}
......@@ -250,7 +249,8 @@ class ZeroconfPrinterDetectorImpl
}
// ServiceDiscoveryDeviceLister::Delegate implementation
void OnDeviceChanged(bool added,
void OnDeviceChanged(const std::string& service_type,
bool added,
const ServiceDescription& service_description) override {
// We don't care if it was added or not; we generate an update either way.
ParsedMetadata metadata(service_description);
......@@ -270,7 +270,8 @@ class ZeroconfPrinterDetectorImpl
}
}
void OnDeviceRemoved(const std::string& service_name) override {
void OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) override {
// Leverage ServiceDescription parsing to pull out the instance name.
ServiceDescription service_description;
service_description.service_name = service_name;
......@@ -285,7 +286,7 @@ class ZeroconfPrinterDetectorImpl
}
// Don't need to do anything here.
void OnDeviceCacheFlushed() override {}
void OnDeviceCacheFlushed(const std::string& service_type) override {}
private:
// Requires that printers_lock_ be held.
......
......@@ -102,30 +102,33 @@ class CastDeviceProvider::DeviceListerDelegate
if (device_lister_)
return;
service_discovery_client_ = ServiceDiscoverySharedClient::GetInstance();
device_lister_.reset(new ServiceDiscoveryDeviceLister(
this, service_discovery_client_.get(), kCastServiceType));
device_lister_ = ServiceDiscoveryDeviceLister::Create(
this, service_discovery_client_.get(), kCastServiceType);
device_lister_->Start();
device_lister_->DiscoverNewDevices();
}
// ServiceDiscoveryDeviceLister::Delegate implementation:
void OnDeviceChanged(bool added,
void OnDeviceChanged(const std::string& service_type,
bool added,
const ServiceDescription& service_description) override {
runner_->PostTask(FROM_HERE,
base::BindOnce(&CastDeviceProvider::OnDeviceChanged,
provider_, added, service_description));
runner_->PostTask(
FROM_HERE,
base::BindOnce(&CastDeviceProvider::OnDeviceChanged, provider_,
service_type, added, service_description));
}
void OnDeviceRemoved(const std::string& service_name) override {
void OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) override {
runner_->PostTask(FROM_HERE,
base::BindOnce(&CastDeviceProvider::OnDeviceRemoved,
provider_, service_name));
provider_, service_type, service_name));
}
void OnDeviceCacheFlushed() override {
runner_->PostTask(
FROM_HERE,
base::BindOnce(&CastDeviceProvider::OnDeviceCacheFlushed, provider_));
void OnDeviceCacheFlushed(const std::string& service_type) override {
runner_->PostTask(FROM_HERE,
base::BindOnce(&CastDeviceProvider::OnDeviceCacheFlushed,
provider_, service_type));
}
private:
......@@ -173,6 +176,7 @@ void CastDeviceProvider::OpenSocket(const std::string& serial,
}
void CastDeviceProvider::OnDeviceChanged(
const std::string& service_type,
bool added,
const ServiceDescription& service_description) {
VLOG(1) << "Device " << (added ? "added: " : "changed: ")
......@@ -190,7 +194,8 @@ void CastDeviceProvider::OnDeviceChanged(
device_info_map_[host] = ServiceDescriptionToDeviceInfo(service_description);
}
void CastDeviceProvider::OnDeviceRemoved(const std::string& service_name) {
void CastDeviceProvider::OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) {
VLOG(1) << "Device removed: " << service_name;
auto it = service_hostname_map_.find(service_name);
if (it == service_hostname_map_.end())
......@@ -200,7 +205,7 @@ void CastDeviceProvider::OnDeviceRemoved(const std::string& service_name) {
service_hostname_map_.erase(it);
}
void CastDeviceProvider::OnDeviceCacheFlushed() {
void CastDeviceProvider::OnDeviceCacheFlushed(const std::string& service_type) {
VLOG(1) << "Device cache flushed";
service_hostname_map_.clear();
device_info_map_.clear();
......
......@@ -35,10 +35,12 @@ class CastDeviceProvider
// ServiceDiscoveryDeviceLister::Delegate implementation:
void OnDeviceChanged(
const std::string& service_type,
bool added,
const local_discovery::ServiceDescription& service_description) override;
void OnDeviceRemoved(const std::string& service_name) override;
void OnDeviceCacheFlushed() override;
void OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) override;
void OnDeviceCacheFlushed(const std::string& service_type) override;
private:
class DeviceListerDelegate;
......
......@@ -52,7 +52,7 @@ TEST(CastDeviceProviderTest, ServiceDiscovery) {
cast_service.metadata.push_back("md=" + cast_service_model);
ASSERT_TRUE(cast_service.ip_address.AssignFromIPLiteral("192.168.1.101"));
device_provider_->OnDeviceChanged(true, cast_service);
device_provider_->OnDeviceChanged(cast_service_type, true, cast_service);
BrowserInfo exp_browser_info;
exp_browser_info.socket_name = "9222";
......@@ -91,7 +91,7 @@ TEST(CastDeviceProviderTest, ServiceDiscovery) {
base::Bind(&DummyCallback, &was_run));
ASSERT_FALSE(was_run);
device_provider_->OnDeviceChanged(true, other_service);
device_provider_->OnDeviceChanged(cast_service_type, true, other_service);
// Callback should not be run, since non-cast services are not discovered by
// this device provider.
......@@ -100,7 +100,8 @@ TEST(CastDeviceProviderTest, ServiceDiscovery) {
ASSERT_FALSE(was_run);
// Remove the cast service.
device_provider_->OnDeviceRemoved(cast_service.service_name);
device_provider_->OnDeviceRemoved(cast_service_type,
cast_service.service_name);
// Callback should not be run, since the cast service has been removed.
device_provider_->QueryDeviceInfo(cast_service.address.host(),
......
......@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
......@@ -20,103 +21,127 @@ namespace {
#if defined(OS_MACOSX)
const int kMacServiceResolvingIntervalSecs = 60;
#endif
} // namespace
ServiceDiscoveryDeviceLister::ServiceDiscoveryDeviceLister(
Delegate* delegate,
ServiceDiscoveryClient* service_discovery_client,
const std::string& service_type)
: delegate_(delegate),
service_discovery_client_(service_discovery_client),
service_type_(service_type),
weak_factory_(this) {
}
ServiceDiscoveryDeviceLister::~ServiceDiscoveryDeviceLister() {
}
void ServiceDiscoveryDeviceLister::Start() {
VLOG(1) << "DeviceListerStart: service_type: " << service_type_;
CreateServiceWatcher();
}
void ServiceDiscoveryDeviceLister::DiscoverNewDevices() {
VLOG(1) << "DiscoverNewDevices: service_type: " << service_type_;
service_watcher_->DiscoverNewServices();
}
void ServiceDiscoveryDeviceLister::OnServiceUpdated(
ServiceWatcher::UpdateType update,
const std::string& service_name) {
VLOG(1) << "OnServiceUpdated: service_type: " << service_type_
<< ", service_name: " << service_name
<< ", update: " << update;
if (update == ServiceWatcher::UPDATE_INVALIDATED) {
resolvers_.clear();
class ServiceDiscoveryDeviceListerImpl : public ServiceDiscoveryDeviceLister {
public:
ServiceDiscoveryDeviceListerImpl(
Delegate* delegate,
ServiceDiscoveryClient* service_discovery_client,
const std::string& service_type)
: delegate_(delegate),
service_discovery_client_(service_discovery_client),
service_type_(service_type),
weak_factory_(this) {}
~ServiceDiscoveryDeviceListerImpl() override = default;
// ServiceDiscoveryDeviceLister implementation.
void Start() override {
VLOG(1) << "DeviceListerStart: service_type: " << service_type_;
CreateServiceWatcher();
delegate_->OnDeviceCacheFlushed();
return;
}
if (update == ServiceWatcher::UPDATE_REMOVED) {
delegate_->OnDeviceRemoved(service_name);
return;
// ServiceDiscoveryDeviceLister implementation.
void DiscoverNewDevices() override {
VLOG(1) << "DiscoverNewDevices: service_type: " << service_type_;
service_watcher_->DiscoverNewServices();
}
// If there is already a resolver working on this service, don't add one.
if (base::ContainsKey(resolvers_, service_name)) {
VLOG(1) << "Resolver already exists, service_name: " << service_name;
return;
const std::string& service_type() const override { return service_type_; }
private:
using ServiceResolverMap =
std::map<std::string, std::unique_ptr<ServiceResolver>>;
void OnServiceUpdated(ServiceWatcher::UpdateType update,
const std::string& service_name) {
VLOG(1) << "OnServiceUpdated: service_type: " << service_type_
<< ", service_name: " << service_name << ", update: " << update;
if (update == ServiceWatcher::UPDATE_INVALIDATED) {
resolvers_.clear();
CreateServiceWatcher();
delegate_->OnDeviceCacheFlushed(service_type_);
return;
}
if (update == ServiceWatcher::UPDATE_REMOVED) {
delegate_->OnDeviceRemoved(service_type_, service_name);
return;
}
// If there is already a resolver working on this service, don't add one.
if (base::ContainsKey(resolvers_, service_name)) {
VLOG(1) << "Resolver already exists, service_name: " << service_name;
return;
}
VLOG(1) << "Adding resolver for service_name: " << service_name;
bool added = (update == ServiceWatcher::UPDATE_ADDED);
std::unique_ptr<ServiceResolver> resolver =
service_discovery_client_->CreateServiceResolver(
service_name,
base::Bind(&ServiceDiscoveryDeviceListerImpl::OnResolveComplete,
weak_factory_.GetWeakPtr(), added, service_name));
resolver->StartResolving();
resolvers_[service_name] = std::move(resolver);
}
VLOG(1) << "Adding resolver for service_name: " << service_name;
bool added = (update == ServiceWatcher::UPDATE_ADDED);
std::unique_ptr<ServiceResolver> resolver =
service_discovery_client_->CreateServiceResolver(
service_name,
base::Bind(&ServiceDiscoveryDeviceLister::OnResolveComplete,
weak_factory_.GetWeakPtr(), added, service_name));
resolver->StartResolving();
resolvers_[service_name] = std::move(resolver);
}
// TODO(noamsml): Update ServiceDiscoveryClient interface to match this.
void ServiceDiscoveryDeviceLister::OnResolveComplete(
bool added,
std::string service_name,
ServiceResolver::RequestStatus status,
const ServiceDescription& service_description) {
VLOG(1) << "OnResolveComplete: service_type: " << service_type_
<< ", service_name: " << service_name
<< ", status: " << status;
if (status == ServiceResolver::STATUS_SUCCESS) {
delegate_->OnDeviceChanged(added, service_description);
// TODO(noamsml): Update ServiceDiscoveryClient interface to match this.
void OnResolveComplete(bool added,
std::string service_name,
ServiceResolver::RequestStatus status,
const ServiceDescription& service_description) {
VLOG(1) << "OnResolveComplete: service_type: " << service_type_
<< ", service_name: " << service_name << ", status: " << status;
if (status == ServiceResolver::STATUS_SUCCESS) {
delegate_->OnDeviceChanged(service_type_, added, service_description);
#if defined(OS_MACOSX)
// On Mac, the Bonjour service does not seem to ever evict a service if a
// device is unplugged, so we need to continuously try to resolve the
// service to detect non-graceful shutdowns.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&ServiceDiscoveryDeviceLister::OnServiceUpdated,
weak_factory_.GetWeakPtr(), ServiceWatcher::UPDATE_CHANGED,
service_description.service_name),
base::TimeDelta::FromSeconds(kMacServiceResolvingIntervalSecs));
// On Mac, the Bonjour service does not seem to ever evict a service if a
// device is unplugged, so we need to continuously try to resolve the
// service to detect non-graceful shutdowns.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&ServiceDiscoveryDeviceListerImpl::OnServiceUpdated,
weak_factory_.GetWeakPtr(), ServiceWatcher::UPDATE_CHANGED,
service_description.service_name),
base::TimeDelta::FromSeconds(kMacServiceResolvingIntervalSecs));
#endif
} else {
// TODO(noamsml): Add retry logic.
} else {
// TODO(noamsml): Add retry logic.
}
resolvers_.erase(service_name);
}
resolvers_.erase(service_name);
}
void ServiceDiscoveryDeviceLister::CreateServiceWatcher() {
service_watcher_ =
service_discovery_client_->CreateServiceWatcher(
service_type_,
base::Bind(&ServiceDiscoveryDeviceLister::OnServiceUpdated,
weak_factory_.GetWeakPtr()));
service_watcher_->Start();
// Create or recreate the service watcher
void CreateServiceWatcher() {
service_watcher_ = service_discovery_client_->CreateServiceWatcher(
service_type_,
base::Bind(&ServiceDiscoveryDeviceListerImpl::OnServiceUpdated,
weak_factory_.GetWeakPtr()));
service_watcher_->Start();
}
Delegate* const delegate_;
ServiceDiscoveryClient* const service_discovery_client_;
const std::string service_type_;
std::unique_ptr<ServiceWatcher> service_watcher_;
ServiceResolverMap resolvers_;
base::WeakPtrFactory<ServiceDiscoveryDeviceListerImpl> weak_factory_;
};
} // namespace
// static
std::unique_ptr<ServiceDiscoveryDeviceLister>
ServiceDiscoveryDeviceLister::Create(
Delegate* delegate,
ServiceDiscoveryClient* service_discovery_client,
const std::string& service_type) {
return std::make_unique<ServiceDiscoveryDeviceListerImpl>(
delegate, service_discovery_client, service_type);
}
} // namespace local_discovery
......@@ -9,60 +9,44 @@
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/local_discovery/service_discovery_client.h"
namespace local_discovery {
// ServiceDiscoveryDeviceLister provides a way to get and maintain a list of all
// discoverable devices of a given service type (e.g. _ipp._tcp).
class ServiceDiscoveryDeviceLister {
public:
// Delegate interface to be implemented by recipients of list updates.
class Delegate {
public:
virtual void OnDeviceChanged(
const std::string& service_type,
bool added,
const ServiceDescription& service_description) = 0;
// Not guaranteed to be called after OnDeviceChanged.
virtual void OnDeviceRemoved(const std::string& service_name) = 0;
virtual void OnDeviceCacheFlushed() = 0;
virtual void OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) = 0;
virtual void OnDeviceCacheFlushed(const std::string& service_type) = 0;
};
ServiceDiscoveryDeviceLister(Delegate* delegate,
ServiceDiscoveryClient* service_discovery_client,
const std::string& service_type);
virtual ~ServiceDiscoveryDeviceLister();
virtual ~ServiceDiscoveryDeviceLister() = default;
void Start();
void DiscoverNewDevices();
virtual void Start() = 0;
virtual void DiscoverNewDevices() = 0;
const std::string& service_type() const { return service_type_; }
virtual const std::string& service_type() const = 0;
private:
using ServiceResolverMap =
std::map<std::string, std::unique_ptr<ServiceResolver>>;
void OnServiceUpdated(ServiceWatcher::UpdateType update,
const std::string& service_name);
void OnResolveComplete(
bool added,
std::string service_name,
ServiceResolver::RequestStatus status,
const ServiceDescription& description);
// Create or recreate the service watcher
void CreateServiceWatcher();
Delegate* const delegate_;
ServiceDiscoveryClient* const service_discovery_client_;
const std::string service_type_;
std::unique_ptr<ServiceWatcher> service_watcher_;
ServiceResolverMap resolvers_;
base::WeakPtrFactory<ServiceDiscoveryDeviceLister> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceDiscoveryDeviceLister);
// Factory function, create and return a default-implementation DeviceLister
// that lists devices of type |service_type|. |delegate| will receive
// callbacks, and |service_discovery_client| will be used as the source of the
// the underlying discovery traffic.
//
// Typically, the ServiceDiscoverySharedClient is used as the client.
static std::unique_ptr<ServiceDiscoveryDeviceLister> Create(
Delegate* delegate,
ServiceDiscoveryClient* service_discovery_client,
const std::string& service_type);
};
} // namespace local_discovery
......
......@@ -31,24 +31,28 @@ DnsSdDeviceLister::DnsSdDeviceLister(
DnsSdDelegate* delegate,
const std::string& service_type)
: delegate_(delegate),
device_lister_(this, service_discovery_client, service_type),
device_lister_(local_discovery::ServiceDiscoveryDeviceLister::Create(
this,
service_discovery_client,
service_type)),
started_(false) {}
DnsSdDeviceLister::~DnsSdDeviceLister() {}
void DnsSdDeviceLister::Discover() {
if (!started_) {
device_lister_.Start();
device_lister_->Start();
started_ = true;
VLOG(1) << "Started device lister for service type "
<< device_lister_.service_type();
<< device_lister_->service_type();
}
device_lister_.DiscoverNewDevices();
device_lister_->DiscoverNewDevices();
VLOG(1) << "Discovery new devices for service type "
<< device_lister_.service_type();
<< device_lister_->service_type();
}
void DnsSdDeviceLister::OnDeviceChanged(
const std::string& service_type,
bool added,
const ServiceDescription& service_description) {
DnsSdService service;
......@@ -56,22 +60,23 @@ void DnsSdDeviceLister::OnDeviceChanged(
VLOG(1) << "OnDeviceChanged: "
<< "service_name: " << service.service_name << ", "
<< "added: " << added << ", "
<< "service_type: " << device_lister_.service_type();
delegate_->ServiceChanged(device_lister_.service_type(), added, service);
<< "service_type: " << device_lister_->service_type();
delegate_->ServiceChanged(device_lister_->service_type(), added, service);
}
void DnsSdDeviceLister::OnDeviceRemoved(const std::string& service_name) {
void DnsSdDeviceLister::OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) {
VLOG(1) << "OnDeviceRemoved: "
<< "service_name: " << service_name << ", "
<< "service_type: " << device_lister_.service_type();
delegate_->ServiceRemoved(device_lister_.service_type(), service_name);
<< "service_type: " << service_type;
delegate_->ServiceRemoved(service_type, service_name);
}
void DnsSdDeviceLister::OnDeviceCacheFlushed() {
void DnsSdDeviceLister::OnDeviceCacheFlushed(const std::string& service_type) {
VLOG(1) << "OnDeviceCacheFlushed: "
<< "service_type: " << device_lister_.service_type();
delegate_->ServicesFlushed(device_lister_.service_type());
device_lister_.DiscoverNewDevices();
<< "service_type: " << device_lister_->service_type();
delegate_->ServicesFlushed(device_lister_->service_type());
device_lister_->DiscoverNewDevices();
}
} // namespace media_router
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_MDNS_DNS_SD_DEVICE_LISTER_H_
#define CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_MDNS_DNS_SD_DEVICE_LISTER_H_
#include <memory>
#include <string>
#include "base/macros.h"
......@@ -32,15 +33,17 @@ class DnsSdDeviceLister
protected:
void OnDeviceChanged(
const std::string& service_type,
bool added,
const local_discovery::ServiceDescription& service_description) override;
void OnDeviceRemoved(const std::string& service_name) override;
void OnDeviceCacheFlushed() override;
void OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) override;
void OnDeviceCacheFlushed(const std::string& service_type) override;
private:
// The delegate to notify of changes to services.
DnsSdDelegate* const delegate_;
local_discovery::ServiceDiscoveryDeviceLister device_lister_;
std::unique_ptr<local_discovery::ServiceDiscoveryDeviceLister> device_lister_;
bool started_;
DISALLOW_COPY_AND_ASSIGN(DnsSdDeviceLister);
......
......@@ -14,21 +14,24 @@ PrivetDeviceListerImpl::PrivetDeviceListerImpl(
local_discovery::ServiceDiscoveryClient* service_discovery_client,
PrivetDeviceLister::Delegate* delegate)
: delegate_(delegate),
device_lister_(this, service_discovery_client, kPrivetDefaultDeviceType) {
}
device_lister_(local_discovery::ServiceDiscoveryDeviceLister::Create(
this,
service_discovery_client,
kPrivetDefaultDeviceType)) {}
PrivetDeviceListerImpl::~PrivetDeviceListerImpl() {
}
void PrivetDeviceListerImpl::Start() {
device_lister_.Start();
device_lister_->Start();
}
void PrivetDeviceListerImpl::DiscoverNewDevices() {
device_lister_.DiscoverNewDevices();
device_lister_->DiscoverNewDevices();
}
void PrivetDeviceListerImpl::OnDeviceChanged(
const std::string& service_type,
bool added,
const local_discovery::ServiceDescription& service_description) {
if (!delegate_)
......@@ -38,12 +41,14 @@ void PrivetDeviceListerImpl::OnDeviceChanged(
DeviceDescription(service_description));
}
void PrivetDeviceListerImpl::OnDeviceRemoved(const std::string& service_name) {
void PrivetDeviceListerImpl::OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) {
if (delegate_)
delegate_->DeviceRemoved(service_name);
}
void PrivetDeviceListerImpl::OnDeviceCacheFlushed() {
void PrivetDeviceListerImpl::OnDeviceCacheFlushed(
const std::string& service_type) {
if (delegate_)
delegate_->DeviceCacheFlushed();
}
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_DEVICE_LISTER_IMPL_H_
#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_DEVICE_LISTER_IMPL_H_
#include <memory>
#include <string>
#include "chrome/browser/local_discovery/service_discovery_device_lister.h"
......@@ -32,14 +33,16 @@ class PrivetDeviceListerImpl
protected:
// ServiceDiscoveryDeviceLister:
void OnDeviceChanged(
const std::string& service_type,
bool added,
const local_discovery::ServiceDescription& service_description) override;
void OnDeviceRemoved(const std::string& service_name) override;
void OnDeviceCacheFlushed() override;
void OnDeviceRemoved(const std::string& service_type,
const std::string& service_name) override;
void OnDeviceCacheFlushed(const std::string& service_type) override;
private:
PrivetDeviceLister::Delegate* const delegate_;
local_discovery::ServiceDiscoveryDeviceLister device_lister_;
std::unique_ptr<local_discovery::ServiceDiscoveryDeviceLister> device_lister_;
};
} // namespace cloud_print
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment