blob: 5cf720c0d7a05b25f1ab0007a9e565830cfa88b2 [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
17#define LOG_TAG "BpBinder"
18//#define LOG_NDEBUG 0
19
Mathias Agopian16475702009-05-19 19:08:10 -070020#include <binder/BpBinder.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070021
Mathias Agopian16475702009-05-19 19:08:10 -070022#include <binder/IPCThreadState.h>
Dianne Hackborn7ce4c3b2015-10-07 17:35:27 -070023#include <binder/IResultReceiver.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070024#include <utils/Log.h>
25
26#include <stdio.h>
27
Steve Block48f4e152011-10-20 11:56:00 +010028//#undef ALOGV
29//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
Mathias Agopian7922fa22009-05-18 15:08:03 -070030
31namespace android {
32
33// ---------------------------------------------------------------------------
34
35BpBinder::ObjectManager::ObjectManager()
36{
37}
38
39BpBinder::ObjectManager::~ObjectManager()
40{
41 kill();
42}
43
44void BpBinder::ObjectManager::attach(
45 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
62void* BpBinder::ObjectManager::find(const void* objectID) const
63{
64 const ssize_t i = mObjects.indexOfKey(objectID);
65 if (i < 0) return NULL;
66 return mObjects.valueAt(i).object;
67}
68
69void BpBinder::ObjectManager::detach(const void* objectID)
70{
71 mObjects.removeItem(objectID);
72}
73
74void BpBinder::ObjectManager::kill()
75{
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);
80 if (e.func != NULL) {
81 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
82 }
83 }
84
85 mObjects.clear();
86}
87
88// ---------------------------------------------------------------------------
89
90BpBinder::BpBinder(int32_t handle)
91 : mHandle(handle)
92 , mAlive(1)
93 , mObitsSent(0)
94 , mObituaries(NULL)
95{
Steve Block48f4e152011-10-20 11:56:00 +010096 ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -070097
98 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
99 IPCThreadState::self()->incWeakHandle(handle);
100}
101
Mathias Agopiana6286c32009-05-22 19:00:22 -0700102bool BpBinder::isDescriptorCached() const {
103 Mutex::Autolock _l(mLock);
104 return mDescriptorCache.size() ? true : false;
105}
106
107const String16& BpBinder::getInterfaceDescriptor() const
Mathias Agopian7922fa22009-05-18 15:08:03 -0700108{
Mathias Agopiana6286c32009-05-22 19:00:22 -0700109 if (isDescriptorCached() == false) {
110 Parcel send, reply;
111 // do the IPC without a lock held.
112 status_t err = const_cast<BpBinder*>(this)->transact(
113 INTERFACE_TRANSACTION, send, &reply);
114 if (err == NO_ERROR) {
115 String16 res(reply.readString16());
116 Mutex::Autolock _l(mLock);
117 // mDescriptorCache could have been assigned while the lock was
118 // released.
119 if (mDescriptorCache.size() == 0)
120 mDescriptorCache = res;
121 }
Mathias Agopian7922fa22009-05-18 15:08:03 -0700122 }
Mark Salyzyn386eb9e2014-05-30 16:35:57 -0700123
Mathias Agopiana6286c32009-05-22 19:00:22 -0700124 // we're returning a reference to a non-static object here. Usually this
Mark Salyzyn386eb9e2014-05-30 16:35:57 -0700125 // is not something smart to do, however, with binder objects it is
Mathias Agopiana6286c32009-05-22 19:00:22 -0700126 // (usually) safe because they are reference-counted.
Mark Salyzyn386eb9e2014-05-30 16:35:57 -0700127
Mathias Agopiana6286c32009-05-22 19:00:22 -0700128 return mDescriptorCache;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700129}
130
131bool BpBinder::isBinderAlive() const
132{
133 return mAlive != 0;
134}
135
136status_t BpBinder::pingBinder()
137{
138 Parcel send;
139 Parcel reply;
140 status_t err = transact(PING_TRANSACTION, send, &reply);
141 if (err != NO_ERROR) return err;
142 if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
143 return (status_t)reply.readInt32();
144}
145
146status_t BpBinder::dump(int fd, const Vector<String16>& args)
147{
148 Parcel send;
149 Parcel reply;
150 send.writeFileDescriptor(fd);
151 const size_t numArgs = args.size();
152 send.writeInt32(numArgs);
153 for (size_t i = 0; i < numArgs; i++) {
154 send.writeString16(args[i]);
155 }
156 status_t err = transact(DUMP_TRANSACTION, send, &reply);
157 return err;
158}
159
Dianne Hackborn7ce4c3b2015-10-07 17:35:27 -0700160status_t BpBinder::shellCommand(int in, int out, int err, Vector<String16>& args,
161 const sp<IResultReceiver>& resultReceiver)
162{
163 Parcel send;
164 Parcel reply;
165 send.writeFileDescriptor(in);
166 send.writeFileDescriptor(out);
167 send.writeFileDescriptor(err);
168 const size_t numArgs = args.size();
169 send.writeInt32(numArgs);
170 for (size_t i = 0; i < numArgs; i++) {
171 send.writeString16(args[i]);
172 }
173 send.writeStrongBinder(resultReceiver != NULL ? IInterface::asBinder(resultReceiver) : NULL);
174 return transact(SHELL_COMMAND_TRANSACTION, send, &reply);
175}
176
Mathias Agopian7922fa22009-05-18 15:08:03 -0700177status_t BpBinder::transact(
178 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
179{
180 // Once a binder has died, it will never come back to life.
181 if (mAlive) {
182 status_t status = IPCThreadState::self()->transact(
183 mHandle, code, data, reply, flags);
184 if (status == DEAD_OBJECT) mAlive = 0;
185 return status;
186 }
187
188 return DEAD_OBJECT;
189}
190
191status_t BpBinder::linkToDeath(
192 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
193{
194 Obituary ob;
195 ob.recipient = recipient;
196 ob.cookie = cookie;
197 ob.flags = flags;
198
199 LOG_ALWAYS_FATAL_IF(recipient == NULL,
200 "linkToDeath(): recipient must be non-NULL");
201
202 {
203 AutoMutex _l(mLock);
204
205 if (!mObitsSent) {
206 if (!mObituaries) {
207 mObituaries = new Vector<Obituary>;
208 if (!mObituaries) {
209 return NO_MEMORY;
210 }
Steve Block48f4e152011-10-20 11:56:00 +0100211 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700212 getWeakRefs()->incWeak(this);
213 IPCThreadState* self = IPCThreadState::self();
214 self->requestDeathNotification(mHandle, this);
215 self->flushCommands();
216 }
217 ssize_t res = mObituaries->add(ob);
218 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
219 }
220 }
221
222 return DEAD_OBJECT;
223}
224
225status_t BpBinder::unlinkToDeath(
226 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
227 wp<DeathRecipient>* outRecipient)
228{
229 AutoMutex _l(mLock);
230
231 if (mObitsSent) {
232 return DEAD_OBJECT;
233 }
234
235 const size_t N = mObituaries ? mObituaries->size() : 0;
236 for (size_t i=0; i<N; i++) {
237 const Obituary& obit = mObituaries->itemAt(i);
238 if ((obit.recipient == recipient
239 || (recipient == NULL && obit.cookie == cookie))
240 && obit.flags == flags) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700241 if (outRecipient != NULL) {
242 *outRecipient = mObituaries->itemAt(i).recipient;
243 }
244 mObituaries->removeAt(i);
245 if (mObituaries->size() == 0) {
Steve Block48f4e152011-10-20 11:56:00 +0100246 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700247 IPCThreadState* self = IPCThreadState::self();
248 self->clearDeathNotification(mHandle, this);
249 self->flushCommands();
250 delete mObituaries;
251 mObituaries = NULL;
252 }
253 return NO_ERROR;
254 }
255 }
256
257 return NAME_NOT_FOUND;
258}
259
260void BpBinder::sendObituary()
261{
Steve Block48f4e152011-10-20 11:56:00 +0100262 ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
Mathias Agopian7922fa22009-05-18 15:08:03 -0700263 this, mHandle, mObitsSent ? "true" : "false");
264
265 mAlive = 0;
266 if (mObitsSent) return;
267
268 mLock.lock();
269 Vector<Obituary>* obits = mObituaries;
270 if(obits != NULL) {
Steve Block48f4e152011-10-20 11:56:00 +0100271 ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700272 IPCThreadState* self = IPCThreadState::self();
273 self->clearDeathNotification(mHandle, this);
274 self->flushCommands();
275 mObituaries = NULL;
276 }
277 mObitsSent = 1;
278 mLock.unlock();
279
Mark Salyzyn386eb9e2014-05-30 16:35:57 -0700280 ALOGV("Reporting death of proxy %p for %zu recipients\n",
281 this, obits ? obits->size() : 0U);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700282
283 if (obits != NULL) {
284 const size_t N = obits->size();
285 for (size_t i=0; i<N; i++) {
286 reportOneDeath(obits->itemAt(i));
287 }
288
289 delete obits;
290 }
291}
292
293void BpBinder::reportOneDeath(const Obituary& obit)
294{
295 sp<DeathRecipient> recipient = obit.recipient.promote();
Steve Block48f4e152011-10-20 11:56:00 +0100296 ALOGV("Reporting death to recipient: %p\n", recipient.get());
Mathias Agopian7922fa22009-05-18 15:08:03 -0700297 if (recipient == NULL) return;
298
299 recipient->binderDied(this);
300}
301
302
303void BpBinder::attachObject(
304 const void* objectID, void* object, void* cleanupCookie,
305 object_cleanup_func func)
306{
307 AutoMutex _l(mLock);
Steve Block48f4e152011-10-20 11:56:00 +0100308 ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700309 mObjects.attach(objectID, object, cleanupCookie, func);
310}
311
312void* BpBinder::findObject(const void* objectID) const
313{
314 AutoMutex _l(mLock);
315 return mObjects.find(objectID);
316}
317
318void BpBinder::detachObject(const void* objectID)
319{
320 AutoMutex _l(mLock);
321 mObjects.detach(objectID);
322}
323
324BpBinder* BpBinder::remoteBinder()
325{
326 return this;
327}
328
329BpBinder::~BpBinder()
330{
Steve Block48f4e152011-10-20 11:56:00 +0100331 ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700332
333 IPCThreadState* ipc = IPCThreadState::self();
334
335 mLock.lock();
336 Vector<Obituary>* obits = mObituaries;
337 if(obits != NULL) {
338 if (ipc) ipc->clearDeathNotification(mHandle, this);
339 mObituaries = NULL;
340 }
341 mLock.unlock();
342
343 if (obits != NULL) {
344 // XXX Should we tell any remaining DeathRecipient
345 // objects that the last strong ref has gone away, so they
346 // are no longer linked?
347 delete obits;
348 }
349
350 if (ipc) {
351 ipc->expungeHandle(mHandle, this);
352 ipc->decWeakHandle(mHandle);
353 }
354}
355
356void BpBinder::onFirstRef()
357{
Steve Block48f4e152011-10-20 11:56:00 +0100358 ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700359 IPCThreadState* ipc = IPCThreadState::self();
360 if (ipc) ipc->incStrongHandle(mHandle);
361}
362
Colin Crossf0487982014-02-05 17:42:44 -0800363void BpBinder::onLastStrongRef(const void* /*id*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700364{
Steve Block48f4e152011-10-20 11:56:00 +0100365 ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
366 IF_ALOGV() {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700367 printRefs();
368 }
369 IPCThreadState* ipc = IPCThreadState::self();
370 if (ipc) ipc->decStrongHandle(mHandle);
371}
372
Colin Crossf0487982014-02-05 17:42:44 -0800373bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700374{
Steve Block48f4e152011-10-20 11:56:00 +0100375 ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700376 IPCThreadState* ipc = IPCThreadState::self();
377 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
378}
379
380// ---------------------------------------------------------------------------
381
382}; // namespace android