• Home
  • History
  • Annotate
  • 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 "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