1//
2//  Copyright (C) 2015 Google, Inc.
3//
4//  Licensed under the Apache License, Version 2.0 (the "License");
5//  you may not use this file except in compliance with the License.
6//  You may obtain a copy of the License at:
7//
8//  http://www.apache.org/licenses/LICENSE-2.0
9//
10//  Unless required by applicable law or agreed to in writing, software
11//  distributed under the License is distributed on an "AS IS" BASIS,
12//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13//  See the License for the specific language governing permissions and
14//  limitations under the License.
15//
16
17#pragma once
18
19#include <memory>
20#include <unordered_map>
21
22#include <base/macros.h>
23
24#include "service/bluetooth_instance.h"
25#include "service/common/bluetooth/uuid.h"
26#include "service/ipc/binder/remote_callback_map.h"
27
28namespace ipc {
29namespace binder {
30
31// InterfaceWithInstancesBase provides a common base class for Binder interface
32// servers that involve instance callback Binders registered with an integer
33// instance ID over an asynchronous lower-level stack API. This class abstracts
34// away the common procedures of managing pending callbacks, listening to death
35// notifications, and maintaining multiple internal maps in one common base
36// class.
37// TODO: add code example here.
38class InterfaceWithInstancesBase
39    : public RemoteCallbackMap<int, android::IInterface>::Delegate,
40      virtual public android::RefBase {
41 public:
42  InterfaceWithInstancesBase() = default;
43  ~InterfaceWithInstancesBase() override = default;
44
45 protected:
46  // The initial entry point for registering a instance. Invoke this from the
47  // registration API to add a instance/UUID pair to the pending list and set up
48  // the generic asynchronous callback handler and initiate the process with the
49  // given |factory| instance. Returns false, if there were any errors that
50  // could be synchronously reported.
51  bool RegisterInstanceBase(const android::sp<IInterface>& callback,
52                            bluetooth::BluetoothInstanceFactory* factory);
53
54  // Unregister the instance with the given ID, if it was registered before.
55  void UnregisterInstanceBase(int instance_id);
56
57  // Unregisters all registered instances.
58  void UnregisterAllBase();
59
60  // Returns a handle to the lock used to synchronize access to the internal
61  // data structures. Subclasses should acquire this before accessing the maps.
62  std::mutex* maps_lock() { return &maps_lock_; }
63
64  // Returns the callback interface binder that is assigned to the given
65  // instance ID |instance_id|. The returned pointer will contain NULL if an
66  // entry for the given ID cannot be found.
67  android::sp<IInterface> GetCallback(int instance_id);
68
69  // Returns the instance instance that is assigned to the given instance ID
70  // |instance_id|. The returned pointer will contain NULL if an entry for the
71  // given ID cannot be found.
72  std::shared_ptr<bluetooth::BluetoothInstance> GetInstance(int instance_id);
73
74 private:
75  // Base implementation of the register callback.
76  void OnRegisterInstance(
77      bluetooth::BLEStatus status, const bluetooth::UUID& uuid,
78      std::unique_ptr<bluetooth::BluetoothInstance> instance);
79
80  // Called when the callback registration has completed. |instance| is owned by
81  // the base class and should not be deleted by the implementation. If the
82  // operation failed, nullptr will be passed for |instance|.
83  virtual void OnRegisterInstanceImpl(
84      bluetooth::BLEStatus status, android::sp<IInterface> callback,
85      bluetooth::BluetoothInstance* instance) = 0;
86
87  // RemoteCallbackMap<int, IBluetoothLowEnergyCallback>::Delegate override:
88  void OnRemoteCallbackRemoved(const int& key) override;
89
90  // Instances that are pending registration. Once their registration is
91  // complete, the entry will be removed from this map.
92  RemoteCallbackMap<bluetooth::UUID, android::IInterface> pending_callbacks_;
93
94  // We keep two maps here: one from instance_id IDs to callback Binders and one
95  // from instance_id IDs to the BluetoothInstance structures themselves.
96  std::mutex maps_lock_;  // Needed for |id_to_instance_|.
97  RemoteCallbackMap<int, IInterface> id_to_cb_;
98  std::unordered_map<int, std::shared_ptr<bluetooth::BluetoothInstance>>
99      id_to_instance_;
100
101  DISALLOW_COPY_AND_ASSIGN(InterfaceWithInstancesBase);
102};
103
104}  // namespace binder
105}  // namespace ipc
106