// // 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 "bluetooth/uuid.h" #include "service/bluetooth_instance.h" #include "service/ipc/binder/remote_callback_map.h" namespace ipc { namespace binder { // InterfaceWithInstancesBase provides a common base class for Binder interface // servers that involve instance callback Binders registered with an integer // instance ID over an asynchronous lower-level stack API. This class abstracts // away the common procedures of managing pending callbacks, listening to death // notifications, and maintaining multiple internal maps in one common base // class. // TODO: add code example here. class InterfaceWithInstancesBase : public RemoteCallbackMap::Delegate, virtual public android::RefBase { public: InterfaceWithInstancesBase() = default; ~InterfaceWithInstancesBase() override = default; protected: // The initial entry point for registering a instance. Invoke this from the // registration API to add a instance/Uuid pair to the pending list and set up // the generic asynchronous callback handler and initiate the process with the // given |factory| instance. Returns false, if there were any errors that // could be synchronously reported. bool RegisterInstanceBase(const android::sp& callback, bluetooth::BluetoothInstanceFactory* factory); // Unregister the instance with the given ID, if it was registered before. void UnregisterInstanceBase(int instance_id); // Unregisters all registered instances. void UnregisterAllBase(); void ForEachCallback(const std::function& func); // Returns a handle to the lock used to synchronize access to the internal // data structures. Subclasses should acquire this before accessing the maps. std::mutex* maps_lock() { return &maps_lock_; } // Returns the callback interface binder that is assigned to the given // instance ID |instance_id|. The returned pointer will contain NULL if an // entry for the given ID cannot be found. android::sp GetCallback(int instance_id); // Returns the instance instance that is assigned to the given instance ID // |instance_id|. The returned pointer will contain NULL if an entry for the // given ID cannot be found. std::shared_ptr GetInstance(int instance_id); private: // Base implementation of the register callback. void OnRegisterInstance( bluetooth::BLEStatus status, const bluetooth::Uuid& uuid, std::unique_ptr instance); // Called when the callback registration has completed. |instance| is owned by // the base class and should not be deleted by the implementation. If the // operation failed, nullptr will be passed for |instance|. virtual void OnRegisterInstanceImpl( bluetooth::BLEStatus status, android::sp callback, bluetooth::BluetoothInstance* instance) = 0; // RemoteCallbackMap::Delegate override: void OnRemoteCallbackRemoved(const int& key) override; // Instances that are pending registration. Once their registration is // complete, the entry will be removed from this map. RemoteCallbackMap pending_callbacks_; // We keep two maps here: one from instance_id IDs to callback Binders and one // from instance_id IDs to the BluetoothInstance structures themselves. std::mutex maps_lock_; // Needed for |id_to_instance_|. RemoteCallbackMap id_to_cb_; std::unordered_map> id_to_instance_; DISALLOW_COPY_AND_ASSIGN(InterfaceWithInstancesBase); }; } // namespace binder } // namespace ipc