156c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius//
256c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// Copyright (C) 2015 The Android Open Source Project
356c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius//
456c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// Licensed under the Apache License, Version 2.0 (the "License");
556c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// you may not use this file except in compliance with the License.
656c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// You may obtain a copy of the License at
756c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius//
856c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius//      http://www.apache.org/licenses/LICENSE-2.0
956c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius//
1056c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// Unless required by applicable law or agreed to in writing, software
1156c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// distributed under the License is distributed on an "AS IS" BASIS,
1256c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// See the License for the specific language governing permissions and
1456c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius// limitations under the License.
1556c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius//
165c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius#include <time.h>
175c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
1802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius#include <base/message_loop/message_loop.h>
1902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
2056c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius#include "proxy_dbus_client.h"
2156c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius
225c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Piusconst char ProxyDbusClient::kCommonLogScopes[] =
235c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  "connection+dbus+device+link+manager+portal+service";
245c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Piusconst int ProxyDbusClient::kLogLevel = -4;
25da0b0a7dee2dff8bbb7d79a09e4410644b6ac503Roshan Piusconst char ProxyDbusClient::kDbusErrorObjectUnknown[] =
26da0b0a7dee2dff8bbb7d79a09e4410644b6ac503Roshan Pius  "org.freedesktop.DBus.Error.UnknownObject";
2756c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius
28ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusnamespace {
29ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piustemplate<typename Proxy> bool GetPropertyValueFromProxy(
30ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    Proxy* proxy,
31fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Pius    const std::string& property_name,
3203e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko    brillo::Any* property_value) {
33ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  CHECK(property_value);
34ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  brillo::VariantDictionary proxy_properties;
3503e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
36ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  CHECK(proxy->GetProperties(&proxy_properties, &error));
37ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  if (proxy_properties.find(property_name) == proxy_properties.end()) {
385c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    return false;
3956c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius  }
40ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  *property_value = proxy_properties[property_name];
415c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  return true;
425c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
43ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
44ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piustemplate<typename Proxy> void IsProxyPropertyValueIn(
4502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    Proxy* proxy,
4602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& property_name,
4702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::vector<brillo::Any>& expected_values,
480ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    base::Time wait_start_time,
49ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    bool* is_success,
5002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    brillo::Any* final_value,
510ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long* elapsed_time_milliseconds) {
5202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  brillo::Any property_value;
53ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  *is_success = false;
5402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  if ((GetPropertyValueFromProxy<Proxy>(proxy, property_name, &property_value)) &&
5502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      (std::find(expected_values.begin(), expected_values.end(),
5602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 property_value) != expected_values.end())) {
57ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    *is_success = true;
58ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  }
59ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  if (final_value) {
60ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    *final_value = property_value;
61ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  }
620ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius  if (elapsed_time_milliseconds) {
630ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    *elapsed_time_milliseconds =
640ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius        (base::Time::Now() - wait_start_time).InMilliseconds();
6502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  }
66ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
6756c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius
6802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius// This is invoked when the dbus detects a change in one of
6902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius// the properties of the proxy. We need to check if the property
7002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius// we're interested in has reached one of the expected values.
7102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piusvoid PropertyChangedSignalCallback(
7202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& watched_property_name,
7302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::vector<brillo::Any>& expected_values,
7402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& changed_property_name,
7502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const brillo::Any& new_property_value) {
7602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  if ((watched_property_name == changed_property_name) &&
7702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      (std::find(expected_values.begin(), expected_values.end(),
7802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 new_property_value) != expected_values.end())) {
7902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    // Unblock the waiting function by stopping the message loop.
8002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    base::MessageLoop::current()->QuitNow();
8156c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius  }
825c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
8356c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius
8402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius// This is invoked to indicate whether dbus successfully connected our
8502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius// signal callback or not.
8602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piusvoid PropertyChangedOnConnectedCallback(
8702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& /* watched_property_name */,
8802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& /* interface */,
8902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& /* signal_name */,
905c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    bool success) {
9102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  CHECK(success);
9256c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius}
9356c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius
9402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piustemplate<typename Proxy>
9502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piusvoid HelpRegisterPropertyChangedSignalHandler(
9602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    Proxy* proxy,
9702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    dbus::ObjectProxy::OnConnectedCallback on_connected_callback,
9802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const DbusPropertyChangeCallback& signal_callback) {
9902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  // Re-order |on_connected_callback| and |signal_callback|, to meet
10002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  // the requirements of RegisterPropertyChangedSignalHandler().
10102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  proxy->RegisterPropertyChangedSignalHandler(
10202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      signal_callback, on_connected_callback);
10302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius}
10402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
105ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piustemplate<typename OutValueType, typename ConditionChangeCallbackType>
106ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piusvoid WaitForCondition(
1070ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    base::Callback<void(base::Time, bool*, OutValueType*, long*)>
10802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius        condition_termination_checker,
10902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    base::Callback<ConditionChangeCallbackType> condition_change_callback,
11002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    base::Callback<void(const base::Callback<ConditionChangeCallbackType>&)>
11102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius        condition_change_callback_registrar,
1120ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long timeout_milliseconds,
113ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    bool* is_success,
114ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    OutValueType* out_value,
1150ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long* elapsed_time_milliseconds) {
116ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  CHECK(is_success);
1170ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius  const base::Time wait_start_time(base::Time::Now());
1180ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius  const base::TimeDelta timeout(
1190ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      base::TimeDelta::FromMilliseconds(timeout_milliseconds));
12002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  base::CancelableClosure wait_timeout_callback;
12102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  base::CancelableCallback<ConditionChangeCallbackType> change_callback;
12202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
123ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  condition_termination_checker.Run(
1240ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      wait_start_time, is_success, out_value, elapsed_time_milliseconds);
125ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  if (*is_success) {
126ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    return;
12756c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius  }
12856c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius
1293a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko  wait_timeout_callback.Reset(base::MessageLoop::QuitWhenIdleClosure());
13002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  change_callback.Reset(condition_change_callback);
13156c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius
13202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  condition_change_callback_registrar.Run(change_callback.callback());
1335c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
13402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  // Add timeout, in case we never hit the expected condition.
13502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  base::MessageLoop::current()->PostDelayedTask(
13602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      FROM_HERE,
13702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      wait_timeout_callback.callback(),
13802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      timeout);
1395c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
1400ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius  // Wait for the condition to occur within |timeout_milliseconds|.
14102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  base::MessageLoop::current()->Run();
14202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
14302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  wait_timeout_callback.Cancel();
14402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  change_callback.Cancel();
14502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
14602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  // We could have reached here either because we timed out or
14702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  // because we reached the condition.
148ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  condition_termination_checker.Run(
1490ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      wait_start_time, is_success, out_value, elapsed_time_milliseconds);
15002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius}
15102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius} // namespace
15202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
15302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan PiusProxyDbusClient::ProxyDbusClient(scoped_refptr<dbus::Bus> bus)
15402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  : dbus_bus_(bus),
155ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    shill_manager_proxy_(dbus_bus_),
156ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    weak_ptr_factory_(this) {
1575c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
1585c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
159fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Piusvoid ProxyDbusClient::SetLogging(Technology tech) {
1605c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  std::string log_scopes(kCommonLogScopes);
1615c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  switch (tech) {
1625c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    case TECHNOLOGY_CELLULAR:
1635c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      log_scopes += "+cellular";
1645c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      break;
1655c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    case TECHNOLOGY_ETHERNET:
1665c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      log_scopes += "+ethernet";
1675c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      break;
1685c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    case TECHNOLOGY_VPN:
1695c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      log_scopes += "+vpn";
1705c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      break;
1715c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    case TECHNOLOGY_WIFI:
1725c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      log_scopes += "+wifi";
1735c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      break;
1745c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    case TECHNOLOGY_WIMAX:
1755c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      log_scopes += "+wimax";
1765c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius      break;
1775c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  }
17802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  SetLoggingInternal(kLogLevel, log_scopes);
1795c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
1805c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
181ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::vector<std::unique_ptr<DeviceProxy>> ProxyDbusClient::GetDeviceProxies() {
182ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetProxies<DeviceProxy>(shill::kDevicesProperty);
1835c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
1845c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
185ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::vector<std::unique_ptr<ServiceProxy>> ProxyDbusClient::GetServiceProxies() {
186ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetProxies<ServiceProxy>(shill::kServicesProperty);
1875c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
1885c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
189ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::vector<std::unique_ptr<ProfileProxy>> ProxyDbusClient::GetProfileProxies() {
190ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetProxies<ProfileProxy>(shill::kProfilesProperty);
1915c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
1925c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
193ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::unique_ptr<DeviceProxy> ProxyDbusClient::GetMatchingDeviceProxy(
194ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const brillo::VariantDictionary& expected_properties) {
195ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetMatchingProxy<DeviceProxy>(shill::kDevicesProperty, expected_properties);
1965c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
1975c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
198ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::unique_ptr<ServiceProxy> ProxyDbusClient::GetMatchingServiceProxy(
199ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const brillo::VariantDictionary& expected_properties) {
200ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetMatchingProxy<ServiceProxy>(shill::kServicesProperty, expected_properties);
2015c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
2025c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
203ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::unique_ptr<ProfileProxy> ProxyDbusClient::GetMatchingProfileProxy(
204ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const brillo::VariantDictionary& expected_properties) {
205ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetMatchingProxy<ProfileProxy>(shill::kProfilesProperty, expected_properties);
2065c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
2075c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
208ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusbool ProxyDbusClient::GetPropertyValueFromDeviceProxy(
209ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    DeviceProxy* proxy,
210ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const std::string& property_name,
211ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    brillo::Any* property_value) {
212ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetPropertyValueFromProxy<DeviceProxy>(
213ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius      proxy, property_name, property_value);
2145c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
2155c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
216ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusbool ProxyDbusClient::GetPropertyValueFromServiceProxy(
217ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    ServiceProxy* proxy,
218ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const std::string& property_name,
219ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    brillo::Any* property_value) {
220ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetPropertyValueFromProxy<ServiceProxy>(
221ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius      proxy, property_name, property_value);
2225c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
2235c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
224ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusbool ProxyDbusClient::GetPropertyValueFromProfileProxy(
225ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    ProfileProxy* proxy,
226ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const std::string& property_name,
227ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    brillo::Any* property_value) {
228ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetPropertyValueFromProxy<ProfileProxy>(
229ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius      proxy, property_name, property_value);
230ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
231ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
23202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piusbool ProxyDbusClient::WaitForDeviceProxyPropertyValueIn(
23302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const dbus::ObjectPath& object_path,
23402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& property_name,
23502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::vector<brillo::Any>& expected_values,
2360ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long timeout_milliseconds,
23702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    brillo::Any* final_value,
2380ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long* elapsed_time_milliseconds) {
23902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return WaitForProxyPropertyValueIn<DeviceProxy>(
2400ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      object_path, property_name, expected_values, timeout_milliseconds,
2410ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      final_value, elapsed_time_milliseconds);
24202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius}
24302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
24402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piusbool ProxyDbusClient::WaitForServiceProxyPropertyValueIn(
24502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const dbus::ObjectPath& object_path,
24602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& property_name,
24702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::vector<brillo::Any>& expected_values,
2480ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long timeout_milliseconds,
24902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    brillo::Any* final_value,
2500ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long* elapsed_time_milliseconds) {
25102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return WaitForProxyPropertyValueIn<ServiceProxy>(
2520ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      object_path, property_name, expected_values, timeout_milliseconds,
2530ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      final_value, elapsed_time_milliseconds);
25402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius}
25502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
25602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piusbool ProxyDbusClient::WaitForProfileProxyPropertyValueIn(
25702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const dbus::ObjectPath& object_path,
25802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& property_name,
25902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::vector<brillo::Any>& expected_values,
2600ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long timeout_milliseconds,
26102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    brillo::Any* final_value,
2620ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long* elapsed_time_milliseconds) {
26302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return WaitForProxyPropertyValueIn<ProfileProxy>(
2640ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      object_path, property_name, expected_values, timeout_milliseconds,
2650ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      final_value, elapsed_time_milliseconds);
26602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius}
26702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
268ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::unique_ptr<ServiceProxy> ProxyDbusClient::GetServiceProxy(
269ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const brillo::VariantDictionary& expected_properties) {
2705c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  dbus::ObjectPath service_path;
27103e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
27202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  if (!shill_manager_proxy_.GetService(
273ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius          expected_properties, &service_path, &error)) {
2745c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    return nullptr;
2755c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  }
27602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return std::unique_ptr<ServiceProxy>(
27702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      new ServiceProxy(dbus_bus_, service_path));
2785c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
2795c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
280ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::unique_ptr<ProfileProxy> ProxyDbusClient::GetActiveProfileProxy() {
281ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetProxyForObjectPath<ProfileProxy>(GetObjectPathForActiveProfile());
282ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
283ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
284ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piusstd::unique_ptr<ServiceProxy> ProxyDbusClient::WaitForMatchingServiceProxy(
285ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    const brillo::VariantDictionary& service_properties,
286ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    const std::string& service_type,
2870ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long timeout_milliseconds,
288ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    int rescan_interval_milliseconds,
2890ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long* elapsed_time_milliseconds) {
290ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  auto condition_termination_checker =
291ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius      base::Bind(&ProxyDbusClient::IsMatchingServicePresent,
292ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius                 weak_ptr_factory_.GetWeakPtr(),
293ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius                 service_properties);
294ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  auto condition_change_callback =
295ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius      base::Bind(&ProxyDbusClient::FindServiceOrRestartScan,
296ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius                 weak_ptr_factory_.GetWeakPtr(),
297ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius                 service_properties,
298ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius                 service_type);
299ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  auto condition_change_callback_registrar =
300ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius      base::Bind(&ProxyDbusClient::InitiateScanForService,
301ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius                 weak_ptr_factory_.GetWeakPtr(),
302ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius                 base::TimeDelta::FromMilliseconds(rescan_interval_milliseconds),
303ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius                 service_type);
304ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius
305ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  std::unique_ptr<ServiceProxy> service_proxy;
306ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  bool is_success;
307ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  WaitForCondition(
308ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius      condition_termination_checker, condition_change_callback,
309ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius      condition_change_callback_registrar,
3100ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      timeout_milliseconds, &is_success, &service_proxy, elapsed_time_milliseconds);
311ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  return service_proxy;
312ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius}
313ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius
3145a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Piusbool ProxyDbusClient::ConfigureService(
3155a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius    const brillo::VariantDictionary& config_params) {
3165c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  dbus::ObjectPath service_path;
31703e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
3185a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  return shill_manager_proxy_.ConfigureService(
3195a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius      config_params, &service_path, &error);
3205c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
3215c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
3225a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Piusbool ProxyDbusClient::ConfigureServiceByGuid(
323fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Pius    const std::string& guid,
3245a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius    const brillo::VariantDictionary& config_params) {
3255c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  dbus::ObjectPath service_path;
32603e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
3275a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  brillo::VariantDictionary guid_config_params(config_params);
3285a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  guid_config_params[shill::kGuidProperty] = guid;
3295a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  return shill_manager_proxy_.ConfigureService(
3305a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius      guid_config_params, &service_path, &error);
3315c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
3325c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
3335c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Piusbool ProxyDbusClient::ConnectService(
33402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const dbus::ObjectPath& object_path,
3350ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long timeout_milliseconds) {
33602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  auto proxy = GetProxyForObjectPath<ServiceProxy>(object_path);
33703e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
3385c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  if (!proxy->Connect(&error)) {
3395c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    return false;
3405c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  }
34103e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  const std::vector<brillo::Any> expected_values = {
34203e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko    brillo::Any(std::string(shill::kStatePortal)),
34303e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko    brillo::Any(std::string(shill::kStateOnline)) };
34402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return WaitForProxyPropertyValueIn<ServiceProxy>(
34502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      object_path, shill::kStateProperty, expected_values,
3460ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      timeout_milliseconds, nullptr, nullptr);
3475c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
3485c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
3495c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Piusbool ProxyDbusClient::DisconnectService(
35002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const dbus::ObjectPath& object_path,
3510ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long timeout_milliseconds) {
35202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  auto proxy = GetProxyForObjectPath<ServiceProxy>(object_path);
35303e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
3545c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  if (!proxy->Disconnect(&error)) {
3555c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius    return false;
3565c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  }
35703e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  const std::vector<brillo::Any> expected_values = {
35803e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko    brillo::Any(std::string(shill::kStateIdle)) };
35902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return WaitForProxyPropertyValueIn<ServiceProxy>(
36002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      object_path, shill::kStateProperty, expected_values,
3610ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      timeout_milliseconds, nullptr, nullptr);
3625c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
3635c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
364fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Piusbool ProxyDbusClient::CreateProfile(const std::string& profile_name) {
3655c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  dbus::ObjectPath profile_path;
36603e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
36702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return shill_manager_proxy_.CreateProfile(
368fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Pius      profile_name, &profile_path, &error);
3695c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
3705c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
371fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Piusbool ProxyDbusClient::RemoveProfile(const std::string& profile_name) {
37203e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
37302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return shill_manager_proxy_.RemoveProfile(profile_name, &error);
3745c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
3755c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
376fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Piusbool ProxyDbusClient::PushProfile(const std::string& profile_name) {
3775c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius  dbus::ObjectPath profile_path;
37803e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
37902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return shill_manager_proxy_.PushProfile(
380fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Pius      profile_name, &profile_path, &error);
3815c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
3825c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
383fa07c8685b2647752cdbb637793e24893c92ab0bRoshan Piusbool ProxyDbusClient::PopProfile(const std::string& profile_name) {
38403e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
38502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return shill_manager_proxy_.PopProfile(profile_name, &error);
3865c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius}
3875c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Pius
3885c01b468e7dc6bfd74928bbd5e9726df374fd252Roshan Piusbool ProxyDbusClient::PopAnyProfile() {
38903e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  brillo::ErrorPtr error;
39002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  return shill_manager_proxy_.PopAnyProfile(&error);
39156c269a533910c37123ed0b37c0f5e5ee3c47e26Roshan Pius}
392ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
393ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piusbool ProxyDbusClient::RequestServiceScan(const std::string& service_type) {
394ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  brillo::ErrorPtr error;
395ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  return shill_manager_proxy_.RequestScan(service_type, &error);
396ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius}
397ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius
3985a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Piusbool ProxyDbusClient::GetServiceOrder(std::string* order) {
3995a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  brillo::ErrorPtr error;
4005a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  return shill_manager_proxy_.GetServiceOrder(order, &error);
4015a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius}
4025a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius
4035a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Piusbool ProxyDbusClient::SetServiceOrder(const std::string& order) {
4045a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  brillo::ErrorPtr error;
4055a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  return shill_manager_proxy_.SetServiceOrder(order, &error);
4065a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius}
4075a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius
4085a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Piusbool ProxyDbusClient::SetSchedScan(bool enable) {
4095a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  brillo::ErrorPtr error;
4105a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius  return shill_manager_proxy_.SetSchedScan(enable, &error);
4115a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius}
4125a93aaa6f32c3dc5eb15594f5caf54c6cb34276cRoshan Pius
413ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusbool ProxyDbusClient::GetPropertyValueFromManager(
414ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const std::string& property_name,
415ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    brillo::Any* property_value) {
416ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return GetPropertyValueFromProxy(
41702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      &shill_manager_proxy_, property_name, property_value);
418ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
419ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
420ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusdbus::ObjectPath ProxyDbusClient::GetObjectPathForActiveProfile() {
421ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  brillo::Any property_value;
422ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  if (!GetPropertyValueFromManager(
423ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius        shill::kActiveProfileProperty, &property_value)) {
424ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    return dbus::ObjectPath();
425ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  }
426ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return dbus::ObjectPath(property_value.Get<std::string>());
427ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
428ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
42902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piusbool ProxyDbusClient::SetLoggingInternal(int level, const std::string& tags) {
430ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  bool is_success = true;
431ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  brillo::ErrorPtr error;
43202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  is_success &= shill_manager_proxy_.SetDebugLevel(level, &error);
43302244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  is_success &= shill_manager_proxy_.SetDebugTags(tags, &error);
434ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return is_success;
435ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
436ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
437ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piustemplate<typename Proxy>
438ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::unique_ptr<Proxy> ProxyDbusClient::GetProxyForObjectPath(
439ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const dbus::ObjectPath& object_path) {
440ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return std::unique_ptr<Proxy>(new Proxy(dbus_bus_, object_path));
441ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
442ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
443ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius// Templated functions to return the object path property_name based on
444ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piustemplate<typename Proxy>
445ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::vector<std::unique_ptr<Proxy>> ProxyDbusClient::GetProxies(
446ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const std::string& object_paths_property_name) {
447ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  brillo::Any object_paths;
448ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  if (!GetPropertyValueFromManager(object_paths_property_name, &object_paths)) {
449ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    return std::vector<std::unique_ptr<Proxy>>();
450ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  }
451ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  std::vector<std::unique_ptr<Proxy>> proxies;
452ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  for (const auto& object_path :
453ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius       object_paths.Get<std::vector<dbus::ObjectPath>>()) {
454ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    proxies.emplace_back(GetProxyForObjectPath<Proxy>(object_path));
455ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  }
456ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return proxies;
457ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
458ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius
459ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piustemplate<typename Proxy>
460ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Piusstd::unique_ptr<Proxy> ProxyDbusClient::GetMatchingProxy(
461ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const std::string& object_paths_property_name,
462ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    const brillo::VariantDictionary& expected_properties) {
463ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  for (auto& proxy : GetProxies<Proxy>(object_paths_property_name)) {
464ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    brillo::VariantDictionary proxy_properties;
465ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    brillo::ErrorPtr error;
466da0b0a7dee2dff8bbb7d79a09e4410644b6ac503Roshan Pius    if (!proxy->GetProperties(&proxy_properties, &error)) {
467da0b0a7dee2dff8bbb7d79a09e4410644b6ac503Roshan Pius      // Ignore unknown object path errors since we might be using some proxies
468da0b0a7dee2dff8bbb7d79a09e4410644b6ac503Roshan Pius      // for objects which may have been destroyed since.
469da0b0a7dee2dff8bbb7d79a09e4410644b6ac503Roshan Pius      CHECK(error->GetCode() == kDbusErrorObjectUnknown);
470da0b0a7dee2dff8bbb7d79a09e4410644b6ac503Roshan Pius      continue;
471da0b0a7dee2dff8bbb7d79a09e4410644b6ac503Roshan Pius    }
472ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    bool all_expected_properties_matched = true;
473ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    for (const auto& expected_property : expected_properties) {
474ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius      if (proxy_properties[expected_property.first] != expected_property.second) {
475ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius        all_expected_properties_matched = false;
476ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius        break;
477ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius      }
478ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    }
479ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    if (all_expected_properties_matched) {
480ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius      return std::move(proxy);
481ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius    }
482ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  }
483ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius  return nullptr;
484ae0da94cb8a611a7c0b58b78778d2cf85ab918e9Roshan Pius}
48502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius
48602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piustemplate<typename Proxy>
48702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Piusbool ProxyDbusClient::WaitForProxyPropertyValueIn(
48802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const dbus::ObjectPath& object_path,
48902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::string& property_name,
49002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    const std::vector<brillo::Any>& expected_values,
4910ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long timeout_milliseconds,
49202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius    brillo::Any* final_value,
4930ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long* elapsed_time_milliseconds) {
49402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  // Creates a local proxy using |object_path| instead of accepting the proxy
49502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  // from the caller since we cannot deregister the signal property change
49602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  // callback associated.
49702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius  auto proxy = GetProxyForObjectPath<Proxy>(object_path);
498ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  auto condition_termination_checker =
49902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      base::Bind(&IsProxyPropertyValueIn<Proxy>,
50002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 proxy.get(),
50102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 property_name,
50202244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 expected_values);
503ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  auto condition_change_callback =
50402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      base::Bind(&PropertyChangedSignalCallback,
50502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 property_name,
50602244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 expected_values);
507ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  auto condition_change_callback_registrar =
50802244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      base::Bind(&HelpRegisterPropertyChangedSignalHandler<Proxy>,
50902244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 base::Unretained(proxy.get()),
51002244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                 base::Bind(&PropertyChangedOnConnectedCallback,
51102244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius                            property_name));
512ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  bool is_success;
513ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  WaitForCondition(
51402244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      condition_termination_checker, condition_change_callback,
51502244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius      condition_change_callback_registrar,
5160ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius      timeout_milliseconds, &is_success, final_value, elapsed_time_milliseconds);
517ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  return is_success;
518ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius}
519ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius
520ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piusvoid ProxyDbusClient::IsMatchingServicePresent(
521ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    const brillo::VariantDictionary& service_properties,
5220ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    base::Time wait_start_time,
523ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    bool* is_success,
524ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    std::unique_ptr<ServiceProxy>* service_proxy_out,
5250ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    long* elapsed_time_milliseconds) {
526ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  auto service_proxy = GetMatchingServiceProxy(service_properties);
527ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  *is_success = false;
528ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  if (service_proxy) {
529ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    *is_success = true;
530ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  }
531ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  if (service_proxy_out) {
532ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    *service_proxy_out = std::move(service_proxy);
533ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  }
5340ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius  if (elapsed_time_milliseconds) {
5350ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius    *elapsed_time_milliseconds =
5360ad14af1781762bfff5feccdbacd79911ce7da9cRoshan Pius        (base::Time::Now() - wait_start_time).InMilliseconds();
537ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  }
538ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius}
539ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius
540ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piusvoid ProxyDbusClient::FindServiceOrRestartScan(
541ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    const brillo::VariantDictionary& service_properties,
542ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    const std::string& service_type) {
543ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  if (GetMatchingServiceProxy(service_properties)) {
544ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    base::MessageLoop::current()->QuitNow();
545ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  } else {
546ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    RestartScanForService(service_type);
547ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  }
548ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius}
549ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius
550ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piusvoid ProxyDbusClient::InitiateScanForService(
551ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    base::TimeDelta rescan_interval,
552ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    const std::string& service_type,
553ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    const base::Closure& timer_callback) {
554ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  // Create a new timer instance for repeatedly calling the provided
555ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  // |timer_callback|. |WaitForCondition| will cancel |timer_callback|'s
556ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  // enclosing CancelableCallback when it exits and hence we need to
557ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  // use the same reference when we repeatedly schedule |timer_callback|.
558ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  wait_for_service_timer_.reset(
559ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius      new base::Timer(FROM_HERE, rescan_interval, timer_callback, false));
560ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  RestartScanForService(service_type);
561ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius}
562ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius
563ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Piusvoid ProxyDbusClient::RestartScanForService(
564ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius    const std::string& service_type) {
565ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  RequestServiceScan(service_type);
566ee39bfa925600a2153d5c5c68c503cb22ed7d3fcRoshan Pius  wait_for_service_timer_->Reset();
56702244d42e5f6a195a41984cf40346a1b07b4c9a0Roshan Pius}
568