blob: 9945f9188f52fabd8e13d95fa642ddd539333117 [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
Mathias Agopian16475702009-05-19 19:08:10 -070017#include <binder/Binder.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070018
19#include <utils/Atomic.h>
Mathias Agopian16475702009-05-19 19:08:10 -070020#include <binder/BpBinder.h>
21#include <binder/IInterface.h>
22#include <binder/Parcel.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070023
24#include <stdio.h>
25
26namespace android {
27
28// ---------------------------------------------------------------------------
29
Mathias Agopiana6286c32009-05-22 19:00:22 -070030IBinder::IBinder()
31 : RefBase()
32{
33}
34
35IBinder::~IBinder()
36{
37}
38
39// ---------------------------------------------------------------------------
40
Mathias Agopian7922fa22009-05-18 15:08:03 -070041sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor)
42{
43 return NULL;
44}
45
46BBinder* IBinder::localBinder()
47{
48 return NULL;
49}
50
51BpBinder* IBinder::remoteBinder()
52{
53 return NULL;
54}
55
56bool IBinder::checkSubclass(const void* /*subclassID*/) const
57{
58 return false;
59}
60
61// ---------------------------------------------------------------------------
62
63class BBinder::Extras
64{
65public:
66 Mutex mLock;
67 BpBinder::ObjectManager mObjects;
68};
69
70// ---------------------------------------------------------------------------
71
72BBinder::BBinder()
73 : mExtras(NULL)
74{
75}
76
77bool BBinder::isBinderAlive() const
78{
79 return true;
80}
81
82status_t BBinder::pingBinder()
83{
84 return NO_ERROR;
85}
86
Mathias Agopiana6286c32009-05-22 19:00:22 -070087const String16& BBinder::getInterfaceDescriptor() const
Mathias Agopian7922fa22009-05-18 15:08:03 -070088{
Dan Egnor87957f72010-05-06 00:55:09 -070089 // This is a local static rather than a global static,
90 // to avoid static initializer ordering issues.
91 static String16 sEmptyDescriptor;
Mathias Agopian7922fa22009-05-18 15:08:03 -070092 LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
Mathias Agopiana6286c32009-05-22 19:00:22 -070093 return sEmptyDescriptor;
Mathias Agopian7922fa22009-05-18 15:08:03 -070094}
95
96status_t BBinder::transact(
97 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
98{
99 data.setDataPosition(0);
100
101 status_t err = NO_ERROR;
102 switch (code) {
103 case PING_TRANSACTION:
104 reply->writeInt32(pingBinder());
105 break;
106 default:
107 err = onTransact(code, data, reply, flags);
108 break;
109 }
110
111 if (reply != NULL) {
112 reply->setDataPosition(0);
113 }
114
115 return err;
116}
117
118status_t BBinder::linkToDeath(
119 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
120{
121 return INVALID_OPERATION;
122}
123
124status_t BBinder::unlinkToDeath(
125 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
126 wp<DeathRecipient>* outRecipient)
127{
128 return INVALID_OPERATION;
129}
130
131status_t BBinder::dump(int fd, const Vector<String16>& args)
132{
133 return NO_ERROR;
134}
135
136void BBinder::attachObject(
137 const void* objectID, void* object, void* cleanupCookie,
138 object_cleanup_func func)
139{
140 Extras* e = mExtras;
141
142 if (!e) {
143 e = new Extras;
144 if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
145 reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
146 delete e;
147 e = mExtras;
148 }
149 if (e == 0) return; // out of memory
150 }
151
152 AutoMutex _l(e->mLock);
153 e->mObjects.attach(objectID, object, cleanupCookie, func);
154}
155
156void* BBinder::findObject(const void* objectID) const
157{
158 Extras* e = mExtras;
159 if (!e) return NULL;
160
161 AutoMutex _l(e->mLock);
162 return e->mObjects.find(objectID);
163}
164
165void BBinder::detachObject(const void* objectID)
166{
167 Extras* e = mExtras;
168 if (!e) return;
169
170 AutoMutex _l(e->mLock);
171 e->mObjects.detach(objectID);
172}
173
174BBinder* BBinder::localBinder()
175{
176 return this;
177}
178
179BBinder::~BBinder()
180{
181 if (mExtras) delete mExtras;
182}
183
184
185status_t BBinder::onTransact(
186 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
187{
188 switch (code) {
189 case INTERFACE_TRANSACTION:
190 reply->writeString16(getInterfaceDescriptor());
191 return NO_ERROR;
192
193 case DUMP_TRANSACTION: {
194 int fd = data.readFileDescriptor();
195 int argc = data.readInt32();
196 Vector<String16> args;
197 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
198 args.add(data.readString16());
199 }
200 return dump(fd, args);
201 }
202 default:
203 return UNKNOWN_TRANSACTION;
204 }
205}
206
207// ---------------------------------------------------------------------------
208
209enum {
210 // This is used to transfer ownership of the remote binder from
211 // the BpRefBase object holding it (when it is constructed), to the
212 // owner of the BpRefBase object when it first acquires that BpRefBase.
213 kRemoteAcquired = 0x00000001
214};
215
216BpRefBase::BpRefBase(const sp<IBinder>& o)
217 : mRemote(o.get()), mRefs(NULL), mState(0)
218{
219 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
220
221 if (mRemote) {
222 mRemote->incStrong(this); // Removed on first IncStrong().
223 mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
224 }
225}
226
227BpRefBase::~BpRefBase()
228{
229 if (mRemote) {
230 if (!(mState&kRemoteAcquired)) {
231 mRemote->decStrong(this);
232 }
233 mRefs->decWeak(this);
234 }
235}
236
237void BpRefBase::onFirstRef()
238{
239 android_atomic_or(kRemoteAcquired, &mState);
240}
241
242void BpRefBase::onLastStrongRef(const void* id)
243{
244 if (mRemote) {
245 mRemote->decStrong(this);
246 }
247}
248
249bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
250{
251 return mRemote ? mRefs->attemptIncStrong(this) : false;
252}
253
254// ---------------------------------------------------------------------------
255
256}; // namespace android