Commit a9be5907 authored by Azeem Arshad's avatar Azeem Arshad Committed by Commit Bot

[Cellular] Add Hermes DBus client fakes.

This CL adds fake implementations for Hermes dbus
Manager and Profile client classes. See
http://go/cros-esim-design-doc for details.

Bug: 1093185
Change-Id: I29a35122ff48f2081ca91bfa9a1896fc547e3ad0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2238672
Commit-Queue: Azeem Arshad <azeemarshad@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#780045}
parent 111fd504
...@@ -34,6 +34,12 @@ const char kFakeOobeConfiguration[] = "fake-oobe-configuration-file"; ...@@ -34,6 +34,12 @@ const char kFakeOobeConfiguration[] = "fake-oobe-configuration-file";
// 'interactive=3' - Interactive mode, connect/scan/etc requests take 3 secs // 'interactive=3' - Interactive mode, connect/scan/etc requests take 3 secs
const char kShillStub[] = "shill-stub"; const char kShillStub[] = "shill-stub";
// Enables Hermes fake behavior. By default, no carrier profiles are setup.
// If a value of "on" is passed for this switch, then hermes fakes are
// initialized with a single installed carrier profile. Fake cellular service
// corresponding to carrier profiles are also setup in Shill.
const char kHermesFake[] = "hermes-fake";
// Sends test messages on first call to RequestUpdate (stub only). // Sends test messages on first call to RequestUpdate (stub only).
const char kSmsTestMessages[] = "sms-test-messages"; const char kSmsTestMessages[] = "sms-test-messages";
......
...@@ -19,6 +19,8 @@ extern const char kFakeOobeConfiguration[]; ...@@ -19,6 +19,8 @@ extern const char kFakeOobeConfiguration[];
COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS) COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS)
extern const char kShillStub[]; extern const char kShillStub[];
COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS) COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS)
extern const char kHermesFake[];
COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS)
extern const char kSmsTestMessages[]; extern const char kSmsTestMessages[];
COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS) COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS)
extern const char kSystemDevMode[]; extern const char kSystemDevMode[];
......
...@@ -5,12 +5,15 @@ ...@@ -5,12 +5,15 @@
assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos") assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
component("hermes") { component("hermes") {
defines = [ "IS_HERMES_CLIENT_IMPL" ] public_deps = [ ":hermes_clients" ]
deps = [ ":hermes_fakes" ]
}
source_set("hermes_clients") {
defines = [ "IS_HERMES_CLIENT_IMPL" ]
deps = [ deps = [
"//base", "//base",
"//chromeos/dbus:common", "//chromeos/dbus:common",
"//chromeos/dbus/constants",
"//components/device_event_log", "//components/device_event_log",
"//dbus", "//dbus",
] ]
...@@ -27,6 +30,25 @@ component("hermes") { ...@@ -27,6 +30,25 @@ component("hermes") {
] ]
} }
source_set("hermes_fakes") {
deps = [
":hermes_clients",
"//base",
"//chromeos/dbus/constants",
"//chromeos/dbus/shill",
"//dbus",
]
sources = [
"fake_hermes_manager_client.cc",
"fake_hermes_manager_client.h",
"fake_hermes_profile_client.cc",
"fake_hermes_profile_client.h",
]
allow_circular_includes_from = [ ":hermes_clients" ]
}
source_set("test_support") { source_set("test_support") {
testonly = true testonly = true
public_deps = [ ":hermes" ] public_deps = [ ":hermes" ]
......
This diff is collapsed.
// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_DBUS_HERMES_FAKE_HERMES_MANAGER_CLIENT_H_
#define CHROMEOS_DBUS_HERMES_FAKE_HERMES_MANAGER_CLIENT_H_
#include <set>
#include "base/component_export.h"
#include "base/macros.h"
#include "chromeos/dbus/hermes/hermes_manager_client.h"
#include "third_party/cros_system_api/dbus/hermes/dbus-constants.h"
namespace chromeos {
// Fake implementation for HermesManagerClient. This class interacts with
// FakeHermesDeviceClient and FakeShillManagerClient to setup stub carrier
// profile objects and corresponding network services.
class COMPONENT_EXPORT(HERMES_CLIENT) FakeHermesManagerClient
: public HermesManagerClient,
public HermesManagerClient::TestInterface {
public:
FakeHermesManagerClient();
FakeHermesManagerClient(const FakeHermesManagerClient&) = delete;
~FakeHermesManagerClient() override;
// HermesManagerClient::TestInterface:
void AddCarrierProfile(const dbus::ObjectPath& path,
const std::string& iccid,
const std::string& name,
const std::string& service_provider,
const std::string& activation_code,
const std::string& network_service_path,
hermes::profile::State state) override;
// HermesManagerClient:
void InstallProfileFromActivationCode(
const std::string& activation_code,
const std::string& confirmation_code,
InstallCarrierProfileCallback callback) override;
void InstallPendingProfile(const dbus::ObjectPath& carrier_profile_path,
const std::string& confirmation_code,
InstallCarrierProfileCallback callback) override;
void RequestPendingEvents(HermesResponseCallback callback) override;
void UninstallProfile(const dbus::ObjectPath& carrier_profile_path,
HermesResponseCallback callback) override;
const std::vector<dbus::ObjectPath>& GetInstalledCarrierProfiles() override;
const std::vector<dbus::ObjectPath>& GetPendingCarrierProfiles() override;
HermesManagerClient::TestInterface* GetTestInterface() override;
FakeHermesManagerClient& operator=(const FakeHermesManagerClient&) = delete;
private:
dbus::ObjectPath AddFakeCarrierProfile(hermes::profile::State state,
std::string activation_code);
void ParseCommandLineSwitch();
bool PopPendingProfile(dbus::ObjectPath carrier_profile_path);
dbus::ObjectPath PopPendingProfileWithActivationCode(
const std::string& activation_code);
void CreateCellularService(const dbus::ObjectPath& carrier_profile_path);
void RemoveCellularService(const dbus::ObjectPath& carrier_profile_path);
void CallNotifyInstalledCarrierProfileListChanged();
void CallNotifyPendingCarrierProfileListChanged();
void NotifyInstalledCarrierProfileListChanged();
void NotifyPendingCarrierProfileListChanged();
// Indicates whether a pending event request has already been made.
bool pending_event_requested_ = false;
int fake_profile_counter_ = 0;
// Mapping between carrier profile objects and their corresponding
// shill network service paths.
std::map<dbus::ObjectPath, std::string> profile_service_path_map_;
// List of paths to installed and pending profile objects.
std::vector<dbus::ObjectPath> installed_profiles_;
std::vector<dbus::ObjectPath> pending_profiles_;
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_HERMES_FAKE_HERMES_MANAGER_CLIENT_H_
// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/dbus/hermes/fake_hermes_profile_client.h"
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "chromeos/dbus/hermes/hermes_profile_client.h"
#include "chromeos/dbus/shill/shill_device_client.h"
#include "chromeos/dbus/shill/shill_manager_client.h"
#include "chromeos/dbus/shill/shill_service_client.h"
#include "dbus/property.h"
#include "third_party/cros_system_api/dbus/hermes/dbus-constants.h"
#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
namespace chromeos {
namespace {
const char* kCellularDevicePath = "/device/cellular1";
const char* kDefaultCountry = "US";
} // namespace
FakeHermesProfileClient::Properties::Properties(
const PropertyChangedCallback& callback)
: HermesProfileClient::Properties(nullptr, callback) {}
FakeHermesProfileClient::Properties::~Properties() = default;
void FakeHermesProfileClient::Properties::Get(
dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) {
DVLOG(1) << "Get " << property->name();
std::move(callback).Run(false);
}
void FakeHermesProfileClient::Properties::GetAll() {
DVLOG(1) << "GetAll";
}
void FakeHermesProfileClient::Properties::Set(
dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) {
DVLOG(1) << "Set " << property->name();
if (property->name() == nick_name().name()) {
// Only nickname property is read/write.
std::move(callback).Run(true);
property->ReplaceValueWithSetValue();
} else {
std::move(callback).Run(false);
}
}
FakeHermesProfileClient::FakeHermesProfileClient() {}
FakeHermesProfileClient::~FakeHermesProfileClient() = default;
void FakeHermesProfileClient::EnableCarrierProfile(
const dbus::ObjectPath& object_path,
HermesResponseCallback callback) {
DVLOG(1) << "Enabling Carrier Profile path=" << object_path.value();
// Update carrier profile states.
HermesProfileClient::Properties* properties = GetProperties(object_path);
if (!properties) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
HermesResponseStatus::kErrorUnknown));
return;
}
if (properties->state().value() == hermes::profile::State::kActive) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
HermesResponseStatus::kErrorAlreadyEnabled));
return;
}
for (PropertiesMap::iterator it = properties_map_.begin();
it != properties_map_.end(); it++) {
it->second.get()->state().ReplaceValue(hermes::profile::State::kInactive);
}
properties->state().ReplaceValue(hermes::profile::State::kActive);
// Update cellular device properties to match this profile.
UpdateCellularDevice(properties);
// Set all cellular services state to idle. The service associated with the
// carrier profile that was just enabled should be connected to with a
// subsequent Connect call for that service.
SetCellularServicesState(shill::kStateIdle);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), HermesResponseStatus::kSuccess));
}
void FakeHermesProfileClient::DisableCarrierProfile(
const dbus::ObjectPath& object_path,
HermesResponseCallback callback) {
DVLOG(1) << "Disabling Carrier Profile path=" << object_path.value();
HermesProfileClient::Properties* properties = GetProperties(object_path);
if (!properties) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
HermesResponseStatus::kErrorUnknown));
return;
}
if (properties->state().value() == hermes::profile::State::kInactive) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
HermesResponseStatus::kErrorAlreadyDisabled));
return;
}
properties->state().ReplaceValue(hermes::profile::State::kInactive);
SetCellularServicesState(shill::kStateIdle);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), HermesResponseStatus::kSuccess));
}
HermesProfileClient::Properties* FakeHermesProfileClient::GetProperties(
const dbus::ObjectPath& object_path) {
PropertiesMap::iterator it = properties_map_.find(object_path);
if (it != properties_map_.end()) {
return it->second.get();
}
DVLOG(1) << "Creating new Fake Profile object path =" << object_path.value();
std::unique_ptr<Properties> properties(new Properties(
base::BindRepeating(&FakeHermesProfileClient::CallNotifyPropertyChanged,
base::Unretained(this), object_path)));
properties_map_[object_path] = std::move(properties);
return properties_map_[object_path].get();
}
// Updates the Shill Cellular device properties so that they match the given
// profile |properties|. This simulates expected hermes - shill interaction
// when a carrier profile is enabled. Shill updates the active cellular device
// properties so that it matches the currently enabled carrier profile.
void FakeHermesProfileClient::UpdateCellularDevice(
HermesProfileClient::Properties* properties) {
ShillDeviceClient::TestInterface* device_test =
ShillDeviceClient::Get()->GetTestInterface();
// Update the cellular device properties so that they match the carrier
// profile that was just enabled.
device_test->SetDeviceProperty(
kCellularDevicePath, shill::kCarrierProperty,
base::Value(properties->service_provider().value()), true);
device_test->SetDeviceProperty(
kCellularDevicePath, shill::kCarrierProperty,
base::Value(properties->service_provider().value()), true);
base::DictionaryValue home_provider;
home_provider.SetKey(shill::kNameProperty,
base::Value(properties->service_provider().value()));
home_provider.SetKey(shill::kCountryProperty, base::Value(kDefaultCountry));
home_provider.SetKey(shill::kNetworkIdProperty,
base::Value(properties->mcc_mnc().value()));
device_test->SetDeviceProperty(
kCellularDevicePath, shill::kHomeProviderProperty, home_provider, true);
}
void FakeHermesProfileClient::SetCellularServicesState(
const std::string& state) {
ShillManagerClient::TestInterface* manager_test =
ShillManagerClient::Get()->GetTestInterface();
ShillServiceClient::TestInterface* service_test =
ShillServiceClient::Get()->GetTestInterface();
base::Value service_list = manager_test->GetEnabledServiceList();
for (const base::Value& service_path : service_list.GetList()) {
const base::DictionaryValue* properties =
service_test->GetServiceProperties(service_path.GetString());
const base::Value* type = properties->FindDictKey(shill::kTypeProperty);
if (!type || type->GetString() != shill::kTypeCellular)
continue;
service_test->SetServiceProperty(service_path.GetString(),
shill::kStateProperty, base::Value(state));
}
}
void FakeHermesProfileClient::CallNotifyPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FakeHermesProfileClient::NotifyPropertyChanged,
base::Unretained(this), object_path, property_name));
}
void FakeHermesProfileClient::NotifyPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
DVLOG(1) << "Property changed path=" << object_path.value()
<< ", property=" << property_name;
for (auto& observer : observers()) {
observer.OnCarrierProfilePropertyChanged(object_path, property_name);
}
}
} // namespace chromeos
// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_DBUS_HERMES_FAKE_HERMES_PROFILE_CLIENT_H_
#define CHROMEOS_DBUS_HERMES_FAKE_HERMES_PROFILE_CLIENT_H_
#include <map>
#include <memory>
#include "base/component_export.h"
#include "base/macros.h"
#include "chromeos/dbus/hermes/hermes_profile_client.h"
#include "dbus/object_path.h"
#include "dbus/property.h"
namespace chromeos {
// Fake implementation for HermesProfileClient.
class COMPONENT_EXPORT(HERMES_CLIENT) FakeHermesProfileClient
: public HermesProfileClient {
public:
struct Properties : public HermesProfileClient::Properties {
explicit Properties(const PropertyChangedCallback& callback);
~Properties() override;
// dbus::PropertySet:
void Get(dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) override;
void GetAll() override;
void Set(dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) override;
};
FakeHermesProfileClient();
FakeHermesProfileClient(const FakeHermesProfileClient&) = delete;
~FakeHermesProfileClient() override;
// HermesProfileClient:
void EnableCarrierProfile(const dbus::ObjectPath& object_path,
HermesResponseCallback callback) override;
void DisableCarrierProfile(const dbus::ObjectPath& object_path,
HermesResponseCallback callback) override;
HermesProfileClient::Properties* GetProperties(
const dbus::ObjectPath& object_path) override;
FakeHermesProfileClient& operator=(const FakeHermesProfileClient&) = delete;
private:
void UpdateCellularDevice(HermesProfileClient::Properties* properties);
void SetCellularServicesState(const std::string& state);
void CallNotifyPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name);
void NotifyPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name);
// Maps fake profile properties to their object paths.
using PropertiesMap =
std::map<const dbus::ObjectPath, std::unique_ptr<Properties>>;
PropertiesMap properties_map_;
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_HERMES_FAKE_HERMES_PROFILE_CLIENT_H_
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/optional.h" #include "base/optional.h"
#include "chromeos/dbus/hermes/fake_hermes_manager_client.h"
#include "chromeos/dbus/hermes/hermes_response_status.h" #include "chromeos/dbus/hermes/hermes_response_status.h"
#include "components/device_event_log/device_event_log.h" #include "components/device_event_log/device_event_log.h"
#include "dbus/bus.h" #include "dbus/bus.h"
...@@ -232,12 +233,12 @@ void HermesManagerClient::Initialize(dbus::Bus* bus) { ...@@ -232,12 +233,12 @@ void HermesManagerClient::Initialize(dbus::Bus* bus) {
// static // static
void HermesManagerClient::InitializeFake() { void HermesManagerClient::InitializeFake() {
// TODO: Initialize Hermes Manager Fake. new FakeHermesManagerClient();
} }
// static // static
void HermesManagerClient::Shutdown() { void HermesManagerClient::Shutdown() {
// TODO: DCHECK(g_instance); DCHECK(g_instance);
delete g_instance; delete g_instance;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chromeos/dbus/hermes/fake_hermes_profile_client.h"
#include "chromeos/dbus/hermes/hermes_response_status.h" #include "chromeos/dbus/hermes/hermes_response_status.h"
#include "dbus/bus.h" #include "dbus/bus.h"
#include "dbus/object_manager.h" #include "dbus/object_manager.h"
...@@ -149,12 +150,12 @@ void HermesProfileClient::Initialize(dbus::Bus* bus) { ...@@ -149,12 +150,12 @@ void HermesProfileClient::Initialize(dbus::Bus* bus) {
// static // static
void HermesProfileClient::InitializeFake() { void HermesProfileClient::InitializeFake() {
// TODO: Initialize Hermes Profile Fake. new FakeHermesProfileClient();
} }
// static // static
void HermesProfileClient::Shutdown() { void HermesProfileClient::Shutdown() {
// TODO: DCHECK(g_instance); DCHECK(g_instance);
delete g_instance; delete g_instance;
} }
......
...@@ -1034,9 +1034,8 @@ void FakeShillManagerClient::SetupDefaultEnvironment() { ...@@ -1034,9 +1034,8 @@ void FakeShillManagerClient::SetupDefaultEnvironment() {
void FakeShillManagerClient::PassStubProperties( void FakeShillManagerClient::PassStubProperties(
DictionaryValueCallback callback) const { DictionaryValueCallback callback) const {
base::Value stub_properties = stub_properties_.Clone(); base::Value stub_properties = stub_properties_.Clone();
stub_properties.SetKey( stub_properties.SetKey(shill::kServiceCompleteListProperty,
shill::kServiceCompleteListProperty, GetEnabledServiceList());
GetEnabledServiceList(shill::kServiceCompleteListProperty));
std::move(callback).Run(DBUS_METHOD_CALL_SUCCESS, std::move(callback).Run(DBUS_METHOD_CALL_SUCCESS,
base::Value::AsDictionaryValue(stub_properties)); base::Value::AsDictionaryValue(stub_properties));
} }
...@@ -1067,7 +1066,7 @@ void FakeShillManagerClient::NotifyObserversPropertyChanged( ...@@ -1067,7 +1066,7 @@ void FakeShillManagerClient::NotifyObserversPropertyChanged(
return; return;
} }
if (property == shill::kServiceCompleteListProperty) { if (property == shill::kServiceCompleteListProperty) {
base::Value services = GetEnabledServiceList(property); base::Value services = GetEnabledServiceList();
for (auto& observer : observer_list_) for (auto& observer : observer_list_)
observer.OnPropertyChanged(property, services); observer.OnPropertyChanged(property, services);
return; return;
...@@ -1118,11 +1117,11 @@ void FakeShillManagerClient::SetTechnologyEnabled(const std::string& type, ...@@ -1118,11 +1117,11 @@ void FakeShillManagerClient::SetTechnologyEnabled(const std::string& type,
SortManagerServices(true); SortManagerServices(true);
} }
base::Value FakeShillManagerClient::GetEnabledServiceList( base::Value FakeShillManagerClient::GetEnabledServiceList() const {
const std::string& property) const {
base::Value new_service_list(base::Value::Type::LIST); base::Value new_service_list(base::Value::Type::LIST);
const base::ListValue* service_list; const base::ListValue* service_list;
if (stub_properties_.GetListWithoutPathExpansion(property, &service_list)) { if (stub_properties_.GetListWithoutPathExpansion(
shill::kServiceCompleteListProperty, &service_list)) {
ShillServiceClient::TestInterface* service_client = ShillServiceClient::TestInterface* service_client =
ShillServiceClient::Get()->GetTestInterface(); ShillServiceClient::Get()->GetTestInterface();
for (base::ListValue::const_iterator iter = service_list->begin(); for (base::ListValue::const_iterator iter = service_list->begin();
......
...@@ -96,6 +96,7 @@ class COMPONENT_EXPORT(SHILL_CLIENT) FakeShillManagerClient ...@@ -96,6 +96,7 @@ class COMPONENT_EXPORT(SHILL_CLIENT) FakeShillManagerClient
bool GetFastTransitionStatus() override; bool GetFastTransitionStatus() override;
void SetSimulateConfigurationResult( void SetSimulateConfigurationResult(
FakeShillSimulatedResult configuration_result) override; FakeShillSimulatedResult configuration_result) override;
base::Value GetEnabledServiceList() const override;
// Constants used for testing. // Constants used for testing.
static const char kFakeEthernetNetworkGuid[]; static const char kFakeEthernetNetworkGuid[];
...@@ -111,7 +112,6 @@ class COMPONENT_EXPORT(SHILL_CLIENT) FakeShillManagerClient ...@@ -111,7 +112,6 @@ class COMPONENT_EXPORT(SHILL_CLIENT) FakeShillManagerClient
void SetTechnologyEnabled(const std::string& type, void SetTechnologyEnabled(const std::string& type,
base::OnceClosure callback, base::OnceClosure callback,
bool enabled); bool enabled);
base::Value GetEnabledServiceList(const std::string& property) const;
void ScanCompleted(const std::string& device_path); void ScanCompleted(const std::string& device_path);
// Parses the command line for Shill stub switches and sets initial states. // Parses the command line for Shill stub switches and sets initial states.
......
...@@ -78,6 +78,9 @@ class COMPONENT_EXPORT(SHILL_CLIENT) ShillManagerClient { ...@@ -78,6 +78,9 @@ class COMPONENT_EXPORT(SHILL_CLIENT) ShillManagerClient {
virtual void RemoveManagerService(const std::string& service_path) = 0; virtual void RemoveManagerService(const std::string& service_path) = 0;
virtual void ClearManagerServices() = 0; virtual void ClearManagerServices() = 0;
// Returns all enabled services in the given property.
virtual base::Value GetEnabledServiceList() const = 0;
// Called by ShillServiceClient when a service's State property changes, // Called by ShillServiceClient when a service's State property changes,
// before notifying observers. Sets the DefaultService property to empty // before notifying observers. Sets the DefaultService property to empty
// if the state changes to a non-connected state. // if the state changes to a non-connected state.
......
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