android_util_Binder.cpp revision 9013ccd9fcf3ac317e122aff08cb27cdac2b95fe
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_util_Binder.h"
21#include "JNIHelp.h"
22
23#include <fcntl.h>
24#include <stdio.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <unistd.h>
28
29#include <utils/Atomic.h>
30#include <binder/IInterface.h>
31#include <binder/IPCThreadState.h>
32#include <utils/Log.h>
33#include <utils/SystemClock.h>
34#include <utils/List.h>
35#include <utils/KeyedVector.h>
36#include <cutils/logger.h>
37#include <binder/Parcel.h>
38#include <binder/ProcessState.h>
39#include <binder/IServiceManager.h>
40#include <utils/threads.h>
41
42#include <android_runtime/AndroidRuntime.h>
43
44//#undef LOGV
45//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
46
47#define DEBUG_DEATH 0
48#if DEBUG_DEATH
49#define LOGDEATH LOGD
50#else
51#define LOGDEATH LOGV
52#endif
53
54using namespace android;
55
56// ----------------------------------------------------------------------------
57
58static struct bindernative_offsets_t
59{
60    // Class state.
61    jclass mClass;
62    jmethodID mExecTransact;
63
64    // Object state.
65    jfieldID mObject;
66
67} gBinderOffsets;
68
69// ----------------------------------------------------------------------------
70
71static struct binderinternal_offsets_t
72{
73    // Class state.
74    jclass mClass;
75    jmethodID mForceGc;
76
77} gBinderInternalOffsets;
78
79// ----------------------------------------------------------------------------
80
81static struct debug_offsets_t
82{
83    // Class state.
84    jclass mClass;
85
86} gDebugOffsets;
87
88// ----------------------------------------------------------------------------
89
90static struct weakreference_offsets_t
91{
92    // Class state.
93    jclass mClass;
94    jmethodID mGet;
95
96} gWeakReferenceOffsets;
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 mConstructor;
110    jmethodID mSendDeathNotice;
111
112    // Object state.
113    jfieldID mObject;
114    jfieldID mSelf;
115    jfieldID mOrgue;
116
117} gBinderProxyOffsets;
118
119// ----------------------------------------------------------------------------
120
121static struct parcel_offsets_t
122{
123    jfieldID mObject;
124    jfieldID mOwnObject;
125} gParcelOffsets;
126
127static struct log_offsets_t
128{
129    // Class state.
130    jclass mClass;
131    jmethodID mLogE;
132} gLogOffsets;
133
134static struct parcel_file_descriptor_offsets_t
135{
136    jclass mClass;
137    jmethodID mConstructor;
138} gParcelFileDescriptorOffsets;
139
140static struct strict_mode_callback_offsets_t
141{
142    jclass mClass;
143    jmethodID mCallback;
144} gStrictModeCallbackOffsets;
145
146// ****************************************************************************
147// ****************************************************************************
148// ****************************************************************************
149
150static volatile int32_t gNumRefsCreated = 0;
151static volatile int32_t gNumProxyRefs = 0;
152static volatile int32_t gNumLocalRefs = 0;
153static volatile int32_t gNumDeathRefs = 0;
154
155static void incRefsCreated(JNIEnv* env)
156{
157    int old = android_atomic_inc(&gNumRefsCreated);
158    if (old == 200) {
159        android_atomic_and(0, &gNumRefsCreated);
160        env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
161                gBinderInternalOffsets.mForceGc);
162    } else {
163        LOGV("Now have %d binder ops", old);
164    }
165}
166
167static JavaVM* jnienv_to_javavm(JNIEnv* env)
168{
169    JavaVM* vm;
170    return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
171}
172
173static JNIEnv* javavm_to_jnienv(JavaVM* vm)
174{
175    JNIEnv* env;
176    return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
177}
178
179static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
180{
181    env->ExceptionClear();
182
183    jstring tagstr = env->NewStringUTF(LOG_TAG);
184    jstring msgstr = env->NewStringUTF(msg);
185
186    if ((tagstr == NULL) || (msgstr == NULL)) {
187        env->ExceptionClear();      /* assume exception (OOM?) was thrown */
188        LOGE("Unable to call Log.e()\n");
189        LOGE("%s", msg);
190        goto bail;
191    }
192
193    env->CallStaticIntMethod(
194        gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep);
195    if (env->ExceptionCheck()) {
196        /* attempting to log the failure has failed */
197        LOGW("Failed trying to log exception, msg='%s'\n", msg);
198        env->ExceptionClear();
199    }
200
201    if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
202        /*
203         * It's an Error: Reraise the exception, detach this thread, and
204         * wait for the fireworks. Die even more blatantly after a minute
205         * if the gentler attempt doesn't do the trick.
206         *
207         * The GetJavaVM function isn't on the "approved" list of JNI calls
208         * that can be made while an exception is pending, so we want to
209         * get the VM ptr, throw the exception, and then detach the thread.
210         */
211        JavaVM* vm = jnienv_to_javavm(env);
212        env->Throw(excep);
213        vm->DetachCurrentThread();
214        sleep(60);
215        LOGE("Forcefully exiting");
216        exit(1);
217        *((int *) 1) = 1;
218    }
219
220bail:
221    /* discard local refs created for us by VM */
222    env->DeleteLocalRef(tagstr);
223    env->DeleteLocalRef(msgstr);
224}
225
226static void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
227{
228    // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
229    // to sync our state back to it.  See the comments in StrictMode.java.
230    env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
231                              gStrictModeCallbackOffsets.mCallback,
232                              strict_policy);
233}
234
235class JavaBBinderHolder;
236
237class JavaBBinder : public BBinder
238{
239public:
240    JavaBBinder(JNIEnv* env, jobject object)
241        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
242    {
243        LOGV("Creating JavaBBinder %p\n", this);
244        android_atomic_inc(&gNumLocalRefs);
245        incRefsCreated(env);
246    }
247
248    bool    checkSubclass(const void* subclassID) const
249    {
250        return subclassID == &gBinderOffsets;
251    }
252
253    jobject object() const
254    {
255        return mObject;
256    }
257
258protected:
259    virtual ~JavaBBinder()
260    {
261        LOGV("Destroying JavaBBinder %p\n", this);
262        android_atomic_dec(&gNumLocalRefs);
263        JNIEnv* env = javavm_to_jnienv(mVM);
264        env->DeleteGlobalRef(mObject);
265    }
266
267    virtual status_t onTransact(
268        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
269    {
270        JNIEnv* env = javavm_to_jnienv(mVM);
271
272        LOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
273
274        IPCThreadState* thread_state = IPCThreadState::self();
275        const int strict_policy_before = thread_state->getStrictModePolicy();
276        thread_state->setLastTransactionBinderFlags(flags);
277
278        //printf("Transact from %p to Java code sending: ", this);
279        //data.print();
280        //printf("\n");
281        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
282            code, (int32_t)&data, (int32_t)reply, flags);
283        jthrowable excep = env->ExceptionOccurred();
284
285        if (excep) {
286            report_exception(env, excep,
287                "*** Uncaught remote exception!  "
288                "(Exceptions are not yet supported across processes.)");
289            res = JNI_FALSE;
290
291            /* clean up JNI local ref -- we don't return to Java code */
292            env->DeleteLocalRef(excep);
293        }
294
295        // Restore the Java binder thread's state if it changed while
296        // processing a call (as it would if the Parcel's header had a
297        // new policy mask and Parcel.enforceInterface() changed
298        // it...)
299        const int strict_policy_after = thread_state->getStrictModePolicy();
300        if (strict_policy_after != strict_policy_before) {
301            // Our thread-local...
302            thread_state->setStrictModePolicy(strict_policy_before);
303            // And the Java-level thread-local...
304            set_dalvik_blockguard_policy(env, strict_policy_before);
305        }
306
307        jthrowable excep2 = env->ExceptionOccurred();
308        if (excep2) {
309            report_exception(env, excep2,
310                "*** Uncaught exception in onBinderStrictModePolicyChange");
311            /* clean up JNI local ref -- we don't return to Java code */
312            env->DeleteLocalRef(excep2);
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
321    virtual status_t dump(int fd, const Vector<String16>& args)
322    {
323        return 0;
324    }
325
326private:
327    JavaVM* const   mVM;
328    jobject const   mObject;
329};
330
331// ----------------------------------------------------------------------------
332
333class JavaBBinderHolder : public RefBase
334{
335public:
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            LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n",
344                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
345        }
346
347        return b;
348    }
349
350    sp<JavaBBinder> getExisting()
351    {
352        AutoMutex _l(mLock);
353        return mBinder.promote();
354    }
355
356private:
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
367class JavaDeathRecipient;
368
369class DeathRecipientList : public RefBase {
370    List< sp<JavaDeathRecipient> > mList;
371    Mutex mLock;
372
373public:
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
382// ----------------------------------------------------------------------------
383
384class JavaDeathRecipient : public IBinder::DeathRecipient
385{
386public:
387    JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
388        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), mList(list)
389    {
390        // These objects manage their own lifetimes so are responsible for final bookkeeping.
391        // The list holds a strong reference to this object.
392        LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
393        list->add(this);
394
395        android_atomic_inc(&gNumDeathRefs);
396        incRefsCreated(env);
397    }
398
399    void binderDied(const wp<IBinder>& who)
400    {
401        JNIEnv* env = javavm_to_jnienv(mVM);
402
403        LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
404
405        env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
406            gBinderProxyOffsets.mSendDeathNotice, mObject);
407        jthrowable excep = env->ExceptionOccurred();
408        if (excep) {
409            report_exception(env, excep,
410                "*** Uncaught exception returned from death notification!");
411        }
412    }
413
414    void clearReference()
415    {
416        sp<DeathRecipientList> list = mList.promote();
417        if (list != NULL) {
418            LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
419            list->remove(this);
420        } else {
421            LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
422        }
423    }
424
425    bool matches(jobject obj) {
426        JNIEnv* env = javavm_to_jnienv(mVM);
427        return env->IsSameObject(obj, mObject);
428    }
429
430protected:
431    virtual ~JavaDeathRecipient()
432    {
433        //LOGI("Removing death ref: recipient=%p\n", mObject);
434        android_atomic_dec(&gNumDeathRefs);
435        JNIEnv* env = javavm_to_jnienv(mVM);
436        env->DeleteGlobalRef(mObject);
437    }
438
439private:
440    JavaVM* const   mVM;
441    jobject const   mObject;
442    wp<DeathRecipientList> mList;
443};
444
445// ----------------------------------------------------------------------------
446
447DeathRecipientList::DeathRecipientList() {
448    LOGDEATH("New DRL @ %p", this);
449}
450
451DeathRecipientList::~DeathRecipientList() {
452    LOGDEATH("Destroy DRL @ %p", this);
453    AutoMutex _l(mLock);
454
455    // Should never happen -- the JavaDeathRecipient objects that have added themselves
456    // to the list are holding references on the list object.  Only when they are torn
457    // down can the list header be destroyed.
458    if (mList.size() > 0) {
459        LOGE("Retiring DRL %p with extant death recipients\n", this);
460    }
461}
462
463void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
464    AutoMutex _l(mLock);
465
466    LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
467    mList.push_back(recipient);
468}
469
470void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
471    AutoMutex _l(mLock);
472
473    List< sp<JavaDeathRecipient> >::iterator iter;
474    for (iter = mList.begin(); iter != mList.end(); iter++) {
475        if (*iter == recipient) {
476            LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
477            mList.erase(iter);
478            return;
479        }
480    }
481}
482
483sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
484    AutoMutex _l(mLock);
485
486    List< sp<JavaDeathRecipient> >::iterator iter;
487    for (iter = mList.begin(); iter != mList.end(); iter++) {
488        if ((*iter)->matches(recipient)) {
489            return *iter;
490        }
491    }
492    return NULL;
493}
494
495// ----------------------------------------------------------------------------
496
497namespace android {
498
499static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
500{
501    android_atomic_dec(&gNumProxyRefs);
502    JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
503    env->DeleteGlobalRef((jobject)obj);
504}
505
506static Mutex mProxyLock;
507
508jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
509{
510    if (val == NULL) return NULL;
511
512    if (val->checkSubclass(&gBinderOffsets)) {
513        // One of our own!
514        jobject object = static_cast<JavaBBinder*>(val.get())->object();
515        //printf("objectForBinder %p: it's our own %p!\n", val.get(), object);
516        return object;
517    }
518
519    // For the rest of the function we will hold this lock, to serialize
520    // looking/creation of Java proxies for native Binder proxies.
521    AutoMutex _l(mProxyLock);
522
523    // Someone else's...  do we know about it?
524    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
525    if (object != NULL) {
526        jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
527        if (res != NULL) {
528            LOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
529            return res;
530        }
531        LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
532        android_atomic_dec(&gNumProxyRefs);
533        val->detachObject(&gBinderProxyOffsets);
534        env->DeleteGlobalRef(object);
535    }
536
537    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
538    if (object != NULL) {
539        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
540        // The proxy holds a reference to the native object.
541        env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
542        val->incStrong(object);
543
544        // The native object needs to hold a weak reference back to the
545        // proxy, so we can retrieve the same proxy if it is still active.
546        jobject refObject = env->NewGlobalRef(
547                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
548        val->attachObject(&gBinderProxyOffsets, refObject,
549                jnienv_to_javavm(env), proxy_cleanup);
550
551        // Also remember the death recipients registered on this proxy
552        sp<DeathRecipientList> drl = new DeathRecipientList;
553        drl->incStrong((void*)javaObjectForIBinder);
554        env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
555
556        // Note that a new object reference has been created.
557        android_atomic_inc(&gNumProxyRefs);
558        incRefsCreated(env);
559    }
560
561    return object;
562}
563
564sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
565{
566    if (obj == NULL) return NULL;
567
568    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
569        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
570            env->GetIntField(obj, gBinderOffsets.mObject);
571        return jbh != NULL ? jbh->get(env, obj) : NULL;
572    }
573
574    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
575        return (IBinder*)
576            env->GetIntField(obj, gBinderProxyOffsets.mObject);
577    }
578
579    LOGW("ibinderForJavaObject: %p is not a Binder object", obj);
580    return NULL;
581}
582
583Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
584{
585    if (obj) {
586        Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mObject);
587        if (p != NULL) {
588            return p;
589        }
590        jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
591    }
592    return NULL;
593}
594
595jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
596{
597    return env->NewObject(
598            gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
599}
600
601void signalExceptionForError(JNIEnv* env, jobject obj, status_t err)
602{
603    switch (err) {
604        case UNKNOWN_ERROR:
605            jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
606            break;
607        case NO_MEMORY:
608            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
609            break;
610        case INVALID_OPERATION:
611            jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
612            break;
613        case BAD_VALUE:
614            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
615            break;
616        case BAD_INDEX:
617            jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
618            break;
619        case BAD_TYPE:
620            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
621            break;
622        case NAME_NOT_FOUND:
623            jniThrowException(env, "java/util/NoSuchElementException", NULL);
624            break;
625        case PERMISSION_DENIED:
626            jniThrowException(env, "java/lang/SecurityException", NULL);
627            break;
628        case NOT_ENOUGH_DATA:
629            jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
630            break;
631        case NO_INIT:
632            jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
633            break;
634        case ALREADY_EXISTS:
635            jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
636            break;
637        case DEAD_OBJECT:
638            jniThrowException(env, "android/os/DeadObjectException", NULL);
639            break;
640        case UNKNOWN_TRANSACTION:
641            jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
642            break;
643        case FAILED_TRANSACTION:
644            LOGE("!!! FAILED BINDER TRANSACTION !!!");
645            //jniThrowException(env, "java/lang/OutOfMemoryError", "Binder transaction too large");
646            break;
647        default:
648            LOGE("Unknown binder error code. 0x%x", err);
649    }
650}
651
652}
653
654// ----------------------------------------------------------------------------
655
656static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
657{
658    return IPCThreadState::self()->getCallingPid();
659}
660
661static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
662{
663    return IPCThreadState::self()->getCallingUid();
664}
665
666static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
667{
668    return IPCThreadState::self()->clearCallingIdentity();
669}
670
671static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
672{
673    // XXX temporary sanity check to debug crashes.
674    int uid = (int)(token>>32);
675    if (uid > 0 && uid < 999) {
676        // In Android currently there are no uids in this range.
677        char buf[128];
678        sprintf(buf, "Restoring bad calling ident: 0x%Lx", token);
679        jniThrowException(env, "java/lang/IllegalStateException", buf);
680        return;
681    }
682    IPCThreadState::self()->restoreCallingIdentity(token);
683}
684
685static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
686{
687    IPCThreadState::self()->setStrictModePolicy(policyMask);
688}
689
690static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
691{
692    return IPCThreadState::self()->getStrictModePolicy();
693}
694
695static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
696{
697    IPCThreadState::self()->flushCommands();
698}
699
700static void android_os_Binder_init(JNIEnv* env, jobject obj)
701{
702    JavaBBinderHolder* jbh = new JavaBBinderHolder();
703    if (jbh == NULL) {
704        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
705        return;
706    }
707    LOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
708    jbh->incStrong((void*)android_os_Binder_init);
709    env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
710}
711
712static void android_os_Binder_destroy(JNIEnv* env, jobject obj)
713{
714    JavaBBinderHolder* jbh = (JavaBBinderHolder*)
715        env->GetIntField(obj, gBinderOffsets.mObject);
716    if (jbh != NULL) {
717        env->SetIntField(obj, gBinderOffsets.mObject, 0);
718        LOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
719        jbh->decStrong((void*)android_os_Binder_init);
720    } else {
721        // Encountering an uninitialized binder is harmless.  All it means is that
722        // the Binder was only partially initialized when its finalizer ran and called
723        // destroy().  The Binder could be partially initialized for several reasons.
724        // For example, a Binder subclass constructor might have thrown an exception before
725        // it could delegate to its superclass's constructor.  Consequently init() would
726        // not have been called and the holder pointer would remain NULL.
727        LOGV("Java Binder %p: ignoring uninitialized binder", obj);
728    }
729}
730
731// ----------------------------------------------------------------------------
732
733static const JNINativeMethod gBinderMethods[] = {
734     /* name, signature, funcPtr */
735    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
736    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
737    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
738    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
739    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
740    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
741    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
742    { "init", "()V", (void*)android_os_Binder_init },
743    { "destroy", "()V", (void*)android_os_Binder_destroy }
744};
745
746const char* const kBinderPathName = "android/os/Binder";
747
748static int int_register_android_os_Binder(JNIEnv* env)
749{
750    jclass clazz;
751
752    clazz = env->FindClass(kBinderPathName);
753    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
754
755    gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
756    gBinderOffsets.mExecTransact
757        = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
758    assert(gBinderOffsets.mExecTransact);
759
760    gBinderOffsets.mObject
761        = env->GetFieldID(clazz, "mObject", "I");
762    assert(gBinderOffsets.mObject);
763
764    return AndroidRuntime::registerNativeMethods(
765        env, kBinderPathName,
766        gBinderMethods, NELEM(gBinderMethods));
767}
768
769// ****************************************************************************
770// ****************************************************************************
771// ****************************************************************************
772
773namespace android {
774
775jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
776{
777    return gNumLocalRefs;
778}
779
780jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
781{
782    return gNumProxyRefs;
783}
784
785jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
786{
787    return gNumDeathRefs;
788}
789
790}
791
792// ****************************************************************************
793// ****************************************************************************
794// ****************************************************************************
795
796static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
797{
798    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
799    return javaObjectForIBinder(env, b);
800}
801
802static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
803{
804    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
805    android::IPCThreadState::self()->joinThreadPool();
806}
807
808static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
809        jobject clazz, jboolean disable)
810{
811    IPCThreadState::disableBackgroundScheduling(disable ? true : false);
812}
813
814static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
815{
816    LOGV("Gc has executed, clearing binder ops");
817    android_atomic_and(0, &gNumRefsCreated);
818}
819
820// ----------------------------------------------------------------------------
821
822static const JNINativeMethod gBinderInternalMethods[] = {
823     /* name, signature, funcPtr */
824    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
825    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
826    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
827    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
828};
829
830const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
831
832static int int_register_android_os_BinderInternal(JNIEnv* env)
833{
834    jclass clazz;
835
836    clazz = env->FindClass(kBinderInternalPathName);
837    LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");
838
839    gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
840    gBinderInternalOffsets.mForceGc
841        = env->GetStaticMethodID(clazz, "forceBinderGc", "()V");
842    assert(gBinderInternalOffsets.mForceGc);
843
844    return AndroidRuntime::registerNativeMethods(
845        env, kBinderInternalPathName,
846        gBinderInternalMethods, NELEM(gBinderInternalMethods));
847}
848
849// ****************************************************************************
850// ****************************************************************************
851// ****************************************************************************
852
853static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
854{
855    IBinder* target = (IBinder*)
856        env->GetIntField(obj, gBinderProxyOffsets.mObject);
857    if (target == NULL) {
858        return JNI_FALSE;
859    }
860    status_t err = target->pingBinder();
861    return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
862}
863
864static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
865{
866    IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject);
867    if (target != NULL) {
868        const String16& desc = target->getInterfaceDescriptor();
869        return env->NewString(desc.string(), desc.size());
870    }
871    jniThrowException(env, "java/lang/RuntimeException",
872            "No binder found for object");
873    return NULL;
874}
875
876static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
877{
878    IBinder* target = (IBinder*)
879        env->GetIntField(obj, gBinderProxyOffsets.mObject);
880    if (target == NULL) {
881        return JNI_FALSE;
882    }
883    bool alive = target->isBinderAlive();
884    return alive ? JNI_TRUE : JNI_FALSE;
885}
886
887static int getprocname(pid_t pid, char *buf, size_t len) {
888    char filename[20];
889    FILE *f;
890
891    sprintf(filename, "/proc/%d/cmdline", pid);
892    f = fopen(filename, "r");
893    if (!f) { *buf = '\0'; return 1; }
894    if (!fgets(buf, len, f)) { *buf = '\0'; return 2; }
895    fclose(f);
896    return 0;
897}
898
899static bool push_eventlog_string(char** pos, const char* end, const char* str) {
900    jint len = strlen(str);
901    int space_needed = 1 + sizeof(len) + len;
902    if (end - *pos < space_needed) {
903        LOGW("not enough space for string. remain=%d; needed=%d",
904             (end - *pos), space_needed);
905        return false;
906    }
907    **pos = EVENT_TYPE_STRING;
908    (*pos)++;
909    memcpy(*pos, &len, sizeof(len));
910    *pos += sizeof(len);
911    memcpy(*pos, str, len);
912    *pos += len;
913    return true;
914}
915
916static bool push_eventlog_int(char** pos, const char* end, jint val) {
917    int space_needed = 1 + sizeof(val);
918    if (end - *pos < space_needed) {
919        LOGW("not enough space for int.  remain=%d; needed=%d",
920             (end - *pos), space_needed);
921        return false;
922    }
923    **pos = EVENT_TYPE_INT;
924    (*pos)++;
925    memcpy(*pos, &val, sizeof(val));
926    *pos += sizeof(val);
927    return true;
928}
929
930// From frameworks/base/core/java/android/content/EventLogTags.logtags:
931#define LOGTAG_BINDER_OPERATION 52004
932
933static void conditionally_log_binder_call(int64_t start_millis,
934                                          IBinder* target, jint code) {
935    int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
936
937    int sample_percent;
938    if (duration_ms >= 500) {
939        sample_percent = 100;
940    } else {
941        sample_percent = 100 * duration_ms / 500;
942        if (sample_percent == 0) {
943            return;
944        }
945        if (sample_percent < (random() % 100 + 1)) {
946            return;
947        }
948    }
949
950    char process_name[40];
951    getprocname(getpid(), process_name, sizeof(process_name));
952    String8 desc(target->getInterfaceDescriptor());
953
954    char buf[LOGGER_ENTRY_MAX_PAYLOAD];
955    buf[0] = EVENT_TYPE_LIST;
956    buf[1] = 5;
957    char* pos = &buf[2];
958    char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1];  // leave room for final \n
959    if (!push_eventlog_string(&pos, end, desc.string())) return;
960    if (!push_eventlog_int(&pos, end, code)) return;
961    if (!push_eventlog_int(&pos, end, duration_ms)) return;
962    if (!push_eventlog_string(&pos, end, process_name)) return;
963    if (!push_eventlog_int(&pos, end, sample_percent)) return;
964    *(pos++) = '\n';   // conventional with EVENT_TYPE_LIST apparently.
965    android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
966}
967
968// We only measure binder call durations to potentially log them if
969// we're on the main thread.  Unfortunately sim-eng doesn't seem to
970// have gettid, so we just ignore this and don't log if we can't
971// get the thread id.
972static bool should_time_binder_calls() {
973#ifdef HAVE_GETTID
974  return (getpid() == androidGetTid());
975#else
976#warning no gettid(), so not logging Binder calls...
977  return false;
978#endif
979}
980
981static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
982                                                jint code, jobject dataObj,
983                                                jobject replyObj, jint flags)
984{
985    if (dataObj == NULL) {
986        jniThrowNullPointerException(env, NULL);
987        return JNI_FALSE;
988    }
989
990    Parcel* data = parcelForJavaObject(env, dataObj);
991    if (data == NULL) {
992        return JNI_FALSE;
993    }
994    Parcel* reply = parcelForJavaObject(env, replyObj);
995    if (reply == NULL && replyObj != NULL) {
996        return JNI_FALSE;
997    }
998
999    IBinder* target = (IBinder*)
1000        env->GetIntField(obj, gBinderProxyOffsets.mObject);
1001    if (target == NULL) {
1002        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1003        return JNI_FALSE;
1004    }
1005
1006    LOGV("Java code calling transact on %p in Java object %p with code %d\n",
1007            target, obj, code);
1008
1009    // Only log the binder call duration for things on the Java-level main thread.
1010    // But if we don't
1011    const bool time_binder_calls = should_time_binder_calls();
1012
1013    int64_t start_millis;
1014    if (time_binder_calls) {
1015        start_millis = uptimeMillis();
1016    }
1017    //printf("Transact from Java code to %p sending: ", target); data->print();
1018    status_t err = target->transact(code, *data, reply, flags);
1019    //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1020    if (time_binder_calls) {
1021        conditionally_log_binder_call(start_millis, target, code);
1022    }
1023
1024    if (err == NO_ERROR) {
1025        return JNI_TRUE;
1026    } else if (err == UNKNOWN_TRANSACTION) {
1027        return JNI_FALSE;
1028    }
1029
1030    signalExceptionForError(env, obj, err);
1031    return JNI_FALSE;
1032}
1033
1034static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
1035                                               jobject recipient, jint flags)
1036{
1037    if (recipient == NULL) {
1038        jniThrowNullPointerException(env, NULL);
1039        return;
1040    }
1041
1042    IBinder* target = (IBinder*)
1043        env->GetIntField(obj, gBinderProxyOffsets.mObject);
1044    if (target == NULL) {
1045        LOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1046        assert(false);
1047    }
1048
1049    LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
1050
1051    if (!target->localBinder()) {
1052        DeathRecipientList* list = (DeathRecipientList*)
1053                env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
1054        sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
1055        status_t err = target->linkToDeath(jdr, NULL, flags);
1056        if (err != NO_ERROR) {
1057            // Failure adding the death recipient, so clear its reference
1058            // now.
1059            jdr->clearReference();
1060            signalExceptionForError(env, obj, err);
1061        }
1062    }
1063}
1064
1065static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1066                                                 jobject recipient, jint flags)
1067{
1068    jboolean res = JNI_FALSE;
1069    if (recipient == NULL) {
1070        jniThrowNullPointerException(env, NULL);
1071        return res;
1072    }
1073
1074    IBinder* target = (IBinder*)
1075        env->GetIntField(obj, gBinderProxyOffsets.mObject);
1076    if (target == NULL) {
1077        LOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1078        return JNI_FALSE;
1079    }
1080
1081    LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
1082
1083    if (!target->localBinder()) {
1084        status_t err = NAME_NOT_FOUND;
1085
1086        // If we find the matching recipient, proceed to unlink using that
1087        DeathRecipientList* list = (DeathRecipientList*)
1088                env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
1089        sp<JavaDeathRecipient> origJDR = list->find(recipient);
1090        LOGDEATH("   unlink found list %p and JDR %p", list, origJDR.get());
1091        if (origJDR != NULL) {
1092            wp<IBinder::DeathRecipient> dr;
1093            err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1094            if (err == NO_ERROR && dr != NULL) {
1095                sp<IBinder::DeathRecipient> sdr = dr.promote();
1096                JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1097                if (jdr != NULL) {
1098                    jdr->clearReference();
1099                }
1100            }
1101        }
1102
1103        if (err == NO_ERROR || err == DEAD_OBJECT) {
1104            res = JNI_TRUE;
1105        } else {
1106            jniThrowException(env, "java/util/NoSuchElementException",
1107                              "Death link does not exist");
1108        }
1109    }
1110
1111    return res;
1112}
1113
1114static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
1115{
1116    IBinder* b = (IBinder*)
1117            env->GetIntField(obj, gBinderProxyOffsets.mObject);
1118    DeathRecipientList* drl = (DeathRecipientList*)
1119            env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
1120
1121    LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
1122    env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
1123    env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0);
1124    drl->decStrong((void*)javaObjectForIBinder);
1125    b->decStrong(obj);
1126
1127    IPCThreadState::self()->flushCommands();
1128}
1129
1130// ----------------------------------------------------------------------------
1131
1132static const JNINativeMethod gBinderProxyMethods[] = {
1133     /* name, signature, funcPtr */
1134    {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},
1135    {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1136    {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
1137    {"transact",            "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
1138    {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1139    {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1140    {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},
1141};
1142
1143const char* const kBinderProxyPathName = "android/os/BinderProxy";
1144
1145static int int_register_android_os_BinderProxy(JNIEnv* env)
1146{
1147    jclass clazz;
1148
1149    clazz = env->FindClass("java/lang/ref/WeakReference");
1150    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference");
1151    gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1152    gWeakReferenceOffsets.mGet
1153        = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");
1154    assert(gWeakReferenceOffsets.mGet);
1155
1156    clazz = env->FindClass("java/lang/Error");
1157    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error");
1158    gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1159
1160    clazz = env->FindClass(kBinderProxyPathName);
1161    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");
1162
1163    gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1164    gBinderProxyOffsets.mConstructor
1165        = env->GetMethodID(clazz, "<init>", "()V");
1166    assert(gBinderProxyOffsets.mConstructor);
1167    gBinderProxyOffsets.mSendDeathNotice
1168        = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
1169    assert(gBinderProxyOffsets.mSendDeathNotice);
1170
1171    gBinderProxyOffsets.mObject
1172        = env->GetFieldID(clazz, "mObject", "I");
1173    assert(gBinderProxyOffsets.mObject);
1174    gBinderProxyOffsets.mSelf
1175        = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
1176    assert(gBinderProxyOffsets.mSelf);
1177    gBinderProxyOffsets.mOrgue
1178        = env->GetFieldID(clazz, "mOrgue", "I");
1179    assert(gBinderProxyOffsets.mOrgue);
1180
1181    return AndroidRuntime::registerNativeMethods(
1182        env, kBinderProxyPathName,
1183        gBinderProxyMethods, NELEM(gBinderProxyMethods));
1184}
1185
1186// ****************************************************************************
1187// ****************************************************************************
1188// ****************************************************************************
1189
1190static jint android_os_Parcel_dataSize(JNIEnv* env, jobject clazz)
1191{
1192    Parcel* parcel = parcelForJavaObject(env, clazz);
1193    return parcel ? parcel->dataSize() : 0;
1194}
1195
1196static jint android_os_Parcel_dataAvail(JNIEnv* env, jobject clazz)
1197{
1198    Parcel* parcel = parcelForJavaObject(env, clazz);
1199    return parcel ? parcel->dataAvail() : 0;
1200}
1201
1202static jint android_os_Parcel_dataPosition(JNIEnv* env, jobject clazz)
1203{
1204    Parcel* parcel = parcelForJavaObject(env, clazz);
1205    return parcel ? parcel->dataPosition() : 0;
1206}
1207
1208static jint android_os_Parcel_dataCapacity(JNIEnv* env, jobject clazz)
1209{
1210    Parcel* parcel = parcelForJavaObject(env, clazz);
1211    return parcel ? parcel->dataCapacity() : 0;
1212}
1213
1214static void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size)
1215{
1216    Parcel* parcel = parcelForJavaObject(env, clazz);
1217    if (parcel != NULL) {
1218        const status_t err = parcel->setDataSize(size);
1219        if (err != NO_ERROR) {
1220            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1221        }
1222    }
1223}
1224
1225static void android_os_Parcel_setDataPosition(JNIEnv* env, jobject clazz, jint pos)
1226{
1227    Parcel* parcel = parcelForJavaObject(env, clazz);
1228    if (parcel != NULL) {
1229        parcel->setDataPosition(pos);
1230    }
1231}
1232
1233static void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint size)
1234{
1235    Parcel* parcel = parcelForJavaObject(env, clazz);
1236    if (parcel != NULL) {
1237        const status_t err = parcel->setDataCapacity(size);
1238        if (err != NO_ERROR) {
1239            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1240        }
1241    }
1242}
1243
1244static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
1245                                          jobject data, jint offset,
1246                                          jint length)
1247{
1248    Parcel* parcel = parcelForJavaObject(env, clazz);
1249    if (parcel == NULL) {
1250        return;
1251    }
1252
1253    const status_t err = parcel->writeInt32(length);
1254    if (err != NO_ERROR) {
1255        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1256    }
1257
1258    void* dest = parcel->writeInplace(length);
1259    if (dest == NULL) {
1260        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1261        return;
1262    }
1263
1264    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
1265    if (ar) {
1266        memcpy(dest, ar + offset, length);
1267        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
1268    }
1269}
1270
1271
1272static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
1273{
1274    Parcel* parcel = parcelForJavaObject(env, clazz);
1275    if (parcel != NULL) {
1276        const status_t err = parcel->writeInt32(val);
1277        if (err != NO_ERROR) {
1278            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1279        }
1280    }
1281}
1282
1283static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
1284{
1285    Parcel* parcel = parcelForJavaObject(env, clazz);
1286    if (parcel != NULL) {
1287        const status_t err = parcel->writeInt64(val);
1288        if (err != NO_ERROR) {
1289            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1290        }
1291    }
1292}
1293
1294static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
1295{
1296    Parcel* parcel = parcelForJavaObject(env, clazz);
1297    if (parcel != NULL) {
1298        const status_t err = parcel->writeFloat(val);
1299        if (err != NO_ERROR) {
1300            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1301        }
1302    }
1303}
1304
1305static void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble val)
1306{
1307    Parcel* parcel = parcelForJavaObject(env, clazz);
1308    if (parcel != NULL) {
1309        const status_t err = parcel->writeDouble(val);
1310        if (err != NO_ERROR) {
1311            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1312        }
1313    }
1314}
1315
1316static void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring val)
1317{
1318    Parcel* parcel = parcelForJavaObject(env, clazz);
1319    if (parcel != NULL) {
1320        status_t err = NO_MEMORY;
1321        if (val) {
1322            const jchar* str = env->GetStringCritical(val, 0);
1323            if (str) {
1324                err = parcel->writeString16(str, env->GetStringLength(val));
1325                env->ReleaseStringCritical(val, str);
1326            }
1327        } else {
1328            err = parcel->writeString16(NULL, 0);
1329        }
1330        if (err != NO_ERROR) {
1331            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1332        }
1333    }
1334}
1335
1336static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
1337{
1338    Parcel* parcel = parcelForJavaObject(env, clazz);
1339    if (parcel != NULL) {
1340        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
1341        if (err != NO_ERROR) {
1342            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1343        }
1344    }
1345}
1346
1347static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
1348{
1349    Parcel* parcel = parcelForJavaObject(env, clazz);
1350    if (parcel != NULL) {
1351        const status_t err =
1352                parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
1353        if (err != NO_ERROR) {
1354            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1355        }
1356    }
1357}
1358
1359static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jobject clazz)
1360{
1361    jbyteArray ret = NULL;
1362
1363    Parcel* parcel = parcelForJavaObject(env, clazz);
1364    if (parcel != NULL) {
1365        int32_t len = parcel->readInt32();
1366
1367        // sanity check the stored length against the true data size
1368        if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
1369            ret = env->NewByteArray(len);
1370
1371            if (ret != NULL) {
1372                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
1373                if (a2) {
1374                    const void* data = parcel->readInplace(len);
1375                    memcpy(a2, data, len);
1376                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
1377                }
1378            }
1379        }
1380    }
1381
1382    return ret;
1383}
1384
1385static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
1386{
1387    Parcel* parcel = parcelForJavaObject(env, clazz);
1388    if (parcel != NULL) {
1389        return parcel->readInt32();
1390    }
1391    return 0;
1392}
1393
1394static jlong android_os_Parcel_readLong(JNIEnv* env, jobject clazz)
1395{
1396    Parcel* parcel = parcelForJavaObject(env, clazz);
1397    if (parcel != NULL) {
1398        return parcel->readInt64();
1399    }
1400    return 0;
1401}
1402
1403static jfloat android_os_Parcel_readFloat(JNIEnv* env, jobject clazz)
1404{
1405    Parcel* parcel = parcelForJavaObject(env, clazz);
1406    if (parcel != NULL) {
1407        return parcel->readFloat();
1408    }
1409    return 0;
1410}
1411
1412static jdouble android_os_Parcel_readDouble(JNIEnv* env, jobject clazz)
1413{
1414    Parcel* parcel = parcelForJavaObject(env, clazz);
1415    if (parcel != NULL) {
1416        return parcel->readDouble();
1417    }
1418    return 0;
1419}
1420
1421static jstring android_os_Parcel_readString(JNIEnv* env, jobject clazz)
1422{
1423    Parcel* parcel = parcelForJavaObject(env, clazz);
1424    if (parcel != NULL) {
1425        size_t len;
1426        const char16_t* str = parcel->readString16Inplace(&len);
1427        if (str) {
1428            return env->NewString(str, len);
1429        }
1430        return NULL;
1431    }
1432    return NULL;
1433}
1434
1435static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz)
1436{
1437    Parcel* parcel = parcelForJavaObject(env, clazz);
1438    if (parcel != NULL) {
1439        return javaObjectForIBinder(env, parcel->readStrongBinder());
1440    }
1441    return NULL;
1442}
1443
1444static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jobject clazz)
1445{
1446    Parcel* parcel = parcelForJavaObject(env, clazz);
1447    if (parcel != NULL) {
1448        int fd = parcel->readFileDescriptor();
1449        if (fd < 0) return NULL;
1450        fd = dup(fd);
1451        if (fd < 0) return NULL;
1452        return jniCreateFileDescriptor(env, fd);
1453    }
1454    return NULL;
1455}
1456
1457static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jobject clazz,
1458                                                    jstring name, jint mode)
1459{
1460    if (name == NULL) {
1461        jniThrowNullPointerException(env, NULL);
1462        return NULL;
1463    }
1464    const jchar* str = env->GetStringCritical(name, 0);
1465    if (str == NULL) {
1466        // Whatever, whatever.
1467        jniThrowException(env, "java/lang/IllegalStateException", NULL);
1468        return NULL;
1469    }
1470    String8 name8(str, env->GetStringLength(name));
1471    env->ReleaseStringCritical(name, str);
1472    int flags=0;
1473    switch (mode&0x30000000) {
1474        case 0:
1475        case 0x10000000:
1476            flags = O_RDONLY;
1477            break;
1478        case 0x20000000:
1479            flags = O_WRONLY;
1480            break;
1481        case 0x30000000:
1482            flags = O_RDWR;
1483            break;
1484    }
1485
1486    if (mode&0x08000000) flags |= O_CREAT;
1487    if (mode&0x04000000) flags |= O_TRUNC;
1488    if (mode&0x02000000) flags |= O_APPEND;
1489
1490    int realMode = S_IRWXU|S_IRWXG;
1491    if (mode&0x00000001) realMode |= S_IROTH;
1492    if (mode&0x00000002) realMode |= S_IWOTH;
1493
1494    int fd = open(name8.string(), flags, realMode);
1495    if (fd < 0) {
1496        jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
1497        return NULL;
1498    }
1499    jobject object = jniCreateFileDescriptor(env, fd);
1500    if (object == NULL) {
1501        close(fd);
1502    }
1503    return object;
1504}
1505
1506static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jobject clazz, jobject orig)
1507{
1508    if (orig == NULL) {
1509        jniThrowNullPointerException(env, NULL);
1510        return NULL;
1511    }
1512    int origfd = jniGetFDFromFileDescriptor(env, orig);
1513    if (origfd < 0) {
1514        jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
1515        return NULL;
1516    }
1517
1518    int fd = dup(origfd);
1519    if (fd < 0) {
1520        jniThrowIOException(env, errno);
1521        return NULL;
1522    }
1523    jobject object = jniCreateFileDescriptor(env, fd);
1524    if (object == NULL) {
1525        close(fd);
1526    }
1527    return object;
1528}
1529
1530static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
1531{
1532    if (object == NULL) {
1533        jniThrowNullPointerException(env, NULL);
1534        return;
1535    }
1536    int fd = jniGetFDFromFileDescriptor(env, object);
1537    if (fd >= 0) {
1538        jniSetFileDescriptorOfFD(env, object, -1);
1539        //LOGI("Closing ParcelFileDescriptor %d\n", fd);
1540        close(fd);
1541    }
1542}
1543
1544static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
1545{
1546    if (object == NULL) {
1547        jniThrowNullPointerException(env, NULL);
1548        return;
1549    }
1550    int fd = jniGetFDFromFileDescriptor(env, object);
1551    if (fd >= 0) {
1552        jniSetFileDescriptorOfFD(env, object, -1);
1553    }
1554}
1555
1556static void android_os_Parcel_freeBuffer(JNIEnv* env, jobject clazz)
1557{
1558    int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
1559    if (own) {
1560        Parcel* parcel = parcelForJavaObject(env, clazz);
1561        if (parcel != NULL) {
1562            //LOGI("Parcel.freeBuffer() called for C++ Parcel %p\n", parcel);
1563            parcel->freeData();
1564        }
1565    }
1566}
1567
1568static void android_os_Parcel_init(JNIEnv* env, jobject clazz, jint parcelInt)
1569{
1570    Parcel* parcel = (Parcel*)parcelInt;
1571    int own = 0;
1572    if (!parcel) {
1573        //LOGI("Initializing obj %p: creating new Parcel\n", clazz);
1574        own = 1;
1575        parcel = new Parcel;
1576    } else {
1577        //LOGI("Initializing obj %p: given existing Parcel %p\n", clazz, parcel);
1578    }
1579    if (parcel == NULL) {
1580        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1581        return;
1582    }
1583    //LOGI("Initializing obj %p from C++ Parcel %p, own=%d\n", clazz, parcel, own);
1584    env->SetIntField(clazz, gParcelOffsets.mOwnObject, own);
1585    env->SetIntField(clazz, gParcelOffsets.mObject, (int)parcel);
1586}
1587
1588static void android_os_Parcel_destroy(JNIEnv* env, jobject clazz)
1589{
1590    int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
1591    if (own) {
1592        Parcel* parcel = parcelForJavaObject(env, clazz);
1593        env->SetIntField(clazz, gParcelOffsets.mObject, 0);
1594        //LOGI("Destroying obj %p: deleting C++ Parcel %p\n", clazz, parcel);
1595        delete parcel;
1596    } else {
1597        env->SetIntField(clazz, gParcelOffsets.mObject, 0);
1598        //LOGI("Destroying obj %p: leaving C++ Parcel %p\n", clazz);
1599    }
1600}
1601
1602static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jobject clazz)
1603{
1604    Parcel* parcel = parcelForJavaObject(env, clazz);
1605    if (parcel == NULL) {
1606       return NULL;
1607    }
1608
1609    // do not marshall if there are binder objects in the parcel
1610    if (parcel->objectsCount())
1611    {
1612        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
1613        return NULL;
1614    }
1615
1616    jbyteArray ret = env->NewByteArray(parcel->dataSize());
1617
1618    if (ret != NULL)
1619    {
1620        jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
1621        if (array != NULL)
1622        {
1623            memcpy(array, parcel->data(), parcel->dataSize());
1624            env->ReleasePrimitiveArrayCritical(ret, array, 0);
1625        }
1626    }
1627
1628    return ret;
1629}
1630
1631static void android_os_Parcel_unmarshall(JNIEnv* env, jobject clazz, jbyteArray data, jint offset, jint length)
1632{
1633    Parcel* parcel = parcelForJavaObject(env, clazz);
1634    if (parcel == NULL || length < 0) {
1635       return;
1636    }
1637
1638    jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
1639    if (array)
1640    {
1641        parcel->setDataSize(length);
1642        parcel->setDataPosition(0);
1643
1644        void* raw = parcel->writeInplace(length);
1645        memcpy(raw, (array + offset), length);
1646
1647        env->ReleasePrimitiveArrayCritical(data, array, 0);
1648    }
1649}
1650
1651static void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject parcel, jint offset, jint length)
1652{
1653    Parcel* thisParcel = parcelForJavaObject(env, clazz);
1654    if (thisParcel == NULL) {
1655       return;
1656    }
1657    Parcel* otherParcel = parcelForJavaObject(env, parcel);
1658    if (otherParcel == NULL) {
1659       return;
1660    }
1661
1662    (void) thisParcel->appendFrom(otherParcel, offset, length);
1663}
1664
1665static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
1666{
1667    jboolean ret = JNI_FALSE;
1668    Parcel* parcel = parcelForJavaObject(env, clazz);
1669    if (parcel != NULL) {
1670        if (parcel->hasFileDescriptors()) {
1671            ret = JNI_TRUE;
1672        }
1673    }
1674    return ret;
1675}
1676
1677static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, jstring name)
1678{
1679    Parcel* parcel = parcelForJavaObject(env, clazz);
1680    if (parcel != NULL) {
1681        // In the current implementation, the token is just the serialized interface name that
1682        // the caller expects to be invoking
1683        const jchar* str = env->GetStringCritical(name, 0);
1684        if (str != NULL) {
1685            parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
1686            env->ReleaseStringCritical(name, str);
1687        }
1688    }
1689}
1690
1691static void android_os_Parcel_enforceInterface(JNIEnv* env, jobject clazz, jstring name)
1692{
1693    jboolean ret = JNI_FALSE;
1694
1695    Parcel* parcel = parcelForJavaObject(env, clazz);
1696    if (parcel != NULL) {
1697        const jchar* str = env->GetStringCritical(name, 0);
1698        if (str) {
1699            IPCThreadState* threadState = IPCThreadState::self();
1700            const int32_t oldPolicy = threadState->getStrictModePolicy();
1701            const bool isValid = parcel->enforceInterface(
1702                String16(str, env->GetStringLength(name)),
1703                threadState);
1704            env->ReleaseStringCritical(name, str);
1705            if (isValid) {
1706                const int32_t newPolicy = threadState->getStrictModePolicy();
1707                if (oldPolicy != newPolicy) {
1708                    // Need to keep the Java-level thread-local strict
1709                    // mode policy in sync for the libcore
1710                    // enforcements, which involves an upcall back
1711                    // into Java.  (We can't modify the
1712                    // Parcel.enforceInterface signature, as it's
1713                    // pseudo-public, and used via AIDL
1714                    // auto-generation...)
1715                    set_dalvik_blockguard_policy(env, newPolicy);
1716                }
1717                return;     // everything was correct -> return silently
1718            }
1719        }
1720    }
1721
1722    // all error conditions wind up here
1723    jniThrowException(env, "java/lang/SecurityException",
1724            "Binder invocation to an incorrect interface");
1725}
1726
1727// ----------------------------------------------------------------------------
1728
1729static const JNINativeMethod gParcelMethods[] = {
1730    {"dataSize",            "()I", (void*)android_os_Parcel_dataSize},
1731    {"dataAvail",           "()I", (void*)android_os_Parcel_dataAvail},
1732    {"dataPosition",        "()I", (void*)android_os_Parcel_dataPosition},
1733    {"dataCapacity",        "()I", (void*)android_os_Parcel_dataCapacity},
1734    {"setDataSize",         "(I)V", (void*)android_os_Parcel_setDataSize},
1735    {"setDataPosition",     "(I)V", (void*)android_os_Parcel_setDataPosition},
1736    {"setDataCapacity",     "(I)V", (void*)android_os_Parcel_setDataCapacity},
1737    {"writeNative",         "([BII)V", (void*)android_os_Parcel_writeNative},
1738    {"writeInt",            "(I)V", (void*)android_os_Parcel_writeInt},
1739    {"writeLong",           "(J)V", (void*)android_os_Parcel_writeLong},
1740    {"writeFloat",          "(F)V", (void*)android_os_Parcel_writeFloat},
1741    {"writeDouble",         "(D)V", (void*)android_os_Parcel_writeDouble},
1742    {"writeString",         "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeString},
1743    {"writeStrongBinder",   "(Landroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
1744    {"writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
1745    {"createByteArray",     "()[B", (void*)android_os_Parcel_createByteArray},
1746    {"readInt",             "()I", (void*)android_os_Parcel_readInt},
1747    {"readLong",            "()J", (void*)android_os_Parcel_readLong},
1748    {"readFloat",           "()F", (void*)android_os_Parcel_readFloat},
1749    {"readDouble",          "()D", (void*)android_os_Parcel_readDouble},
1750    {"readString",          "()Ljava/lang/String;", (void*)android_os_Parcel_readString},
1751    {"readStrongBinder",    "()Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
1752    {"internalReadFileDescriptor",  "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
1753    {"openFileDescriptor",  "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
1754    {"dupFileDescriptor",   "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
1755    {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
1756    {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
1757    {"freeBuffer",          "()V", (void*)android_os_Parcel_freeBuffer},
1758    {"init",                "(I)V", (void*)android_os_Parcel_init},
1759    {"destroy",             "()V", (void*)android_os_Parcel_destroy},
1760    {"marshall",            "()[B", (void*)android_os_Parcel_marshall},
1761    {"unmarshall",          "([BII)V", (void*)android_os_Parcel_unmarshall},
1762    {"appendFrom",          "(Landroid/os/Parcel;II)V", (void*)android_os_Parcel_appendFrom},
1763    {"hasFileDescriptors",  "()Z", (void*)android_os_Parcel_hasFileDescriptors},
1764    {"writeInterfaceToken", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
1765    {"enforceInterface",    "(Ljava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
1766};
1767
1768const char* const kParcelPathName = "android/os/Parcel";
1769
1770static int int_register_android_os_Parcel(JNIEnv* env)
1771{
1772    jclass clazz;
1773
1774    clazz = env->FindClass("android/util/Log");
1775    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.util.Log");
1776    gLogOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1777    gLogOffsets.mLogE = env->GetStaticMethodID(
1778        clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
1779    assert(gLogOffsets.mLogE);
1780
1781    clazz = env->FindClass("android/os/ParcelFileDescriptor");
1782    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
1783    gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1784    gParcelFileDescriptorOffsets.mConstructor
1785        = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
1786
1787    clazz = env->FindClass(kParcelPathName);
1788    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
1789
1790    gParcelOffsets.mObject
1791        = env->GetFieldID(clazz, "mObject", "I");
1792    gParcelOffsets.mOwnObject
1793        = env->GetFieldID(clazz, "mOwnObject", "I");
1794
1795    clazz = env->FindClass("android/os/StrictMode");
1796    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.StrictMode");
1797    gStrictModeCallbackOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1798    gStrictModeCallbackOffsets.mCallback = env->GetStaticMethodID(
1799        clazz, "onBinderStrictModePolicyChange", "(I)V");
1800    LOG_FATAL_IF(gStrictModeCallbackOffsets.mCallback == NULL,
1801                 "Unable to find strict mode callback.");
1802
1803    return AndroidRuntime::registerNativeMethods(
1804        env, kParcelPathName,
1805        gParcelMethods, NELEM(gParcelMethods));
1806}
1807
1808int register_android_os_Binder(JNIEnv* env)
1809{
1810    if (int_register_android_os_Binder(env) < 0)
1811        return -1;
1812    if (int_register_android_os_BinderInternal(env) < 0)
1813        return -1;
1814    if (int_register_android_os_BinderProxy(env) < 0)
1815        return -1;
1816    if (int_register_android_os_Parcel(env) < 0)
1817        return -1;
1818    return 0;
1819}
1820