blob: f5eb657b80c9cbf38c2e1adb67d99bff48b58d8e [file] [log] [blame]
//
// Copyright (C) 2016 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/binder/manager_binder_adaptor.h"
#include <base/bind.h>
#include <binder/Status.h>
#include <binderwrapper/binder_wrapper.h>
#include <utils/String8.h>
// TODO(samueltan): remove these includes once b/27270173 is resolved,
// and Manager is no longer reliant on D-Bus service constants.
#if defined(__ANDROID__)
#include <dbus/service_constants.h>
#else
#include <chromeos/dbus/service_constants.h>
#endif // __ANDROID__
#include "shill/binder/binder_control.h"
#include "shill/binder/device_binder_service.h"
#include "shill/binder/manager_binder_service.h"
#include "shill/binder/service_binder_service.h"
#include "shill/error.h"
#include "shill/logging.h"
#include "shill/manager.h"
using android::binder::Status;
using android::BinderWrapper;
using android::IBinder;
using android::interface_cast;
using android::sp;
using android::String8;
using android::system::connectivity::shill::IManager;
using android::system::connectivity::shill::IPropertyChangedCallback;
using android::system::connectivity::shill::IService;
using base::Bind;
using std::string;
using std::vector;
namespace shill {
namespace Logging {
static auto kModuleLogScope = ScopeLogger::kBinder;
static string ObjectID(ManagerBinderAdaptor* m) {
return "Manager binder adaptor (id " + m->GetRpcIdentifier() + ")";
}
} // namespace Logging
ManagerBinderAdaptor::ManagerBinderAdaptor(BinderControl* control,
Manager* manager,
const std::string& id)
: BinderAdaptor(control, id),
manager_(manager),
ap_mode_setter_(nullptr),
device_claimer_(nullptr),
weak_ptr_factory_(this) {
set_binder_service(
new ManagerBinderService(weak_ptr_factory_.GetWeakPtr(), id));
}
ManagerBinderAdaptor::~ManagerBinderAdaptor() {
if (ap_mode_setter_ != nullptr) {
BinderWrapper::Get()->UnregisterForDeathNotifications(ap_mode_setter_);
}
if (device_claimer_ != nullptr) {
BinderWrapper::Get()->UnregisterForDeathNotifications(device_claimer_);
}
}
void ManagerBinderAdaptor::RegisterAsync(
const base::Callback<void(bool)>& /*completion_callback*/) {
// Registration is performed synchronously in Binder.
BinderWrapper::Get()->RegisterService(
String8(binder_service()->getInterfaceDescriptor()).string(),
binder_service());
}
void ManagerBinderAdaptor::EmitBoolChanged(const string& name, bool /*value*/) {
SLOG(this, 2) << __func__ << ": " << name;
SendPropertyChangedSignal(name);
}
void ManagerBinderAdaptor::EmitUintChanged(const string& name,
uint32_t /*value*/) {
SLOG(this, 2) << __func__ << ": " << name;
SendPropertyChangedSignal(name);
}
void ManagerBinderAdaptor::EmitIntChanged(const string& name, int /*value*/) {
SLOG(this, 2) << __func__ << ": " << name;
SendPropertyChangedSignal(name);
}
void ManagerBinderAdaptor::EmitStringChanged(const string& name,
const string& /*value*/) {
SLOG(this, 2) << __func__ << ": " << name;
SendPropertyChangedSignal(name);
}
void ManagerBinderAdaptor::EmitStringsChanged(const string& name,
const vector<string>& /*value*/) {
SLOG(this, 2) << __func__ << ": " << name;
SendPropertyChangedSignal(name);
}
void ManagerBinderAdaptor::EmitRpcIdentifierChanged(const string& name,
const string& /*value*/) {
SLOG(this, 2) << __func__ << ": " << name;
SendPropertyChangedSignal(name);
}
void ManagerBinderAdaptor::EmitRpcIdentifierArrayChanged(
const string& name, const vector<string>& /*value*/) {
SLOG(this, 2) << __func__ << ": " << name;
SendPropertyChangedSignal(name);
}
Status ManagerBinderAdaptor::SetupApModeInterface(
const sp<IBinder>& ap_mode_setter, std::string* _aidl_return) {
SLOG(this, 2) << __func__;
Error e;
#if !defined(DISABLE_WIFI) && defined(__BRILLO__)
manager_->SetupApModeInterface(_aidl_return, &e);
if (e.IsFailure()) {
return e.ToBinderStatus();
}
// Register for death notifications from the caller. This will restore
// interface mode to station mode if the caller vanishes.
ap_mode_setter_ = ap_mode_setter;
BinderWrapper::Get()->RegisterForDeathNotifications(
ap_mode_setter, Bind(&ManagerBinderAdaptor::OnApModeSetterVanished,
base::Unretained(this)));
return Status::ok();
#else
return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
#endif // !DISABLE_WIFI && __BRILLO__
}
Status ManagerBinderAdaptor::SetupStationModeInterface(
std::string* _aidl_return) {
SLOG(this, 2) << __func__;
#if !defined(DISABLE_WIFI) && defined(__BRILLO__)
Error e;
manager_->SetupStationModeInterface(_aidl_return, &e);
if (e.IsFailure()) {
return e.ToBinderStatus();
}
if (ap_mode_setter_ != nullptr) {
// Unregister for death notifications from the AP mode setter, if case
// SetupApModeInterface() was previously called.
BinderWrapper::Get()->UnregisterForDeathNotifications(ap_mode_setter_);
ap_mode_setter_ = nullptr;
}
return Status::ok();
#else
return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
#endif // !DISABLE_WIFI && __BRILLO__
}
Status ManagerBinderAdaptor::ClaimInterface(const sp<IBinder>& claimer,
const std::string& claimer_name,
const std::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).
manager_->ClaimDevice(claimer_name, interface_name, &e);
if (e.IsFailure()) {
return e.ToBinderStatus();
}
if (!claimer_name.empty()) {
device_claimer_ = claimer;
BinderWrapper::Get()->RegisterForDeathNotifications(
claimer, Bind(&ManagerBinderAdaptor::OnDeviceClaimerVanished,
base::Unretained(this)));
}
return Status::ok();
}
Status ManagerBinderAdaptor::ReleaseInterface(
const sp<IBinder>& claimer, const std::string& claimer_name,
const std::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, interface_name, &claimer_removed, &e);
if (e.IsFailure()) {
return e.ToBinderStatus();
}
if (claimer_removed) {
BinderWrapper::Get()->UnregisterForDeathNotifications(claimer);
}
return Status::ok();
}
Status ManagerBinderAdaptor::ConfigureService(
const android::os::PersistableBundle& properties,
sp<IService>* _aidl_return) {
SLOG(this, 2) << __func__;
ServiceRefPtr service;
KeyValueStore args_store;
KeyValueStore::ConvertFromPersistableBundle(properties, &args_store);
Error e;
service = manager_->ConfigureService(args_store, &e);
if (e.IsFailure()) {
return e.ToBinderStatus();
}
*_aidl_return = interface_cast<IService>(static_cast<ServiceBinderService*>(
control()->GetBinderServiceForRpcIdentifier(
service->GetRpcIdentifier()).get()));
return Status::ok();
}
Status ManagerBinderAdaptor::RequestScan(int32_t type) {
string technology;
switch (type) {
// TODO(samueltan): remove the use of these D-Bus service constants once
// b/27270173 is resolved, and Manager is no longer reliant on them.
case IManager::TECHNOLOGY_ANY:
technology = "";
break;
case IManager::TECHNOLOGY_WIFI:
technology = kTypeWifi;
break;
default:
return Status::fromExceptionCode(
Status::EX_ILLEGAL_ARGUMENT,
String8::format("%s: invalid technology type %d", __func__, type));
}
SLOG(this, 2) << __func__ << ": " << technology;
Error e;
manager_->RequestScan(technology, &e);
return e.ToBinderStatus();
}
Status ManagerBinderAdaptor::GetDevices(vector<sp<IBinder>>* _aidl_return) {
SLOG(this, 2) << __func__;
Error e;
RpcIdentifiers device_rpc_ids = manager_->EnumerateDevices(&e);
if (e.IsFailure()) {
return e.ToBinderStatus();
}
for (const auto& device_rpc_id : device_rpc_ids) {
_aidl_return->emplace_back(static_cast<DeviceBinderService*>(
control()->GetBinderServiceForRpcIdentifier(device_rpc_id).get()));
}
return Status::ok();
}
Status ManagerBinderAdaptor::GetDefaultService(sp<IBinder>* _aidl_return) {
SLOG(this, 2) << __func__;
Error e;
RpcIdentifier default_service_rpc_id =
manager_->GetDefaultServiceRpcIdentifier(&e);
if (e.IsFailure()) {
return e.ToBinderStatus();
}
*_aidl_return = static_cast<ServiceBinderService*>(
control()->GetBinderServiceForRpcIdentifier(default_service_rpc_id).get());
return Status::ok();
}
Status ManagerBinderAdaptor::RegisterPropertyChangedSignalHandler(
const sp<IPropertyChangedCallback>& callback) {
AddPropertyChangedSignalHandler(callback);
return Status::ok();
}
void ManagerBinderAdaptor::OnApModeSetterVanished() {
SLOG(this, 3) << __func__;
#if !defined(DISABLE_WIFI) && defined(__BRILLO__)
manager_->OnApModeSetterVanished();
#endif // !DISABLE_WIFI && __BRILLO__
BinderWrapper::Get()->UnregisterForDeathNotifications(ap_mode_setter_);
ap_mode_setter_ = nullptr;
}
void ManagerBinderAdaptor::OnDeviceClaimerVanished() {
SLOG(this, 3) << __func__;
manager_->OnDeviceClaimerVanished();
BinderWrapper::Get()->UnregisterForDeathNotifications(device_claimer_);
device_claimer_ = nullptr;
}
} // namespace shill