1f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//
2f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  Copyright (C) 2015 Google, Inc.
3f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//
4f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  Licensed under the Apache License, Version 2.0 (the "License");
5f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  you may not use this file except in compliance with the License.
6f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  You may obtain a copy of the License at:
7f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//
8f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  http://www.apache.org/licenses/LICENSE-2.0
9f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//
10f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  Unless required by applicable law or agreed to in writing, software
11f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  distributed under the License is distributed on an "AS IS" BASIS,
12f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  See the License for the specific language governing permissions and
14f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//  limitations under the License.
15f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//
16f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
17f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray#pragma once
18f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
19f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray#include <mutex>
20f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray#include <unordered_map>
21f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
22f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray#include <base/logging.h>
23f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray#include <base/macros.h>
24f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray#include <binder/IBinder.h>
25f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray#include <binder/IInterface.h>
26f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
27f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraynamespace ipc {
28f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraynamespace binder {
29f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
30f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// A map of remote interfaces where the value type "V" must inherit from
31f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// android::IInterface. This is just like RemoteCallbackList except it provides
32f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// a key-value mapping.
33f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray//
34f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// TODO(armansito): We should make this class non-final and the template
35f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// interface abstract, so that code that depends on this can be unit tested
36f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// against a mock version of this class.
37911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
38f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayclass RemoteCallbackMap final {
39f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray public:
40f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  RemoteCallbackMap() = default;
41f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  ~RemoteCallbackMap();
42f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
43f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // The Delegate interface is used to notify when a registered callback is
44f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // removed from the map as a result of the death of the remote process that
45f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // owns the registered callback.
46f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  class Delegate {
47f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray   public:
48f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    virtual ~Delegate() = default;
49f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
50f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    // Called when a remote callback associated with the key |key| has been
51f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    // removed. This won't get called if the callback was removed as a result of
52f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    // a call to RemoteCallbackMap::Unregister.
53f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    virtual void OnRemoteCallbackRemoved(const K& key) = 0;
54f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  };
55f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
56f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Register a callback interface and associate it with the given key.
57f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Registering will automatically start tracking for death notifications in
58f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // case the remote process hosting the Binder dies. In such a case, the Binder
59f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // is automatically removed from the map.
60f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  //
61f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // An optional |delegate| can be passed which will be assocated with the given
62f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // key/value pair. |delegate| must outlive this map.
63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool Register(const K& key, const android::sp<V>& callback,
64f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray                Delegate* delegate = nullptr);
65f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
66f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Unregisters a previously registered callback with the given key. Returns
67f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // false if |key| doesn't exist.
68f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  bool Unregister(const K& key);
69f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
70f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Returns the callback associated with the given key. Returns NULL if |key|
71f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // doesn't exist.
72f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  android::sp<V> Get(const K& key);
73f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
74f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Removes the callback associated with the given key from the map and returns
75f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // the value. Returns NULL if the key doesn't exists.
76f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  android::sp<V> Remove(const K& key);
77f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
78f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Clear the contents of the map.
79f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  void Clear();
80f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
81f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray private:
82f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  class CallbackDeathRecipient : public android::IBinder::DeathRecipient {
83f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray   public:
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    CallbackDeathRecipient(const K& key, const android::sp<V>& callback,
85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                           RemoteCallbackMap<K, V>* owner, Delegate* delegate);
86f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
87f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    android::sp<V> get_callback() const { return callback_; }
88f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
89f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    // android::IBinder::DeathRecipient override:
90f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    void binderDied(const android::wp<android::IBinder>& who) override;
91f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
92f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray   private:
93f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    K key_;
94f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    android::sp<V> callback_;
95f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    RemoteCallbackMap<K, V>* owner_;  // weak
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    Delegate* delegate_;              // weak
97f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  };
98f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
99f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Typedef for internal map container.
100f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  using CallbackMap =
101f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray      std::unordered_map<K, android::sp<CallbackDeathRecipient>>;
102f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
103f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  bool UnregisterInternal(typename CallbackMap::iterator iter);
104f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
105f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  std::mutex map_lock_;
106f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  CallbackMap map_;
107f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
108f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  DISALLOW_COPY_AND_ASSIGN(RemoteCallbackMap);
109f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray};
110f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
111f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// Template Implementation details below
112f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// ========================================================
113f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
114f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayusing android::IBinder;
115f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayusing android::IInterface;
116f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayusing android::sp;
117f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayusing android::wp;
118f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayusing std::lock_guard;
119f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayusing std::mutex;
120f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
122f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman UgurayRemoteCallbackMap<K, V>::~RemoteCallbackMap() {
123f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  Clear();
124f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
125f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool RemoteCallbackMap<K, V>::Register(const K& key, const sp<V>& callback,
128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                       Delegate* delegate) {
129f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  lock_guard<mutex> lock(map_lock_);
130f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
131f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  if (map_.find(key) != map_.end()) {
132f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    VLOG(1) << "Callback map already contains key";
133f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    return false;
134f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  }
135f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
136f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  sp<CallbackDeathRecipient> dr(
137f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray      new CallbackDeathRecipient(key, callback, this, delegate));
138f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  sp<IBinder> binder = IInterface::asBinder(callback.get());
139f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  if (binder->linkToDeath(dr) != android::NO_ERROR) {
140f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    LOG(ERROR) << "Failed to link death recipient to binder";
141f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    return false;
142f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  }
143f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
144f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  map_[key] = dr;
145f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
146f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  VLOG(2) << "Callback successfully registered with map";
147f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
148f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  return true;
149f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
150f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
152f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraybool RemoteCallbackMap<K, V>::Unregister(const K& key) {
153f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  lock_guard<mutex> lock(map_lock_);
154f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
155f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  auto iter = map_.find(key);
156f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  if (iter == map_.end()) {
157f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    VLOG(1) << "Callback with given key not found";
158f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    return false;
159f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  }
160f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
161f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  return UnregisterInternal(iter);
162f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
163f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
164911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
165f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraysp<V> RemoteCallbackMap<K, V>::Get(const K& key) {
166f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  lock_guard<mutex> lock(map_lock_);
167f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
168f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  auto iter = map_.find(key);
169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (iter == map_.end()) return nullptr;
170f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
171b2b1ecd3c282412773f5ca70ee2798542bc2920fArman Uguray  return iter->second->get_callback();
172f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
173f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
175f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraysp<V> RemoteCallbackMap<K, V>::Remove(const K& key) {
176f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  lock_guard<mutex> lock(map_lock_);
177f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
178f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  auto iter = map_.find(key);
179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (iter == map_.end()) return nullptr;
180f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
181f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  sp<V> val = iter->second->get_callback();
182f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  UnregisterInternal(iter);
183f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
184f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  return val;
185f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
187f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayvoid RemoteCallbackMap<K, V>::Clear() {
188f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  lock_guard<mutex> lock(map_lock_);
189f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
190f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  for (auto iter = map_.begin(); iter != map_.end();)
191f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    UnregisterInternal(iter++);
192f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
193f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
195f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraybool RemoteCallbackMap<K, V>::UnregisterInternal(
196f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    typename CallbackMap::iterator iter) {
197f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  sp<CallbackDeathRecipient> dr = iter->second;
198f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  map_.erase(iter);
199f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
200f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  if (IInterface::asBinder(dr->get_callback().get())->unlinkToDeath(dr) !=
201f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray      android::NO_ERROR) {
202f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    LOG(ERROR) << "Failed to unlink death recipient from binder";
203f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
204f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    // We removed the entry from |map_| but unlinkToDeath failed. There isn't
205f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    // really much we can do here other than deleting the binder and returning
206f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    // an error.
207f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    return false;
208f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  }
209f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
210f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  VLOG(2) << "Callback successfully removed from map";
211f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
212f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  return true;
213f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
214f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
216f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman UgurayRemoteCallbackMap<K, V>::CallbackDeathRecipient::CallbackDeathRecipient(
217911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    const K& key, const sp<V>& callback, RemoteCallbackMap<K, V>* owner,
218f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    Delegate* delegate)
219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    : key_(key), callback_(callback), owner_(owner), delegate_(delegate) {
220f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  CHECK(callback_.get());
221f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
222f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsontemplate <typename K, typename V>
224f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Ugurayvoid RemoteCallbackMap<K, V>::CallbackDeathRecipient::binderDied(
225f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    const wp<IBinder>& who) {
226f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  VLOG(1) << "Received binderDied";
227f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
228f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  sp<IBinder> binder = IInterface::asBinder(callback_.get());
229f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  CHECK(who.unsafe_get() == binder.get());
230f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
231f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Remove the callback but no need to call unlinkToDeath.
232f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  {
233f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    lock_guard<mutex> lock(owner_->map_lock_);
234f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    auto iter = owner_->map_.find(key_);
235f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    CHECK(iter != owner_->map_.end());
236f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    owner_->map_.erase(iter);
237f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  }
238f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
239f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  VLOG(1) << "Callback from dead process unregistered; notifying delegate";
240f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
241f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  // Notify delegate.
242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (delegate_) delegate_->OnRemoteCallbackRemoved(key_);
243f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}
244f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
245f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}  // namespace binder
246f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}  // namespace ipc
247