android_util_Binder.cpp revision ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "JavaBinder"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_util_Binder.h"
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
24ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick#include <stdio.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h>
262c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick#include <sys/types.h>
278f26b323d8f78c6a183e74c464864ef7da457267Brad Fitzpatrick#include <unistd.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Atomic.h>
300795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IInterface.h>
310795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IPCThreadState.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
332c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick#include <utils/SystemClock.h>
340b41448506610f73302cc631677823fd8b865ea5Christopher Tate#include <utils/List.h>
350b41448506610f73302cc631677823fd8b865ea5Christopher Tate#include <utils/KeyedVector.h>
362c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick#include <cutils/logger.h>
370795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/Parcel.h>
380795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/ProcessState.h>
390795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IServiceManager.h>
405348c014129b766d621ef82a6e42007009ffc310Brad Fitzpatrick#include <utils/threads.h>
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate#include <ScopedUtfChars.h>
43ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate#include <ScopedLocalRef.h>
44ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#undef LOGV
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5079dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate#define DEBUG_DEATH 0
5179dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate#if DEBUG_DEATH
5279dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate#define LOGDEATH LOGD
5379dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate#else
5479dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate#define LOGDEATH LOGV
5579dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate#endif
5679dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct bindernative_offsets_t
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Class state.
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass mClass;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jmethodID mExecTransact;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Object state.
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mObject;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gBinderOffsets;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct binderinternal_offsets_t
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Class state.
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass mClass;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jmethodID mForceGc;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gBinderInternalOffsets;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct debug_offsets_t
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Class state.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass mClass;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gDebugOffsets;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct weakreference_offsets_t
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Class state.
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass mClass;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jmethodID mGet;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gWeakReferenceOffsets;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct error_offsets_t
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass mClass;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gErrorOffsets;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct binderproxy_offsets_t
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Class state.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass mClass;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jmethodID mConstructor;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jmethodID mSendDeathNotice;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Object state.
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mObject;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mSelf;
118bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    jfieldID mOrgue;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gBinderProxyOffsets;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct parcel_offsets_t
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mObject;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mOwnObject;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gParcelOffsets;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct log_offsets_t
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Class state.
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass mClass;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jmethodID mLogE;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gLogOffsets;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct parcel_file_descriptor_offsets_t
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass mClass;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jmethodID mConstructor;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gParcelFileDescriptorOffsets;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
143727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrickstatic struct strict_mode_callback_offsets_t
144727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick{
145727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    jclass mClass;
146727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    jmethodID mCallback;
147727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick} gStrictModeCallbackOffsets;
148727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic volatile int32_t gNumRefsCreated = 0;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic volatile int32_t gNumProxyRefs = 0;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic volatile int32_t gNumLocalRefs = 0;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic volatile int32_t gNumDeathRefs = 0;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void incRefsCreated(JNIEnv* env)
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int old = android_atomic_inc(&gNumRefsCreated);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (old == 200) {
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_and(0, &gNumRefsCreated);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                gBinderInternalOffsets.mForceGc);
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("Now have %d binder ops", old);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JavaVM* jnienv_to_javavm(JNIEnv* env)
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JavaVM* vm;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNIEnv* javavm_to_jnienv(JavaVM* vm)
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv* env;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ExceptionClear();
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jstring tagstr = env->NewStringUTF(LOG_TAG);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jstring msgstr = env->NewStringUTF(msg);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((tagstr == NULL) || (msgstr == NULL)) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ExceptionClear();      /* assume exception (OOM?) was thrown */
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Unable to call Log.e()\n");
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("%s", msg);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto bail;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->CallStaticIntMethod(
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep);
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (env->ExceptionCheck()) {
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* attempting to log the failure has failed */
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGW("Failed trying to log exception, msg='%s'\n", msg);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ExceptionClear();
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * It's an Error: Reraise the exception, detach this thread, and
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * wait for the fireworks. Die even more blatantly after a minute
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * if the gentler attempt doesn't do the trick.
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The GetJavaVM function isn't on the "approved" list of JNI calls
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * that can be made while an exception is pending, so we want to
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * get the VM ptr, throw the exception, and then detach the thread.
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JavaVM* vm = jnienv_to_javavm(env);
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->Throw(excep);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        vm->DetachCurrentThread();
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sleep(60);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Forcefully exiting");
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        exit(1);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *((int *) 1) = 1;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail:
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* discard local refs created for us by VM */
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->DeleteLocalRef(tagstr);
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->DeleteLocalRef(msgstr);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrickstatic void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
230727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick{
231727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
232727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    // to sync our state back to it.  See the comments in StrictMode.java.
233727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
234727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                              gStrictModeCallbackOffsets.mCallback,
235727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                              strict_policy);
236727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick}
237727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass JavaBBinderHolder;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass JavaBBinder : public BBinder
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JavaBBinder(JNIEnv* env, jobject object)
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("Creating JavaBBinder %p\n", this);
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_inc(&gNumLocalRefs);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        incRefsCreated(env);
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool    checkSubclass(const void* subclassID) const
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return subclassID == &gBinderOffsets;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jobject object() const
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mObject;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprotected:
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    virtual ~JavaBBinder()
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("Destroying JavaBBinder %p\n", this);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_dec(&gNumLocalRefs);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JNIEnv* env = javavm_to_jnienv(mVM);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->DeleteGlobalRef(mObject);
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    virtual status_t onTransact(
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JNIEnv* env = javavm_to_jnienv(mVM);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
277727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        IPCThreadState* thread_state = IPCThreadState::self();
278727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        const int strict_policy_before = thread_state->getStrictModePolicy();
2790234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick        thread_state->setLastTransactionBinderFlags(flags);
280727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("Transact from %p to Java code sending: ", this);
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //data.print();
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //printf("\n");
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            code, (int32_t)&data, (int32_t)reply, flags);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jthrowable excep = env->ExceptionOccurred();
287727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
2889013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert        if (excep) {
2899013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert            report_exception(env, excep,
2909013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert                "*** Uncaught remote exception!  "
2919013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert                "(Exceptions are not yet supported across processes.)");
2929013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert            res = JNI_FALSE;
2939013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert
2949013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert            /* clean up JNI local ref -- we don't return to Java code */
2959013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert            env->DeleteLocalRef(excep);
2969013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert        }
2979013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert
298727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // Restore the Java binder thread's state if it changed while
299727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // processing a call (as it would if the Parcel's header had a
300727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // new policy mask and Parcel.enforceInterface() changed
301727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // it...)
302727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        const int strict_policy_after = thread_state->getStrictModePolicy();
303727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        if (strict_policy_after != strict_policy_before) {
304727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick            // Our thread-local...
305727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick            thread_state->setStrictModePolicy(strict_policy_before);
306727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick            // And the Java-level thread-local...
307727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick            set_dalvik_blockguard_policy(env, strict_policy_before);
308727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        }
309727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
3109013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert        jthrowable excep2 = env->ExceptionOccurred();
3119013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert        if (excep2) {
3129013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert            report_exception(env, excep2,
3139013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert                "*** Uncaught exception in onBinderStrictModePolicyChange");
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* clean up JNI local ref -- we don't return to Java code */
3159013ccd9fcf3ac317e122aff08cb27cdac2b95feBjorn Bringert            env->DeleteLocalRef(excep2);
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //aout << "onTransact to Java code; result=" << res << endl
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    << "Transact from " << this << " to Java code returning "
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    << reply << ": " << *reply << endl;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    virtual status_t dump(int fd, const Vector<String16>& args)
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate:
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JavaVM* const   mVM;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jobject const   mObject;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass JavaBBinderHolder : public RefBase
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
3390b41448506610f73302cc631677823fd8b865ea5Christopher Tate    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoMutex _l(mLock);
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<JavaBBinder> b = mBinder.promote();
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (b == NULL) {
3440b41448506610f73302cc631677823fd8b865ea5Christopher Tate            b = new JavaBBinder(env, obj);
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBinder = b;
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n",
3470b41448506610f73302cc631677823fd8b865ea5Christopher Tate                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return b;
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<JavaBBinder> getExisting()
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AutoMutex _l(mLock);
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBinder.promote();
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate:
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Mutex           mLock;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    wp<JavaBBinder> mBinder;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3660b41448506610f73302cc631677823fd8b865ea5Christopher Tate// Per-IBinder death recipient bookkeeping.  This is how we reconcile local jobject
3670b41448506610f73302cc631677823fd8b865ea5Christopher Tate// death recipient references passed in through JNI with the permanent corresponding
3680b41448506610f73302cc631677823fd8b865ea5Christopher Tate// JavaDeathRecipient objects.
3690b41448506610f73302cc631677823fd8b865ea5Christopher Tate
3700b41448506610f73302cc631677823fd8b865ea5Christopher Tateclass JavaDeathRecipient;
3710b41448506610f73302cc631677823fd8b865ea5Christopher Tate
3720b41448506610f73302cc631677823fd8b865ea5Christopher Tateclass DeathRecipientList : public RefBase {
3730b41448506610f73302cc631677823fd8b865ea5Christopher Tate    List< sp<JavaDeathRecipient> > mList;
3740b41448506610f73302cc631677823fd8b865ea5Christopher Tate    Mutex mLock;
3750b41448506610f73302cc631677823fd8b865ea5Christopher Tate
3760b41448506610f73302cc631677823fd8b865ea5Christopher Tatepublic:
37779dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate    DeathRecipientList();
3780b41448506610f73302cc631677823fd8b865ea5Christopher Tate    ~DeathRecipientList();
3790b41448506610f73302cc631677823fd8b865ea5Christopher Tate
3800b41448506610f73302cc631677823fd8b865ea5Christopher Tate    void add(const sp<JavaDeathRecipient>& recipient);
3810b41448506610f73302cc631677823fd8b865ea5Christopher Tate    void remove(const sp<JavaDeathRecipient>& recipient);
3820b41448506610f73302cc631677823fd8b865ea5Christopher Tate    sp<JavaDeathRecipient> find(jobject recipient);
3830b41448506610f73302cc631677823fd8b865ea5Christopher Tate};
3840b41448506610f73302cc631677823fd8b865ea5Christopher Tate
3850b41448506610f73302cc631677823fd8b865ea5Christopher Tate// ----------------------------------------------------------------------------
3860b41448506610f73302cc631677823fd8b865ea5Christopher Tate
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass JavaDeathRecipient : public IBinder::DeathRecipient
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
390bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
39186284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
39286284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate          mObjectWeak(NULL), mList(list)
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
3940b41448506610f73302cc631677823fd8b865ea5Christopher Tate        // These objects manage their own lifetimes so are responsible for final bookkeeping.
3950b41448506610f73302cc631677823fd8b865ea5Christopher Tate        // The list holds a strong reference to this object.
39679dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate        LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
397bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        list->add(this);
3980b41448506610f73302cc631677823fd8b865ea5Christopher Tate
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_inc(&gNumDeathRefs);
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        incRefsCreated(env);
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void binderDied(const wp<IBinder>& who)
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
40579dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate        LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
40686284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        if (mObject != NULL) {
40786284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            JNIEnv* env = javavm_to_jnienv(mVM);
40886284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate
40986284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
41086284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate                    gBinderProxyOffsets.mSendDeathNotice, mObject);
41186284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            jthrowable excep = env->ExceptionOccurred();
41286284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            if (excep) {
41386284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate                report_exception(env, excep,
41486284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate                        "*** Uncaught exception returned from death notification!");
41586284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            }
41686284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate
41786284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            // Demote from strong ref to weak after binderDied() has been delivered,
41886284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
41986284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            mObjectWeak = env->NewWeakGlobalRef(mObject);
42086284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            env->DeleteGlobalRef(mObject);
42186284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            mObject = NULL;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void clearReference()
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
427bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        sp<DeathRecipientList> list = mList.promote();
428bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        if (list != NULL) {
42979dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate            LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
430bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate            list->remove(this);
43179dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate        } else {
43279dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate            LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
433bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        }
4340b41448506610f73302cc631677823fd8b865ea5Christopher Tate    }
4350b41448506610f73302cc631677823fd8b865ea5Christopher Tate
4360b41448506610f73302cc631677823fd8b865ea5Christopher Tate    bool matches(jobject obj) {
43786284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        bool result;
4380b41448506610f73302cc631677823fd8b865ea5Christopher Tate        JNIEnv* env = javavm_to_jnienv(mVM);
43986284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate
44086284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        if (mObject != NULL) {
44186284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            result = env->IsSameObject(obj, mObject);
44286284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        } else {
44386284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            jobject me = env->NewLocalRef(mObjectWeak);
44486284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            result = env->IsSameObject(obj, me);
44586284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            env->DeleteLocalRef(me);
44686284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        }
44786284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        return result;
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
450ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate    void warnIfStillLive() {
451ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate        if (mObject != NULL) {
452ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate            // Okay, something is wrong -- we have a hard reference to a live death
453ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate            // recipient on the VM side, but the list is being torn down.
454ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate            JNIEnv* env = javavm_to_jnienv(mVM);
455ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate            ScopedLocalRef<jclass> classRef(env, env->GetObjectClass(mObject));
456ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate            jmethodID getnameMethod = env->GetMethodID(classRef.get(),
457ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                    "getName", "()Ljava/lang/String;");
458ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate            if (getnameMethod) {
459ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                ScopedLocalRef<jstring> nameRef(env,
460ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                        (jstring) env->CallObjectMethod(classRef.get(), getnameMethod));
461ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                ScopedUtfChars nameUtf(env, nameRef.get());
462ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                if (nameUtf.c_str() != NULL) {
463ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                    LOGW("BinderProxy is being destroyed but the application did not call "
464ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                            "unlinkToDeath to unlink all of its death recipients beforehand.  "
465ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                            "Releasing leaked death recipient: %s", nameUtf.c_str());
466ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                } else {
467ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                    LOGW("BinderProxy being destroyed; unable to get DR object name");
468ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                    env->ExceptionClear();
469ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate                }
470ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate            } else LOGW("BinderProxy being destroyed; unable to find DR class getName");
471ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate        }
472ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate    }
473ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprotected:
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    virtual ~JavaDeathRecipient()
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //LOGI("Removing death ref: recipient=%p\n", mObject);
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_dec(&gNumDeathRefs);
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JNIEnv* env = javavm_to_jnienv(mVM);
48086284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        if (mObject != NULL) {
48186284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            env->DeleteGlobalRef(mObject);
48286284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        } else {
48386284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate            env->DeleteWeakGlobalRef(mObjectWeak);
48486284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        }
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate:
48886284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate    JavaVM* const mVM;
48986284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate    jobject mObject;
49086284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate    jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied()
491bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    wp<DeathRecipientList> mList;
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49679dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher TateDeathRecipientList::DeathRecipientList() {
49779dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate    LOGDEATH("New DRL @ %p", this);
49879dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate}
49979dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate
5000b41448506610f73302cc631677823fd8b865ea5Christopher TateDeathRecipientList::~DeathRecipientList() {
50179dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate    LOGDEATH("Destroy DRL @ %p", this);
5020b41448506610f73302cc631677823fd8b865ea5Christopher Tate    AutoMutex _l(mLock);
5030b41448506610f73302cc631677823fd8b865ea5Christopher Tate
5040b41448506610f73302cc631677823fd8b865ea5Christopher Tate    // Should never happen -- the JavaDeathRecipient objects that have added themselves
5050b41448506610f73302cc631677823fd8b865ea5Christopher Tate    // to the list are holding references on the list object.  Only when they are torn
5060b41448506610f73302cc631677823fd8b865ea5Christopher Tate    // down can the list header be destroyed.
5070b41448506610f73302cc631677823fd8b865ea5Christopher Tate    if (mList.size() > 0) {
508ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate        List< sp<JavaDeathRecipient> >::iterator iter;
509ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate        for (iter = mList.begin(); iter != mList.end(); iter++) {
510ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate            (*iter)->warnIfStillLive();
511ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81Christopher Tate        }
5120b41448506610f73302cc631677823fd8b865ea5Christopher Tate    }
5130b41448506610f73302cc631677823fd8b865ea5Christopher Tate}
5140b41448506610f73302cc631677823fd8b865ea5Christopher Tate
5150b41448506610f73302cc631677823fd8b865ea5Christopher Tatevoid DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
5160b41448506610f73302cc631677823fd8b865ea5Christopher Tate    AutoMutex _l(mLock);
5170b41448506610f73302cc631677823fd8b865ea5Christopher Tate
51879dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate    LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
5190b41448506610f73302cc631677823fd8b865ea5Christopher Tate    mList.push_back(recipient);
5200b41448506610f73302cc631677823fd8b865ea5Christopher Tate}
5210b41448506610f73302cc631677823fd8b865ea5Christopher Tate
5220b41448506610f73302cc631677823fd8b865ea5Christopher Tatevoid DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
5230b41448506610f73302cc631677823fd8b865ea5Christopher Tate    AutoMutex _l(mLock);
5240b41448506610f73302cc631677823fd8b865ea5Christopher Tate
5250b41448506610f73302cc631677823fd8b865ea5Christopher Tate    List< sp<JavaDeathRecipient> >::iterator iter;
5260b41448506610f73302cc631677823fd8b865ea5Christopher Tate    for (iter = mList.begin(); iter != mList.end(); iter++) {
5270b41448506610f73302cc631677823fd8b865ea5Christopher Tate        if (*iter == recipient) {
52879dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate            LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
5290b41448506610f73302cc631677823fd8b865ea5Christopher Tate            mList.erase(iter);
5300b41448506610f73302cc631677823fd8b865ea5Christopher Tate            return;
5310b41448506610f73302cc631677823fd8b865ea5Christopher Tate        }
5320b41448506610f73302cc631677823fd8b865ea5Christopher Tate    }
5330b41448506610f73302cc631677823fd8b865ea5Christopher Tate}
5340b41448506610f73302cc631677823fd8b865ea5Christopher Tate
5350b41448506610f73302cc631677823fd8b865ea5Christopher Tatesp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
5360b41448506610f73302cc631677823fd8b865ea5Christopher Tate    AutoMutex _l(mLock);
5370b41448506610f73302cc631677823fd8b865ea5Christopher Tate
5380b41448506610f73302cc631677823fd8b865ea5Christopher Tate    List< sp<JavaDeathRecipient> >::iterator iter;
5390b41448506610f73302cc631677823fd8b865ea5Christopher Tate    for (iter = mList.begin(); iter != mList.end(); iter++) {
5400b41448506610f73302cc631677823fd8b865ea5Christopher Tate        if ((*iter)->matches(recipient)) {
5410b41448506610f73302cc631677823fd8b865ea5Christopher Tate            return *iter;
5420b41448506610f73302cc631677823fd8b865ea5Christopher Tate        }
5430b41448506610f73302cc631677823fd8b865ea5Christopher Tate    }
5440b41448506610f73302cc631677823fd8b865ea5Christopher Tate    return NULL;
5450b41448506610f73302cc631677823fd8b865ea5Christopher Tate}
5460b41448506610f73302cc631677823fd8b865ea5Christopher Tate
5470b41448506610f73302cc631677823fd8b865ea5Christopher Tate// ----------------------------------------------------------------------------
5480b41448506610f73302cc631677823fd8b865ea5Christopher Tate
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    android_atomic_dec(&gNumProxyRefs);
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->DeleteGlobalRef((jobject)obj);
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic Mutex mProxyLock;
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (val == NULL) return NULL;
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (val->checkSubclass(&gBinderOffsets)) {
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // One of our own!
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jobject object = static_cast<JavaBBinder*>(val.get())->object();
56786284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return object;
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // For the rest of the function we will hold this lock, to serialize
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // looking/creation of Java proxies for native Binder proxies.
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AutoMutex _l(mProxyLock);
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Someone else's...  do we know about it?
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (object != NULL) {
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (res != NULL) {
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return res;
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
58386284c60b52c40f027427aa32dbe8dc0899b63d5Christopher Tate        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_dec(&gNumProxyRefs);
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        val->detachObject(&gBinderProxyOffsets);
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->DeleteGlobalRef(object);
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (object != NULL) {
59179dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The proxy holds a reference to the native object.
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        val->incStrong(object);
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The native object needs to hold a weak reference back to the
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // proxy, so we can retrieve the same proxy if it is still active.
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jobject refObject = env->NewGlobalRef(
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        val->attachObject(&gBinderProxyOffsets, refObject,
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                jnienv_to_javavm(env), proxy_cleanup);
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
603bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        // Also remember the death recipients registered on this proxy
604bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        sp<DeathRecipientList> drl = new DeathRecipientList;
605bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        drl->incStrong((void*)javaObjectForIBinder);
606bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
607bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Note that a new object reference has been created.
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_inc(&gNumProxyRefs);
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        incRefsCreated(env);
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return object;
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (obj == NULL) return NULL;
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetIntField(obj, gBinderOffsets.mObject);
6230b41448506610f73302cc631677823fd8b865ea5Christopher Tate        return jbh != NULL ? jbh->get(env, obj) : NULL;
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (IBinder*)
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetIntField(obj, gBinderProxyOffsets.mObject);
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGW("ibinderForJavaObject: %p is not a Binder object", obj);
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectParcel* parcelForJavaObject(JNIEnv* env, jobject obj)
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (obj) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mObject);
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p != NULL) {
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return p;
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return env->NewObject(
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid signalExceptionForError(JNIEnv* env, jobject obj, status_t err)
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (err) {
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case UNKNOWN_ERROR:
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case NO_MEMORY:
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case INVALID_OPERATION:
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case BAD_VALUE:
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case BAD_INDEX:
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case BAD_TYPE:
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case NAME_NOT_FOUND:
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/util/NoSuchElementException", NULL);
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case PERMISSION_DENIED:
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/SecurityException", NULL);
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case NOT_ENOUGH_DATA:
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case NO_INIT:
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case ALREADY_EXISTS:
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DEAD_OBJECT:
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "android/os/DeadObjectException", NULL);
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case UNKNOWN_TRANSACTION:
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case FAILED_TRANSACTION:
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("!!! FAILED BINDER TRANSACTION !!!");
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //jniThrowException(env, "java/lang/OutOfMemoryError", "Binder transaction too large");
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("Unknown binder error code. 0x%x", err);
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return IPCThreadState::self()->getCallingPid();
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return IPCThreadState::self()->getCallingUid();
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return IPCThreadState::self()->clearCallingIdentity();
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
725cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn    // XXX temporary sanity check to debug crashes.
726cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn    int uid = (int)(token>>32);
727cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn    if (uid > 0 && uid < 999) {
728cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn        // In Android currently there are no uids in this range.
729cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn        char buf[128];
730cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn        sprintf(buf, "Restoring bad calling ident: 0x%Lx", token);
731cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn        jniThrowException(env, "java/lang/IllegalStateException", buf);
732cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn        return;
733cf3004a46eabb49f3eee483067e75aef7b0a69e7Dianne Hackborn    }
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IPCThreadState::self()->restoreCallingIdentity(token);
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
737727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrickstatic void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
738727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick{
739727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    IPCThreadState::self()->setStrictModePolicy(policyMask);
740727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick}
741727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
742727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrickstatic jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
743727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick{
744727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    return IPCThreadState::self()->getStrictModePolicy();
745727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick}
746727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IPCThreadState::self()->flushCommands();
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7520b41448506610f73302cc631677823fd8b865ea5Christopher Tatestatic void android_os_Binder_init(JNIEnv* env, jobject obj)
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7540b41448506610f73302cc631677823fd8b865ea5Christopher Tate    JavaBBinderHolder* jbh = new JavaBBinderHolder();
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (jbh == NULL) {
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7590b41448506610f73302cc631677823fd8b865ea5Christopher Tate    LOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
7600b41448506610f73302cc631677823fd8b865ea5Christopher Tate    jbh->incStrong((void*)android_os_Binder_init);
7610b41448506610f73302cc631677823fd8b865ea5Christopher Tate    env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7640b41448506610f73302cc631677823fd8b865ea5Christopher Tatestatic void android_os_Binder_destroy(JNIEnv* env, jobject obj)
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JavaBBinderHolder* jbh = (JavaBBinderHolder*)
7670b41448506610f73302cc631677823fd8b865ea5Christopher Tate        env->GetIntField(obj, gBinderOffsets.mObject);
768582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown    if (jbh != NULL) {
7690b41448506610f73302cc631677823fd8b865ea5Christopher Tate        env->SetIntField(obj, gBinderOffsets.mObject, 0);
7700b41448506610f73302cc631677823fd8b865ea5Christopher Tate        LOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
7710b41448506610f73302cc631677823fd8b865ea5Christopher Tate        jbh->decStrong((void*)android_os_Binder_init);
772582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown    } else {
773582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown        // Encountering an uninitialized binder is harmless.  All it means is that
774582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown        // the Binder was only partially initialized when its finalizer ran and called
775582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown        // destroy().  The Binder could be partially initialized for several reasons.
776582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown        // For example, a Binder subclass constructor might have thrown an exception before
777582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown        // it could delegate to its superclass's constructor.  Consequently init() would
778582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown        // not have been called and the holder pointer would remain NULL.
7790b41448506610f73302cc631677823fd8b865ea5Christopher Tate        LOGV("Java Binder %p: ignoring uninitialized binder", obj);
780582763ae4e2910b4059dccdfd30a447e9fc974d5Jeff Brown    }
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const JNINativeMethod gBinderMethods[] = {
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
791727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
792727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "init", "()V", (void*)android_os_Binder_init },
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "destroy", "()V", (void*)android_os_Binder_destroy }
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const kBinderPathName = "android/os/Binder";
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int int_register_android_os_Binder(JNIEnv* env)
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz;
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass(kBinderPathName);
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderOffsets.mExecTransact
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gBinderOffsets.mExecTransact);
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderOffsets.mObject
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetFieldID(clazz, "mObject", "I");
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gBinderOffsets.mObject);
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env, kBinderPathName,
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        gBinderMethods, NELEM(gBinderMethods));
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return gNumLocalRefs;
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return gNumProxyRefs;
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return gNumDeathRefs;
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return javaObjectForIBinder(env, b);
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    android::IPCThreadState::self()->joinThreadPool();
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
860887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackbornstatic void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
861887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn        jobject clazz, jboolean disable)
862887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn{
863887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn    IPCThreadState::disableBackgroundScheduling(disable ? true : false);
864887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn}
865887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Gc has executed, clearing binder ops");
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    android_atomic_and(0, &gNumRefsCreated);
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const JNINativeMethod gBinderInternalMethods[] = {
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
878887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int int_register_android_os_BinderInternal(JNIEnv* env)
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz;
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass(kBinderInternalPathName);
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderInternalOffsets.mForceGc
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetStaticMethodID(clazz, "forceBinderGc", "()V");
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gBinderInternalOffsets.mForceGc);
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env, kBinderInternalPathName,
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        gBinderInternalMethods, NELEM(gBinderInternalMethods));
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder* target = (IBinder*)
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->GetIntField(obj, gBinderProxyOffsets.mObject);
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (target == NULL) {
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_FALSE;
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = target->pingBinder();
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject);
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (target != NULL) {
9202c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        const String16& desc = target->getInterfaceDescriptor();
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return env->NewString(desc.string(), desc.size());
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jniThrowException(env, "java/lang/RuntimeException",
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "No binder found for object");
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder* target = (IBinder*)
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->GetIntField(obj, gBinderProxyOffsets.mObject);
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (target == NULL) {
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_FALSE;
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool alive = target->isBinderAlive();
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return alive ? JNI_TRUE : JNI_FALSE;
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9392c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrickstatic int getprocname(pid_t pid, char *buf, size_t len) {
9402c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    char filename[20];
9412c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    FILE *f;
9422c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
9432c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    sprintf(filename, "/proc/%d/cmdline", pid);
9442c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    f = fopen(filename, "r");
9452c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (!f) { *buf = '\0'; return 1; }
9462c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (!fgets(buf, len, f)) { *buf = '\0'; return 2; }
9472c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    fclose(f);
9482c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    return 0;
9492c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick}
9502c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
9512c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrickstatic bool push_eventlog_string(char** pos, const char* end, const char* str) {
9522c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    jint len = strlen(str);
9532c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    int space_needed = 1 + sizeof(len) + len;
9542c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (end - *pos < space_needed) {
9552c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        LOGW("not enough space for string. remain=%d; needed=%d",
9562c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick             (end - *pos), space_needed);
9572c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        return false;
9582c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    }
9592c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    **pos = EVENT_TYPE_STRING;
9602c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    (*pos)++;
9612c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    memcpy(*pos, &len, sizeof(len));
9622c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    *pos += sizeof(len);
9632c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    memcpy(*pos, str, len);
9642c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    *pos += len;
9652c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    return true;
9662c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick}
9672c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
9682c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrickstatic bool push_eventlog_int(char** pos, const char* end, jint val) {
9692c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    int space_needed = 1 + sizeof(val);
9702c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (end - *pos < space_needed) {
9712c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        LOGW("not enough space for int.  remain=%d; needed=%d",
9722c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick             (end - *pos), space_needed);
9732c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        return false;
9742c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    }
9752c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    **pos = EVENT_TYPE_INT;
9762c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    (*pos)++;
9772c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    memcpy(*pos, &val, sizeof(val));
9782c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    *pos += sizeof(val);
9792c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    return true;
9802c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick}
9812c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
9822c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick// From frameworks/base/core/java/android/content/EventLogTags.logtags:
9832c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick#define LOGTAG_BINDER_OPERATION 52004
9842c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
9852c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrickstatic void conditionally_log_binder_call(int64_t start_millis,
9862c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick                                          IBinder* target, jint code) {
9872c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
9882c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
9892c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    int sample_percent;
9902c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (duration_ms >= 500) {
9912c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        sample_percent = 100;
9922c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    } else {
9932c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        sample_percent = 100 * duration_ms / 500;
9942c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        if (sample_percent == 0) {
9952c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick            return;
9962c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        }
9972c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        if (sample_percent < (random() % 100 + 1)) {
9982c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick            return;
9992c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        }
10002c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    }
10012c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
10022c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    char process_name[40];
10032c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    getprocname(getpid(), process_name, sizeof(process_name));
10042c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    String8 desc(target->getInterfaceDescriptor());
10052c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
10062c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    char buf[LOGGER_ENTRY_MAX_PAYLOAD];
10072c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    buf[0] = EVENT_TYPE_LIST;
10082c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    buf[1] = 5;
10092c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    char* pos = &buf[2];
10102c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1];  // leave room for final \n
10112c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (!push_eventlog_string(&pos, end, desc.string())) return;
10122c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (!push_eventlog_int(&pos, end, code)) return;
10132c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (!push_eventlog_int(&pos, end, duration_ms)) return;
10142c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (!push_eventlog_string(&pos, end, process_name)) return;
10152c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    if (!push_eventlog_int(&pos, end, sample_percent)) return;
10162c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    *(pos++) = '\n';   // conventional with EVENT_TYPE_LIST apparently.
10172c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
10182c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick}
10192c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
1020ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick// We only measure binder call durations to potentially log them if
1021ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick// we're on the main thread.  Unfortunately sim-eng doesn't seem to
1022ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick// have gettid, so we just ignore this and don't log if we can't
1023ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick// get the thread id.
1024ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrickstatic bool should_time_binder_calls() {
10255348c014129b766d621ef82a6e42007009ffc310Brad Fitzpatrick#ifdef HAVE_GETTID
10265348c014129b766d621ef82a6e42007009ffc310Brad Fitzpatrick  return (getpid() == androidGetTid());
1027ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick#else
1028ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick#warning no gettid(), so not logging Binder calls...
1029ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick  return false;
1030ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick#endif
1031ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick}
1032ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                jint code, jobject dataObj,
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                jobject replyObj, jint flags)
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dataObj == NULL) {
103869a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        jniThrowNullPointerException(env, NULL);
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_FALSE;
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* data = parcelForJavaObject(env, dataObj);
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (data == NULL) {
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_FALSE;
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* reply = parcelForJavaObject(env, replyObj);
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (reply == NULL && replyObj != NULL) {
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_FALSE;
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder* target = (IBinder*)
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->GetIntField(obj, gBinderProxyOffsets.mObject);
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (target == NULL) {
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_FALSE;
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGV("Java code calling transact on %p in Java object %p with code %d\n",
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            target, obj, code);
10602c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
10612c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    // Only log the binder call duration for things on the Java-level main thread.
1062ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick    // But if we don't
1063ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick    const bool time_binder_calls = should_time_binder_calls();
1064ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick
10652c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    int64_t start_millis;
1066ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick    if (time_binder_calls) {
10672c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        start_millis = uptimeMillis();
10682c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    }
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("Transact from Java code to %p sending: ", target); data->print();
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = target->transact(code, *data, reply, flags);
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1072ad8fd282dde705ad090b2ecdc5b363df399230abBrad Fitzpatrick    if (time_binder_calls) {
10732c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick        conditionally_log_binder_call(start_millis, target, code);
10742c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick    }
10752c5da313dd72c284fbc2c11839f8a452ab5ce574Brad Fitzpatrick
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err == NO_ERROR) {
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_TRUE;
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (err == UNKNOWN_TRANSACTION) {
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_FALSE;
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    signalExceptionForError(env, obj, err);
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return JNI_FALSE;
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               jobject recipient, jint flags)
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (recipient == NULL) {
109069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        jniThrowNullPointerException(env, NULL);
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder* target = (IBinder*)
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->GetIntField(obj, gBinderProxyOffsets.mObject);
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (target == NULL) {
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assert(false);
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
110179dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate    LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!target->localBinder()) {
1104bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        DeathRecipientList* list = (DeathRecipientList*)
1105bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate                env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
1106bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
11070b41448506610f73302cc631677823fd8b865ea5Christopher Tate        status_t err = target->linkToDeath(jdr, NULL, flags);
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Failure adding the death recipient, so clear its reference
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // now.
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jdr->clearReference();
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            signalExceptionForError(env, obj, err);
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 jobject recipient, jint flags)
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean res = JNI_FALSE;
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (recipient == NULL) {
112269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        jniThrowNullPointerException(env, NULL);
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return res;
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder* target = (IBinder*)
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->GetIntField(obj, gBinderProxyOffsets.mObject);
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (target == NULL) {
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return JNI_FALSE;
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
113379dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate    LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!target->localBinder()) {
11360b41448506610f73302cc631677823fd8b865ea5Christopher Tate        status_t err = NAME_NOT_FOUND;
1137bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate
1138bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        // If we find the matching recipient, proceed to unlink using that
1139bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        DeathRecipientList* list = (DeathRecipientList*)
1140bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate                env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
1141bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        sp<JavaDeathRecipient> origJDR = list->find(recipient);
114279dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate        LOGDEATH("   unlink found list %p and JDR %p", list, origJDR.get());
11430b41448506610f73302cc631677823fd8b865ea5Christopher Tate        if (origJDR != NULL) {
11440b41448506610f73302cc631677823fd8b865ea5Christopher Tate            wp<IBinder::DeathRecipient> dr;
11450b41448506610f73302cc631677823fd8b865ea5Christopher Tate            err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
11460b41448506610f73302cc631677823fd8b865ea5Christopher Tate            if (err == NO_ERROR && dr != NULL) {
11470b41448506610f73302cc631677823fd8b865ea5Christopher Tate                sp<IBinder::DeathRecipient> sdr = dr.promote();
11480b41448506610f73302cc631677823fd8b865ea5Christopher Tate                JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
11490b41448506610f73302cc631677823fd8b865ea5Christopher Tate                if (jdr != NULL) {
11500b41448506610f73302cc631677823fd8b865ea5Christopher Tate                    jdr->clearReference();
11510b41448506610f73302cc631677823fd8b865ea5Christopher Tate                }
11520b41448506610f73302cc631677823fd8b865ea5Christopher Tate            }
11530b41448506610f73302cc631677823fd8b865ea5Christopher Tate        }
11540b41448506610f73302cc631677823fd8b865ea5Christopher Tate
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err == NO_ERROR || err == DEAD_OBJECT) {
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            res = JNI_TRUE;
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/util/NoSuchElementException",
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              "Death link does not exist");
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder* b = (IBinder*)
1169bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate            env->GetIntField(obj, gBinderProxyOffsets.mObject);
1170bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    DeathRecipientList* drl = (DeathRecipientList*)
1171bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate            env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
1172bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate
117379dd31f73d8ca4432d6f83bef1221cc3e93e932cChristopher Tate    LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
1175bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0);
1176bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    drl->decStrong((void*)javaObjectForIBinder);
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    b->decStrong(obj);
11780b41448506610f73302cc631677823fd8b865ea5Christopher Tate
1179bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    IPCThreadState::self()->flushCommands();
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const JNINativeMethod gBinderProxyMethods[] = {
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"transact",            "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const kBinderProxyPathName = "android/os/BinderProxy";
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int int_register_android_os_BinderProxy(JNIEnv* env)
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz;
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass("java/lang/ref/WeakReference");
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference");
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gWeakReferenceOffsets.mGet
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gWeakReferenceOffsets.mGet);
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass("java/lang/Error");
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error");
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
121169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass(kBinderProxyPathName);
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderProxyOffsets.mConstructor
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetMethodID(clazz, "<init>", "()V");
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gBinderProxyOffsets.mConstructor);
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderProxyOffsets.mSendDeathNotice
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gBinderProxyOffsets.mSendDeathNotice);
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderProxyOffsets.mObject
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetFieldID(clazz, "mObject", "I");
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gBinderProxyOffsets.mObject);
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gBinderProxyOffsets.mSelf
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gBinderProxyOffsets.mSelf);
1229bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    gBinderProxyOffsets.mOrgue
1230bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate        = env->GetFieldID(clazz, "mOrgue", "I");
1231bd8b6f25bb48daea4aeb0c7463661c8e69baece0Christopher Tate    assert(gBinderProxyOffsets.mOrgue);
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env, kBinderProxyPathName,
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        gBinderProxyMethods, NELEM(gBinderProxyMethods));
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ****************************************************************************
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Parcel_dataSize(JNIEnv* env, jobject clazz)
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return parcel ? parcel->dataSize() : 0;
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Parcel_dataAvail(JNIEnv* env, jobject clazz)
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return parcel ? parcel->dataAvail() : 0;
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Parcel_dataPosition(JNIEnv* env, jobject clazz)
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return parcel ? parcel->dataPosition() : 0;
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Parcel_dataCapacity(JNIEnv* env, jobject clazz)
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return parcel ? parcel->dataCapacity() : 0;
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size)
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const status_t err = parcel->setDataSize(size);
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_setDataPosition(JNIEnv* env, jobject clazz, jint pos)
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel->setDataPosition(pos);
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint size)
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const status_t err = parcel->setDataCapacity(size);
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                          jobject data, jint offset,
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                          jint length)
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel == NULL) {
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const status_t err = parcel->writeInt32(length);
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1310a28b83ee04ca25100781f37a50665d6e1b05e3a2Elliott Hughes    void* dest = parcel->writeInplace(length);
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dest == NULL) {
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0);
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ar) {
1318a28b83ee04ca25100781f37a50665d6e1b05e3a2Elliott Hughes        memcpy(dest, ar + offset, length);
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0);
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const status_t err = parcel->writeInt32(val);
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const status_t err = parcel->writeInt64(val);
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const status_t err = parcel->writeFloat(val);
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble val)
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const status_t err = parcel->writeDouble(val);
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring val)
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = NO_MEMORY;
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (val) {
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const jchar* str = env->GetStringCritical(val, 0);
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (str) {
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = parcel->writeString16(str, env->GetStringLength(val));
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                env->ReleaseStringCritical(val, str);
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            err = parcel->writeString16(NULL, 0);
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
1403a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes        const status_t err =
1404a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes                parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err != NO_ERROR) {
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jobject clazz)
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jbyteArray ret = NULL;
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t len = parcel->readInt32();
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // sanity check the stored length against the true data size
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret = env->NewByteArray(len);
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ret != NULL) {
14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (a2) {
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const void* data = parcel->readInplace(len);
14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    memcpy(a2, data, len);
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    env->ReleasePrimitiveArrayCritical(ret, a2, 0);
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ret;
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return parcel->readInt32();
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Parcel_readLong(JNIEnv* env, jobject clazz)
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return parcel->readInt64();
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfloat android_os_Parcel_readFloat(JNIEnv* env, jobject clazz)
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return parcel->readFloat();
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jdouble android_os_Parcel_readDouble(JNIEnv* env, jobject clazz)
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return parcel->readDouble();
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring android_os_Parcel_readString(JNIEnv* env, jobject clazz)
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t len;
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char16_t* str = parcel->readString16Inplace(&len);
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (str) {
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return env->NewString(str, len);
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz)
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return javaObjectForIBinder(env, parcel->readStrongBinder());
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jobject clazz)
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int fd = parcel->readFileDescriptor();
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fd < 0) return NULL;
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fd = dup(fd);
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fd < 0) return NULL;
1504a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes        return jniCreateFileDescriptor(env, fd);
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jobject clazz,
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    jstring name, jint mode)
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name == NULL) {
151369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        jniThrowNullPointerException(env, NULL);
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const jchar* str = env->GetStringCritical(name, 0);
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (str == NULL) {
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Whatever, whatever.
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/IllegalStateException", NULL);
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 name8(str, env->GetStringLength(name));
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseStringCritical(name, str);
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int flags=0;
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (mode&0x30000000) {
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 0:
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 0x10000000:
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flags = O_RDONLY;
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 0x20000000:
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flags = O_WRONLY;
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 0x30000000:
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flags = O_RDWR;
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mode&0x08000000) flags |= O_CREAT;
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mode&0x04000000) flags |= O_TRUNC;
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mode&0x02000000) flags |= O_APPEND;
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int realMode = S_IRWXU|S_IRWXG;
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mode&0x00000001) realMode |= S_IROTH;
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mode&0x00000002) realMode |= S_IWOTH;
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int fd = open(name8.string(), flags, realMode);
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fd < 0) {
1548e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
1549e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        return NULL;
1550e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
1551a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes    jobject object = jniCreateFileDescriptor(env, fd);
1552e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    if (object == NULL) {
1553e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        close(fd);
1554e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
1555e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    return object;
1556e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn}
1557e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
1558e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornstatic jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jobject clazz, jobject orig)
1559e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn{
1560e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    if (orig == NULL) {
156169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        jniThrowNullPointerException(env, NULL);
1562e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        return NULL;
1563e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
1564a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes    int origfd = jniGetFDFromFileDescriptor(env, orig);
1565e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    if (origfd < 0) {
1566e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor");
1567e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        return NULL;
1568e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
1569e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
1570e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    int fd = dup(origfd);
1571e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    if (fd < 0) {
157269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        jniThrowIOException(env, errno);
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1575a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes    jobject object = jniCreateFileDescriptor(env, fd);
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (object == NULL) {
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        close(fd);
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return object;
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1584e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    if (object == NULL) {
158569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        jniThrowNullPointerException(env, NULL);
1586e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        return;
1587e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
1588a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes    int fd = jniGetFDFromFileDescriptor(env, object);
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fd >= 0) {
1590a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes        jniSetFileDescriptorOfFD(env, object, -1);
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //LOGI("Closing ParcelFileDescriptor %d\n", fd);
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        close(fd);
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1596c9119f5034d36f548bbddd8f60291e24ab4e270bDianne Hackbornstatic void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
1597c9119f5034d36f548bbddd8f60291e24ab4e270bDianne Hackborn{
1598e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    if (object == NULL) {
159969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes        jniThrowNullPointerException(env, NULL);
1600e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        return;
1601e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
1602a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes    int fd = jniGetFDFromFileDescriptor(env, object);
1603c9119f5034d36f548bbddd8f60291e24ab4e270bDianne Hackborn    if (fd >= 0) {
1604a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes        jniSetFileDescriptorOfFD(env, object, -1);
1605c9119f5034d36f548bbddd8f60291e24ab4e270bDianne Hackborn    }
1606c9119f5034d36f548bbddd8f60291e24ab4e270bDianne Hackborn}
1607c9119f5034d36f548bbddd8f60291e24ab4e270bDianne Hackborn
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_freeBuffer(JNIEnv* env, jobject clazz)
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (own) {
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel* parcel = parcelForJavaObject(env, clazz);
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (parcel != NULL) {
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //LOGI("Parcel.freeBuffer() called for C++ Parcel %p\n", parcel);
16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parcel->freeData();
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_init(JNIEnv* env, jobject clazz, jint parcelInt)
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = (Parcel*)parcelInt;
16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int own = 0;
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!parcel) {
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //LOGI("Initializing obj %p: creating new Parcel\n", clazz);
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        own = 1;
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel = new Parcel;
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //LOGI("Initializing obj %p: given existing Parcel %p\n", clazz, parcel);
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel == NULL) {
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //LOGI("Initializing obj %p from C++ Parcel %p, own=%d\n", clazz, parcel, own);
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(clazz, gParcelOffsets.mOwnObject, own);
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(clazz, gParcelOffsets.mObject, (int)parcel);
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_destroy(JNIEnv* env, jobject clazz)
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (own) {
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel* parcel = parcelForJavaObject(env, clazz);
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetIntField(clazz, gParcelOffsets.mObject, 0);
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //LOGI("Destroying obj %p: deleting C++ Parcel %p\n", clazz, parcel);
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete parcel;
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetIntField(clazz, gParcelOffsets.mObject, 0);
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //LOGI("Destroying obj %p: leaving C++ Parcel %p\n", clazz);
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jbyteArray android_os_Parcel_marshall(JNIEnv* env, jobject clazz)
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel == NULL) {
16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project       return NULL;
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // do not marshall if there are binder objects in the parcel
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel->objectsCount())
16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jbyteArray ret = env->NewByteArray(parcel->dataSize());
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ret != NULL)
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (array != NULL)
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(array, parcel->data(), parcel->dataSize());
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleasePrimitiveArrayCritical(ret, array, 0);
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ret;
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_unmarshall(JNIEnv* env, jobject clazz, jbyteArray data, jint offset, jint length)
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel == NULL || length < 0) {
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project       return;
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (array)
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel->setDataSize(length);
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel->setDataPosition(0);
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void* raw = parcel->writeInplace(length);
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(raw, (array + offset), length);
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ReleasePrimitiveArrayCritical(data, array, 0);
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject parcel, jint offset, jint length)
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* thisParcel = parcelForJavaObject(env, clazz);
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (thisParcel == NULL) {
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project       return;
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* otherParcel = parcelForJavaObject(env, parcel);
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (otherParcel == NULL) {
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project       return;
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    (void) thisParcel->appendFrom(otherParcel, offset, length);
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean ret = JNI_FALSE;
17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (parcel->hasFileDescriptors()) {
17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ret = JNI_TRUE;
17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ret;
17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, jstring name)
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // In the current implementation, the token is just the serialized interface name that
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the caller expects to be invoking
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* str = env->GetStringCritical(name, 0);
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (str != NULL) {
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleaseStringCritical(name, str);
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_os_Parcel_enforceInterface(JNIEnv* env, jobject clazz, jstring name)
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean ret = JNI_FALSE;
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel* parcel = parcelForJavaObject(env, clazz);
17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (parcel != NULL) {
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const jchar* str = env->GetStringCritical(name, 0);
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (str) {
17517bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick            IPCThreadState* threadState = IPCThreadState::self();
17527bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick            const int32_t oldPolicy = threadState->getStrictModePolicy();
17537bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick            const bool isValid = parcel->enforceInterface(
1754727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                String16(str, env->GetStringLength(name)),
17557bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick                threadState);
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleaseStringCritical(name, str);
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isValid) {
17587bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick                const int32_t newPolicy = threadState->getStrictModePolicy();
17597bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick                if (oldPolicy != newPolicy) {
1760727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // Need to keep the Java-level thread-local strict
1761727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // mode policy in sync for the libcore
1762727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // enforcements, which involves an upcall back
1763727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // into Java.  (We can't modify the
1764727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // Parcel.enforceInterface signature, as it's
1765727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // pseudo-public, and used via AIDL
1766727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // auto-generation...)
17677bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick                    set_dalvik_blockguard_policy(env, newPolicy);
1768727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                }
17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;     // everything was correct -> return silently
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // all error conditions wind up here
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jniThrowException(env, "java/lang/SecurityException",
17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "Binder invocation to an incorrect interface");
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const JNINativeMethod gParcelMethods[] = {
17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"dataSize",            "()I", (void*)android_os_Parcel_dataSize},
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"dataAvail",           "()I", (void*)android_os_Parcel_dataAvail},
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"dataPosition",        "()I", (void*)android_os_Parcel_dataPosition},
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"dataCapacity",        "()I", (void*)android_os_Parcel_dataCapacity},
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"setDataSize",         "(I)V", (void*)android_os_Parcel_setDataSize},
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"setDataPosition",     "(I)V", (void*)android_os_Parcel_setDataPosition},
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"setDataCapacity",     "(I)V", (void*)android_os_Parcel_setDataCapacity},
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeNative",         "([BII)V", (void*)android_os_Parcel_writeNative},
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeInt",            "(I)V", (void*)android_os_Parcel_writeInt},
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeLong",           "(J)V", (void*)android_os_Parcel_writeLong},
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeFloat",          "(F)V", (void*)android_os_Parcel_writeFloat},
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeDouble",         "(D)V", (void*)android_os_Parcel_writeDouble},
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeString",         "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeString},
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeStrongBinder",   "(Landroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"createByteArray",     "()[B", (void*)android_os_Parcel_createByteArray},
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"readInt",             "()I", (void*)android_os_Parcel_readInt},
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"readLong",            "()J", (void*)android_os_Parcel_readLong},
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"readFloat",           "()F", (void*)android_os_Parcel_readFloat},
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"readDouble",          "()D", (void*)android_os_Parcel_readDouble},
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"readString",          "()Ljava/lang/String;", (void*)android_os_Parcel_readString},
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"readStrongBinder",    "()Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"internalReadFileDescriptor",  "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"openFileDescriptor",  "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
1806e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    {"dupFileDescriptor",   "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
1808c9119f5034d36f548bbddd8f60291e24ab4e270bDianne Hackborn    {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"freeBuffer",          "()V", (void*)android_os_Parcel_freeBuffer},
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"init",                "(I)V", (void*)android_os_Parcel_init},
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"destroy",             "()V", (void*)android_os_Parcel_destroy},
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"marshall",            "()[B", (void*)android_os_Parcel_marshall},
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"unmarshall",          "([BII)V", (void*)android_os_Parcel_unmarshall},
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"appendFrom",          "(Landroid/os/Parcel;II)V", (void*)android_os_Parcel_appendFrom},
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"hasFileDescriptors",  "()Z", (void*)android_os_Parcel_hasFileDescriptors},
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"writeInterfaceToken", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"enforceInterface",    "(Ljava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* const kParcelPathName = "android/os/Parcel";
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int int_register_android_os_Parcel(JNIEnv* env)
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz;
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass("android/util/Log");
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.util.Log");
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gLogOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gLogOffsets.mLogE = env->GetStaticMethodID(
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    assert(gLogOffsets.mLogE);
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass("android/os/ParcelFileDescriptor");
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gParcelFileDescriptorOffsets.mConstructor
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass(kParcelPathName);
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gParcelOffsets.mObject
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetFieldID(clazz, "mObject", "I");
18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gParcelOffsets.mOwnObject
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        = env->GetFieldID(clazz, "mOwnObject", "I");
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1847727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    clazz = env->FindClass("android/os/StrictMode");
1848727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.StrictMode");
1849727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    gStrictModeCallbackOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
1850727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    gStrictModeCallbackOffsets.mCallback = env->GetStaticMethodID(
1851727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        clazz, "onBinderStrictModePolicyChange", "(I)V");
1852727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    LOG_FATAL_IF(gStrictModeCallbackOffsets.mCallback == NULL,
1853727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                 "Unable to find strict mode callback.");
1854727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env, kParcelPathName,
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        gParcelMethods, NELEM(gParcelMethods));
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_os_Binder(JNIEnv* env)
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (int_register_android_os_Binder(env) < 0)
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (int_register_android_os_BinderInternal(env) < 0)
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (int_register_android_os_BinderProxy(env) < 0)
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (int_register_android_os_Parcel(env) < 0)
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1872