• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <binder/Binder.h>
18 
19 #include <atomic>
20 #include <utils/misc.h>
21 #include <binder/BpBinder.h>
22 #include <binder/IInterface.h>
23 #include <binder/IResultReceiver.h>
24 #include <binder/IShellCallback.h>
25 #include <binder/Parcel.h>
26 
27 #include <stdio.h>
28 
29 namespace android {
30 
31 // ---------------------------------------------------------------------------
32 
IBinder()33 IBinder::IBinder()
34     : RefBase()
35 {
36 }
37 
~IBinder()38 IBinder::~IBinder()
39 {
40 }
41 
42 // ---------------------------------------------------------------------------
43 
queryLocalInterface(const String16 &)44 sp<IInterface>  IBinder::queryLocalInterface(const String16& /*descriptor*/)
45 {
46     return nullptr;
47 }
48 
localBinder()49 BBinder* IBinder::localBinder()
50 {
51     return nullptr;
52 }
53 
remoteBinder()54 BpBinder* IBinder::remoteBinder()
55 {
56     return nullptr;
57 }
58 
checkSubclass(const void *) const59 bool IBinder::checkSubclass(const void* /*subclassID*/) const
60 {
61     return false;
62 }
63 
64 
shellCommand(const sp<IBinder> & target,int in,int out,int err,Vector<String16> & args,const sp<IShellCallback> & callback,const sp<IResultReceiver> & resultReceiver)65 status_t IBinder::shellCommand(const sp<IBinder>& target, int in, int out, int err,
66     Vector<String16>& args, const sp<IShellCallback>& callback,
67     const sp<IResultReceiver>& resultReceiver)
68 {
69     Parcel send;
70     Parcel reply;
71     send.writeFileDescriptor(in);
72     send.writeFileDescriptor(out);
73     send.writeFileDescriptor(err);
74     const size_t numArgs = args.size();
75     send.writeInt32(numArgs);
76     for (size_t i = 0; i < numArgs; i++) {
77         send.writeString16(args[i]);
78     }
79     send.writeStrongBinder(callback != nullptr ? IInterface::asBinder(callback) : nullptr);
80     send.writeStrongBinder(resultReceiver != nullptr ? IInterface::asBinder(resultReceiver) : nullptr);
81     return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
82 }
83 
84 // ---------------------------------------------------------------------------
85 
86 class BBinder::Extras
87 {
88 public:
89     // unlocked objects
90     bool mRequestingSid = false;
91 
92     // for below objects
93     Mutex mLock;
94     BpBinder::ObjectManager mObjects;
95 };
96 
97 // ---------------------------------------------------------------------------
98 
BBinder()99 BBinder::BBinder() : mExtras(nullptr)
100 {
101 }
102 
isBinderAlive() const103 bool BBinder::isBinderAlive() const
104 {
105     return true;
106 }
107 
pingBinder()108 status_t BBinder::pingBinder()
109 {
110     return NO_ERROR;
111 }
112 
getInterfaceDescriptor() const113 const String16& BBinder::getInterfaceDescriptor() const
114 {
115     // This is a local static rather than a global static,
116     // to avoid static initializer ordering issues.
117     static String16 sEmptyDescriptor;
118     ALOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
119     return sEmptyDescriptor;
120 }
121 
122 // NOLINTNEXTLINE(google-default-arguments)
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)123 status_t BBinder::transact(
124     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
125 {
126     data.setDataPosition(0);
127 
128     status_t err = NO_ERROR;
129     switch (code) {
130         case PING_TRANSACTION:
131             reply->writeInt32(pingBinder());
132             break;
133         default:
134             err = onTransact(code, data, reply, flags);
135             break;
136     }
137 
138     if (reply != nullptr) {
139         reply->setDataPosition(0);
140     }
141 
142     return err;
143 }
144 
145 // NOLINTNEXTLINE(google-default-arguments)
linkToDeath(const sp<DeathRecipient> &,void *,uint32_t)146 status_t BBinder::linkToDeath(
147     const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
148     uint32_t /*flags*/)
149 {
150     return INVALID_OPERATION;
151 }
152 
153 // NOLINTNEXTLINE(google-default-arguments)
unlinkToDeath(const wp<DeathRecipient> &,void *,uint32_t,wp<DeathRecipient> *)154 status_t BBinder::unlinkToDeath(
155     const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
156     uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
157 {
158     return INVALID_OPERATION;
159 }
160 
dump(int,const Vector<String16> &)161 status_t BBinder::dump(int /*fd*/, const Vector<String16>& /*args*/)
162 {
163     return NO_ERROR;
164 }
165 
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)166 void BBinder::attachObject(
167     const void* objectID, void* object, void* cleanupCookie,
168     object_cleanup_func func)
169 {
170     Extras* e = getOrCreateExtras();
171     if (!e) return; // out of memory
172 
173     AutoMutex _l(e->mLock);
174     e->mObjects.attach(objectID, object, cleanupCookie, func);
175 }
176 
findObject(const void * objectID) const177 void* BBinder::findObject(const void* objectID) const
178 {
179     Extras* e = mExtras.load(std::memory_order_acquire);
180     if (!e) return nullptr;
181 
182     AutoMutex _l(e->mLock);
183     return e->mObjects.find(objectID);
184 }
185 
detachObject(const void * objectID)186 void BBinder::detachObject(const void* objectID)
187 {
188     Extras* e = mExtras.load(std::memory_order_acquire);
189     if (!e) return;
190 
191     AutoMutex _l(e->mLock);
192     e->mObjects.detach(objectID);
193 }
194 
localBinder()195 BBinder* BBinder::localBinder()
196 {
197     return this;
198 }
199 
isRequestingSid()200 bool BBinder::isRequestingSid()
201 {
202     Extras* e = mExtras.load(std::memory_order_acquire);
203 
204     return e && e->mRequestingSid;
205 }
206 
setRequestingSid(bool requestingSid)207 void BBinder::setRequestingSid(bool requestingSid)
208 {
209     Extras* e = mExtras.load(std::memory_order_acquire);
210 
211     if (!e) {
212         // default is false. Most things don't need sids, so avoiding allocations when possible.
213         if (!requestingSid) {
214             return;
215         }
216 
217         e = getOrCreateExtras();
218         if (!e) return; // out of memory
219     }
220 
221     e->mRequestingSid = requestingSid;
222 }
223 
~BBinder()224 BBinder::~BBinder()
225 {
226     Extras* e = mExtras.load(std::memory_order_relaxed);
227     if (e) delete e;
228 }
229 
230 
231 // NOLINTNEXTLINE(google-default-arguments)
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t)232 status_t BBinder::onTransact(
233     uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
234 {
235     switch (code) {
236         case INTERFACE_TRANSACTION:
237             reply->writeString16(getInterfaceDescriptor());
238             return NO_ERROR;
239 
240         case DUMP_TRANSACTION: {
241             int fd = data.readFileDescriptor();
242             int argc = data.readInt32();
243             Vector<String16> args;
244             for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
245                args.add(data.readString16());
246             }
247             return dump(fd, args);
248         }
249 
250         case SHELL_COMMAND_TRANSACTION: {
251             int in = data.readFileDescriptor();
252             int out = data.readFileDescriptor();
253             int err = data.readFileDescriptor();
254             int argc = data.readInt32();
255             Vector<String16> args;
256             for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
257                args.add(data.readString16());
258             }
259             sp<IShellCallback> shellCallback = IShellCallback::asInterface(
260                     data.readStrongBinder());
261             sp<IResultReceiver> resultReceiver = IResultReceiver::asInterface(
262                     data.readStrongBinder());
263 
264             // XXX can't add virtuals until binaries are updated.
265             //return shellCommand(in, out, err, args, resultReceiver);
266             (void)in;
267             (void)out;
268             (void)err;
269 
270             if (resultReceiver != nullptr) {
271                 resultReceiver->send(INVALID_OPERATION);
272             }
273 
274             return NO_ERROR;
275         }
276 
277         case SYSPROPS_TRANSACTION: {
278             report_sysprop_change();
279             return NO_ERROR;
280         }
281 
282         default:
283             return UNKNOWN_TRANSACTION;
284     }
285 }
286 
getOrCreateExtras()287 BBinder::Extras* BBinder::getOrCreateExtras()
288 {
289     Extras* e = mExtras.load(std::memory_order_acquire);
290 
291     if (!e) {
292         e = new Extras;
293         Extras* expected = nullptr;
294         if (!mExtras.compare_exchange_strong(expected, e,
295                                              std::memory_order_release,
296                                              std::memory_order_acquire)) {
297             delete e;
298             e = expected;  // Filled in by CAS
299         }
300         if (e == nullptr) return nullptr; // out of memory
301     }
302 
303     return e;
304 }
305 
306 // ---------------------------------------------------------------------------
307 
308 enum {
309     // This is used to transfer ownership of the remote binder from
310     // the BpRefBase object holding it (when it is constructed), to the
311     // owner of the BpRefBase object when it first acquires that BpRefBase.
312     kRemoteAcquired = 0x00000001
313 };
314 
BpRefBase(const sp<IBinder> & o)315 BpRefBase::BpRefBase(const sp<IBinder>& o)
316     : mRemote(o.get()), mRefs(nullptr), mState(0)
317 {
318     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
319 
320     if (mRemote) {
321         mRemote->incStrong(this);           // Removed on first IncStrong().
322         mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
323     }
324 }
325 
~BpRefBase()326 BpRefBase::~BpRefBase()
327 {
328     if (mRemote) {
329         if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
330             mRemote->decStrong(this);
331         }
332         mRefs->decWeak(this);
333     }
334 }
335 
onFirstRef()336 void BpRefBase::onFirstRef()
337 {
338     mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
339 }
340 
onLastStrongRef(const void *)341 void BpRefBase::onLastStrongRef(const void* /*id*/)
342 {
343     if (mRemote) {
344         mRemote->decStrong(this);
345     }
346 }
347 
onIncStrongAttempted(uint32_t,const void *)348 bool BpRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
349 {
350     return mRemote ? mRefs->attemptIncStrong(this) : false;
351 }
352 
353 // ---------------------------------------------------------------------------
354 
355 }; // namespace android
356