From 67ab1c856dfc0ca9fb44b94b3621d4183a693a5a Mon Sep 17 00:00:00 2001 From: Arman Uguray Date: Thu, 20 Aug 2015 12:36:20 -0700 Subject: [PATCH] service: Introduce IBluetoothCallback.h This CL introduces the native bindings for the IBluetoothCallback Binder interface and implements the IBluetooth registerCallback and unregisterCallback methods. Bug: 23328384 Change-Id: I6fbf72cff7e3f037a412be8678ea97f3a7ada0c8 --- service/Android.mk | 3 +- service/ipc/binder/IBluetooth.cpp | 28 +++++++++ service/ipc/binder/IBluetooth.h | 10 +++ service/ipc/binder/IBluetoothCallback.cpp | 86 +++++++++++++++++++++++++ service/ipc/binder/IBluetoothCallback.h | 87 ++++++++++++++++++++++++++ service/ipc/binder/bluetooth_binder_server.cpp | 28 +++++++++ service/ipc/binder/bluetooth_binder_server.h | 26 ++++++-- service/ipc/binder/ipc_handler_binder.cpp | 4 +- 8 files changed, 263 insertions(+), 9 deletions(-) create mode 100644 service/ipc/binder/IBluetoothCallback.cpp create mode 100644 service/ipc/binder/IBluetoothCallback.h diff --git a/service/Android.mk b/service/Android.mk index 956e534cc..ae42010af 100644 --- a/service/Android.mk +++ b/service/Android.mk @@ -34,8 +34,9 @@ btserviceCommonSrc := \ uuid.cpp btserviceBinderSrc := \ - ipc/binder/IBluetooth.cpp \ ipc/binder/bluetooth_binder_server.cpp \ + ipc/binder/IBluetooth.cpp \ + ipc/binder/IBluetoothCallback.cpp \ ipc/binder/ipc_handler_binder.cpp btserviceCommonIncludes := $(LOCAL_PATH)/../ diff --git a/service/ipc/binder/IBluetooth.cpp b/service/ipc/binder/IBluetooth.cpp index c14ed05c4..dd9781ca2 100644 --- a/service/ipc/binder/IBluetooth.cpp +++ b/service/ipc/binder/IBluetooth.cpp @@ -111,6 +111,16 @@ android::status_t BnBluetooth::onTransact( reply->writeCString(name.c_str()); return android::NO_ERROR; } + case REGISTER_CALLBACK_TRANSACTION: { + sp callback = data.readStrongBinder(); + RegisterCallback(interface_cast(callback)); + return android::NO_ERROR; + } + case UNREGISTER_CALLBACK_TRANSACTION: { + sp callback = data.readStrongBinder(); + UnregisterCallback(interface_cast(callback)); + return android::NO_ERROR; + } default: return BBinder::onTransact(code, data, reply, flags); } @@ -203,6 +213,24 @@ std::string BpBluetooth::GetName() { return reply.readCString(); } +void BpBluetooth::RegisterCallback(const sp& callback) { + Parcel data, reply; + + data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor()); + data.writeStrongBinder(IInterface::asBinder(callback.get())); + + remote()->transact(IBluetooth::REGISTER_CALLBACK_TRANSACTION, data, &reply); +} + +void BpBluetooth::UnregisterCallback(const sp& callback) { + Parcel data, reply; + + data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor()); + data.writeStrongBinder(IInterface::asBinder(callback.get())); + + remote()->transact(IBluetooth::UNREGISTER_CALLBACK_TRANSACTION, data, &reply); +} + IMPLEMENT_META_INTERFACE(Bluetooth, IBluetooth::kBluetoothServiceName); } // namespace binder diff --git a/service/ipc/binder/IBluetooth.h b/service/ipc/binder/IBluetooth.h index f48c38532..a40af70e2 100644 --- a/service/ipc/binder/IBluetooth.h +++ b/service/ipc/binder/IBluetooth.h @@ -23,6 +23,7 @@ #include #include +#include "service/ipc/binder/IBluetoothCallback.h" #include "service/uuid.h" namespace ipc { @@ -136,6 +137,11 @@ class IBluetooth : public android::IInterface { virtual bool SetName(const std::string& name) = 0; virtual std::string GetName() = 0; + virtual void RegisterCallback( + const android::sp& callback) = 0; + virtual void UnregisterCallback( + const android::sp& callback) = 0; + // TODO(armansito): Complete the API definition. private: DISALLOW_COPY_AND_ASSIGN(IBluetooth); @@ -174,6 +180,10 @@ class BpBluetooth : public android::BpInterface { std::vector GetUUIDs() override; bool SetName(const std::string& name) override; std::string GetName() override; + void RegisterCallback( + const android::sp& callback) override; + void UnregisterCallback( + const android::sp& callback) override; private: DISALLOW_COPY_AND_ASSIGN(BpBluetooth); diff --git a/service/ipc/binder/IBluetoothCallback.cpp b/service/ipc/binder/IBluetoothCallback.cpp new file mode 100644 index 000000000..7cb4f8d8d --- /dev/null +++ b/service/ipc/binder/IBluetoothCallback.cpp @@ -0,0 +1,86 @@ +// +// Copyright (C) 2015 Google, Inc. +// +// 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 "service/ipc/binder/IBluetoothCallback.h" + +#include +#include + +using android::IBinder; +using android::Parcel; +using android::sp; + +namespace ipc { +namespace binder { + +// static +const char IBluetoothCallback::kBluetoothCallbackServiceName[] = + "bluetooth-callback-service"; + +// BnBluetoothCallback (server) implementation +// ======================================================== + +android::status_t BnBluetoothCallback::onTransact( + uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags) { + VLOG(2) << "IBluetoothCallback transaction: " << code; + if (!data.checkInterface(this)) + return android::PERMISSION_DENIED; + + switch (code) { + case ON_BLUETOOTH_STATE_CHANGE_TRANSACTION: { + int prev_state, new_state; + if (data.readInt32(&prev_state) != android::NO_ERROR || + data.readInt32(&new_state) != android::NO_ERROR) + return android::NOT_ENOUGH_DATA; + + OnBluetoothStateChange( + static_cast(prev_state), + static_cast(new_state)); + return android::NO_ERROR; + } + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// BpBluetoothCallback (client) implementation +// ======================================================== + +BpBluetoothCallback::BpBluetoothCallback(const sp& impl) + : BpInterface(impl) { +} + +void BpBluetoothCallback::OnBluetoothStateChange( + bluetooth::AdapterState prev_state, + bluetooth::AdapterState new_state) { + Parcel data, reply; + + data.writeInterfaceToken(IBluetoothCallback::getInterfaceDescriptor()); + data.writeInt32(prev_state); + data.writeInt32(new_state); + + remote()->transact(IBluetoothCallback::ON_BLUETOOTH_STATE_CHANGE_TRANSACTION, + data, &reply); +} + +IMPLEMENT_META_INTERFACE(BluetoothCallback, + IBluetoothCallback::kBluetoothCallbackServiceName); + +} // namespace binder +} // namespace ipc diff --git a/service/ipc/binder/IBluetoothCallback.h b/service/ipc/binder/IBluetoothCallback.h new file mode 100644 index 000000000..3ae60a329 --- /dev/null +++ b/service/ipc/binder/IBluetoothCallback.h @@ -0,0 +1,87 @@ +// +// Copyright (C) 2015 Google, Inc. +// +// 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. +// + +#pragma once + +#include +#include +#include + +#include "service/adapter_state.h" + +namespace ipc { +namespace binder { + +// This class defines the Binder IPC interface for receiving adapter state +// updates from the Bluetooth service. This class was written based on the +// corresponding AIDL file at +// /frameworks/base/core/java/android/bluetooth/IBluetoothCallback.aidl. +// +// NOTE: KEEP THIS FILE UP-TO-DATE with the corresponding AIDL, otherwise this +// won't be compatible with the Android framework. +class IBluetoothCallback : public android::IInterface { + public: + DECLARE_META_INTERFACE(BluetoothCallback); + + static const char kBluetoothCallbackServiceName[]; + + // Transaction codes for interface methods. + enum { + ON_BLUETOOTH_STATE_CHANGE_TRANSACTION = + android::IBinder::FIRST_CALL_TRANSACTION, + }; + + virtual void OnBluetoothStateChange( + bluetooth::AdapterState prev_state, + bluetooth::AdapterState new_state) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(IBluetoothCallback); +}; + +// TODO(armansito): Implement notification for when the process dies. + +// The Binder server interface to IBluetoothCallback. A class that implements +// IBluetoothCallback must inherit from this class. +class BnBluetoothCallback : public android::BnInterface { + public: + BnBluetoothCallback() = default; + virtual ~BnBluetoothCallback() = default; + + private: + virtual android::status_t onTransact( + uint32_t code, + const android::Parcel& data, + android::Parcel* reply, + uint32_t flags = 0); +}; + +// The Binder client interface to IBluetoothCallback. +class BpBluetoothCallback : public android::BpInterface { + public: + BpBluetoothCallback(const android::sp& impl); + virtual ~BpBluetoothCallback() = default; + + // IBluetoothCallback override: + void OnBluetoothStateChange(bluetooth::AdapterState prev_state, + bluetooth::AdapterState new_state) override; + + private: + DISALLOW_COPY_AND_ASSIGN(BpBluetoothCallback); +}; + +} // namespace binder +} // namespace ipc diff --git a/service/ipc/binder/bluetooth_binder_server.cpp b/service/ipc/binder/bluetooth_binder_server.cpp index 0155c05cf..813a36606 100644 --- a/service/ipc/binder/bluetooth_binder_server.cpp +++ b/service/ipc/binder/bluetooth_binder_server.cpp @@ -21,13 +21,16 @@ #include "service/adapter.h" namespace ipc { +namespace binder { BluetoothBinderServer::BluetoothBinderServer(bluetooth::Adapter* adapter) : adapter_(adapter) { CHECK(adapter_); + adapter_->AddObserver(this); } BluetoothBinderServer::~BluetoothBinderServer() { + adapter_->RemoveObserver(this); } // binder::BnBluetooth overrides: @@ -74,4 +77,29 @@ std::string BluetoothBinderServer::GetName() { return adapter_->GetName(); } +void BluetoothBinderServer::RegisterCallback( + const android::sp& callback) { + VLOG(2) << __func__; + callbacks_.Register(callback); +} + +void BluetoothBinderServer::UnregisterCallback( + const android::sp& callback) { + VLOG(2) << __func__; + callbacks_.Unregister(callback); +} + +void BluetoothBinderServer::OnAdapterStateChanged( + bluetooth::Adapter* adapter, + bluetooth::AdapterState prev_state, + bluetooth::AdapterState new_state) { + CHECK_EQ(adapter, adapter_); + VLOG(2) << "Received adapter state update - prev: " << prev_state + << " new: " << new_state; + callbacks_.ForEach([prev_state, new_state](IBluetoothCallback* callback) { + callback->OnBluetoothStateChange(prev_state, new_state); + }); +} + +} // namespace binder } // namespace ipc diff --git a/service/ipc/binder/bluetooth_binder_server.h b/service/ipc/binder/bluetooth_binder_server.h index 819b9b9ec..cf0069e26 100644 --- a/service/ipc/binder/bluetooth_binder_server.h +++ b/service/ipc/binder/bluetooth_binder_server.h @@ -21,37 +21,51 @@ #include +#include "service/adapter.h" #include "service/ipc/binder/IBluetooth.h" +#include "service/ipc/binder/IBluetoothCallback.h" +#include "service/ipc/binder/remote_callback_list.h" #include "service/uuid.h" -namespace bluetooth { -class Adapter; -} // namespace bluetooth - namespace ipc { +namespace binder { // Implements the server side of the IBluetooth Binder interface. -class BluetoothBinderServer : public binder::BnBluetooth { +class BluetoothBinderServer : public BnBluetooth, + public bluetooth::Adapter::Observer { public: explicit BluetoothBinderServer(bluetooth::Adapter* adapter); ~BluetoothBinderServer() override; - // binder::BnBluetooth overrides: + // IBluetooth overrides: bool IsEnabled() override; int GetState() override; bool Enable() override; bool EnableNoAutoConnect() override; bool Disable() override; + std::string GetAddress() override; std::vector GetUUIDs() override; bool SetName(const std::string& name) override; std::string GetName() override; + void RegisterCallback( + const android::sp& callback) override; + void UnregisterCallback( + const android::sp& callback) override; + + // bluetooth::Adapter::Observer overrides: + void OnAdapterStateChanged(bluetooth::Adapter* adapter, + bluetooth::AdapterState prev_state, + bluetooth::AdapterState new_state) override; + private: // Weak handle on the Adapter. bluetooth::Adapter* adapter_; + RemoteCallbackList callbacks_; DISALLOW_COPY_AND_ASSIGN(BluetoothBinderServer); }; +} // namespace binder } // namespace ipc diff --git a/service/ipc/binder/ipc_handler_binder.cpp b/service/ipc/binder/ipc_handler_binder.cpp index 46e8a5f96..e3571570e 100644 --- a/service/ipc/binder/ipc_handler_binder.cpp +++ b/service/ipc/binder/ipc_handler_binder.cpp @@ -45,8 +45,8 @@ bool IPCHandlerBinder::Run() { CHECK(adapter()); // Register the IBluetooth service with the Android ServiceManager. - android::sp bt_server = - new BluetoothBinderServer(adapter()); + android::sp bt_server = + new binder::BluetoothBinderServer(adapter()); status_t status = defaultServiceManager()->addService( String16(binder::IBluetooth::kBluetoothServiceName), bt_server); -- 2.11.0