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