108f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//
208f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  Copyright (C) 2015 Google, Inc.
308f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//
408f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  Licensed under the Apache License, Version 2.0 (the "License");
508f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  you may not use this file except in compliance with the License.
608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  You may obtain a copy of the License at:
708f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//
808f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  http://www.apache.org/licenses/LICENSE-2.0
908f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//
1008f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  Unless required by applicable law or agreed to in writing, software
1108f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  distributed under the License is distributed on an "AS IS" BASIS,
1208f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  See the License for the specific language governing permissions and
1408f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//  limitations under the License.
1508f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray//
1608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
1708f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray#pragma once
1808f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
1908f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray#include <memory>
2008f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray#include <unordered_map>
2108f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
2208f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray#include <base/macros.h>
2308f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
24bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray#include "service/bluetooth_instance.h"
25234138e2606dd7a54fbcc540643511abc0a3598dArman Uguray#include "service/common/bluetooth/uuid.h"
2608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray#include "service/ipc/binder/remote_callback_map.h"
2708f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
2808f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguraynamespace ipc {
2908f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguraynamespace binder {
3008f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
31bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray// InterfaceWithInstancesBase provides a common base class for Binder interface
32bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray// servers that involve instance callback Binders registered with an integer
33bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray// instance ID over an asynchronous lower-level stack API. This class abstracts
3408f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray// away the common procedures of managing pending callbacks, listening to death
3508f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray// notifications, and maintaining multiple internal maps in one common base
3608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray// class.
3708f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray// TODO: add code example here.
38bb18c41ffa0370d4eb0c4a15904b114355606466Arman Ugurayclass InterfaceWithInstancesBase
3908f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray    : public RemoteCallbackMap<int, android::IInterface>::Delegate,
4008f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray      virtual public android::RefBase {
4108f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray public:
42bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  InterfaceWithInstancesBase() = default;
43bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  ~InterfaceWithInstancesBase() override = default;
4408f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
4508f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray protected:
46bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // The initial entry point for registering a instance. Invoke this from the
47bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // registration API to add a instance/UUID pair to the pending list and set up
4808f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // the generic asynchronous callback handler and initiate the process with the
4908f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // given |factory| instance. Returns false, if there were any errors that
5008f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // could be synchronously reported.
51bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  bool RegisterInstanceBase(const android::sp<IInterface>& callback,
52bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray                            bluetooth::BluetoothInstanceFactory* factory);
5308f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
54bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // Unregister the instance with the given ID, if it was registered before.
55bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  void UnregisterInstanceBase(int instance_id);
5608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
57bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // Unregisters all registered instances.
5808f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  void UnregisterAllBase();
5908f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
6008f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // Returns a handle to the lock used to synchronize access to the internal
6108f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // data structures. Subclasses should acquire this before accessing the maps.
6208f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  std::mutex* maps_lock() { return &maps_lock_; }
6308f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
64bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // Returns the callback interface binder that is assigned to the given
65bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // instance ID |instance_id|. The returned pointer will contain NULL if an
66bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // entry for the given ID cannot be found.
67bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  android::sp<IInterface> GetCallback(int instance_id);
6808f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
69bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // Returns the instance instance that is assigned to the given instance ID
70bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // |instance_id|. The returned pointer will contain NULL if an entry for the
7108f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // given ID cannot be found.
72bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  std::shared_ptr<bluetooth::BluetoothInstance> GetInstance(
73bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray      int instance_id);
7408f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
7508f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray private:
7608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // Base implementation of the register callback.
77bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  void OnRegisterInstance(
7808f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray      bluetooth::BLEStatus status,
7908f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray      const bluetooth::UUID& uuid,
80bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray      std::unique_ptr<bluetooth::BluetoothInstance> instance);
8108f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
82bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // Called when the callback registration has completed. |instance| is owned by
8308f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // the base class and should not be deleted by the implementation. If the
84bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // operation failed, nullptr will be passed for |instance|.
85bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  virtual void OnRegisterInstanceImpl(
8608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray      bluetooth::BLEStatus status,
8708f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray      android::sp<IInterface> callback,
88bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray      bluetooth::BluetoothInstance* instance) = 0;
8908f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
9008f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  // RemoteCallbackMap<int, IBluetoothLowEnergyCallback>::Delegate override:
9108f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  void OnRemoteCallbackRemoved(const int& key) override;
9208f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
93bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // Instances that are pending registration. Once their registration is
94bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // complete, the entry will be removed from this map.
9508f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray  RemoteCallbackMap<bluetooth::UUID, android::IInterface> pending_callbacks_;
9608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
97bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // We keep two maps here: one from instance_id IDs to callback Binders and one
98bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  // from instance_id IDs to the BluetoothInstance structures themselves.
99bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  std::mutex maps_lock_;  // Needed for |id_to_instance_|.
100bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  RemoteCallbackMap<int, IInterface> id_to_cb_;
101bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  std::unordered_map<int, std::shared_ptr<bluetooth::BluetoothInstance>>
102bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray      id_to_instance_;
10308f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
104bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  DISALLOW_COPY_AND_ASSIGN(InterfaceWithInstancesBase);
10508f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray};
10608f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray
10708f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray}  // namespace binder
10808f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray}  // namespace ipc
109