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