blob: 0dd762212f0858b6eace8bd4f844b819b2428992 [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
Mathias Agopiana6286c32009-05-22 19:00:22 -070072String16 BBinder::sEmptyDescriptor;
73
Mathias Agopian7922fa22009-05-18 15:08:03 -070074BBinder::BBinder()
75 : mExtras(NULL)
76{
77}
78
79bool BBinder::isBinderAlive() const
80{
81 return true;
82}
83
84status_t BBinder::pingBinder()
85{
86 return NO_ERROR;
87}
88
Mathias Agopiana6286c32009-05-22 19:00:22 -070089const String16& BBinder::getInterfaceDescriptor() const
Mathias Agopian7922fa22009-05-18 15:08:03 -070090{
91 LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
Mathias Agopiana6286c32009-05-22 19:00:22 -070092 return sEmptyDescriptor;
Mathias Agopian7922fa22009-05-18 15:08:03 -070093}
94
95status_t BBinder::transact(
96 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
97{
98 data.setDataPosition(0);
99
100 status_t err = NO_ERROR;
101 switch (code) {
102 case PING_TRANSACTION:
103 reply->writeInt32(pingBinder());
104 break;
105 default:
106 err = onTransact(code, data, reply, flags);
107 break;
108 }
109
110 if (reply != NULL) {
111 reply->setDataPosition(0);
112 }
113
114 return err;
115}
116
117status_t BBinder::linkToDeath(
118 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
119{
120 return INVALID_OPERATION;
121}
122
123status_t BBinder::unlinkToDeath(
124 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
125 wp<DeathRecipient>* outRecipient)
126{
127 return INVALID_OPERATION;
128}
129
130status_t BBinder::dump(int fd, const Vector<String16>& args)
131{
132 return NO_ERROR;
133}
134
135void BBinder::attachObject(
136 const void* objectID, void* object, void* cleanupCookie,
137 object_cleanup_func func)
138{
139 Extras* e = mExtras;
140
141 if (!e) {
142 e = new Extras;
143 if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
144 reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
145 delete e;
146 e = mExtras;
147 }
148 if (e == 0) return; // out of memory
149 }
150
151 AutoMutex _l(e->mLock);
152 e->mObjects.attach(objectID, object, cleanupCookie, func);
153}
154
155void* BBinder::findObject(const void* objectID) const
156{
157 Extras* e = mExtras;
158 if (!e) return NULL;
159
160 AutoMutex _l(e->mLock);
161 return e->mObjects.find(objectID);
162}
163
164void BBinder::detachObject(const void* objectID)
165{
166 Extras* e = mExtras;
167 if (!e) return;
168
169 AutoMutex _l(e->mLock);
170 e->mObjects.detach(objectID);
171}
172
173BBinder* BBinder::localBinder()
174{
175 return this;
176}
177
178BBinder::~BBinder()
179{
180 if (mExtras) delete mExtras;
181}
182
183
184status_t BBinder::onTransact(
185 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
186{
187 switch (code) {
188 case INTERFACE_TRANSACTION:
189 reply->writeString16(getInterfaceDescriptor());
190 return NO_ERROR;
191
192 case DUMP_TRANSACTION: {
193 int fd = data.readFileDescriptor();
194 int argc = data.readInt32();
195 Vector<String16> args;
196 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
197 args.add(data.readString16());
198 }
199 return dump(fd, args);
200 }
201 default:
202 return UNKNOWN_TRANSACTION;
203 }
204}
205
206// ---------------------------------------------------------------------------
207
208enum {
209 // This is used to transfer ownership of the remote binder from
210 // the BpRefBase object holding it (when it is constructed), to the
211 // owner of the BpRefBase object when it first acquires that BpRefBase.
212 kRemoteAcquired = 0x00000001
213};
214
215BpRefBase::BpRefBase(const sp<IBinder>& o)
216 : mRemote(o.get()), mRefs(NULL), mState(0)
217{
218 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
219
220 if (mRemote) {
221 mRemote->incStrong(this); // Removed on first IncStrong().
222 mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
223 }
224}
225
226BpRefBase::~BpRefBase()
227{
228 if (mRemote) {
229 if (!(mState&kRemoteAcquired)) {
230 mRemote->decStrong(this);
231 }
232 mRefs->decWeak(this);
233 }
234}
235
236void BpRefBase::onFirstRef()
237{
238 android_atomic_or(kRemoteAcquired, &mState);
239}
240
241void BpRefBase::onLastStrongRef(const void* id)
242{
243 if (mRemote) {
244 mRemote->decStrong(this);
245 }
246}
247
248bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
249{
250 return mRemote ? mRefs->attemptIncStrong(this) : false;
251}
252
253// ---------------------------------------------------------------------------
254
255}; // namespace android