From 94ecc4af842bd8c94259d5580627d5988f51da82 Mon Sep 17 00:00:00 2001 From: Samuel Tan Date: Tue, 3 May 2016 00:16:17 -0700 Subject: shill: add BinderService for each BinderAdaptor Have each BinderAdaptor hold a strong pointer to a *BinderService object that actually implements the relevant Bn* class. This configuratoin ensures that the Binder service for each shill object stays alive for at least as long as the shill object itself. (See documentation in binder_adaptor.h for more details.) BUG: 28542219 TEST: shill compiles. TEST: Manual test test instructions in forthcoming CL where Binder support is added to shill_setup_wifi. Change-Id: Ie178a7fe163a3636ab890653679ac742763ad69d --- Android.mk | 3 + binder/binder_adaptor.cc | 20 ++++++- binder/binder_adaptor.h | 46 +++++++++++++- binder/binder_control.cc | 4 +- binder/binder_control.h | 10 +++- binder/device_binder_adaptor.cc | 16 ++--- binder/device_binder_adaptor.h | 22 ++++--- binder/device_binder_service.cc | 66 +++++++++++++++++++++ binder/device_binder_service.h | 80 +++++++++++++++++++++++++ binder/manager_binder_adaptor.cc | 29 +++++---- binder/manager_binder_adaptor.h | 49 ++++++++------- binder/manager_binder_service.cc | 125 +++++++++++++++++++++++++++++++++++++++ binder/manager_binder_service.h | 98 ++++++++++++++++++++++++++++++ binder/service_binder_adaptor.cc | 9 ++- binder/service_binder_adaptor.h | 40 +++++++------ binder/service_binder_service.cc | 106 +++++++++++++++++++++++++++++++++ binder/service_binder_service.h | 84 ++++++++++++++++++++++++++ 17 files changed, 727 insertions(+), 80 deletions(-) create mode 100644 binder/device_binder_service.cc create mode 100644 binder/device_binder_service.h create mode 100644 binder/manager_binder_service.cc create mode 100644 binder/manager_binder_service.h create mode 100644 binder/service_binder_service.cc create mode 100644 binder/service_binder_service.h diff --git a/Android.mk b/Android.mk index d9bc6c3f..458c50d2 100644 --- a/Android.mk +++ b/Android.mk @@ -293,8 +293,11 @@ LOCAL_SRC_FILES += \ binder/binder_adaptor.cc \ binder/binder_control.cc \ binder/device_binder_adaptor.cc \ + binder/device_binder_service.cc \ binder/manager_binder_adaptor.cc \ + binder/manager_binder_service.cc \ binder/service_binder_adaptor.cc \ + binder/service_binder_service.cc \ ipconfig_adaptor_stub.cc \ profile_adaptor_stub.cc \ rpc_task_adaptor_stub.cc \ diff --git a/binder/binder_adaptor.cc b/binder/binder_adaptor.cc index 0aa4fc95..7381051f 100644 --- a/binder/binder_adaptor.cc +++ b/binder/binder_adaptor.cc @@ -18,14 +18,25 @@ #include +#include +#include + #include "android/system/connectivity/shill/IPropertyChangedCallback.h" #include "shill/binder/binder_control.h" #include "shill/logging.h" +using android::binder::Status; using android::sp; +using android::String8; using android::system::connectivity::shill::IPropertyChangedCallback; using std::string; +namespace { +const int kShillObjectNotAliveErrorCode = -2; +const char kShillObjectNotAliveErrorMessage[] = + "shill object is no longer alive."; +} + namespace shill { namespace Logging { @@ -40,7 +51,14 @@ BinderAdaptor::BinderAdaptor(BinderControl* control, const string& rpc_id) SLOG(this, 2) << "BinderAdaptor: " << rpc_id; } -BinderAdaptor::~BinderAdaptor() { control_->OnAdaptorDestructed(rpc_id()); } +BinderAdaptor::~BinderAdaptor() { + control_->OnAdaptorDestructed(rpc_id()); +} + +Status BinderAdaptor::GenerateShillObjectNotAliveErrorStatus() { + return Status::fromServiceSpecificError( + kShillObjectNotAliveErrorCode, String8(kShillObjectNotAliveErrorMessage)); +} void BinderAdaptor::AddPropertyChangedSignalHandler( const sp& property_changed_callback) { diff --git a/binder/binder_adaptor.h b/binder/binder_adaptor.h index 33d50c6b..0e25cf3c 100644 --- a/binder/binder_adaptor.h +++ b/binder/binder_adaptor.h @@ -21,9 +21,13 @@ #include #include +#include #include namespace android { +namespace binder { +class Status; +} // namespace binder namespace system { namespace connectivity { namespace shill { @@ -37,11 +41,42 @@ namespace shill { class BinderControl; -// Superclass for all Binder-backed Adaptor objects. +// Superclass for all Binder Adaptor objects. +// +// The following diagram illustrates the relationship between shill objects +// (e.g. Manager, Service), Binder adaptor objects (e.g. ManagerBinderAdaptor, +// ServiceBinderAdaptor), and Binder service objects (e.g. ManagerBinderService, +// ServiceBinderService): +// +// [Shill Object] <-----> [BinderAdaptor] <-----> [BinderService] +// 1:1 1:1 +// +// Each shill object exposed on shill's Binder interface will own a single +// BinderAdaptor. This BinderAdaptor contains all the logic and state to +// service the methods exposed on the shill object's Binder interface. +// +// Each BinderAdaptor object, in turn, owns a single binder service object. The +// Binder service object actually inherits from the AIDL-generated Bn* class +// (e.g. ManagerBinderService implements BnManager), and is therefore a Binder +// object. The methods implementations in the Binder service class are thin +// wrappers around the actual method handling logic in the corresponding +// BinderAdaptor. +// +// The Binder service object is ref-counted across process boundaries via +// the Binder driver and Android Strong Pointers (android::sp). By having each +// BinderAdaptor hold a Strong Pointer to its corresponding Binder service, +// we ensure that the Binder service backing the shill object will stay alive +// for at least as long as the shill object does. class BinderAdaptor { public: - explicit BinderAdaptor(BinderControl* control, const std::string& rpc_id); - ~BinderAdaptor(); + BinderAdaptor(BinderControl* control, const std::string& rpc_id); + virtual ~BinderAdaptor(); + + static android::binder::Status GenerateShillObjectNotAliveErrorStatus(); + + const android::sp& binder_service() { + return binder_service_; + } protected: // Add a IPropertyChangedCallback binder to |property_changed_callbacks_|. @@ -59,6 +94,9 @@ class BinderAdaptor { BinderControl* control() { return control_; } const std::string& rpc_id() { return rpc_id_; } + void set_binder_service(const android::sp& binder_service) { + binder_service_ = binder_service; + } private: // Storing this pointer is safe since the ordering of the members of @@ -68,6 +106,8 @@ class BinderAdaptor { // Used to uniquely identify this Binder adaptor. std::string rpc_id_; + android::sp binder_service_; + std::vector> property_changed_callbacks_; diff --git a/binder/binder_control.cc b/binder/binder_control.cc index 8e90c9b4..21b046a9 100644 --- a/binder/binder_control.cc +++ b/binder/binder_control.cc @@ -185,14 +185,14 @@ FirewallProxyInterface* BinderControl::CreateFirewallProxy() { return new ChromeosFirewalldProxy(proxy_bus_); } -BinderAdaptor* BinderControl::GetBinderAdaptorForRpcIdentifier( +sp BinderControl::GetBinderServiceForRpcIdentifier( const std::string& rpc_id) { const auto& it = rpc_id_to_adaptor_map_.find(rpc_id); if (it == rpc_id_to_adaptor_map_.end()) { return nullptr; } - return it->second; + return it->second->binder_service(); } template diff --git a/binder/binder_control.h b/binder/binder_control.h index 17ee9f40..50afbe0f 100644 --- a/binder/binder_control.h +++ b/binder/binder_control.h @@ -20,6 +20,9 @@ #include #include +#include +#include + #include #include "shill/control_interface.h" @@ -82,9 +85,10 @@ class BinderControl : public ControlInterface { FirewallProxyInterface* CreateFirewallProxy() override; - // Returns a Binder reference to the object uniquely identified by |rpc_id|, - // if it exists, NULL otherwise. - BinderAdaptor* GetBinderAdaptorForRpcIdentifier(const std::string& rpc_id); + // Returns a Binder reference to the Binder service backing the object + // uniquely identified by |rpc_id| if it exists, nullptr otherwise. + android::sp GetBinderServiceForRpcIdentifier( + const std::string& rpc_id); // Called by binder adaptors on destruction to clear their entries in // |rpc_id_to_adaptor_map_|. diff --git a/binder/device_binder_adaptor.cc b/binder/device_binder_adaptor.cc index 7fd13f3f..6878e045 100644 --- a/binder/device_binder_adaptor.cc +++ b/binder/device_binder_adaptor.cc @@ -19,7 +19,8 @@ #include #include "shill/binder/binder_control.h" -#include "shill/binder/service_binder_adaptor.h" +#include "shill/binder/device_binder_service.h" +#include "shill/binder/service_binder_service.h" #include "shill/device.h" #include "shill/logging.h" #include "shill/refptr_types.h" @@ -43,9 +44,10 @@ static string ObjectID(DeviceBinderAdaptor* d) { DeviceBinderAdaptor::DeviceBinderAdaptor(BinderControl* control, Device* device, const string& id) - : BinderAdaptor(control, id), device_(device) {} - -DeviceBinderAdaptor::~DeviceBinderAdaptor() { device_ = nullptr; } + : BinderAdaptor(control, id), device_(device), weak_ptr_factory_(this) { + set_binder_service( + new DeviceBinderService(weak_ptr_factory_.GetWeakPtr(), id)); +} void DeviceBinderAdaptor::EmitBoolChanged(const string& name, bool /*value*/) { SLOG(this, 2) << __func__ << ": " << name; @@ -123,9 +125,9 @@ Status DeviceBinderAdaptor::GetSelectedService(sp* _aidl_return) { if (!selected_service) { *_aidl_return = NULL; } else { - *_aidl_return = static_cast( - control()->GetBinderAdaptorForRpcIdentifier( - selected_service->GetRpcIdentifier())); + *_aidl_return = static_cast( + control()->GetBinderServiceForRpcIdentifier( + selected_service->GetRpcIdentifier()).get()); } return Status::ok(); } diff --git a/binder/device_binder_adaptor.h b/binder/device_binder_adaptor.h index 33e754a6..e50994ba 100644 --- a/binder/device_binder_adaptor.h +++ b/binder/device_binder_adaptor.h @@ -21,6 +21,7 @@ #include #include +#include #include #include "android/system/connectivity/shill/BnDevice.h" @@ -49,14 +50,12 @@ class Device; // Furthermore, the Device owns the DeviceBinderAdaptor and manages its // lifetime, so we're OK with DeviceBinderAdaptor having a bare pointer to its // owner device. -class DeviceBinderAdaptor - : public android::system::connectivity::shill::BnDevice, - public BinderAdaptor, - public DeviceAdaptorInterface { +class DeviceBinderAdaptor : public BinderAdaptor, + public DeviceAdaptorInterface { public: DeviceBinderAdaptor(BinderControl* control, Device* device, const std::string& id); - ~DeviceBinderAdaptor() override; + ~DeviceBinderAdaptor() override {}; // Implementation of DeviceAdaptorInterface. const std::string& GetRpcIdentifier() override { return rpc_id(); } @@ -79,20 +78,25 @@ class DeviceBinderAdaptor void EmitRpcIdentifierArrayChanged( const std::string& name, const std::vector& value) override; - // Implementation of BnDevice. - android::binder::Status GetInterface(std::string* _aidl_return) override; + // Implementation of BnDevice methods. Called by DeviceBinderService. + android::binder::Status GetInterface(std::string* _aidl_return); android::binder::Status GetSelectedService( - android::sp* _aidl_return) override; + android::sp* _aidl_return); android::binder::Status RegisterPropertyChangedSignalHandler( const android::sp< android::system::connectivity::shill::IPropertyChangedCallback>& - callback) override; + callback); Device* device() const { return device_; } private: Device* device_; + // IMPORTANT: this needs to be the last member of the class, so that it is + // destroyed first, invalidating all weak pointers before the remaining state + // of the object is destroyed. + base::WeakPtrFactory weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(DeviceBinderAdaptor); }; diff --git a/binder/device_binder_service.cc b/binder/device_binder_service.cc new file mode 100644 index 00000000..760a33e8 --- /dev/null +++ b/binder/device_binder_service.cc @@ -0,0 +1,66 @@ +// +// 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/device_binder_service.h" + +#include "shill/binder/device_binder_adaptor.h" +#include "shill/logging.h" + +using android::binder::Status; +using android::sp; +using android::system::connectivity::shill::IPropertyChangedCallback; +using base::WeakPtr; +using std::string; + +namespace shill { + +namespace Logging { +static auto kModuleLogScope = ScopeLogger::kBinder; +static string ObjectID(DeviceBinderService* s) { + return "Device binder service (id " + s->rpc_id() + ")"; +} +} // namespace Logging + +DeviceBinderService::DeviceBinderService(WeakPtr adaptor, + const string& rpc_id) + : adaptor_(adaptor), rpc_id_(rpc_id) {} + +Status DeviceBinderService::GetInterface(string* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": device object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetInterface(_aidl_return); +} + +Status DeviceBinderService::GetSelectedService(sp* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": device object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetSelectedService(_aidl_return); +} + +Status DeviceBinderService::RegisterPropertyChangedSignalHandler( + const sp& callback) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": device object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->RegisterPropertyChangedSignalHandler(callback); +} + +} // namespace shill diff --git a/binder/device_binder_service.h b/binder/device_binder_service.h new file mode 100644 index 00000000..ccd0e167 --- /dev/null +++ b/binder/device_binder_service.h @@ -0,0 +1,80 @@ +// +// 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. +// + +#ifndef SHILL_BINDER_DEVICE_BINDER_SERVICE_H_ +#define SHILL_BINDER_DEVICE_BINDER_SERVICE_H_ + +#include + +#include +#include +#include + +#include "android/system/connectivity/shill/BnDevice.h" + +namespace android { +namespace binder { +class Status; +} // namespace binder +namespace system { +namespace connectivity { +namespace shill { +class IPropertyChangedCallback; +} // namespace shill +} // namespace connectivity +} // namespace system +} // namespace android + +namespace shill { + +class DeviceBinderAdaptor; + +// Subclass of the AIDL-generated BnDevice class. Objects of this class are +// Binder objects, and are ref-counted across process boundaries via the Binder +// Driver and Android Strong Pointers (android::sp). Consequently, this object +// might outlive its |adaptor_|. Therefore, |adaptor_| should always be +// null-tested before using it. +class DeviceBinderService + : public android::system::connectivity::shill::BnDevice { + public: + DeviceBinderService(base::WeakPtr adaptor, + const std::string& rpc_id); + ~DeviceBinderService() override {} + + const std::string& rpc_id() { return rpc_id_; } + + // Implementation of BnDevice. Calls the actual implementation of these + // methods in DeviceBinderAdaptor. + android::binder::Status GetInterface(std::string* _aidl_return) override; + android::binder::Status GetSelectedService( + android::sp* _aidl_return) override; + android::binder::Status RegisterPropertyChangedSignalHandler( + const android::sp< + android::system::connectivity::shill::IPropertyChangedCallback>& + callback) override; + + private: + base::WeakPtr adaptor_; + + // Stored for logging. + std::string rpc_id_; + + DISALLOW_COPY_AND_ASSIGN(DeviceBinderService); +}; + +} // namespace shill + +#endif // SHILL_BINDER_DEVICE_BINDER_SERVICE_H_ diff --git a/binder/manager_binder_adaptor.cc b/binder/manager_binder_adaptor.cc index 474e1c28..e7f17615 100644 --- a/binder/manager_binder_adaptor.cc +++ b/binder/manager_binder_adaptor.cc @@ -29,8 +29,9 @@ #endif // __ANDROID__ #include "shill/binder/binder_control.h" -#include "shill/binder/device_binder_adaptor.h" -#include "shill/binder/service_binder_adaptor.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" @@ -41,6 +42,7 @@ 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; @@ -62,7 +64,11 @@ ManagerBinderAdaptor::ManagerBinderAdaptor(BinderControl* control, : BinderAdaptor(control, id), manager_(manager), ap_mode_setter_(nullptr), - device_claimer_(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) { @@ -77,7 +83,8 @@ void ManagerBinderAdaptor::RegisterAsync( const base::Callback& /*completion_callback*/) { // Registration is performed synchronously in Binder. BinderWrapper::Get()->RegisterService( - String8(getInterfaceDescriptor()).string(), this); + String8(binder_service()->getInterfaceDescriptor()).string(), + binder_service()); } void ManagerBinderAdaptor::EmitBoolChanged(const string& name, bool /*value*/) { @@ -215,9 +222,9 @@ Status ManagerBinderAdaptor::ConfigureService( if (e.IsFailure()) { return e.ToBinderStatus(); } - *_aidl_return = interface_cast(static_cast( - control()->GetBinderAdaptorForRpcIdentifier( - service->GetRpcIdentifier()))); + *_aidl_return = interface_cast(static_cast( + control()->GetBinderServiceForRpcIdentifier( + service->GetRpcIdentifier()).get())); return Status::ok(); } @@ -252,8 +259,8 @@ Status ManagerBinderAdaptor::GetDevices(vector>* _aidl_return) { return e.ToBinderStatus(); } for (const auto& device_rpc_id : device_rpc_ids) { - _aidl_return->emplace_back(static_cast( - control()->GetBinderAdaptorForRpcIdentifier(device_rpc_id))); + _aidl_return->emplace_back(static_cast( + control()->GetBinderServiceForRpcIdentifier(device_rpc_id).get())); } return Status::ok(); } @@ -266,8 +273,8 @@ Status ManagerBinderAdaptor::GetDefaultService(sp* _aidl_return) { if (e.IsFailure()) { return e.ToBinderStatus(); } - *_aidl_return = static_cast( - control()->GetBinderAdaptorForRpcIdentifier(default_service_rpc_id)); + *_aidl_return = static_cast( + control()->GetBinderServiceForRpcIdentifier(default_service_rpc_id).get()); return Status::ok(); } diff --git a/binder/manager_binder_adaptor.h b/binder/manager_binder_adaptor.h index 4109a866..1f063153 100644 --- a/binder/manager_binder_adaptor.h +++ b/binder/manager_binder_adaptor.h @@ -21,6 +21,7 @@ #include #include +#include #include #include "android/system/connectivity/shill/BnManager.h" @@ -49,10 +50,8 @@ class Manager; // instances. Furthermore, the Manager owns the ManagerBinderAdaptor // and manages its lifetime, so we're OK with ManagerBinderAdaptor // having a bare pointer to its owner manager. -class ManagerBinderAdaptor - : public android::system::connectivity::shill::BnManager, - public BinderAdaptor, - public ManagerAdaptorInterface { +class ManagerBinderAdaptor : public BinderAdaptor, + public ManagerAdaptorInterface { public: ManagerBinderAdaptor(BinderControl* control, Manager* manager, const std::string& id); @@ -69,44 +68,48 @@ class ManagerBinderAdaptor const std::string& value) override; void EmitStringsChanged(const std::string& name, const std::vector& value) override; - void EmitRpcIdentifierChanged( - const std::string& name, const std::string& value) override; + void EmitRpcIdentifierChanged(const std::string& name, + const std::string& value) override; void EmitRpcIdentifierArrayChanged( const std::string& name, const std::vector& value) override; - // Implementation of BnManager. + // Implementation of BnManager methods. Called by ManagerBinderService. android::binder::Status SetupApModeInterface( - const android::sp& ap_mode_setter, - std::string* _aidl_return) override; - android::binder::Status SetupStationModeInterface( - std::string* _aidl_return) override; + const android::sp& ap_mode_setter, + std::string* _aidl_return); + android::binder::Status SetupStationModeInterface(std::string* _aidl_return); android::binder::Status ClaimInterface( - const android::sp& claimer, const std::string& claimer_name, - const std::string& interface_name) override; + const android::sp& claimer, + const std::string& claimer_name, const std::string& interface_name); android::binder::Status ReleaseInterface( - const android::sp& claimer, const std::string& claimer_name, - const std::string& interface_name) override; + const android::sp& claimer, + const std::string& claimer_name, const std::string& interface_name); android::binder::Status ConfigureService( const android::os::PersistableBundle& properties, - android::sp* _aidl_return) - override; - android::binder::Status RequestScan(int32_t type) override; + android::sp* + _aidl_return); + android::binder::Status RequestScan(int32_t type); android::binder::Status GetDevices( - std::vector>* _aidl_return) override; + std::vector>* _aidl_return); android::binder::Status GetDefaultService( - android::sp* _aidl_return) override; + android::sp* _aidl_return); android::binder::Status RegisterPropertyChangedSignalHandler( const android::sp< android::system::connectivity::shill::IPropertyChangedCallback>& - callback) override; + callback); private: void OnApModeSetterVanished(); void OnDeviceClaimerVanished(); Manager* manager_; - android::sp ap_mode_setter_; - android::sp device_claimer_; + android::sp ap_mode_setter_; + android::sp device_claimer_; + + // IMPORTANT: this needs to be the last member of the class, so that it is + // destroyed first, invalidating all weak pointers before the remaining state + // of the object is destroyed. + base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ManagerBinderAdaptor); }; diff --git a/binder/manager_binder_service.cc b/binder/manager_binder_service.cc new file mode 100644 index 00000000..f6c1476f --- /dev/null +++ b/binder/manager_binder_service.cc @@ -0,0 +1,125 @@ +// +// 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_service.h" + +#include "shill/binder/manager_binder_adaptor.h" +#include "shill/logging.h" + +using android::binder::Status; +using android::sp; +using android::String8; +using android::system::connectivity::shill::IPropertyChangedCallback; +using android::system::connectivity::shill::IService; +using base::WeakPtr; +using std::string; +using std::vector; + +namespace shill { + +namespace Logging { +static auto kModuleLogScope = ScopeLogger::kBinder; +static string ObjectID(ManagerBinderService* s) { + return "Manager binder service (id " + s->rpc_id() + ")"; +} +} // namespace Logging + +ManagerBinderService::ManagerBinderService( + WeakPtr adaptor, const string& rpc_id) + : adaptor_(adaptor), rpc_id_(rpc_id) {} + +Status ManagerBinderService::SetupApModeInterface( + const sp& ap_mode_setter, std::string* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->SetupApModeInterface(ap_mode_setter, _aidl_return); +} + +Status ManagerBinderService::SetupStationModeInterface( + std::string* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->SetupStationModeInterface(_aidl_return); +} + +Status ManagerBinderService::ClaimInterface(const sp& claimer, + const std::string& claimer_name, + const std::string& interface_name) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->ClaimInterface(claimer, claimer_name, interface_name); +} + +Status ManagerBinderService::ReleaseInterface( + const sp& claimer, const std::string& claimer_name, + const std::string& interface_name) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->ReleaseInterface(claimer, claimer_name, interface_name); +} + +Status ManagerBinderService::ConfigureService( + const android::os::PersistableBundle& properties, + sp* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->ConfigureService(properties, _aidl_return); +} + +Status ManagerBinderService::RequestScan(int32_t type) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->RequestScan(type); +} + +Status ManagerBinderService::GetDevices(vector>* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetDevices(_aidl_return); +} + +Status ManagerBinderService::GetDefaultService(sp* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetDefaultService(_aidl_return); +} + +Status ManagerBinderService::RegisterPropertyChangedSignalHandler( + const sp& callback) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": manager object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->RegisterPropertyChangedSignalHandler(callback); +} + +} // namespace shill diff --git a/binder/manager_binder_service.h b/binder/manager_binder_service.h new file mode 100644 index 00000000..bfe45f56 --- /dev/null +++ b/binder/manager_binder_service.h @@ -0,0 +1,98 @@ +// +// 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. +// + +#ifndef SHILL_BINDER_MANAGER_BINDER_SERVICE_H_ +#define SHILL_BINDER_MANAGER_BINDER_SERVICE_H_ + +#include +#include + +#include +#include +#include + +#include "android/system/connectivity/shill/BnManager.h" + +namespace android { +namespace binder { +class Status; +} // namespace binder +namespace system { +namespace connectivity { +namespace shill { +class IPropertyChangedCallback; +} // namespace shill +} // namespace connectivity +} // namespace system +} // namespace android + +namespace shill { + +class ManagerBinderAdaptor; + +// Subclass of the AIDL-generated BnManager class. Objects of this class are +// Binder objects, and are ref-counted across process boundaries via the Binder +// Driver and Android Strong Pointers (android::sp). Consequently, this object +// might outlive its |adaptor_|. Therefore, |adaptor_| should always be +// null-tested before using it. +class ManagerBinderService + : public android::system::connectivity::shill::BnManager { + public: + ManagerBinderService(const base::WeakPtr adaptor, + const std::string& rpc_id); + ~ManagerBinderService() override {} + + const std::string& rpc_id() { return rpc_id_; } + + // Implementation of BnManager. Calls the actual implementation of these + // methods in ManagerBinderAdaptor. + android::binder::Status SetupApModeInterface( + const android::sp& ap_mode_setter, + std::string* _aidl_return) override; + android::binder::Status SetupStationModeInterface( + std::string* _aidl_return) override; + android::binder::Status ClaimInterface( + const android::sp& claimer, const std::string& claimer_name, + const std::string& interface_name) override; + android::binder::Status ReleaseInterface( + const android::sp& claimer, const std::string& claimer_name, + const std::string& interface_name) override; + android::binder::Status ConfigureService( + const android::os::PersistableBundle& properties, + android::sp* _aidl_return) + override; + android::binder::Status RequestScan(int32_t type) override; + android::binder::Status GetDevices( + std::vector>* _aidl_return); + android::binder::Status GetDefaultService( + android::sp* _aidl_return) override; + android::binder::Status RegisterPropertyChangedSignalHandler( + const android::sp< + android::system::connectivity::shill::IPropertyChangedCallback>& + callback) override; + + private: + base::WeakPtr adaptor_; + + // Stored for logging. + std::string rpc_id_; + + DISALLOW_COPY_AND_ASSIGN(ManagerBinderService); +}; + +} // namespace shill + +#endif // SHILL_BINDER_MANAGER_BINDER_SERVICE_H_ diff --git a/binder/service_binder_adaptor.cc b/binder/service_binder_adaptor.cc index 2f0716e4..98b3f09a 100644 --- a/binder/service_binder_adaptor.cc +++ b/binder/service_binder_adaptor.cc @@ -26,6 +26,7 @@ #include #endif // __ANDROID__ +#include "shill/binder/service_binder_service.h" #include "shill/logging.h" #include "shill/service.h" #include "shill/vpn/vpn_service.h" @@ -35,6 +36,7 @@ using android::IBinder; using android::sp; using android::String8; using android::system::connectivity::shill::IPropertyChangedCallback; +using android::system::connectivity::shill::IService; using std::string; namespace { @@ -56,9 +58,10 @@ static string ObjectID(ServiceBinderAdaptor* s) { ServiceBinderAdaptor::ServiceBinderAdaptor(BinderControl* control, Service* service, const std::string& id) - : BinderAdaptor(control, id), service_(service) {} - -ServiceBinderAdaptor::~ServiceBinderAdaptor() { service_ = nullptr; } + : BinderAdaptor(control, id), service_(service), weak_ptr_factory_(this) { + set_binder_service( + new ServiceBinderService(weak_ptr_factory_.GetWeakPtr(), id)); +} void ServiceBinderAdaptor::EmitBoolChanged(const string& name, bool /*value*/) { SLOG(this, 2) << __func__ << ": " << name; diff --git a/binder/service_binder_adaptor.h b/binder/service_binder_adaptor.h index f7804a9b..d6096767 100644 --- a/binder/service_binder_adaptor.h +++ b/binder/service_binder_adaptor.h @@ -20,6 +20,7 @@ #include #include +#include #include #include "android/system/connectivity/shill/BnService.h" @@ -48,14 +49,12 @@ class Service; // instances. Furthermore, the Service owns the ServiceBinderAdaptor // and manages its lifetime, so we're OK with ServiceBinderAdaptor // having a bare pointer to its owner service. -class ServiceBinderAdaptor - : public android::system::connectivity::shill::BnService, - public BinderAdaptor, - public ServiceAdaptorInterface { +class ServiceBinderAdaptor : public BinderAdaptor, + public ServiceAdaptorInterface { public: ServiceBinderAdaptor(BinderControl* control, Service* service, const std::string& id); - ~ServiceBinderAdaptor() override; + ~ServiceBinderAdaptor() override {}; // Implementation of ServiceAdaptorInterface. const std::string& GetRpcIdentifier() override { return rpc_id(); } @@ -66,25 +65,25 @@ class ServiceBinderAdaptor const Uint16s& value) override; void EmitUintChanged(const std::string& name, uint32_t value) override; void EmitIntChanged(const std::string& name, int value) override; - void EmitRpcIdentifierChanged( - const std::string& name, const std::string& value) override; - void EmitStringChanged( - const std::string& name, const std::string& value) override; + void EmitRpcIdentifierChanged(const std::string& name, + const std::string& value) override; + void EmitStringChanged(const std::string& name, + const std::string& value) override; void EmitStringmapChanged(const std::string& name, const Stringmap& value) override; - // Implementation of BnService. - android::binder::Status Connect() override; - android::binder::Status GetState(int32_t* _aidl_return) override; - android::binder::Status GetStrength(int8_t* _aidl_return) override; - android::binder::Status GetError(int32_t* _aidl_return) override; - android::binder::Status GetTethering(int32_t* _aidl_return) override; - android::binder::Status GetType(int32_t* _aidl_return) override; - android::binder::Status GetPhysicalTechnology(int32_t* _aidl_return) override; + // Implementation of BnService methods. Called by ServiceBinderService. + android::binder::Status Connect(); + android::binder::Status GetState(int32_t* _aidl_return); + android::binder::Status GetStrength(int8_t* _aidl_return); + android::binder::Status GetError(int32_t* _aidl_return); + android::binder::Status GetTethering(int32_t* _aidl_return); + android::binder::Status GetType(int32_t* _aidl_return); + android::binder::Status GetPhysicalTechnology(int32_t* _aidl_return); android::binder::Status RegisterPropertyChangedSignalHandler( const android::sp< android::system::connectivity::shill::IPropertyChangedCallback>& - callback) override; + callback); Service* service() const { return service_; } @@ -96,6 +95,11 @@ class ServiceBinderAdaptor Service* service_; + // IMPORTANT: this needs to be the last member of the class, so that it is + // destroyed first, invalidating all weak pointers before the remaining state + // of the object is destroyed. + base::WeakPtrFactory weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ServiceBinderAdaptor); }; diff --git a/binder/service_binder_service.cc b/binder/service_binder_service.cc new file mode 100644 index 00000000..99291eea --- /dev/null +++ b/binder/service_binder_service.cc @@ -0,0 +1,106 @@ +// +// 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/service_binder_service.h" + +#include "shill/binder/service_binder_adaptor.h" +#include "shill/logging.h" + +using android::binder::Status; +using android::sp; +using android::system::connectivity::shill::IPropertyChangedCallback; +using base::WeakPtr; +using std::string; + +namespace shill { + +namespace Logging { +static auto kModuleLogScope = ScopeLogger::kBinder; +static string ObjectID(ServiceBinderService* s) { + return "Service binder service (id " + s->rpc_id() + ")"; +} +} // namespace Logging + +ServiceBinderService::ServiceBinderService( + WeakPtr adaptor, const string& rpc_id) + : adaptor_(adaptor), rpc_id_(rpc_id) {} + +Status ServiceBinderService::Connect() { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": service object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->Connect(); +} + +Status ServiceBinderService::GetState(int32_t* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": service object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetState(_aidl_return); +} + +Status ServiceBinderService::GetStrength(int8_t* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": service object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetStrength(_aidl_return); +} + +Status ServiceBinderService::GetError(int32_t* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": service object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetError(_aidl_return); +} + +Status ServiceBinderService::GetTethering(int32_t* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": service object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetTethering(_aidl_return); +} + +Status ServiceBinderService::GetType(int32_t* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": service object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetType(_aidl_return); +} + +Status ServiceBinderService::GetPhysicalTechnology(int32_t* _aidl_return) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": service object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->GetPhysicalTechnology(_aidl_return); +} + +Status ServiceBinderService::RegisterPropertyChangedSignalHandler( + const sp& callback) { + if (!adaptor_) { + SLOG(this, 2) << __func__ << ": service object is no longer alive."; + return BinderAdaptor::GenerateShillObjectNotAliveErrorStatus(); + } + return adaptor_->RegisterPropertyChangedSignalHandler(callback); +} + +} // namespace shill diff --git a/binder/service_binder_service.h b/binder/service_binder_service.h new file mode 100644 index 00000000..abdd4019 --- /dev/null +++ b/binder/service_binder_service.h @@ -0,0 +1,84 @@ +// +// 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. +// + +#ifndef SHILL_BINDER_SERVICE_BINDER_SERVICE_H_ +#define SHILL_BINDER_SERVICE_BINDER_SERVICE_H_ + +#include + +#include +#include +#include + +#include "android/system/connectivity/shill/BnService.h" + +namespace android { +namespace binder { +class Status; +} // namespace binder +namespace system { +namespace connectivity { +namespace shill { +class IPropertyChangedCallback; +} // namespace shill +} // namespace connectivity +} // namespace system +} // namespace android + +namespace shill { + +class ServiceBinderAdaptor; + +// Subclass of the AIDL-generated BnService class. Objects of this class are +// Binder objects, and are ref-counted across process boundaries via the Binder +// Driver and Android Strong Pointers (android::sp). Consequently, this object +// might outlive its |adaptor_|. Therefore, |adaptor_| should always be +// null-tested before using it. +class ServiceBinderService + : public android::system::connectivity::shill::BnService { + public: + ServiceBinderService(base::WeakPtr adaptor, + const std::string& rpc_id); + ~ServiceBinderService() override {} + + const std::string& rpc_id() { return rpc_id_; } + + // Implementation of BnService. Calls the actual implementation of these + // methods in ServiceBinderAdaptor. + android::binder::Status Connect() override; + android::binder::Status GetState(int32_t* _aidl_return) override; + android::binder::Status GetStrength(int8_t* _aidl_return) override; + android::binder::Status GetError(int32_t* _aidl_return) override; + android::binder::Status GetTethering(int32_t* _aidl_return) override; + android::binder::Status GetType(int32_t* _aidl_return) override; + android::binder::Status GetPhysicalTechnology(int32_t* _aidl_return) override; + android::binder::Status RegisterPropertyChangedSignalHandler( + const android::sp< + android::system::connectivity::shill::IPropertyChangedCallback>& + callback) override; + + private: + base::WeakPtr adaptor_; + + // Stored for logging. + std::string rpc_id_; + + DISALLOW_COPY_AND_ASSIGN(ServiceBinderService); +}; + +} // namespace shill + +#endif // SHILL_BINDER_SERVICE_BINDER_SERVICE_H_ -- cgit v1.2.3