blob: e39093d52e62852518ecafccf8e4c4b70db660bd [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
Bailey Forreste20d6f42015-08-18 17:15:10 -070019#include <atomic>
Dianne Hackborn86a50a62012-05-08 18:54:22 -070020#include <utils/misc.h>
Mathias Agopian16475702009-05-19 19:08:10 -070021#include <binder/BpBinder.h>
22#include <binder/IInterface.h>
23#include <binder/Parcel.h>
Mathias Agopian7922fa22009-05-18 15:08:03 -070024
25#include <stdio.h>
26
27namespace android {
28
29// ---------------------------------------------------------------------------
30
Mathias Agopiana6286c32009-05-22 19:00:22 -070031IBinder::IBinder()
32 : RefBase()
33{
34}
35
36IBinder::~IBinder()
37{
38}
39
40// ---------------------------------------------------------------------------
41
Colin Crossf0487982014-02-05 17:42:44 -080042sp<IInterface> IBinder::queryLocalInterface(const String16& /*descriptor*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -070043{
44 return NULL;
45}
46
47BBinder* IBinder::localBinder()
48{
49 return NULL;
50}
51
52BpBinder* IBinder::remoteBinder()
53{
54 return NULL;
55}
56
57bool IBinder::checkSubclass(const void* /*subclassID*/) const
58{
59 return false;
60}
61
62// ---------------------------------------------------------------------------
63
64class BBinder::Extras
65{
66public:
67 Mutex mLock;
68 BpBinder::ObjectManager mObjects;
69};
70
71// ---------------------------------------------------------------------------
72
Bailey Forreste20d6f42015-08-18 17:15:10 -070073BBinder::BBinder() : mExtras(nullptr)
Mathias Agopian7922fa22009-05-18 15:08:03 -070074{
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;
Steve Blockd8e19162012-01-05 23:22:43 +000092 ALOGW("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(
Colin Crossf0487982014-02-05 17:42:44 -0800119 const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
120 uint32_t /*flags*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700121{
122 return INVALID_OPERATION;
123}
124
125status_t BBinder::unlinkToDeath(
Colin Crossf0487982014-02-05 17:42:44 -0800126 const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
127 uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700128{
129 return INVALID_OPERATION;
130}
131
Colin Crossf0487982014-02-05 17:42:44 -0800132 status_t BBinder::dump(int /*fd*/, const Vector<String16>& /*args*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700133{
134 return NO_ERROR;
135}
136
137void BBinder::attachObject(
138 const void* objectID, void* object, void* cleanupCookie,
139 object_cleanup_func func)
140{
Bailey Forreste20d6f42015-08-18 17:15:10 -0700141 Extras* e = mExtras.load(std::memory_order_acquire);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700142
143 if (!e) {
144 e = new Extras;
Bailey Forreste20d6f42015-08-18 17:15:10 -0700145 Extras* expected = nullptr;
146 if (!mExtras.compare_exchange_strong(expected, e,
147 std::memory_order_release,
148 std::memory_order_acquire)) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700149 delete e;
Bailey Forreste20d6f42015-08-18 17:15:10 -0700150 e = expected; // Filled in by CAS
Mathias Agopian7922fa22009-05-18 15:08:03 -0700151 }
152 if (e == 0) return; // out of memory
153 }
154
155 AutoMutex _l(e->mLock);
156 e->mObjects.attach(objectID, object, cleanupCookie, func);
157}
158
159void* BBinder::findObject(const void* objectID) const
160{
Bailey Forreste20d6f42015-08-18 17:15:10 -0700161 Extras* e = mExtras.load(std::memory_order_acquire);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700162 if (!e) return NULL;
163
164 AutoMutex _l(e->mLock);
165 return e->mObjects.find(objectID);
166}
167
168void BBinder::detachObject(const void* objectID)
169{
Bailey Forreste20d6f42015-08-18 17:15:10 -0700170 Extras* e = mExtras.load(std::memory_order_acquire);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700171 if (!e) return;
172
173 AutoMutex _l(e->mLock);
174 e->mObjects.detach(objectID);
175}
176
177BBinder* BBinder::localBinder()
178{
179 return this;
180}
181
182BBinder::~BBinder()
183{
Bailey Forreste20d6f42015-08-18 17:15:10 -0700184 Extras* e = mExtras.load(std::memory_order_relaxed);
Hans Boehm99c620a2014-08-12 22:56:00 +0000185 if (e) delete e;
Mathias Agopian7922fa22009-05-18 15:08:03 -0700186}
187
188
189status_t BBinder::onTransact(
Colin Crossf0487982014-02-05 17:42:44 -0800190 uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700191{
192 switch (code) {
193 case INTERFACE_TRANSACTION:
194 reply->writeString16(getInterfaceDescriptor());
195 return NO_ERROR;
196
197 case DUMP_TRANSACTION: {
198 int fd = data.readFileDescriptor();
199 int argc = data.readInt32();
200 Vector<String16> args;
201 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
202 args.add(data.readString16());
203 }
204 return dump(fd, args);
205 }
Dianne Hackborn86a50a62012-05-08 18:54:22 -0700206
207 case SYSPROPS_TRANSACTION: {
208 report_sysprop_change();
209 return NO_ERROR;
210 }
211
Mathias Agopian7922fa22009-05-18 15:08:03 -0700212 default:
213 return UNKNOWN_TRANSACTION;
214 }
215}
216
217// ---------------------------------------------------------------------------
218
219enum {
220 // This is used to transfer ownership of the remote binder from
221 // the BpRefBase object holding it (when it is constructed), to the
222 // owner of the BpRefBase object when it first acquires that BpRefBase.
223 kRemoteAcquired = 0x00000001
224};
225
226BpRefBase::BpRefBase(const sp<IBinder>& o)
227 : mRemote(o.get()), mRefs(NULL), mState(0)
228{
229 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
230
231 if (mRemote) {
232 mRemote->incStrong(this); // Removed on first IncStrong().
233 mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
234 }
235}
236
237BpRefBase::~BpRefBase()
238{
239 if (mRemote) {
Bailey Forreste20d6f42015-08-18 17:15:10 -0700240 if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
Mathias Agopian7922fa22009-05-18 15:08:03 -0700241 mRemote->decStrong(this);
242 }
243 mRefs->decWeak(this);
244 }
245}
246
247void BpRefBase::onFirstRef()
248{
Bailey Forreste20d6f42015-08-18 17:15:10 -0700249 mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
Mathias Agopian7922fa22009-05-18 15:08:03 -0700250}
251
Colin Crossf0487982014-02-05 17:42:44 -0800252void BpRefBase::onLastStrongRef(const void* /*id*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700253{
254 if (mRemote) {
255 mRemote->decStrong(this);
256 }
257}
258
Colin Crossf0487982014-02-05 17:42:44 -0800259bool BpRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
Mathias Agopian7922fa22009-05-18 15:08:03 -0700260{
261 return mRemote ? mRefs->attemptIncStrong(this) : false;
262}
263
264// ---------------------------------------------------------------------------
265
266}; // namespace android