567 lines
20 KiB
C++
567 lines
20 KiB
C++
//
|
|
// Copyright (C) 2015 The Android Open Source Project
|
|
//
|
|
// 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
|
|
//
|
|
// http://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 <time.h>
|
|
|
|
#include <base/message_loop/message_loop.h>
|
|
|
|
#include "proxy_dbus_client.h"
|
|
|
|
const char ProxyDbusClient::kCommonLogScopes[] =
|
|
"connection+dbus+device+link+manager+portal+service";
|
|
const int ProxyDbusClient::kLogLevel = -4;
|
|
const char ProxyDbusClient::kDbusErrorObjectUnknown[] =
|
|
"org.freedesktop.DBus.Error.UnknownObject";
|
|
|
|
namespace {
|
|
template<typename Proxy> bool GetPropertyValueFromProxy(
|
|
Proxy* proxy,
|
|
const std::string& property_name,
|
|
brillo::Any* property_value) {
|
|
CHECK(property_value);
|
|
brillo::VariantDictionary proxy_properties;
|
|
brillo::ErrorPtr error;
|
|
CHECK(proxy->GetProperties(&proxy_properties, &error));
|
|
if (proxy_properties.find(property_name) == proxy_properties.end()) {
|
|
return false;
|
|
}
|
|
*property_value = proxy_properties[property_name];
|
|
return true;
|
|
}
|
|
|
|
template<typename Proxy> void IsProxyPropertyValueIn(
|
|
Proxy* proxy,
|
|
const std::string& property_name,
|
|
const std::vector<brillo::Any>& expected_values,
|
|
base::Time wait_start_time,
|
|
bool* is_success,
|
|
brillo::Any* final_value,
|
|
long* elapsed_time_milliseconds) {
|
|
brillo::Any property_value;
|
|
*is_success = false;
|
|
if ((GetPropertyValueFromProxy<Proxy>(proxy, property_name, &property_value)) &&
|
|
(std::find(expected_values.begin(), expected_values.end(),
|
|
property_value) != expected_values.end())) {
|
|
*is_success = true;
|
|
}
|
|
if (final_value) {
|
|
*final_value = property_value;
|
|
}
|
|
if (elapsed_time_milliseconds) {
|
|
*elapsed_time_milliseconds =
|
|
(base::Time::Now() - wait_start_time).InMilliseconds();
|
|
}
|
|
}
|
|
|
|
// This is invoked when the dbus detects a change in one of
|
|
// the properties of the proxy. We need to check if the property
|
|
// we're interested in has reached one of the expected values.
|
|
void PropertyChangedSignalCallback(
|
|
const std::string& watched_property_name,
|
|
const std::vector<brillo::Any>& expected_values,
|
|
const std::string& changed_property_name,
|
|
const brillo::Any& new_property_value) {
|
|
if ((watched_property_name == changed_property_name) &&
|
|
(std::find(expected_values.begin(), expected_values.end(),
|
|
new_property_value) != expected_values.end())) {
|
|
// Unblock the waiting function by stopping the message loop.
|
|
base::MessageLoop::current()->QuitNow();
|
|
}
|
|
}
|
|
|
|
// This is invoked to indicate whether dbus successfully connected our
|
|
// signal callback or not.
|
|
void PropertyChangedOnConnectedCallback(
|
|
const std::string& /* watched_property_name */,
|
|
const std::string& /* interface */,
|
|
const std::string& /* signal_name */,
|
|
bool success) {
|
|
CHECK(success);
|
|
}
|
|
|
|
template<typename Proxy>
|
|
void HelpRegisterPropertyChangedSignalHandler(
|
|
Proxy* proxy,
|
|
dbus::ObjectProxy::OnConnectedCallback on_connected_callback,
|
|
const DbusPropertyChangeCallback& signal_callback) {
|
|
// Re-order |on_connected_callback| and |signal_callback|, to meet
|
|
// the requirements of RegisterPropertyChangedSignalHandler().
|
|
proxy->RegisterPropertyChangedSignalHandler(
|
|
signal_callback, on_connected_callback);
|
|
}
|
|
|
|
template<typename OutValueType, typename ConditionChangeCallbackType>
|
|
void WaitForCondition(
|
|
base::Callback<void(base::Time, bool*, OutValueType*, long*)>
|
|
condition_termination_checker,
|
|
base::Callback<ConditionChangeCallbackType> condition_change_callback,
|
|
base::Callback<void(const base::Callback<ConditionChangeCallbackType>&)>
|
|
condition_change_callback_registrar,
|
|
long timeout_milliseconds,
|
|
bool* is_success,
|
|
OutValueType* out_value,
|
|
long* elapsed_time_milliseconds) {
|
|
CHECK(is_success);
|
|
const base::Time wait_start_time(base::Time::Now());
|
|
const base::TimeDelta timeout(
|
|
base::TimeDelta::FromMilliseconds(timeout_milliseconds));
|
|
base::CancelableClosure wait_timeout_callback;
|
|
base::CancelableCallback<ConditionChangeCallbackType> change_callback;
|
|
|
|
condition_termination_checker.Run(
|
|
wait_start_time, is_success, out_value, elapsed_time_milliseconds);
|
|
if (*is_success) {
|
|
return;
|
|
}
|
|
|
|
wait_timeout_callback.Reset(base::MessageLoop::QuitWhenIdleClosure());
|
|
change_callback.Reset(condition_change_callback);
|
|
|
|
condition_change_callback_registrar.Run(change_callback.callback());
|
|
|
|
// Add timeout, in case we never hit the expected condition.
|
|
base::MessageLoop::current()->PostDelayedTask(
|
|
FROM_HERE,
|
|
wait_timeout_callback.callback(),
|
|
timeout);
|
|
|
|
// Wait for the condition to occur within |timeout_milliseconds|.
|
|
base::MessageLoop::current()->Run();
|
|
|
|
wait_timeout_callback.Cancel();
|
|
change_callback.Cancel();
|
|
|
|
// We could have reached here either because we timed out or
|
|
// because we reached the condition.
|
|
condition_termination_checker.Run(
|
|
wait_start_time, is_success, out_value, elapsed_time_milliseconds);
|
|
}
|
|
} // namespace
|
|
|
|
ProxyDbusClient::ProxyDbusClient(scoped_refptr<dbus::Bus> bus)
|
|
: dbus_bus_(bus),
|
|
shill_manager_proxy_(dbus_bus_),
|
|
weak_ptr_factory_(this) {
|
|
}
|
|
|
|
void ProxyDbusClient::SetLogging(Technology tech) {
|
|
std::string log_scopes(kCommonLogScopes);
|
|
switch (tech) {
|
|
case TECHNOLOGY_CELLULAR:
|
|
log_scopes += "+cellular";
|
|
break;
|
|
case TECHNOLOGY_ETHERNET:
|
|
log_scopes += "+ethernet";
|
|
break;
|
|
case TECHNOLOGY_VPN:
|
|
log_scopes += "+vpn";
|
|
break;
|
|
case TECHNOLOGY_WIFI:
|
|
log_scopes += "+wifi";
|
|
break;
|
|
case TECHNOLOGY_WIMAX:
|
|
log_scopes += "+wimax";
|
|
break;
|
|
}
|
|
SetLoggingInternal(kLogLevel, log_scopes);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<DeviceProxy>> ProxyDbusClient::GetDeviceProxies() {
|
|
return GetProxies<DeviceProxy>(shill::kDevicesProperty);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<ServiceProxy>> ProxyDbusClient::GetServiceProxies() {
|
|
return GetProxies<ServiceProxy>(shill::kServicesProperty);
|
|
}
|
|
|
|
std::vector<std::unique_ptr<ProfileProxy>> ProxyDbusClient::GetProfileProxies() {
|
|
return GetProxies<ProfileProxy>(shill::kProfilesProperty);
|
|
}
|
|
|
|
std::unique_ptr<DeviceProxy> ProxyDbusClient::GetMatchingDeviceProxy(
|
|
const brillo::VariantDictionary& expected_properties) {
|
|
return GetMatchingProxy<DeviceProxy>(shill::kDevicesProperty, expected_properties);
|
|
}
|
|
|
|
std::unique_ptr<ServiceProxy> ProxyDbusClient::GetMatchingServiceProxy(
|
|
const brillo::VariantDictionary& expected_properties) {
|
|
return GetMatchingProxy<ServiceProxy>(shill::kServicesProperty, expected_properties);
|
|
}
|
|
|
|
std::unique_ptr<ProfileProxy> ProxyDbusClient::GetMatchingProfileProxy(
|
|
const brillo::VariantDictionary& expected_properties) {
|
|
return GetMatchingProxy<ProfileProxy>(shill::kProfilesProperty, expected_properties);
|
|
}
|
|
|
|
bool ProxyDbusClient::GetPropertyValueFromDeviceProxy(
|
|
DeviceProxy* proxy,
|
|
const std::string& property_name,
|
|
brillo::Any* property_value) {
|
|
return GetPropertyValueFromProxy<DeviceProxy>(
|
|
proxy, property_name, property_value);
|
|
}
|
|
|
|
bool ProxyDbusClient::GetPropertyValueFromServiceProxy(
|
|
ServiceProxy* proxy,
|
|
const std::string& property_name,
|
|
brillo::Any* property_value) {
|
|
return GetPropertyValueFromProxy<ServiceProxy>(
|
|
proxy, property_name, property_value);
|
|
}
|
|
|
|
bool ProxyDbusClient::GetPropertyValueFromProfileProxy(
|
|
ProfileProxy* proxy,
|
|
const std::string& property_name,
|
|
brillo::Any* property_value) {
|
|
return GetPropertyValueFromProxy<ProfileProxy>(
|
|
proxy, property_name, property_value);
|
|
}
|
|
|
|
bool ProxyDbusClient::WaitForDeviceProxyPropertyValueIn(
|
|
const dbus::ObjectPath& object_path,
|
|
const std::string& property_name,
|
|
const std::vector<brillo::Any>& expected_values,
|
|
long timeout_milliseconds,
|
|
brillo::Any* final_value,
|
|
long* elapsed_time_milliseconds) {
|
|
return WaitForProxyPropertyValueIn<DeviceProxy>(
|
|
object_path, property_name, expected_values, timeout_milliseconds,
|
|
final_value, elapsed_time_milliseconds);
|
|
}
|
|
|
|
bool ProxyDbusClient::WaitForServiceProxyPropertyValueIn(
|
|
const dbus::ObjectPath& object_path,
|
|
const std::string& property_name,
|
|
const std::vector<brillo::Any>& expected_values,
|
|
long timeout_milliseconds,
|
|
brillo::Any* final_value,
|
|
long* elapsed_time_milliseconds) {
|
|
return WaitForProxyPropertyValueIn<ServiceProxy>(
|
|
object_path, property_name, expected_values, timeout_milliseconds,
|
|
final_value, elapsed_time_milliseconds);
|
|
}
|
|
|
|
bool ProxyDbusClient::WaitForProfileProxyPropertyValueIn(
|
|
const dbus::ObjectPath& object_path,
|
|
const std::string& property_name,
|
|
const std::vector<brillo::Any>& expected_values,
|
|
long timeout_milliseconds,
|
|
brillo::Any* final_value,
|
|
long* elapsed_time_milliseconds) {
|
|
return WaitForProxyPropertyValueIn<ProfileProxy>(
|
|
object_path, property_name, expected_values, timeout_milliseconds,
|
|
final_value, elapsed_time_milliseconds);
|
|
}
|
|
|
|
std::unique_ptr<ServiceProxy> ProxyDbusClient::GetServiceProxy(
|
|
const brillo::VariantDictionary& expected_properties) {
|
|
dbus::ObjectPath service_path;
|
|
brillo::ErrorPtr error;
|
|
if (!shill_manager_proxy_.GetService(
|
|
expected_properties, &service_path, &error)) {
|
|
return nullptr;
|
|
}
|
|
return std::unique_ptr<ServiceProxy>(
|
|
new ServiceProxy(dbus_bus_, service_path));
|
|
}
|
|
|
|
std::unique_ptr<ProfileProxy> ProxyDbusClient::GetActiveProfileProxy() {
|
|
return GetProxyForObjectPath<ProfileProxy>(GetObjectPathForActiveProfile());
|
|
}
|
|
|
|
std::unique_ptr<ServiceProxy> ProxyDbusClient::WaitForMatchingServiceProxy(
|
|
const brillo::VariantDictionary& service_properties,
|
|
const std::string& service_type,
|
|
long timeout_milliseconds,
|
|
int rescan_interval_milliseconds,
|
|
long* elapsed_time_milliseconds) {
|
|
auto condition_termination_checker =
|
|
base::Bind(&ProxyDbusClient::IsMatchingServicePresent,
|
|
weak_ptr_factory_.GetWeakPtr(),
|
|
service_properties);
|
|
auto condition_change_callback =
|
|
base::Bind(&ProxyDbusClient::FindServiceOrRestartScan,
|
|
weak_ptr_factory_.GetWeakPtr(),
|
|
service_properties,
|
|
service_type);
|
|
auto condition_change_callback_registrar =
|
|
base::Bind(&ProxyDbusClient::InitiateScanForService,
|
|
weak_ptr_factory_.GetWeakPtr(),
|
|
base::TimeDelta::FromMilliseconds(rescan_interval_milliseconds),
|
|
service_type);
|
|
|
|
std::unique_ptr<ServiceProxy> service_proxy;
|
|
bool is_success;
|
|
WaitForCondition(
|
|
condition_termination_checker, condition_change_callback,
|
|
condition_change_callback_registrar,
|
|
timeout_milliseconds, &is_success, &service_proxy, elapsed_time_milliseconds);
|
|
return service_proxy;
|
|
}
|
|
|
|
bool ProxyDbusClient::ConfigureService(
|
|
const brillo::VariantDictionary& config_params) {
|
|
dbus::ObjectPath service_path;
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.ConfigureService(
|
|
config_params, &service_path, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::ConfigureServiceByGuid(
|
|
const std::string& guid,
|
|
const brillo::VariantDictionary& config_params) {
|
|
dbus::ObjectPath service_path;
|
|
brillo::ErrorPtr error;
|
|
brillo::VariantDictionary guid_config_params(config_params);
|
|
guid_config_params[shill::kGuidProperty] = guid;
|
|
return shill_manager_proxy_.ConfigureService(
|
|
guid_config_params, &service_path, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::ConnectService(
|
|
const dbus::ObjectPath& object_path,
|
|
long timeout_milliseconds) {
|
|
auto proxy = GetProxyForObjectPath<ServiceProxy>(object_path);
|
|
brillo::ErrorPtr error;
|
|
if (!proxy->Connect(&error)) {
|
|
return false;
|
|
}
|
|
const std::vector<brillo::Any> expected_values = {
|
|
brillo::Any(std::string(shill::kStatePortal)),
|
|
brillo::Any(std::string(shill::kStateOnline)) };
|
|
return WaitForProxyPropertyValueIn<ServiceProxy>(
|
|
object_path, shill::kStateProperty, expected_values,
|
|
timeout_milliseconds, nullptr, nullptr);
|
|
}
|
|
|
|
bool ProxyDbusClient::DisconnectService(
|
|
const dbus::ObjectPath& object_path,
|
|
long timeout_milliseconds) {
|
|
auto proxy = GetProxyForObjectPath<ServiceProxy>(object_path);
|
|
brillo::ErrorPtr error;
|
|
if (!proxy->Disconnect(&error)) {
|
|
return false;
|
|
}
|
|
const std::vector<brillo::Any> expected_values = {
|
|
brillo::Any(std::string(shill::kStateIdle)) };
|
|
return WaitForProxyPropertyValueIn<ServiceProxy>(
|
|
object_path, shill::kStateProperty, expected_values,
|
|
timeout_milliseconds, nullptr, nullptr);
|
|
}
|
|
|
|
bool ProxyDbusClient::CreateProfile(const std::string& profile_name) {
|
|
dbus::ObjectPath profile_path;
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.CreateProfile(
|
|
profile_name, &profile_path, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::RemoveProfile(const std::string& profile_name) {
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.RemoveProfile(profile_name, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::PushProfile(const std::string& profile_name) {
|
|
dbus::ObjectPath profile_path;
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.PushProfile(
|
|
profile_name, &profile_path, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::PopProfile(const std::string& profile_name) {
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.PopProfile(profile_name, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::PopAnyProfile() {
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.PopAnyProfile(&error);
|
|
}
|
|
|
|
bool ProxyDbusClient::RequestServiceScan(const std::string& service_type) {
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.RequestScan(service_type, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::GetServiceOrder(std::string* order) {
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.GetServiceOrder(order, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::SetServiceOrder(const std::string& order) {
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.SetServiceOrder(order, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::SetSchedScan(bool enable) {
|
|
brillo::ErrorPtr error;
|
|
return shill_manager_proxy_.SetSchedScan(enable, &error);
|
|
}
|
|
|
|
bool ProxyDbusClient::GetPropertyValueFromManager(
|
|
const std::string& property_name,
|
|
brillo::Any* property_value) {
|
|
return GetPropertyValueFromProxy(
|
|
&shill_manager_proxy_, property_name, property_value);
|
|
}
|
|
|
|
dbus::ObjectPath ProxyDbusClient::GetObjectPathForActiveProfile() {
|
|
brillo::Any property_value;
|
|
if (!GetPropertyValueFromManager(
|
|
shill::kActiveProfileProperty, &property_value)) {
|
|
return dbus::ObjectPath();
|
|
}
|
|
return dbus::ObjectPath(property_value.Get<std::string>());
|
|
}
|
|
|
|
bool ProxyDbusClient::SetLoggingInternal(int level, const std::string& tags) {
|
|
bool is_success = true;
|
|
brillo::ErrorPtr error;
|
|
is_success &= shill_manager_proxy_.SetDebugLevel(level, &error);
|
|
is_success &= shill_manager_proxy_.SetDebugTags(tags, &error);
|
|
return is_success;
|
|
}
|
|
|
|
template<typename Proxy>
|
|
std::unique_ptr<Proxy> ProxyDbusClient::GetProxyForObjectPath(
|
|
const dbus::ObjectPath& object_path) {
|
|
return std::unique_ptr<Proxy>(new Proxy(dbus_bus_, object_path));
|
|
}
|
|
|
|
// Templated functions to return the object path property_name based on
|
|
template<typename Proxy>
|
|
std::vector<std::unique_ptr<Proxy>> ProxyDbusClient::GetProxies(
|
|
const std::string& object_paths_property_name) {
|
|
brillo::Any object_paths;
|
|
if (!GetPropertyValueFromManager(object_paths_property_name, &object_paths)) {
|
|
return std::vector<std::unique_ptr<Proxy>>();
|
|
}
|
|
std::vector<std::unique_ptr<Proxy>> proxies;
|
|
for (const auto& object_path :
|
|
object_paths.Get<std::vector<dbus::ObjectPath>>()) {
|
|
proxies.emplace_back(GetProxyForObjectPath<Proxy>(object_path));
|
|
}
|
|
return proxies;
|
|
}
|
|
|
|
template<typename Proxy>
|
|
std::unique_ptr<Proxy> ProxyDbusClient::GetMatchingProxy(
|
|
const std::string& object_paths_property_name,
|
|
const brillo::VariantDictionary& expected_properties) {
|
|
for (auto& proxy : GetProxies<Proxy>(object_paths_property_name)) {
|
|
brillo::VariantDictionary proxy_properties;
|
|
brillo::ErrorPtr error;
|
|
if (!proxy->GetProperties(&proxy_properties, &error)) {
|
|
// Ignore unknown object path errors since we might be using some proxies
|
|
// for objects which may have been destroyed since.
|
|
CHECK(error->GetCode() == kDbusErrorObjectUnknown);
|
|
continue;
|
|
}
|
|
bool all_expected_properties_matched = true;
|
|
for (const auto& expected_property : expected_properties) {
|
|
if (proxy_properties[expected_property.first] != expected_property.second) {
|
|
all_expected_properties_matched = false;
|
|
break;
|
|
}
|
|
}
|
|
if (all_expected_properties_matched) {
|
|
return std::move(proxy);
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
template<typename Proxy>
|
|
bool ProxyDbusClient::WaitForProxyPropertyValueIn(
|
|
const dbus::ObjectPath& object_path,
|
|
const std::string& property_name,
|
|
const std::vector<brillo::Any>& expected_values,
|
|
long timeout_milliseconds,
|
|
brillo::Any* final_value,
|
|
long* elapsed_time_milliseconds) {
|
|
// Creates a local proxy using |object_path| instead of accepting the proxy
|
|
// from the caller since we cannot deregister the signal property change
|
|
// callback associated.
|
|
auto proxy = GetProxyForObjectPath<Proxy>(object_path);
|
|
auto condition_termination_checker =
|
|
base::Bind(&IsProxyPropertyValueIn<Proxy>,
|
|
proxy.get(),
|
|
property_name,
|
|
expected_values);
|
|
auto condition_change_callback =
|
|
base::Bind(&PropertyChangedSignalCallback,
|
|
property_name,
|
|
expected_values);
|
|
auto condition_change_callback_registrar =
|
|
base::Bind(&HelpRegisterPropertyChangedSignalHandler<Proxy>,
|
|
base::Unretained(proxy.get()),
|
|
base::Bind(&PropertyChangedOnConnectedCallback,
|
|
property_name));
|
|
bool is_success;
|
|
WaitForCondition(
|
|
condition_termination_checker, condition_change_callback,
|
|
condition_change_callback_registrar,
|
|
timeout_milliseconds, &is_success, final_value, elapsed_time_milliseconds);
|
|
return is_success;
|
|
}
|
|
|
|
void ProxyDbusClient::IsMatchingServicePresent(
|
|
const brillo::VariantDictionary& service_properties,
|
|
base::Time wait_start_time,
|
|
bool* is_success,
|
|
std::unique_ptr<ServiceProxy>* service_proxy_out,
|
|
long* elapsed_time_milliseconds) {
|
|
auto service_proxy = GetMatchingServiceProxy(service_properties);
|
|
*is_success = false;
|
|
if (service_proxy) {
|
|
*is_success = true;
|
|
}
|
|
if (service_proxy_out) {
|
|
*service_proxy_out = std::move(service_proxy);
|
|
}
|
|
if (elapsed_time_milliseconds) {
|
|
*elapsed_time_milliseconds =
|
|
(base::Time::Now() - wait_start_time).InMilliseconds();
|
|
}
|
|
}
|
|
|
|
void ProxyDbusClient::FindServiceOrRestartScan(
|
|
const brillo::VariantDictionary& service_properties,
|
|
const std::string& service_type) {
|
|
if (GetMatchingServiceProxy(service_properties)) {
|
|
base::MessageLoop::current()->QuitNow();
|
|
} else {
|
|
RestartScanForService(service_type);
|
|
}
|
|
}
|
|
|
|
void ProxyDbusClient::InitiateScanForService(
|
|
base::TimeDelta rescan_interval,
|
|
const std::string& service_type,
|
|
const base::Closure& timer_callback) {
|
|
// Create a new timer instance for repeatedly calling the provided
|
|
// |timer_callback|. |WaitForCondition| will cancel |timer_callback|'s
|
|
// enclosing CancelableCallback when it exits and hence we need to
|
|
// use the same reference when we repeatedly schedule |timer_callback|.
|
|
wait_for_service_timer_.reset(
|
|
new base::Timer(FROM_HERE, rescan_interval, timer_callback, false));
|
|
RestartScanForService(service_type);
|
|
}
|
|
|
|
void ProxyDbusClient::RestartScanForService(
|
|
const std::string& service_type) {
|
|
RequestServiceScan(service_type);
|
|
wait_for_service_timer_->Reset();
|
|
}
|