OSDN Git Service

Merge "MediaResourceMonitor: Change argument type from string to int" into nyc-dev
[android-x86/frameworks-native.git] / libs / binder / BpBinder.cpp
1 /*
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 <binder/BpBinder.h>
21
22 #include <binder/IPCThreadState.h>
23 #include <binder/IResultReceiver.h>
24 #include <utils/Log.h>
25
26 #include <stdio.h>
27
28 //#undef ALOGV
29 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
30
31 namespace android {
32
33 // ---------------------------------------------------------------------------
34
35 BpBinder::ObjectManager::ObjectManager()
36 {
37 }
38
39 BpBinder::ObjectManager::~ObjectManager()
40 {
41     kill();
42 }
43
44 void 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) {
54         ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
55                 objectID, this,  object);
56         return;
57     }
58
59     mObjects.add(objectID, e);
60 }
61
62 void* 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
69 void BpBinder::ObjectManager::detach(const void* objectID)
70 {
71     mObjects.removeItem(objectID);
72 }
73
74 void BpBinder::ObjectManager::kill()
75 {
76     const size_t N = mObjects.size();
77     ALOGV("Killing %zu objects in manager %p", N, this);
78     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
90 BpBinder::BpBinder(int32_t handle)
91     : mHandle(handle)
92     , mAlive(1)
93     , mObitsSent(0)
94     , mObituaries(NULL)
95 {
96     ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
97
98     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
99     IPCThreadState::self()->incWeakHandle(handle);
100 }
101
102 bool BpBinder::isDescriptorCached() const {
103     Mutex::Autolock _l(mLock);
104     return mDescriptorCache.size() ? true : false;
105 }
106
107 const String16& BpBinder::getInterfaceDescriptor() const
108 {
109     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         }
122     }
123
124     // we're returning a reference to a non-static object here. Usually this
125     // is not something smart to do, however, with binder objects it is
126     // (usually) safe because they are reference-counted.
127
128     return mDescriptorCache;
129 }
130
131 bool BpBinder::isBinderAlive() const
132 {
133     return mAlive != 0;
134 }
135
136 status_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
146 status_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
160 status_t BpBinder::transact(
161     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
162 {
163     // Once a binder has died, it will never come back to life.
164     if (mAlive) {
165         status_t status = IPCThreadState::self()->transact(
166             mHandle, code, data, reply, flags);
167         if (status == DEAD_OBJECT) mAlive = 0;
168         return status;
169     }
170
171     return DEAD_OBJECT;
172 }
173
174 status_t BpBinder::linkToDeath(
175     const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
176 {
177     Obituary ob;
178     ob.recipient = recipient;
179     ob.cookie = cookie;
180     ob.flags = flags;
181
182     LOG_ALWAYS_FATAL_IF(recipient == NULL,
183                         "linkToDeath(): recipient must be non-NULL");
184
185     {
186         AutoMutex _l(mLock);
187
188         if (!mObitsSent) {
189             if (!mObituaries) {
190                 mObituaries = new Vector<Obituary>;
191                 if (!mObituaries) {
192                     return NO_MEMORY;
193                 }
194                 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
195                 getWeakRefs()->incWeak(this);
196                 IPCThreadState* self = IPCThreadState::self();
197                 self->requestDeathNotification(mHandle, this);
198                 self->flushCommands();
199             }
200             ssize_t res = mObituaries->add(ob);
201             return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
202         }
203     }
204
205     return DEAD_OBJECT;
206 }
207
208 status_t BpBinder::unlinkToDeath(
209     const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
210     wp<DeathRecipient>* outRecipient)
211 {
212     AutoMutex _l(mLock);
213
214     if (mObitsSent) {
215         return DEAD_OBJECT;
216     }
217
218     const size_t N = mObituaries ? mObituaries->size() : 0;
219     for (size_t i=0; i<N; i++) {
220         const Obituary& obit = mObituaries->itemAt(i);
221         if ((obit.recipient == recipient
222                     || (recipient == NULL && obit.cookie == cookie))
223                 && obit.flags == flags) {
224             if (outRecipient != NULL) {
225                 *outRecipient = mObituaries->itemAt(i).recipient;
226             }
227             mObituaries->removeAt(i);
228             if (mObituaries->size() == 0) {
229                 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
230                 IPCThreadState* self = IPCThreadState::self();
231                 self->clearDeathNotification(mHandle, this);
232                 self->flushCommands();
233                 delete mObituaries;
234                 mObituaries = NULL;
235             }
236             return NO_ERROR;
237         }
238     }
239
240     return NAME_NOT_FOUND;
241 }
242
243 void BpBinder::sendObituary()
244 {
245     ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
246         this, mHandle, mObitsSent ? "true" : "false");
247
248     mAlive = 0;
249     if (mObitsSent) return;
250
251     mLock.lock();
252     Vector<Obituary>* obits = mObituaries;
253     if(obits != NULL) {
254         ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
255         IPCThreadState* self = IPCThreadState::self();
256         self->clearDeathNotification(mHandle, this);
257         self->flushCommands();
258         mObituaries = NULL;
259     }
260     mObitsSent = 1;
261     mLock.unlock();
262
263     ALOGV("Reporting death of proxy %p for %zu recipients\n",
264         this, obits ? obits->size() : 0U);
265
266     if (obits != NULL) {
267         const size_t N = obits->size();
268         for (size_t i=0; i<N; i++) {
269             reportOneDeath(obits->itemAt(i));
270         }
271
272         delete obits;
273     }
274 }
275
276 void BpBinder::reportOneDeath(const Obituary& obit)
277 {
278     sp<DeathRecipient> recipient = obit.recipient.promote();
279     ALOGV("Reporting death to recipient: %p\n", recipient.get());
280     if (recipient == NULL) return;
281
282     recipient->binderDied(this);
283 }
284
285
286 void BpBinder::attachObject(
287     const void* objectID, void* object, void* cleanupCookie,
288     object_cleanup_func func)
289 {
290     AutoMutex _l(mLock);
291     ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
292     mObjects.attach(objectID, object, cleanupCookie, func);
293 }
294
295 void* BpBinder::findObject(const void* objectID) const
296 {
297     AutoMutex _l(mLock);
298     return mObjects.find(objectID);
299 }
300
301 void BpBinder::detachObject(const void* objectID)
302 {
303     AutoMutex _l(mLock);
304     mObjects.detach(objectID);
305 }
306
307 BpBinder* BpBinder::remoteBinder()
308 {
309     return this;
310 }
311
312 BpBinder::~BpBinder()
313 {
314     ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
315
316     IPCThreadState* ipc = IPCThreadState::self();
317
318     mLock.lock();
319     Vector<Obituary>* obits = mObituaries;
320     if(obits != NULL) {
321         if (ipc) ipc->clearDeathNotification(mHandle, this);
322         mObituaries = NULL;
323     }
324     mLock.unlock();
325
326     if (obits != NULL) {
327         // XXX Should we tell any remaining DeathRecipient
328         // objects that the last strong ref has gone away, so they
329         // are no longer linked?
330         delete obits;
331     }
332
333     if (ipc) {
334         ipc->expungeHandle(mHandle, this);
335         ipc->decWeakHandle(mHandle);
336     }
337 }
338
339 void BpBinder::onFirstRef()
340 {
341     ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
342     IPCThreadState* ipc = IPCThreadState::self();
343     if (ipc) ipc->incStrongHandle(mHandle);
344 }
345
346 void BpBinder::onLastStrongRef(const void* /*id*/)
347 {
348     ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
349     IF_ALOGV() {
350         printRefs();
351     }
352     IPCThreadState* ipc = IPCThreadState::self();
353     if (ipc) ipc->decStrongHandle(mHandle);
354 }
355
356 bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
357 {
358     ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
359     IPCThreadState* ipc = IPCThreadState::self();
360     return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
361 }
362
363 // ---------------------------------------------------------------------------
364
365 }; // namespace android