blob: 81ce7ccbd328cb2a9399ac57dea273b143e7d59c [file] [log] [blame]
Mathias Agopian7922fa22009-05-18 15:08:03 -07001/*
2 * Copyright (C) 2005 The Android Open Source Project
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
Steven Morelandc4dd2102017-02-23 13:57:21 -080017#define LOG_TAG "hw-BpHwBinder"
Mathias Agopian7922fa22009-05-18 15:08:03 -070018//#define LOG_NDEBUG 0
19
Yifan Hong1e118d22017-01-12 14:42:28 -080020#include <hwbinder/BpHwBinder.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070021
Martijn Coenen4080edc2016-05-04 14:17:02 +020022#include <hwbinder/IPCThreadState.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070023#include <utils/Log.h>
24
25#include <stdio.h>
26
Steve Block48f4e152011-10-20 11:56:00 +010027//#undef ALOGV
28//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
Mathias Agopian7922fa22009-05-18 15:08:03 -070029
30namespace android {
Martijn Coenenf75a23d2016-08-01 11:55:17 +020031namespace hardware {
Mathias Agopian7922fa22009-05-18 15:08:03 -070032
33// ---------------------------------------------------------------------------
34
Yifan Hong1e118d22017-01-12 14:42:28 -080035BpHwBinder::ObjectManager::ObjectManager()
Mathias Agopian7922fa22009-05-18 15:08:03 -070036{
37}
38
Yifan Hong1e118d22017-01-12 14:42:28 -080039BpHwBinder::ObjectManager::~ObjectManager()
Mathias Agopian7922fa22009-05-18 15:08:03 -070040{
41 kill();
42}
43
Yifan Hong1e118d22017-01-12 14:42:28 -080044void BpHwBinder::ObjectManager::attach(
Mathias Agopian7922fa22009-05-18 15:08:03 -070045 const void* objectID, void* object, void* cleanupCookie,
46 IBinder::object_cleanup_func func)
47{
48 entry_t e;
49 e.object = object;
50 e.cleanupCookie = cleanupCookie;
51 e.func = func;
52
53 if (mObjects.indexOfKey(objectID) >= 0) {
Steve Blockeafc6212012-01-06 19:20:56 +000054 ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
Mathias Agopian7922fa22009-05-18 15:08:03 -070055 objectID, this, object);
56 return;
57 }
58
59 mObjects.add(objectID, e);
60}
61
Yifan Hong1e118d22017-01-12 14:42:28 -080062void* BpHwBinder::ObjectManager::find(const void* objectID) const
Mathias Agopian7922fa22009-05-18 15:08:03 -070063{
64 const ssize_t i = mObjects.indexOfKey(objectID);
Yi Kong55d41072018-07-23 14:55:39 -070065 if (i < 0) return nullptr;
Mathias Agopian7922fa22009-05-18 15:08:03 -070066 return mObjects.valueAt(i).object;
67}
68
Yifan Hong1e118d22017-01-12 14:42:28 -080069void BpHwBinder::ObjectManager::detach(const void* objectID)
Mathias Agopian7922fa22009-05-18 15:08:03 -070070{
71 mObjects.removeItem(objectID);
72}
73
Yifan Hong1e118d22017-01-12 14:42:28 -080074void BpHwBinder::ObjectManager::kill()
Mathias Agopian7922fa22009-05-18 15:08:03 -070075{
76 const size_t N = mObjects.size();
Mark Salyzyn386eb9e2014-05-30 16:35:57 -070077 ALOGV("Killing %zu objects in manager %p", N, this);
Mathias Agopian7922fa22009-05-18 15:08:03 -070078 for (size_t i=0; i<N; i++) {
79 const entry_t& e = mObjects.valueAt(i);
Yi Kong55d41072018-07-23 14:55:39 -070080 if (e.func != nullptr) {
Mathias Agopian7922fa22009-05-18 15:08:03 -070081 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
82 }
83 }
84
85 mObjects.clear();
86}
87
88// ---------------------------------------------------------------------------
89
Yifan Hong1e118d22017-01-12 14:42:28 -080090BpHwBinder::BpHwBinder(int32_t handle)
Mathias Agopian7922fa22009-05-18 15:08:03 -070091 : mHandle(handle)
92 , mAlive(1)
93 , mObitsSent(0)
Yi Kong55d41072018-07-23 14:55:39 -070094 , mObituaries(nullptr)
Mathias Agopian7922fa22009-05-18 15:08:03 -070095{
Yifan Hong1e118d22017-01-12 14:42:28 -080096 ALOGV("Creating BpHwBinder %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -070097
98 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
Martijn Coenenb8253722018-05-23 15:33:22 +020099 IPCThreadState::self()->incWeakHandle(handle, this);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700100}
101
Yifan Hong1e118d22017-01-12 14:42:28 -0800102status_t BpHwBinder::transact(
Steven Moreland4cbd6ec2019-04-30 19:29:52 -0700103 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700104{
105 // Once a binder has died, it will never come back to life.
106 if (mAlive) {
107 status_t status = IPCThreadState::self()->transact(
108 mHandle, code, data, reply, flags);
Steven Moreland4cbd6ec2019-04-30 19:29:52 -0700109
110 if (status == ::android::OK && callback != nullptr) {
111 callback(*reply);
112 }
113
Mathias Agopian7922fa22009-05-18 15:08:03 -0700114 if (status == DEAD_OBJECT) mAlive = 0;
115 return status;
116 }
117
118 return DEAD_OBJECT;
119}
120
Yifan Hong1e118d22017-01-12 14:42:28 -0800121status_t BpHwBinder::linkToDeath(
Mathias Agopian7922fa22009-05-18 15:08:03 -0700122 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
123{
124 Obituary ob;
125 ob.recipient = recipient;
126 ob.cookie = cookie;
127 ob.flags = flags;
128
Yi Kong55d41072018-07-23 14:55:39 -0700129 LOG_ALWAYS_FATAL_IF(recipient == nullptr,
Mathias Agopian7922fa22009-05-18 15:08:03 -0700130 "linkToDeath(): recipient must be non-NULL");
131
132 {
133 AutoMutex _l(mLock);
134
135 if (!mObitsSent) {
136 if (!mObituaries) {
137 mObituaries = new Vector<Obituary>;
138 if (!mObituaries) {
139 return NO_MEMORY;
140 }
Steve Block48f4e152011-10-20 11:56:00 +0100141 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700142 getWeakRefs()->incWeak(this);
143 IPCThreadState* self = IPCThreadState::self();
144 self->requestDeathNotification(mHandle, this);
145 self->flushCommands();
146 }
147 ssize_t res = mObituaries->add(ob);
148 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
149 }
150 }
151
152 return DEAD_OBJECT;
153}
154
Yifan Hong1e118d22017-01-12 14:42:28 -0800155status_t BpHwBinder::unlinkToDeath(
Mathias Agopian7922fa22009-05-18 15:08:03 -0700156 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
157 wp<DeathRecipient>* outRecipient)
158{
159 AutoMutex _l(mLock);
160
161 if (mObitsSent) {
162 return DEAD_OBJECT;
163 }
164
165 const size_t N = mObituaries ? mObituaries->size() : 0;
166 for (size_t i=0; i<N; i++) {
167 const Obituary& obit = mObituaries->itemAt(i);
168 if ((obit.recipient == recipient
Yi Kong55d41072018-07-23 14:55:39 -0700169 || (recipient == nullptr && obit.cookie == cookie))
Mathias Agopian7922fa22009-05-18 15:08:03 -0700170 && obit.flags == flags) {
Yi Kong55d41072018-07-23 14:55:39 -0700171 if (outRecipient != nullptr) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700172 *outRecipient = mObituaries->itemAt(i).recipient;
173 }
174 mObituaries->removeAt(i);
175 if (mObituaries->size() == 0) {
Steve Block48f4e152011-10-20 11:56:00 +0100176 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700177 IPCThreadState* self = IPCThreadState::self();
178 self->clearDeathNotification(mHandle, this);
179 self->flushCommands();
180 delete mObituaries;
Yi Kong55d41072018-07-23 14:55:39 -0700181 mObituaries = nullptr;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700182 }
183 return NO_ERROR;
184 }
185 }
186
187 return NAME_NOT_FOUND;
188}
189
Yifan Hong1e118d22017-01-12 14:42:28 -0800190void BpHwBinder::sendObituary()
Mathias Agopian7922fa22009-05-18 15:08:03 -0700191{
Steve Block48f4e152011-10-20 11:56:00 +0100192 ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
Mathias Agopian7922fa22009-05-18 15:08:03 -0700193 this, mHandle, mObitsSent ? "true" : "false");
194
195 mAlive = 0;
196 if (mObitsSent) return;
197
198 mLock.lock();
199 Vector<Obituary>* obits = mObituaries;
Yi Kong55d41072018-07-23 14:55:39 -0700200 if(obits != nullptr) {
Steve Block48f4e152011-10-20 11:56:00 +0100201 ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700202 IPCThreadState* self = IPCThreadState::self();
203 self->clearDeathNotification(mHandle, this);
204 self->flushCommands();
Yi Kong55d41072018-07-23 14:55:39 -0700205 mObituaries = nullptr;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700206 }
207 mObitsSent = 1;
208 mLock.unlock();
209
Mark Salyzyn386eb9e2014-05-30 16:35:57 -0700210 ALOGV("Reporting death of proxy %p for %zu recipients\n",
211 this, obits ? obits->size() : 0U);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700212
Yi Kong55d41072018-07-23 14:55:39 -0700213 if (obits != nullptr) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700214 const size_t N = obits->size();
215 for (size_t i=0; i<N; i++) {
216 reportOneDeath(obits->itemAt(i));
217 }
218
219 delete obits;
220 }
221}
222
Martijn Coenen320e1d32018-09-07 10:41:33 +0200223// Returns the strong refcount on the object this proxy points to, or
224// -1 in case of failure.
225ssize_t BpHwBinder::getNodeStrongRefCount()
226{
227 return ProcessState::self()->getStrongRefCountForNodeByHandle(mHandle);
228}
229
Yifan Hong1e118d22017-01-12 14:42:28 -0800230void BpHwBinder::reportOneDeath(const Obituary& obit)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700231{
232 sp<DeathRecipient> recipient = obit.recipient.promote();
Steve Block48f4e152011-10-20 11:56:00 +0100233 ALOGV("Reporting death to recipient: %p\n", recipient.get());
Yi Kong55d41072018-07-23 14:55:39 -0700234 if (recipient == nullptr) return;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700235
236 recipient->binderDied(this);
237}
238
239
Yifan Hong1e118d22017-01-12 14:42:28 -0800240void BpHwBinder::attachObject(
Mathias Agopian7922fa22009-05-18 15:08:03 -0700241 const void* objectID, void* object, void* cleanupCookie,
242 object_cleanup_func func)
243{
244 AutoMutex _l(mLock);
Steve Block48f4e152011-10-20 11:56:00 +0100245 ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700246 mObjects.attach(objectID, object, cleanupCookie, func);
247}
248
Yifan Hong1e118d22017-01-12 14:42:28 -0800249void* BpHwBinder::findObject(const void* objectID) const
Mathias Agopian7922fa22009-05-18 15:08:03 -0700250{
251 AutoMutex _l(mLock);
252 return mObjects.find(objectID);
253}
254
Yifan Hong1e118d22017-01-12 14:42:28 -0800255void BpHwBinder::detachObject(const void* objectID)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700256{
257 AutoMutex _l(mLock);
258 mObjects.detach(objectID);
259}
260
Yifan Hong1e118d22017-01-12 14:42:28 -0800261BpHwBinder* BpHwBinder::remoteBinder()
Mathias Agopian7922fa22009-05-18 15:08:03 -0700262{
263 return this;
264}
265
Yifan Hong1e118d22017-01-12 14:42:28 -0800266BpHwBinder::~BpHwBinder()
Mathias Agopian7922fa22009-05-18 15:08:03 -0700267{
Yifan Hong1e118d22017-01-12 14:42:28 -0800268 ALOGV("Destroying BpHwBinder %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700269
270 IPCThreadState* ipc = IPCThreadState::self();
271
Mathias Agopian7922fa22009-05-18 15:08:03 -0700272 if (ipc) {
273 ipc->expungeHandle(mHandle, this);
274 ipc->decWeakHandle(mHandle);
275 }
276}
277
Yifan Hong1e118d22017-01-12 14:42:28 -0800278void BpHwBinder::onFirstRef()
Mathias Agopian7922fa22009-05-18 15:08:03 -0700279{
Yifan Hong1e118d22017-01-12 14:42:28 -0800280 ALOGV("onFirstRef BpHwBinder %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700281 IPCThreadState* ipc = IPCThreadState::self();
Martijn Coenenb8253722018-05-23 15:33:22 +0200282 if (ipc) ipc->incStrongHandle(mHandle, this);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700283}
284
Yifan Hong1e118d22017-01-12 14:42:28 -0800285void BpHwBinder::onLastStrongRef(const void* /*id*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700286{
Yifan Hong1e118d22017-01-12 14:42:28 -0800287 ALOGV("onLastStrongRef BpHwBinder %p handle %d\n", this, mHandle);
Steve Block48f4e152011-10-20 11:56:00 +0100288 IF_ALOGV() {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700289 printRefs();
290 }
291 IPCThreadState* ipc = IPCThreadState::self();
Tomasz Wasilczyke4f0b992017-02-27 13:50:50 -0800292 if (ipc) {
293 ipc->decStrongHandle(mHandle);
294 ipc->flushCommands();
295 }
Steven Morelandd6d3aa72019-06-07 12:36:50 -0700296
297 mLock.lock();
298 Vector<Obituary>* obits = mObituaries;
299 if(obits != nullptr) {
300 if (!obits->isEmpty()) {
301 ALOGI("onLastStrongRef automatically unlinking death recipients");
302 }
303
304 if (ipc) ipc->clearDeathNotification(mHandle, this);
305 mObituaries = nullptr;
306 }
307 mLock.unlock();
308
309 if (obits != nullptr) {
310 // XXX Should we tell any remaining DeathRecipient
311 // objects that the last strong ref has gone away, so they
312 // are no longer linked?
313 delete obits;
314 obits = nullptr;
315 }
Mathias Agopian7922fa22009-05-18 15:08:03 -0700316}
317
Yifan Hong1e118d22017-01-12 14:42:28 -0800318bool BpHwBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700319{
Yifan Hong1e118d22017-01-12 14:42:28 -0800320 ALOGV("onIncStrongAttempted BpHwBinder %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700321 IPCThreadState* ipc = IPCThreadState::self();
322 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
323}
324
325// ---------------------------------------------------------------------------
326
Steven Moreland7173a4c2019-09-26 15:55:02 -0700327} // namespace hardware
328} // namespace android