| // |
| // 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 "shill/dbus/chromeos_manager_dbus_adaptor.h" |
| |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| #include "shill/callbacks.h" |
| #include "shill/dbus/dbus_service_watcher_factory.h" |
| #include "shill/device.h" |
| #include "shill/error.h" |
| #include "shill/geolocation_info.h" |
| #include "shill/key_value_store.h" |
| #include "shill/logging.h" |
| #include "shill/manager.h" |
| #include "shill/property_store.h" |
| |
| using base::Unretained; |
| using std::map; |
| using std::string; |
| using std::vector; |
| |
| namespace shill { |
| |
| namespace Logging { |
| static auto kModuleLogScope = ScopeLogger::kDBus; |
| static string ObjectID(ChromeosManagerDBusAdaptor* m) { |
| return m->GetRpcIdentifier(); |
| } |
| } |
| |
| // static |
| const char ChromeosManagerDBusAdaptor::kPath[] = "/"; |
| |
| ChromeosManagerDBusAdaptor::ChromeosManagerDBusAdaptor( |
| const scoped_refptr<dbus::Bus>& adaptor_bus, |
| const scoped_refptr<dbus::Bus> proxy_bus, |
| Manager* manager) |
| : org::chromium::flimflam::ManagerAdaptor(this), |
| ChromeosDBusAdaptor(adaptor_bus, kPath), |
| manager_(manager), |
| proxy_bus_(proxy_bus), |
| dbus_service_watcher_factory_(DBusServiceWatcherFactory::GetInstance()) {} |
| |
| ChromeosManagerDBusAdaptor::~ChromeosManagerDBusAdaptor() { |
| manager_ = nullptr; |
| } |
| |
| void ChromeosManagerDBusAdaptor::RegisterAsync( |
| const base::Callback<void(bool)>& completion_callback) { |
| RegisterWithDBusObject(dbus_object()); |
| dbus_object()->RegisterAsync(completion_callback); |
| } |
| |
| void ChromeosManagerDBusAdaptor::EmitBoolChanged(const string& name, |
| bool value) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| SendPropertyChangedSignal(name, brillo::Any(value)); |
| } |
| |
| void ChromeosManagerDBusAdaptor::EmitUintChanged(const string& name, |
| uint32_t value) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| SendPropertyChangedSignal(name, brillo::Any(value)); |
| } |
| |
| void ChromeosManagerDBusAdaptor::EmitIntChanged(const string& name, int value) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| SendPropertyChangedSignal(name, brillo::Any(value)); |
| } |
| |
| void ChromeosManagerDBusAdaptor::EmitStringChanged(const string& name, |
| const string& value) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| SendPropertyChangedSignal(name, brillo::Any(value)); |
| } |
| |
| void ChromeosManagerDBusAdaptor::EmitStringsChanged(const string& name, |
| const vector<string>& value) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| SendPropertyChangedSignal(name, brillo::Any(value)); |
| } |
| |
| void ChromeosManagerDBusAdaptor::EmitRpcIdentifierChanged( |
| const string& name, |
| const string& value) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| SendPropertyChangedSignal(name, brillo::Any(dbus::ObjectPath(value))); |
| } |
| |
| void ChromeosManagerDBusAdaptor::EmitRpcIdentifierArrayChanged( |
| const string& name, |
| const vector<string>& value) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| vector<dbus::ObjectPath> paths; |
| for (const auto& element : value) { |
| paths.push_back(dbus::ObjectPath(element)); |
| } |
| |
| SendPropertyChangedSignal(name, brillo::Any(paths)); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::GetProperties( |
| brillo::ErrorPtr* error, brillo::VariantDictionary* properties) { |
| SLOG(this, 2) << __func__; |
| return ChromeosDBusAdaptor::GetProperties(manager_->store(), |
| properties, |
| error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::SetProperty(brillo::ErrorPtr* error, |
| const string& name, |
| const brillo::Any& value) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| return ChromeosDBusAdaptor::SetProperty(manager_->mutable_store(), |
| name, |
| value, |
| error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::GetState(brillo::ErrorPtr* /*error*/, |
| string* state) { |
| SLOG(this, 2) << __func__; |
| *state = manager_->CalculateState(nullptr); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::CreateProfile(brillo::ErrorPtr* error, |
| const string& name, |
| dbus::ObjectPath* profile_path) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| Error e; |
| string path; |
| manager_->CreateProfile(name, &path, &e); |
| if (e.ToChromeosError(error)) { |
| return false; |
| } |
| *profile_path = dbus::ObjectPath(path); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::RemoveProfile(brillo::ErrorPtr* error, |
| const string& name) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| Error e; |
| manager_->RemoveProfile(name, &e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::PushProfile(brillo::ErrorPtr* error, |
| const string& name, |
| dbus::ObjectPath* profile_path) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| Error e; |
| string path; |
| manager_->PushProfile(name, &path, &e); |
| if (e.ToChromeosError(error)) { |
| return false; |
| } |
| *profile_path = dbus::ObjectPath(path); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::InsertUserProfile( |
| brillo::ErrorPtr* error, |
| const string& name, |
| const string& user_hash, |
| dbus::ObjectPath* profile_path) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| Error e; |
| string path; |
| manager_->InsertUserProfile(name, user_hash, &path, &e); |
| if (e.ToChromeosError(error)) { |
| return false; |
| } |
| *profile_path = dbus::ObjectPath(path); |
| return true;; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::PopProfile(brillo::ErrorPtr* error, |
| const string& name) { |
| SLOG(this, 2) << __func__ << ": " << name; |
| Error e; |
| manager_->PopProfile(name, &e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::PopAnyProfile(brillo::ErrorPtr* error) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| manager_->PopAnyProfile(&e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::PopAllUserProfiles(brillo::ErrorPtr* error) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| manager_->PopAllUserProfiles(&e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::RecheckPortal(brillo::ErrorPtr* error) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| manager_->RecheckPortal(&e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::RequestScan(brillo::ErrorPtr* error, |
| const string& technology) { // NOLINT |
| SLOG(this, 2) << __func__ << ": " << technology; |
| Error e; |
| manager_->RequestScan(Device::kFullScan, technology, &e); |
| return !e.ToChromeosError(error); |
| } |
| |
| void ChromeosManagerDBusAdaptor::EnableTechnology( |
| DBusMethodResponsePtr<> response, const string& technology_name) { |
| SLOG(this, 2) << __func__ << ": " << technology_name; |
| Error e(Error::kOperationInitiated); |
| ResultCallback callback = GetMethodReplyCallback(std::move(response)); |
| const bool kPersistentSave = true; |
| manager_->SetEnabledStateForTechnology(technology_name, true, |
| kPersistentSave, &e, callback); |
| ReturnResultOrDefer(callback, e); |
| } |
| |
| void ChromeosManagerDBusAdaptor::DisableTechnology( |
| DBusMethodResponsePtr<> response, const string& technology_name) { |
| SLOG(this, 2) << __func__ << ": " << technology_name; |
| Error e(Error::kOperationInitiated); |
| ResultCallback callback = GetMethodReplyCallback(std::move(response)); |
| const bool kPersistentSave = true; |
| manager_->SetEnabledStateForTechnology(technology_name, false, |
| kPersistentSave, &e, callback); |
| ReturnResultOrDefer(callback, e); |
| } |
| |
| // Called, e.g., to get WiFiService handle for a hidden SSID. |
| bool ChromeosManagerDBusAdaptor::GetService( |
| brillo::ErrorPtr* error, |
| const brillo::VariantDictionary& args, |
| dbus::ObjectPath* service_path) { |
| SLOG(this, 2) << __func__; |
| ServiceRefPtr service; |
| KeyValueStore args_store; |
| Error e; |
| KeyValueStore::ConvertFromVariantDictionary(args, &args_store); |
| service = manager_->GetService(args_store, &e); |
| if (e.ToChromeosError(error)) { |
| return false; |
| } |
| *service_path = dbus::ObjectPath(service->GetRpcIdentifier()); |
| return true; |
| } |
| |
| // Obsolete, use GetService instead. |
| bool ChromeosManagerDBusAdaptor::GetVPNService( |
| brillo::ErrorPtr* error, |
| const brillo::VariantDictionary& args, |
| dbus::ObjectPath* service_path) { |
| SLOG(this, 2) << __func__; |
| return GetService(error, args, service_path); |
| } |
| |
| // Obsolete, use GetService instead. |
| bool ChromeosManagerDBusAdaptor::GetWifiService( |
| brillo::ErrorPtr* error, |
| const brillo::VariantDictionary& args, |
| dbus::ObjectPath* service_path) { |
| SLOG(this, 2) << __func__; |
| return GetService(error, args, service_path); |
| } |
| |
| |
| bool ChromeosManagerDBusAdaptor::ConfigureService( |
| brillo::ErrorPtr* error, |
| const brillo::VariantDictionary& args, |
| dbus::ObjectPath* service_path) { |
| SLOG(this, 2) << __func__; |
| ServiceRefPtr service; |
| KeyValueStore args_store; |
| KeyValueStore::ConvertFromVariantDictionary(args, &args_store); |
| Error configure_error; |
| service = manager_->ConfigureService(args_store, &configure_error); |
| if (configure_error.ToChromeosError(error)) { |
| return false; |
| } |
| *service_path = dbus::ObjectPath(service->GetRpcIdentifier()); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::ConfigureServiceForProfile( |
| brillo::ErrorPtr* error, |
| const dbus::ObjectPath& profile_rpcid, |
| const brillo::VariantDictionary& args, |
| dbus::ObjectPath* service_path) { |
| SLOG(this, 2) << __func__; |
| ServiceRefPtr service; |
| KeyValueStore args_store; |
| KeyValueStore::ConvertFromVariantDictionary(args, &args_store); |
| Error configure_error; |
| service = manager_->ConfigureServiceForProfile( |
| profile_rpcid.value(), args_store, &configure_error); |
| if (!service || configure_error.ToChromeosError(error)) { |
| return false; |
| } |
| *service_path = dbus::ObjectPath(service->GetRpcIdentifier()); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::FindMatchingService( |
| brillo::ErrorPtr* error, |
| const brillo::VariantDictionary& args, |
| dbus::ObjectPath* service_path) { // NOLINT |
| SLOG(this, 2) << __func__; |
| KeyValueStore args_store; |
| KeyValueStore::ConvertFromVariantDictionary(args, &args_store); |
| |
| Error find_error; |
| ServiceRefPtr service = |
| manager_->FindMatchingService(args_store, &find_error); |
| if (find_error.ToChromeosError(error)) { |
| return false; |
| } |
| |
| *service_path = dbus::ObjectPath(service->GetRpcIdentifier()); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::GetDebugLevel(brillo::ErrorPtr* /*error*/, |
| int32_t* level) { |
| SLOG(this, 2) << __func__; |
| *level = logging::GetMinLogLevel(); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::SetDebugLevel(brillo::ErrorPtr* /*error*/, |
| int32_t level) { |
| SLOG(this, 2) << __func__ << ": " << level; |
| if (level < logging::LOG_NUM_SEVERITIES) { |
| logging::SetMinLogLevel(level); |
| // Like VLOG, SLOG uses negative verbose level. |
| ScopeLogger::GetInstance()->set_verbose_level(-level); |
| } else { |
| LOG(WARNING) << "Ignoring attempt to set log level to " << level; |
| } |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::GetServiceOrder(brillo::ErrorPtr* /*error*/, |
| string* order) { |
| SLOG(this, 2) << __func__; |
| *order = manager_->GetTechnologyOrder(); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::SetServiceOrder(brillo::ErrorPtr* error, |
| const string& order) { |
| SLOG(this, 2) << __func__ << ": " << order; |
| Error e; |
| manager_->SetTechnologyOrder(order, &e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::GetDebugTags(brillo::ErrorPtr* /*error*/, |
| string* tags) { |
| SLOG(this, 2) << __func__; |
| *tags = ScopeLogger::GetInstance()->GetEnabledScopeNames(); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::SetDebugTags(brillo::ErrorPtr* /*error*/, |
| const string& tags) { |
| SLOG(this, 2) << __func__ << ": " << tags; |
| ScopeLogger::GetInstance()->EnableScopesByName(tags); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::ListDebugTags(brillo::ErrorPtr* /*error*/, |
| string* tags) { |
| SLOG(this, 2) << __func__; |
| *tags = ScopeLogger::GetInstance()->GetAllScopeNames(); |
| return true; |
| } |
| |
| bool ChromeosManagerDBusAdaptor::GetNetworksForGeolocation( |
| brillo::ErrorPtr* /*error*/, |
| brillo::VariantDictionary* networks) { |
| SLOG(this, 2) << __func__; |
| for (const auto& network : manager_->GetNetworksForGeolocation()) { |
| Stringmaps value; |
| // Convert GeolocationInfos to their Stringmaps equivalent. |
| for (const auto& info : network.second) { |
| value.push_back(info.properties()); |
| } |
| networks->insert(std::make_pair(network.first, brillo::Any(value))); |
| } |
| return true; |
| } |
| |
| void ChromeosManagerDBusAdaptor::VerifyDestination( |
| DBusMethodResponsePtr<bool> response, |
| const string& certificate, |
| const string& public_key, |
| const string& nonce, |
| const string& signed_data, |
| const string& destination_udn, |
| const string& hotspot_ssid, |
| const string& hotspot_bssid) { |
| SLOG(this, 2) << __func__; |
| ResultBoolCallback callback = GetBoolMethodReplyCallback(std::move(response)); |
| #if !defined(DISABLE_WIFI) |
| Error e(Error::kOperationInitiated); |
| manager_->VerifyDestination(certificate, public_key, nonce, |
| signed_data, destination_udn, |
| hotspot_ssid, hotspot_bssid, |
| callback, &e); |
| #else |
| Error e(Error::kNotImplemented); |
| #endif // DISABLE_WIFI |
| if (e.IsOngoing()) { |
| return; |
| } |
| // Command failed synchronously. |
| CHECK(e.IsFailure()) << __func__ << " should only return directly on error."; |
| callback.Run(e, false); |
| } |
| |
| void ChromeosManagerDBusAdaptor::VerifyAndEncryptCredentials( |
| DBusMethodResponsePtr<string> response, |
| const string& certificate, |
| const string& public_key, |
| const string& nonce, |
| const string& signed_data, |
| const string& destination_udn, |
| const string& hotspot_ssid, |
| const string& hotspot_bssid, |
| const dbus::ObjectPath& network) { |
| SLOG(this, 2) << __func__; |
| ResultStringCallback callback = |
| GetStringMethodReplyCallback(std::move(response)); |
| #if !defined(DISABLE_WIFI) |
| Error e(Error::kOperationInitiated); |
| manager_->VerifyAndEncryptCredentials(certificate, public_key, nonce, |
| signed_data, destination_udn, |
| hotspot_ssid, hotspot_bssid, |
| network.value(), |
| callback, |
| &e); |
| #else |
| Error e(Error::kNotImplemented); |
| #endif // DISABLE_WIFI |
| if (e.IsOngoing()) { |
| return; |
| } |
| // Command failed synchronously. |
| CHECK(e.IsFailure()) << __func__ << " should only return directly on error."; |
| callback.Run(e, ""); |
| } |
| |
| void ChromeosManagerDBusAdaptor::VerifyAndEncryptData( |
| DBusMethodResponsePtr<string> response, |
| const string& certificate, |
| const string& public_key, |
| const string& nonce, |
| const string& signed_data, |
| const string& destination_udn, |
| const string& hotspot_ssid, |
| const string& hotspot_bssid, |
| const string& data) { |
| SLOG(this, 2) << __func__; |
| ResultStringCallback callback = |
| GetStringMethodReplyCallback(std::move(response)); |
| #if !defined(DISABLE_WIFI) |
| Error e(Error::kOperationInitiated); |
| manager_->VerifyAndEncryptData(certificate, public_key, nonce, |
| signed_data, destination_udn, |
| hotspot_ssid, hotspot_bssid, |
| data, callback, |
| &e); |
| #else |
| Error e(Error::kNotImplemented); |
| #endif // DISABLE_WIFI |
| if (e.IsOngoing()) { |
| return; |
| } |
| // Command failed synchronously. |
| CHECK(e.IsFailure()) << __func__ << " should only return directly on error."; |
| callback.Run(e, ""); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::ConnectToBestServices( |
| brillo::ErrorPtr* error) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| manager_->ConnectToBestServices(&e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::CreateConnectivityReport( |
| brillo::ErrorPtr* error) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| manager_->CreateConnectivityReport(&e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::ClaimInterface( |
| brillo::ErrorPtr* error, |
| dbus::Message* message, |
| const string& claimer_name, |
| const string& interface_name) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| // Empty claimer name is used to indicate default claimer. |
| // TODO(samueltan): update this API or make a new API to use a flag to |
| // indicate default claimer instead (b/27924738). |
| string claimer = (claimer_name == "" ? "" : message->GetSender()); |
| manager_->ClaimDevice(claimer, interface_name, &e); |
| if (e.IsSuccess() && claimer_name != "") { |
| // Only setup watcher for non-default claimer. |
| watcher_for_device_claimer_.reset( |
| dbus_service_watcher_factory_->CreateDBusServiceWatcher( |
| proxy_bus_, claimer, |
| Bind(&ChromeosManagerDBusAdaptor::OnDeviceClaimerVanished, |
| Unretained(this)))); |
| } |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::ReleaseInterface( |
| brillo::ErrorPtr* error, |
| dbus::Message* message, |
| const string& claimer_name, |
| const string& interface_name) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| bool claimer_removed; |
| // Empty claimer name is used to indicate default claimer. |
| // TODO(samueltan): update this API or make a new API to use a flag to |
| // indicate default claimer instead (b/27924738). |
| manager_->ReleaseDevice( |
| claimer_name == "" ? "" : message->GetSender(), |
| interface_name, |
| &claimer_removed, |
| &e); |
| if (claimer_removed) { |
| watcher_for_device_claimer_.reset(); |
| } |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::SetSchedScan(brillo::ErrorPtr* error, |
| bool enable) { |
| SLOG(this, 2) << __func__ << ": " << enable; |
| Error e; |
| manager_->SetSchedScan(enable, &e); |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::SetupApModeInterface( |
| brillo::ErrorPtr* error, |
| dbus::Message* message, |
| string* out_interface_name) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| #if !defined(DISABLE_WIFI) && defined(__BRILLO__) |
| manager_->SetupApModeInterface(out_interface_name, &e); |
| if (e.IsSuccess()) { |
| // Setup a service watcher for the caller. This will restore interface mode |
| // back to station mode if the caller vanished. |
| watcher_for_ap_mode_setter_.reset( |
| dbus_service_watcher_factory_->CreateDBusServiceWatcher( |
| proxy_bus_, message->GetSender(), |
| Bind(&ChromeosManagerDBusAdaptor::OnApModeSetterVanished, |
| Unretained(this)))); |
| } |
| #else |
| e.Populate(Error::kNotSupported); |
| #endif // !DISABLE_WIFI && __BRILLO__ |
| return !e.ToChromeosError(error); |
| } |
| |
| bool ChromeosManagerDBusAdaptor::SetupStationModeInterface( |
| brillo::ErrorPtr* error, |
| string* out_interface_name) { |
| SLOG(this, 2) << __func__; |
| Error e; |
| #if !defined(DISABLE_WIFI) && defined(__BRILLO__) |
| manager_->SetupStationModeInterface(out_interface_name, &e); |
| // Remove the service watcher for the AP mode setter. |
| watcher_for_ap_mode_setter_.reset(); |
| #else |
| e.Populate(Error::kNotSupported); |
| #endif // !DISABLE_WIFI && __BRILLO__ |
| return !e.ToChromeosError(error); |
| } |
| |
| void ChromeosManagerDBusAdaptor::OnApModeSetterVanished() { |
| SLOG(this, 3) << __func__; |
| #if !defined(DISABLE_WIFI) && defined(__BRILLO__) |
| manager_->OnApModeSetterVanished(); |
| #endif // !DISABLE_WIFI && __BRILLO__ |
| watcher_for_ap_mode_setter_.reset(); |
| } |
| |
| void ChromeosManagerDBusAdaptor::OnDeviceClaimerVanished() { |
| SLOG(this, 3) << __func__; |
| manager_->OnDeviceClaimerVanished(); |
| watcher_for_device_claimer_.reset(); |
| } |
| |
| } // namespace shill |