1 /*
2 * Copyright (C) 2006 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 "JavaBinder"
18 //#define LOG_NDEBUG 0
19
20 #include "android_os_Parcel.h"
21 #include "android_util_Binder.h"
22
23 #include "JNIHelp.h"
24
25 #include <fcntl.h>
26 #include <inttypes.h>
27 #include <stdio.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31
32 #include <android-base/stringprintf.h>
33 #include <binder/IInterface.h>
34 #include <binder/IServiceManager.h>
35 #include <binder/IPCThreadState.h>
36 #include <binder/Parcel.h>
37 #include <binder/ProcessState.h>
38 #include <log/log.h>
39 #include <utils/Atomic.h>
40 #include <utils/KeyedVector.h>
41 #include <utils/List.h>
42 #include <utils/Log.h>
43 #include <utils/String8.h>
44 #include <utils/SystemClock.h>
45 #include <utils/threads.h>
46
47 #include <ScopedUtfChars.h>
48 #include <ScopedLocalRef.h>
49
50 #include "core_jni_helpers.h"
51
52 //#undef ALOGV
53 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
54
55 #define DEBUG_DEATH 0
56 #if DEBUG_DEATH
57 #define LOGDEATH ALOGD
58 #else
59 #define LOGDEATH ALOGV
60 #endif
61
62 using namespace android;
63
64 // ----------------------------------------------------------------------------
65
66 static struct bindernative_offsets_t
67 {
68 // Class state.
69 jclass mClass;
70 jmethodID mExecTransact;
71
72 // Object state.
73 jfieldID mObject;
74
75 } gBinderOffsets;
76
77 // ----------------------------------------------------------------------------
78
79 static struct binderinternal_offsets_t
80 {
81 // Class state.
82 jclass mClass;
83 jmethodID mForceGc;
84
85 } gBinderInternalOffsets;
86
87 // ----------------------------------------------------------------------------
88
89 static struct error_offsets_t
90 {
91 jclass mClass;
92 } gErrorOffsets;
93
94 // ----------------------------------------------------------------------------
95
96 static struct binderproxy_offsets_t
97 {
98 // Class state.
99 jclass mClass;
100 jmethodID mConstructor;
101 jmethodID mSendDeathNotice;
102
103 // Object state.
104 jfieldID mObject;
105 jfieldID mSelf;
106 jfieldID mOrgue;
107
108 } gBinderProxyOffsets;
109
110 static struct class_offsets_t
111 {
112 jmethodID mGetName;
113 } gClassOffsets;
114
115 // ----------------------------------------------------------------------------
116
117 static struct log_offsets_t
118 {
119 // Class state.
120 jclass mClass;
121 jmethodID mLogE;
122 } gLogOffsets;
123
124 static struct parcel_file_descriptor_offsets_t
125 {
126 jclass mClass;
127 jmethodID mConstructor;
128 } gParcelFileDescriptorOffsets;
129
130 static struct strict_mode_callback_offsets_t
131 {
132 jclass mClass;
133 jmethodID mCallback;
134 } gStrictModeCallbackOffsets;
135
136 // ****************************************************************************
137 // ****************************************************************************
138 // ****************************************************************************
139
140 static volatile int32_t gNumRefsCreated = 0;
141 static volatile int32_t gNumProxyRefs = 0;
142 static volatile int32_t gNumLocalRefs = 0;
143 static volatile int32_t gNumDeathRefs = 0;
144
incRefsCreated(JNIEnv * env)145 static void incRefsCreated(JNIEnv* env)
146 {
147 int old = android_atomic_inc(&gNumRefsCreated);
148 if (old == 200) {
149 android_atomic_and(0, &gNumRefsCreated);
150 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
151 gBinderInternalOffsets.mForceGc);
152 } else {
153 ALOGV("Now have %d binder ops", old);
154 }
155 }
156
jnienv_to_javavm(JNIEnv * env)157 static JavaVM* jnienv_to_javavm(JNIEnv* env)
158 {
159 JavaVM* vm;
160 return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
161 }
162
javavm_to_jnienv(JavaVM * vm)163 static JNIEnv* javavm_to_jnienv(JavaVM* vm)
164 {
165 JNIEnv* env;
166 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
167 }
168
report_exception(JNIEnv * env,jthrowable excep,const char * msg)169 static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
170 {
171 env->ExceptionClear();
172
173 jstring tagstr = env->NewStringUTF(LOG_TAG);
174 jstring msgstr = NULL;
175 if (tagstr != NULL) {
176 msgstr = env->NewStringUTF(msg);
177 }
178
179 if ((tagstr == NULL) || (msgstr == NULL)) {
180 env->ExceptionClear(); /* assume exception (OOM?) was thrown */
181 ALOGE("Unable to call Log.e()\n");
182 ALOGE("%s", msg);
183 goto bail;
184 }
185
186 env->CallStaticIntMethod(
187 gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep);
188 if (env->ExceptionCheck()) {
189 /* attempting to log the failure has failed */
190 ALOGW("Failed trying to log exception, msg='%s'\n", msg);
191 env->ExceptionClear();
192 }
193
194 if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
195 /*
196 * It's an Error: Reraise the exception and ask the runtime to abort.
197 */
198
199 // Try to get the exception string. Sometimes logcat isn't available,
200 // so try to add it to the abort message.
201 std::string exc_msg = "(Unknown exception message)";
202 {
203 ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(excep));
204 jmethodID method_id = env->GetMethodID(exc_class.get(),
205 "toString",
206 "()Ljava/lang/String;");
207 ScopedLocalRef<jstring> jstr(
208 env,
209 reinterpret_cast<jstring>(
210 env->CallObjectMethod(excep, method_id)));
211 env->ExceptionClear(); // Just for good measure.
212 if (jstr.get() != nullptr) {
213 ScopedUtfChars jstr_utf(env, jstr.get());
214 exc_msg = jstr_utf.c_str();
215 }
216 }
217
218 env->Throw(excep);
219 ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
220 env->ExceptionDescribe();
221
222 std::string error_msg = base::StringPrintf(
223 "java.lang.Error thrown during binder transaction: %s",
224 exc_msg.c_str());
225 env->FatalError(error_msg.c_str());
226 }
227
228 bail:
229 /* discard local refs created for us by VM */
230 env->DeleteLocalRef(tagstr);
231 env->DeleteLocalRef(msgstr);
232 }
233
234 class JavaBBinderHolder;
235
236 class JavaBBinder : public BBinder
237 {
238 public:
JavaBBinder(JNIEnv * env,jobject object)239 JavaBBinder(JNIEnv* env, jobject object)
240 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
241 {
242 ALOGV("Creating JavaBBinder %p\n", this);
243 android_atomic_inc(&gNumLocalRefs);
244 incRefsCreated(env);
245 }
246
checkSubclass(const void * subclassID) const247 bool checkSubclass(const void* subclassID) const
248 {
249 return subclassID == &gBinderOffsets;
250 }
251
object() const252 jobject object() const
253 {
254 return mObject;
255 }
256
257 protected:
~JavaBBinder()258 virtual ~JavaBBinder()
259 {
260 ALOGV("Destroying JavaBBinder %p\n", this);
261 android_atomic_dec(&gNumLocalRefs);
262 JNIEnv* env = javavm_to_jnienv(mVM);
263 env->DeleteGlobalRef(mObject);
264 }
265
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags=0)266 virtual status_t onTransact(
267 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
268 {
269 JNIEnv* env = javavm_to_jnienv(mVM);
270
271 ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
272
273 IPCThreadState* thread_state = IPCThreadState::self();
274 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
275
276 //printf("Transact from %p to Java code sending: ", this);
277 //data.print();
278 //printf("\n");
279 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
280 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
281
282 if (env->ExceptionCheck()) {
283 jthrowable excep = env->ExceptionOccurred();
284 report_exception(env, excep,
285 "*** Uncaught remote exception! "
286 "(Exceptions are not yet supported across processes.)");
287 res = JNI_FALSE;
288
289 /* clean up JNI local ref -- we don't return to Java code */
290 env->DeleteLocalRef(excep);
291 }
292
293 // Check if the strict mode state changed while processing the
294 // call. The Binder state will be restored by the underlying
295 // Binder system in IPCThreadState, however we need to take care
296 // of the parallel Java state as well.
297 if (thread_state->getStrictModePolicy() != strict_policy_before) {
298 set_dalvik_blockguard_policy(env, strict_policy_before);
299 }
300
301 if (env->ExceptionCheck()) {
302 jthrowable excep = env->ExceptionOccurred();
303 report_exception(env, excep,
304 "*** Uncaught exception in onBinderStrictModePolicyChange");
305 /* clean up JNI local ref -- we don't return to Java code */
306 env->DeleteLocalRef(excep);
307 }
308
309 // Need to always call through the native implementation of
310 // SYSPROPS_TRANSACTION.
311 if (code == SYSPROPS_TRANSACTION) {
312 BBinder::onTransact(code, data, reply, flags);
313 }
314
315 //aout << "onTransact to Java code; result=" << res << endl
316 // << "Transact from " << this << " to Java code returning "
317 // << reply << ": " << *reply << endl;
318 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
319 }
320
dump(int fd,const Vector<String16> & args)321 virtual status_t dump(int fd, const Vector<String16>& args)
322 {
323 return 0;
324 }
325
326 private:
327 JavaVM* const mVM;
328 jobject const mObject;
329 };
330
331 // ----------------------------------------------------------------------------
332
333 class JavaBBinderHolder : public RefBase
334 {
335 public:
get(JNIEnv * env,jobject obj)336 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
337 {
338 AutoMutex _l(mLock);
339 sp<JavaBBinder> b = mBinder.promote();
340 if (b == NULL) {
341 b = new JavaBBinder(env, obj);
342 mBinder = b;
343 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
344 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
345 }
346
347 return b;
348 }
349
getExisting()350 sp<JavaBBinder> getExisting()
351 {
352 AutoMutex _l(mLock);
353 return mBinder.promote();
354 }
355
356 private:
357 Mutex mLock;
358 wp<JavaBBinder> mBinder;
359 };
360
361 // ----------------------------------------------------------------------------
362
363 // Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
364 // death recipient references passed in through JNI with the permanent corresponding
365 // JavaDeathRecipient objects.
366
367 class JavaDeathRecipient;
368
369 class DeathRecipientList : public RefBase {
370 List< sp<JavaDeathRecipient> > mList;
371 Mutex mLock;
372
373 public:
374 DeathRecipientList();
375 ~DeathRecipientList();
376
377 void add(const sp<JavaDeathRecipient>& recipient);
378 void remove(const sp<JavaDeathRecipient>& recipient);
379 sp<JavaDeathRecipient> find(jobject recipient);
380
381 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
382 };
383
384 // ----------------------------------------------------------------------------
385
386 class JavaDeathRecipient : public IBinder::DeathRecipient
387 {
388 public:
JavaDeathRecipient(JNIEnv * env,jobject object,const sp<DeathRecipientList> & list)389 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
390 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
391 mObjectWeak(NULL), mList(list)
392 {
393 // These objects manage their own lifetimes so are responsible for final bookkeeping.
394 // The list holds a strong reference to this object.
395 LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
396 list->add(this);
397
398 android_atomic_inc(&gNumDeathRefs);
399 incRefsCreated(env);
400 }
401
binderDied(const wp<IBinder> & who)402 void binderDied(const wp<IBinder>& who)
403 {
404 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
405 if (mObject != NULL) {
406 JNIEnv* env = javavm_to_jnienv(mVM);
407
408 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
409 gBinderProxyOffsets.mSendDeathNotice, mObject);
410 if (env->ExceptionCheck()) {
411 jthrowable excep = env->ExceptionOccurred();
412 report_exception(env, excep,
413 "*** Uncaught exception returned from death notification!");
414 }
415
416 // Serialize with our containing DeathRecipientList so that we can't
417 // delete the global ref on mObject while the list is being iterated.
418 sp<DeathRecipientList> list = mList.promote();
419 if (list != NULL) {
420 AutoMutex _l(list->lock());
421
422 // Demote from strong ref to weak after binderDied() has been delivered,
423 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
424 mObjectWeak = env->NewWeakGlobalRef(mObject);
425 env->DeleteGlobalRef(mObject);
426 mObject = NULL;
427 }
428 }
429 }
430
clearReference()431 void clearReference()
432 {
433 sp<DeathRecipientList> list = mList.promote();
434 if (list != NULL) {
435 LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
436 list->remove(this);
437 } else {
438 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
439 }
440 }
441
matches(jobject obj)442 bool matches(jobject obj) {
443 bool result;
444 JNIEnv* env = javavm_to_jnienv(mVM);
445
446 if (mObject != NULL) {
447 result = env->IsSameObject(obj, mObject);
448 } else {
449 jobject me = env->NewLocalRef(mObjectWeak);
450 result = env->IsSameObject(obj, me);
451 env->DeleteLocalRef(me);
452 }
453 return result;
454 }
455
warnIfStillLive()456 void warnIfStillLive() {
457 if (mObject != NULL) {
458 // Okay, something is wrong -- we have a hard reference to a live death
459 // recipient on the VM side, but the list is being torn down.
460 JNIEnv* env = javavm_to_jnienv(mVM);
461 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
462 ScopedLocalRef<jstring> nameRef(env,
463 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
464 ScopedUtfChars nameUtf(env, nameRef.get());
465 if (nameUtf.c_str() != NULL) {
466 ALOGW("BinderProxy is being destroyed but the application did not call "
467 "unlinkToDeath to unlink all of its death recipients beforehand. "
468 "Releasing leaked death recipient: %s", nameUtf.c_str());
469 } else {
470 ALOGW("BinderProxy being destroyed; unable to get DR object name");
471 env->ExceptionClear();
472 }
473 }
474 }
475
476 protected:
~JavaDeathRecipient()477 virtual ~JavaDeathRecipient()
478 {
479 //ALOGI("Removing death ref: recipient=%p\n", mObject);
480 android_atomic_dec(&gNumDeathRefs);
481 JNIEnv* env = javavm_to_jnienv(mVM);
482 if (mObject != NULL) {
483 env->DeleteGlobalRef(mObject);
484 } else {
485 env->DeleteWeakGlobalRef(mObjectWeak);
486 }
487 }
488
489 private:
490 JavaVM* const mVM;
491 jobject mObject;
492 jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied()
493 wp<DeathRecipientList> mList;
494 };
495
496 // ----------------------------------------------------------------------------
497
DeathRecipientList()498 DeathRecipientList::DeathRecipientList() {
499 LOGDEATH("New DRL @ %p", this);
500 }
501
~DeathRecipientList()502 DeathRecipientList::~DeathRecipientList() {
503 LOGDEATH("Destroy DRL @ %p", this);
504 AutoMutex _l(mLock);
505
506 // Should never happen -- the JavaDeathRecipient objects that have added themselves
507 // to the list are holding references on the list object. Only when they are torn
508 // down can the list header be destroyed.
509 if (mList.size() > 0) {
510 List< sp<JavaDeathRecipient> >::iterator iter;
511 for (iter = mList.begin(); iter != mList.end(); iter++) {
512 (*iter)->warnIfStillLive();
513 }
514 }
515 }
516
add(const sp<JavaDeathRecipient> & recipient)517 void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
518 AutoMutex _l(mLock);
519
520 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
521 mList.push_back(recipient);
522 }
523
remove(const sp<JavaDeathRecipient> & recipient)524 void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
525 AutoMutex _l(mLock);
526
527 List< sp<JavaDeathRecipient> >::iterator iter;
528 for (iter = mList.begin(); iter != mList.end(); iter++) {
529 if (*iter == recipient) {
530 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
531 mList.erase(iter);
532 return;
533 }
534 }
535 }
536
find(jobject recipient)537 sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
538 AutoMutex _l(mLock);
539
540 List< sp<JavaDeathRecipient> >::iterator iter;
541 for (iter = mList.begin(); iter != mList.end(); iter++) {
542 if ((*iter)->matches(recipient)) {
543 return *iter;
544 }
545 }
546 return NULL;
547 }
548
lock()549 Mutex& DeathRecipientList::lock() {
550 return mLock;
551 }
552
553 // ----------------------------------------------------------------------------
554
555 namespace android {
556
proxy_cleanup(const void * id,void * obj,void * cleanupCookie)557 static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
558 {
559 android_atomic_dec(&gNumProxyRefs);
560 JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
561 env->DeleteGlobalRef((jobject)obj);
562 }
563
564 static Mutex mProxyLock;
565
javaObjectForIBinder(JNIEnv * env,const sp<IBinder> & val)566 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
567 {
568 if (val == NULL) return NULL;
569
570 if (val->checkSubclass(&gBinderOffsets)) {
571 // One of our own!
572 jobject object = static_cast<JavaBBinder*>(val.get())->object();
573 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
574 return object;
575 }
576
577 // For the rest of the function we will hold this lock, to serialize
578 // looking/creation/destruction of Java proxies for native Binder proxies.
579 AutoMutex _l(mProxyLock);
580
581 // Someone else's... do we know about it?
582 jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
583 if (object != NULL) {
584 jobject res = jniGetReferent(env, object);
585 if (res != NULL) {
586 ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
587 return res;
588 }
589 LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
590 android_atomic_dec(&gNumProxyRefs);
591 val->detachObject(&gBinderProxyOffsets);
592 env->DeleteGlobalRef(object);
593 }
594
595 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
596 if (object != NULL) {
597 LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
598 // The proxy holds a reference to the native object.
599 env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
600 val->incStrong((void*)javaObjectForIBinder);
601
602 // The native object needs to hold a weak reference back to the
603 // proxy, so we can retrieve the same proxy if it is still active.
604 jobject refObject = env->NewGlobalRef(
605 env->GetObjectField(object, gBinderProxyOffsets.mSelf));
606 val->attachObject(&gBinderProxyOffsets, refObject,
607 jnienv_to_javavm(env), proxy_cleanup);
608
609 // Also remember the death recipients registered on this proxy
610 sp<DeathRecipientList> drl = new DeathRecipientList;
611 drl->incStrong((void*)javaObjectForIBinder);
612 env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
613
614 // Note that a new object reference has been created.
615 android_atomic_inc(&gNumProxyRefs);
616 incRefsCreated(env);
617 }
618
619 return object;
620 }
621
ibinderForJavaObject(JNIEnv * env,jobject obj)622 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
623 {
624 if (obj == NULL) return NULL;
625
626 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
627 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
628 env->GetLongField(obj, gBinderOffsets.mObject);
629 return jbh != NULL ? jbh->get(env, obj) : NULL;
630 }
631
632 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
633 return (IBinder*)
634 env->GetLongField(obj, gBinderProxyOffsets.mObject);
635 }
636
637 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
638 return NULL;
639 }
640
newParcelFileDescriptor(JNIEnv * env,jobject fileDesc)641 jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
642 {
643 return env->NewObject(
644 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
645 }
646
set_dalvik_blockguard_policy(JNIEnv * env,jint strict_policy)647 void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
648 {
649 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
650 // to sync our state back to it. See the comments in StrictMode.java.
651 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
652 gStrictModeCallbackOffsets.mCallback,
653 strict_policy);
654 }
655
signalExceptionForError(JNIEnv * env,jobject obj,status_t err,bool canThrowRemoteException,int parcelSize)656 void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
657 bool canThrowRemoteException, int parcelSize)
658 {
659 switch (err) {
660 case UNKNOWN_ERROR:
661 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
662 break;
663 case NO_MEMORY:
664 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
665 break;
666 case INVALID_OPERATION:
667 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
668 break;
669 case BAD_VALUE:
670 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
671 break;
672 case BAD_INDEX:
673 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
674 break;
675 case BAD_TYPE:
676 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
677 break;
678 case NAME_NOT_FOUND:
679 jniThrowException(env, "java/util/NoSuchElementException", NULL);
680 break;
681 case PERMISSION_DENIED:
682 jniThrowException(env, "java/lang/SecurityException", NULL);
683 break;
684 case NOT_ENOUGH_DATA:
685 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
686 break;
687 case NO_INIT:
688 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
689 break;
690 case ALREADY_EXISTS:
691 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
692 break;
693 case DEAD_OBJECT:
694 // DeadObjectException is a checked exception, only throw from certain methods.
695 jniThrowException(env, canThrowRemoteException
696 ? "android/os/DeadObjectException"
697 : "java/lang/RuntimeException", NULL);
698 break;
699 case UNKNOWN_TRANSACTION:
700 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
701 break;
702 case FAILED_TRANSACTION: {
703 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
704 const char* exceptionToThrow;
705 char msg[128];
706 // TransactionTooLargeException is a checked exception, only throw from certain methods.
707 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
708 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
709 // for other reasons also, such as if the transaction is malformed or
710 // refers to an FD that has been closed. We should change the driver
711 // to enable us to distinguish these cases in the future.
712 if (canThrowRemoteException && parcelSize > 200*1024) {
713 // bona fide large payload
714 exceptionToThrow = "android/os/TransactionTooLargeException";
715 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
716 } else {
717 // Heuristic: a payload smaller than this threshold "shouldn't" be too
718 // big, so it's probably some other, more subtle problem. In practice
719 // it seems to always mean that the remote process died while the binder
720 // transaction was already in flight.
721 exceptionToThrow = (canThrowRemoteException)
722 ? "android/os/DeadObjectException"
723 : "java/lang/RuntimeException";
724 snprintf(msg, sizeof(msg)-1,
725 "Transaction failed on small parcel; remote process probably died");
726 }
727 jniThrowException(env, exceptionToThrow, msg);
728 } break;
729 case FDS_NOT_ALLOWED:
730 jniThrowException(env, "java/lang/RuntimeException",
731 "Not allowed to write file descriptors here");
732 break;
733 case UNEXPECTED_NULL:
734 jniThrowNullPointerException(env, NULL);
735 break;
736 case -EBADF:
737 jniThrowException(env, "java/lang/RuntimeException",
738 "Bad file descriptor");
739 break;
740 case -ENFILE:
741 jniThrowException(env, "java/lang/RuntimeException",
742 "File table overflow");
743 break;
744 case -EMFILE:
745 jniThrowException(env, "java/lang/RuntimeException",
746 "Too many open files");
747 break;
748 case -EFBIG:
749 jniThrowException(env, "java/lang/RuntimeException",
750 "File too large");
751 break;
752 case -ENOSPC:
753 jniThrowException(env, "java/lang/RuntimeException",
754 "No space left on device");
755 break;
756 case -ESPIPE:
757 jniThrowException(env, "java/lang/RuntimeException",
758 "Illegal seek");
759 break;
760 case -EROFS:
761 jniThrowException(env, "java/lang/RuntimeException",
762 "Read-only file system");
763 break;
764 case -EMLINK:
765 jniThrowException(env, "java/lang/RuntimeException",
766 "Too many links");
767 break;
768 default:
769 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
770 String8 msg;
771 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
772 // RemoteException is a checked exception, only throw from certain methods.
773 jniThrowException(env, canThrowRemoteException
774 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
775 break;
776 }
777 }
778
779 }
780
781 // ----------------------------------------------------------------------------
782
android_os_Binder_getCallingPid(JNIEnv * env,jobject clazz)783 static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
784 {
785 return IPCThreadState::self()->getCallingPid();
786 }
787
android_os_Binder_getCallingUid(JNIEnv * env,jobject clazz)788 static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
789 {
790 return IPCThreadState::self()->getCallingUid();
791 }
792
android_os_Binder_clearCallingIdentity(JNIEnv * env,jobject clazz)793 static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
794 {
795 return IPCThreadState::self()->clearCallingIdentity();
796 }
797
android_os_Binder_restoreCallingIdentity(JNIEnv * env,jobject clazz,jlong token)798 static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
799 {
800 // XXX temporary sanity check to debug crashes.
801 int uid = (int)(token>>32);
802 if (uid > 0 && uid < 999) {
803 // In Android currently there are no uids in this range.
804 char buf[128];
805 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
806 jniThrowException(env, "java/lang/IllegalStateException", buf);
807 return;
808 }
809 IPCThreadState::self()->restoreCallingIdentity(token);
810 }
811
android_os_Binder_setThreadStrictModePolicy(JNIEnv * env,jobject clazz,jint policyMask)812 static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
813 {
814 IPCThreadState::self()->setStrictModePolicy(policyMask);
815 }
816
android_os_Binder_getThreadStrictModePolicy(JNIEnv * env,jobject clazz)817 static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
818 {
819 return IPCThreadState::self()->getStrictModePolicy();
820 }
821
android_os_Binder_flushPendingCommands(JNIEnv * env,jobject clazz)822 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
823 {
824 IPCThreadState::self()->flushCommands();
825 }
826
android_os_Binder_init(JNIEnv * env,jobject obj)827 static void android_os_Binder_init(JNIEnv* env, jobject obj)
828 {
829 JavaBBinderHolder* jbh = new JavaBBinderHolder();
830 if (jbh == NULL) {
831 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
832 return;
833 }
834 ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
835 jbh->incStrong((void*)android_os_Binder_init);
836 env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
837 }
838
android_os_Binder_destroy(JNIEnv * env,jobject obj)839 static void android_os_Binder_destroy(JNIEnv* env, jobject obj)
840 {
841 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
842 env->GetLongField(obj, gBinderOffsets.mObject);
843 if (jbh != NULL) {
844 env->SetLongField(obj, gBinderOffsets.mObject, 0);
845 ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
846 jbh->decStrong((void*)android_os_Binder_init);
847 } else {
848 // Encountering an uninitialized binder is harmless. All it means is that
849 // the Binder was only partially initialized when its finalizer ran and called
850 // destroy(). The Binder could be partially initialized for several reasons.
851 // For example, a Binder subclass constructor might have thrown an exception before
852 // it could delegate to its superclass's constructor. Consequently init() would
853 // not have been called and the holder pointer would remain NULL.
854 ALOGV("Java Binder %p: ignoring uninitialized binder", obj);
855 }
856 }
857
android_os_Binder_blockUntilThreadAvailable(JNIEnv * env,jobject clazz)858 static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
859 {
860 return IPCThreadState::self()->blockUntilThreadAvailable();
861 }
862
863 // ----------------------------------------------------------------------------
864
865 static const JNINativeMethod gBinderMethods[] = {
866 /* name, signature, funcPtr */
867 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
868 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
869 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
870 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
871 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
872 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
873 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
874 { "init", "()V", (void*)android_os_Binder_init },
875 { "destroy", "()V", (void*)android_os_Binder_destroy },
876 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
877 };
878
879 const char* const kBinderPathName = "android/os/Binder";
880
int_register_android_os_Binder(JNIEnv * env)881 static int int_register_android_os_Binder(JNIEnv* env)
882 {
883 jclass clazz = FindClassOrDie(env, kBinderPathName);
884
885 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
886 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
887 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
888
889 return RegisterMethodsOrDie(
890 env, kBinderPathName,
891 gBinderMethods, NELEM(gBinderMethods));
892 }
893
894 // ****************************************************************************
895 // ****************************************************************************
896 // ****************************************************************************
897
898 namespace android {
899
android_os_Debug_getLocalObjectCount(JNIEnv * env,jobject clazz)900 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
901 {
902 return gNumLocalRefs;
903 }
904
android_os_Debug_getProxyObjectCount(JNIEnv * env,jobject clazz)905 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
906 {
907 return gNumProxyRefs;
908 }
909
android_os_Debug_getDeathObjectCount(JNIEnv * env,jobject clazz)910 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
911 {
912 return gNumDeathRefs;
913 }
914
915 }
916
917 // ****************************************************************************
918 // ****************************************************************************
919 // ****************************************************************************
920
android_os_BinderInternal_getContextObject(JNIEnv * env,jobject clazz)921 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
922 {
923 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
924 return javaObjectForIBinder(env, b);
925 }
926
android_os_BinderInternal_joinThreadPool(JNIEnv * env,jobject clazz)927 static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
928 {
929 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
930 android::IPCThreadState::self()->joinThreadPool();
931 }
932
android_os_BinderInternal_disableBackgroundScheduling(JNIEnv * env,jobject clazz,jboolean disable)933 static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
934 jobject clazz, jboolean disable)
935 {
936 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
937 }
938
android_os_BinderInternal_setMaxThreads(JNIEnv * env,jobject clazz,jint maxThreads)939 static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
940 jobject clazz, jint maxThreads)
941 {
942 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
943 }
944
android_os_BinderInternal_handleGc(JNIEnv * env,jobject clazz)945 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
946 {
947 ALOGV("Gc has executed, clearing binder ops");
948 android_atomic_and(0, &gNumRefsCreated);
949 }
950
951 // ----------------------------------------------------------------------------
952
953 static const JNINativeMethod gBinderInternalMethods[] = {
954 /* name, signature, funcPtr */
955 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
956 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
957 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
958 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
959 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
960 };
961
962 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
963
int_register_android_os_BinderInternal(JNIEnv * env)964 static int int_register_android_os_BinderInternal(JNIEnv* env)
965 {
966 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
967
968 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
969 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
970
971 return RegisterMethodsOrDie(
972 env, kBinderInternalPathName,
973 gBinderInternalMethods, NELEM(gBinderInternalMethods));
974 }
975
976 // ****************************************************************************
977 // ****************************************************************************
978 // ****************************************************************************
979
android_os_BinderProxy_pingBinder(JNIEnv * env,jobject obj)980 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
981 {
982 IBinder* target = (IBinder*)
983 env->GetLongField(obj, gBinderProxyOffsets.mObject);
984 if (target == NULL) {
985 return JNI_FALSE;
986 }
987 status_t err = target->pingBinder();
988 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
989 }
990
android_os_BinderProxy_getInterfaceDescriptor(JNIEnv * env,jobject obj)991 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
992 {
993 IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
994 if (target != NULL) {
995 const String16& desc = target->getInterfaceDescriptor();
996 return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
997 desc.size());
998 }
999 jniThrowException(env, "java/lang/RuntimeException",
1000 "No binder found for object");
1001 return NULL;
1002 }
1003
android_os_BinderProxy_isBinderAlive(JNIEnv * env,jobject obj)1004 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1005 {
1006 IBinder* target = (IBinder*)
1007 env->GetLongField(obj, gBinderProxyOffsets.mObject);
1008 if (target == NULL) {
1009 return JNI_FALSE;
1010 }
1011 bool alive = target->isBinderAlive();
1012 return alive ? JNI_TRUE : JNI_FALSE;
1013 }
1014
getprocname(pid_t pid,char * buf,size_t len)1015 static int getprocname(pid_t pid, char *buf, size_t len) {
1016 char filename[32];
1017 FILE *f;
1018
1019 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
1020 f = fopen(filename, "r");
1021 if (!f) {
1022 *buf = '\0';
1023 return 1;
1024 }
1025 if (!fgets(buf, len, f)) {
1026 *buf = '\0';
1027 fclose(f);
1028 return 2;
1029 }
1030 fclose(f);
1031 return 0;
1032 }
1033
push_eventlog_string(char ** pos,const char * end,const char * str)1034 static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1035 jint len = strlen(str);
1036 int space_needed = 1 + sizeof(len) + len;
1037 if (end - *pos < space_needed) {
1038 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
1039 end - *pos, space_needed);
1040 return false;
1041 }
1042 **pos = EVENT_TYPE_STRING;
1043 (*pos)++;
1044 memcpy(*pos, &len, sizeof(len));
1045 *pos += sizeof(len);
1046 memcpy(*pos, str, len);
1047 *pos += len;
1048 return true;
1049 }
1050
push_eventlog_int(char ** pos,const char * end,jint val)1051 static bool push_eventlog_int(char** pos, const char* end, jint val) {
1052 int space_needed = 1 + sizeof(val);
1053 if (end - *pos < space_needed) {
1054 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d",
1055 end - *pos, space_needed);
1056 return false;
1057 }
1058 **pos = EVENT_TYPE_INT;
1059 (*pos)++;
1060 memcpy(*pos, &val, sizeof(val));
1061 *pos += sizeof(val);
1062 return true;
1063 }
1064
1065 // From frameworks/base/core/java/android/content/EventLogTags.logtags:
1066
1067 static const bool kEnableBinderSample = false;
1068
1069 #define LOGTAG_BINDER_OPERATION 52004
1070
conditionally_log_binder_call(int64_t start_millis,IBinder * target,jint code)1071 static void conditionally_log_binder_call(int64_t start_millis,
1072 IBinder* target, jint code) {
1073 int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1074
1075 int sample_percent;
1076 if (duration_ms >= 500) {
1077 sample_percent = 100;
1078 } else {
1079 sample_percent = 100 * duration_ms / 500;
1080 if (sample_percent == 0) {
1081 return;
1082 }
1083 if (sample_percent < (random() % 100 + 1)) {
1084 return;
1085 }
1086 }
1087
1088 char process_name[40];
1089 getprocname(getpid(), process_name, sizeof(process_name));
1090 String8 desc(target->getInterfaceDescriptor());
1091
1092 char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1093 buf[0] = EVENT_TYPE_LIST;
1094 buf[1] = 5;
1095 char* pos = &buf[2];
1096 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n
1097 if (!push_eventlog_string(&pos, end, desc.string())) return;
1098 if (!push_eventlog_int(&pos, end, code)) return;
1099 if (!push_eventlog_int(&pos, end, duration_ms)) return;
1100 if (!push_eventlog_string(&pos, end, process_name)) return;
1101 if (!push_eventlog_int(&pos, end, sample_percent)) return;
1102 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently.
1103 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1104 }
1105
1106 // We only measure binder call durations to potentially log them if
1107 // we're on the main thread.
should_time_binder_calls()1108 static bool should_time_binder_calls() {
1109 return (getpid() == gettid());
1110 }
1111
android_os_BinderProxy_transact(JNIEnv * env,jobject obj,jint code,jobject dataObj,jobject replyObj,jint flags)1112 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1113 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1114 {
1115 if (dataObj == NULL) {
1116 jniThrowNullPointerException(env, NULL);
1117 return JNI_FALSE;
1118 }
1119
1120 Parcel* data = parcelForJavaObject(env, dataObj);
1121 if (data == NULL) {
1122 return JNI_FALSE;
1123 }
1124 Parcel* reply = parcelForJavaObject(env, replyObj);
1125 if (reply == NULL && replyObj != NULL) {
1126 return JNI_FALSE;
1127 }
1128
1129 IBinder* target = (IBinder*)
1130 env->GetLongField(obj, gBinderProxyOffsets.mObject);
1131 if (target == NULL) {
1132 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1133 return JNI_FALSE;
1134 }
1135
1136 ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
1137 target, obj, code);
1138
1139
1140 bool time_binder_calls;
1141 int64_t start_millis;
1142 if (kEnableBinderSample) {
1143 // Only log the binder call duration for things on the Java-level main thread.
1144 // But if we don't
1145 time_binder_calls = should_time_binder_calls();
1146
1147 if (time_binder_calls) {
1148 start_millis = uptimeMillis();
1149 }
1150 }
1151
1152 //printf("Transact from Java code to %p sending: ", target); data->print();
1153 status_t err = target->transact(code, *data, reply, flags);
1154 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1155
1156 if (kEnableBinderSample) {
1157 if (time_binder_calls) {
1158 conditionally_log_binder_call(start_millis, target, code);
1159 }
1160 }
1161
1162 if (err == NO_ERROR) {
1163 return JNI_TRUE;
1164 } else if (err == UNKNOWN_TRANSACTION) {
1165 return JNI_FALSE;
1166 }
1167
1168 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
1169 return JNI_FALSE;
1170 }
1171
android_os_BinderProxy_linkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1172 static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
1173 jobject recipient, jint flags) // throws RemoteException
1174 {
1175 if (recipient == NULL) {
1176 jniThrowNullPointerException(env, NULL);
1177 return;
1178 }
1179
1180 IBinder* target = (IBinder*)
1181 env->GetLongField(obj, gBinderProxyOffsets.mObject);
1182 if (target == NULL) {
1183 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1184 assert(false);
1185 }
1186
1187 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
1188
1189 if (!target->localBinder()) {
1190 DeathRecipientList* list = (DeathRecipientList*)
1191 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
1192 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
1193 status_t err = target->linkToDeath(jdr, NULL, flags);
1194 if (err != NO_ERROR) {
1195 // Failure adding the death recipient, so clear its reference
1196 // now.
1197 jdr->clearReference();
1198 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1199 }
1200 }
1201 }
1202
android_os_BinderProxy_unlinkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1203 static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1204 jobject recipient, jint flags)
1205 {
1206 jboolean res = JNI_FALSE;
1207 if (recipient == NULL) {
1208 jniThrowNullPointerException(env, NULL);
1209 return res;
1210 }
1211
1212 IBinder* target = (IBinder*)
1213 env->GetLongField(obj, gBinderProxyOffsets.mObject);
1214 if (target == NULL) {
1215 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1216 return JNI_FALSE;
1217 }
1218
1219 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
1220
1221 if (!target->localBinder()) {
1222 status_t err = NAME_NOT_FOUND;
1223
1224 // If we find the matching recipient, proceed to unlink using that
1225 DeathRecipientList* list = (DeathRecipientList*)
1226 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
1227 sp<JavaDeathRecipient> origJDR = list->find(recipient);
1228 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
1229 if (origJDR != NULL) {
1230 wp<IBinder::DeathRecipient> dr;
1231 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1232 if (err == NO_ERROR && dr != NULL) {
1233 sp<IBinder::DeathRecipient> sdr = dr.promote();
1234 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1235 if (jdr != NULL) {
1236 jdr->clearReference();
1237 }
1238 }
1239 }
1240
1241 if (err == NO_ERROR || err == DEAD_OBJECT) {
1242 res = JNI_TRUE;
1243 } else {
1244 jniThrowException(env, "java/util/NoSuchElementException",
1245 "Death link does not exist");
1246 }
1247 }
1248
1249 return res;
1250 }
1251
android_os_BinderProxy_destroy(JNIEnv * env,jobject obj)1252 static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
1253 {
1254 // Don't race with construction/initialization
1255 AutoMutex _l(mProxyLock);
1256
1257 IBinder* b = (IBinder*)
1258 env->GetLongField(obj, gBinderProxyOffsets.mObject);
1259 DeathRecipientList* drl = (DeathRecipientList*)
1260 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
1261
1262 LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
1263 if (b != nullptr) {
1264 env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
1265 env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
1266 drl->decStrong((void*)javaObjectForIBinder);
1267 b->decStrong((void*)javaObjectForIBinder);
1268 }
1269
1270 IPCThreadState::self()->flushCommands();
1271 }
1272
1273 // ----------------------------------------------------------------------------
1274
1275 static const JNINativeMethod gBinderProxyMethods[] = {
1276 /* name, signature, funcPtr */
1277 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1278 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1279 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
1280 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
1281 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1282 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1283 {"destroy", "()V", (void*)android_os_BinderProxy_destroy},
1284 };
1285
1286 const char* const kBinderProxyPathName = "android/os/BinderProxy";
1287
int_register_android_os_BinderProxy(JNIEnv * env)1288 static int int_register_android_os_BinderProxy(JNIEnv* env)
1289 {
1290 jclass clazz = FindClassOrDie(env, "java/lang/Error");
1291 gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1292
1293 clazz = FindClassOrDie(env, kBinderProxyPathName);
1294 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1295 gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
1296 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1297 "(Landroid/os/IBinder$DeathRecipient;)V");
1298
1299 gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
1300 gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
1301 "Ljava/lang/ref/WeakReference;");
1302 gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
1303
1304 clazz = FindClassOrDie(env, "java/lang/Class");
1305 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
1306
1307 return RegisterMethodsOrDie(
1308 env, kBinderProxyPathName,
1309 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1310 }
1311
1312 // ****************************************************************************
1313 // ****************************************************************************
1314 // ****************************************************************************
1315
register_android_os_Binder(JNIEnv * env)1316 int register_android_os_Binder(JNIEnv* env)
1317 {
1318 if (int_register_android_os_Binder(env) < 0)
1319 return -1;
1320 if (int_register_android_os_BinderInternal(env) < 0)
1321 return -1;
1322 if (int_register_android_os_BinderProxy(env) < 0)
1323 return -1;
1324
1325 jclass clazz = FindClassOrDie(env, "android/util/Log");
1326 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1327 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1328 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
1329
1330 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1331 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1332 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1333 "(Ljava/io/FileDescriptor;)V");
1334
1335 clazz = FindClassOrDie(env, "android/os/StrictMode");
1336 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1337 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1338 "onBinderStrictModePolicyChange", "(I)V");
1339
1340 return 0;
1341 }
1342