blob: 69ab19574e642683646144fdd772ef20147b6b40 [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -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
20#include <utils/BpBinder.h>
21
22#include <utils/IPCThreadState.h>
23#include <utils/Log.h>
24
25#include <stdio.h>
26
27//#undef LOGV
28//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
29
30namespace android {
31
32// ---------------------------------------------------------------------------
33
34BpBinder::ObjectManager::ObjectManager()
35{
36}
37
38BpBinder::ObjectManager::~ObjectManager()
39{
40 kill();
41}
42
43void BpBinder::ObjectManager::attach(
44 const void* objectID, void* object, void* cleanupCookie,
45 IBinder::object_cleanup_func func)
46{
47 entry_t e;
48 e.object = object;
49 e.cleanupCookie = cleanupCookie;
50 e.func = func;
51
52 if (mObjects.indexOfKey(objectID) >= 0) {
53 LOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
54 objectID, this, object);
55 return;
56 }
57
58 mObjects.add(objectID, e);
59}
60
61void* BpBinder::ObjectManager::find(const void* objectID) const
62{
63 const ssize_t i = mObjects.indexOfKey(objectID);
64 if (i < 0) return NULL;
65 return mObjects.valueAt(i).object;
66}
67
68void BpBinder::ObjectManager::detach(const void* objectID)
69{
70 mObjects.removeItem(objectID);
71}
72
73void BpBinder::ObjectManager::kill()
74{
75 const size_t N = mObjects.size();
76 LOGV("Killing %d objects in manager %p", N, this);
77 for (size_t i=0; i<N; i++) {
78 const entry_t& e = mObjects.valueAt(i);
79 if (e.func != NULL) {
80 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
81 }
82 }
83
84 mObjects.clear();
85}
86
87// ---------------------------------------------------------------------------
88
89BpBinder::BpBinder(int32_t handle)
90 : mHandle(handle)
91 , mAlive(1)
92 , mObitsSent(0)
93 , mObituaries(NULL)
94{
95 LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
96
97 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
98 IPCThreadState::self()->incWeakHandle(handle);
99}
100
101String16 BpBinder::getInterfaceDescriptor() const
102{
103 String16 res;
104 Parcel send, reply;
105 status_t err = const_cast<BpBinder*>(this)->transact(
106 INTERFACE_TRANSACTION, send, &reply);
107 if (err == NO_ERROR) {
108 res = reply.readString16();
109 }
110 return res;
111}
112
113bool BpBinder::isBinderAlive() const
114{
115 return mAlive != 0;
116}
117
118status_t BpBinder::pingBinder()
119{
120 Parcel send;
121 Parcel reply;
122 status_t err = transact(PING_TRANSACTION, send, &reply);
123 if (err != NO_ERROR) return err;
124 if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
125 return (status_t)reply.readInt32();
126}
127
128status_t BpBinder::dump(int fd, const Vector<String16>& args)
129{
130 Parcel send;
131 Parcel reply;
132 send.writeFileDescriptor(fd);
133 const size_t numArgs = args.size();
134 send.writeInt32(numArgs);
135 for (size_t i = 0; i < numArgs; i++) {
136 send.writeString16(args[i]);
137 }
138 status_t err = transact(DUMP_TRANSACTION, send, &reply);
139 return err;
140}
141
142status_t BpBinder::transact(
143 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
144{
145 // Once a binder has died, it will never come back to life.
146 if (mAlive) {
147 status_t status = IPCThreadState::self()->transact(
148 mHandle, code, data, reply, flags);
149 if (status == DEAD_OBJECT) mAlive = 0;
150 return status;
151 }
152
153 return DEAD_OBJECT;
154}
155
156status_t BpBinder::linkToDeath(
157 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
158{
159 Obituary ob;
160 ob.recipient = recipient;
161 ob.cookie = cookie;
162 ob.flags = flags;
163
164 LOG_ALWAYS_FATAL_IF(recipient == NULL,
165 "linkToDeath(): recipient must be non-NULL");
166
167 {
168 AutoMutex _l(mLock);
169
170 if (!mObitsSent) {
171 if (!mObituaries) {
172 mObituaries = new Vector<Obituary>;
173 if (!mObituaries) {
174 return NO_MEMORY;
175 }
176 LOGV("Requesting death notification: %p handle %d\n", this, mHandle);
177 getWeakRefs()->incWeak(this);
178 IPCThreadState* self = IPCThreadState::self();
179 self->requestDeathNotification(mHandle, this);
180 self->flushCommands();
181 }
182 ssize_t res = mObituaries->add(ob);
183 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
184 }
185 }
186
187 return DEAD_OBJECT;
188}
189
190status_t BpBinder::unlinkToDeath(
191 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
192 wp<DeathRecipient>* outRecipient)
193{
194 AutoMutex _l(mLock);
195
196 if (mObitsSent) {
197 return DEAD_OBJECT;
198 }
199
200 const size_t N = mObituaries ? mObituaries->size() : 0;
201 for (size_t i=0; i<N; i++) {
202 const Obituary& obit = mObituaries->itemAt(i);
203 if ((obit.recipient == recipient
204 || (recipient == NULL && obit.cookie == cookie))
205 && obit.flags == flags) {
206 const uint32_t allFlags = obit.flags|flags;
207 if (outRecipient != NULL) {
208 *outRecipient = mObituaries->itemAt(i).recipient;
209 }
210 mObituaries->removeAt(i);
211 if (mObituaries->size() == 0) {
212 LOGV("Clearing death notification: %p handle %d\n", this, mHandle);
213 IPCThreadState* self = IPCThreadState::self();
214 self->clearDeathNotification(mHandle, this);
215 self->flushCommands();
216 delete mObituaries;
217 mObituaries = NULL;
218 }
219 return NO_ERROR;
220 }
221 }
222
223 return NAME_NOT_FOUND;
224}
225
226void BpBinder::sendObituary()
227{
228 LOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
229 this, mHandle, mObitsSent ? "true" : "false");
230
231 mAlive = 0;
232 if (mObitsSent) return;
233
234 mLock.lock();
235 Vector<Obituary>* obits = mObituaries;
236 if(obits != NULL) {
237 LOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
238 IPCThreadState* self = IPCThreadState::self();
239 self->clearDeathNotification(mHandle, this);
240 self->flushCommands();
241 mObituaries = NULL;
242 }
243 mObitsSent = 1;
244 mLock.unlock();
245
246 LOGV("Reporting death of proxy %p for %d recipients\n",
247 this, obits ? obits->size() : 0);
248
249 if (obits != NULL) {
250 const size_t N = obits->size();
251 for (size_t i=0; i<N; i++) {
252 reportOneDeath(obits->itemAt(i));
253 }
254
255 delete obits;
256 }
257}
258
259void BpBinder::reportOneDeath(const Obituary& obit)
260{
261 sp<DeathRecipient> recipient = obit.recipient.promote();
262 LOGV("Reporting death to recipient: %p\n", recipient.get());
263 if (recipient == NULL) return;
264
265 recipient->binderDied(this);
266}
267
268
269void BpBinder::attachObject(
270 const void* objectID, void* object, void* cleanupCookie,
271 object_cleanup_func func)
272{
273 AutoMutex _l(mLock);
274 LOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
275 mObjects.attach(objectID, object, cleanupCookie, func);
276}
277
278void* BpBinder::findObject(const void* objectID) const
279{
280 AutoMutex _l(mLock);
281 return mObjects.find(objectID);
282}
283
284void BpBinder::detachObject(const void* objectID)
285{
286 AutoMutex _l(mLock);
287 mObjects.detach(objectID);
288}
289
290BpBinder* BpBinder::remoteBinder()
291{
292 return this;
293}
294
295BpBinder::~BpBinder()
296{
297 LOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
298
299 IPCThreadState* ipc = IPCThreadState::self();
300
301 mLock.lock();
302 Vector<Obituary>* obits = mObituaries;
303 if(obits != NULL) {
304 if (ipc) ipc->clearDeathNotification(mHandle, this);
305 mObituaries = NULL;
306 }
307 mLock.unlock();
308
309 if (obits != NULL) {
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 }
315
316 if (ipc) {
317 ipc->expungeHandle(mHandle, this);
318 ipc->decWeakHandle(mHandle);
319 }
320}
321
322void BpBinder::onFirstRef()
323{
324 LOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
325 IPCThreadState* ipc = IPCThreadState::self();
326 if (ipc) ipc->incStrongHandle(mHandle);
327}
328
329void BpBinder::onLastStrongRef(const void* id)
330{
331 LOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
332 IF_LOGV() {
333 printRefs();
334 }
335 IPCThreadState* ipc = IPCThreadState::self();
336 if (ipc) ipc->decStrongHandle(mHandle);
337}
338
339bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
340{
341 LOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
342 IPCThreadState* ipc = IPCThreadState::self();
343 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
344}
345
346// ---------------------------------------------------------------------------
347
348}; // namespace android