blob: 26b00344b789da2b9134b81fcf2d11e5834ac7b2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "JavaBinder"
18//#define LOG_NDEBUG 0
19
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080020#include "android_os_Parcel.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021#include "android_util_Binder.h"
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -080022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023#include "JNIHelp.h"
24
25#include <fcntl.h>
Mark Salyzyncfd91e72014-04-17 15:40:01 -070026#include <inttypes.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027#include <stdio.h>
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -070028#include <sys/stat.h>
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -070029#include <sys/types.h>
Brad Fitzpatrick8f26b322010-03-25 00:25:37 -070030#include <unistd.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
Andreas Gampe58383ba2017-06-12 10:43:05 -070032#include <android-base/stringprintf.h>
Mathias Agopian07952722009-05-19 19:08:10 -070033#include <binder/IInterface.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070034#include <binder/IServiceManager.h>
Mathias Agopian07952722009-05-19 19:08:10 -070035#include <binder/IPCThreadState.h>
Mathias Agopian07952722009-05-19 19:08:10 -070036#include <binder/Parcel.h>
37#include <binder/ProcessState.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070038#include <log/log.h>
39#include <utils/Atomic.h>
40#include <utils/KeyedVector.h>
41#include <utils/List.h>
42#include <utils/Log.h>
Jeff Brown0bde66a2011-11-07 12:50:08 -080043#include <utils/String8.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070044#include <utils/SystemClock.h>
45#include <utils/threads.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046
Christopher Tateac5e3502011-08-25 15:48:09 -070047#include <ScopedUtfChars.h>
48#include <ScopedLocalRef.h>
49
Andreas Gampe987f79f2014-11-18 17:29:46 -080050#include "core_jni_helpers.h"
51
Steve Block71f2cf12011-10-20 11:56:00 +010052//#undef ALOGV
53//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054
Christopher Tate79dd31f2011-03-04 17:45:00 -080055#define DEBUG_DEATH 0
56#if DEBUG_DEATH
Steve Block5baa3a62011-12-20 16:23:08 +000057#define LOGDEATH ALOGD
Christopher Tate79dd31f2011-03-04 17:45:00 -080058#else
Steve Block71f2cf12011-10-20 11:56:00 +010059#define LOGDEATH ALOGV
Christopher Tate79dd31f2011-03-04 17:45:00 -080060#endif
61
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062using namespace android;
63
64// ----------------------------------------------------------------------------
65
66static struct bindernative_offsets_t
67{
68 // Class state.
69 jclass mClass;
70 jmethodID mExecTransact;
71
72 // Object state.
73 jfieldID mObject;
74
75} gBinderOffsets;
76
77// ----------------------------------------------------------------------------
78
79static struct binderinternal_offsets_t
80{
81 // Class state.
82 jclass mClass;
83 jmethodID mForceGc;
84
85} gBinderInternalOffsets;
86
87// ----------------------------------------------------------------------------
88
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089static struct error_offsets_t
90{
91 jclass mClass;
92} gErrorOffsets;
93
94// ----------------------------------------------------------------------------
95
96static struct binderproxy_offsets_t
97{
98 // Class state.
99 jclass mClass;
100 jmethodID mConstructor;
101 jmethodID mSendDeathNotice;
102
103 // Object state.
104 jfieldID mObject;
105 jfieldID mSelf;
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800106 jfieldID mOrgue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
108} gBinderProxyOffsets;
109
Christopher Tate0d4a7922011-08-30 12:09:43 -0700110static struct class_offsets_t
111{
112 jmethodID mGetName;
113} gClassOffsets;
114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115// ----------------------------------------------------------------------------
116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117static struct log_offsets_t
118{
119 // Class state.
120 jclass mClass;
121 jmethodID mLogE;
122} gLogOffsets;
123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124static struct parcel_file_descriptor_offsets_t
125{
126 jclass mClass;
127 jmethodID mConstructor;
128} gParcelFileDescriptorOffsets;
129
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700130static struct strict_mode_callback_offsets_t
131{
132 jclass mClass;
133 jmethodID mCallback;
134} gStrictModeCallbackOffsets;
135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136// ****************************************************************************
137// ****************************************************************************
138// ****************************************************************************
139
140static volatile int32_t gNumRefsCreated = 0;
141static volatile int32_t gNumProxyRefs = 0;
142static volatile int32_t gNumLocalRefs = 0;
143static volatile int32_t gNumDeathRefs = 0;
144
145static void incRefsCreated(JNIEnv* env)
146{
147 int old = android_atomic_inc(&gNumRefsCreated);
148 if (old == 200) {
149 android_atomic_and(0, &gNumRefsCreated);
150 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
151 gBinderInternalOffsets.mForceGc);
152 } else {
Steve Block71f2cf12011-10-20 11:56:00 +0100153 ALOGV("Now have %d binder ops", old);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 }
155}
156
157static JavaVM* jnienv_to_javavm(JNIEnv* env)
158{
159 JavaVM* vm;
160 return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
161}
162
163static JNIEnv* javavm_to_jnienv(JavaVM* vm)
164{
165 JNIEnv* env;
166 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
167}
168
169static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
170{
171 env->ExceptionClear();
172
173 jstring tagstr = env->NewStringUTF(LOG_TAG);
Mathieu Chartiercf6775e2014-08-06 13:39:17 -0700174 jstring msgstr = NULL;
175 if (tagstr != NULL) {
176 msgstr = env->NewStringUTF(msg);
177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178
179 if ((tagstr == NULL) || (msgstr == NULL)) {
180 env->ExceptionClear(); /* assume exception (OOM?) was thrown */
Steve Block3762c312012-01-06 19:20:56 +0000181 ALOGE("Unable to call Log.e()\n");
182 ALOGE("%s", msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 goto bail;
184 }
185
186 env->CallStaticIntMethod(
187 gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep);
188 if (env->ExceptionCheck()) {
189 /* attempting to log the failure has failed */
Steve Block8564c8d2012-01-05 23:22:43 +0000190 ALOGW("Failed trying to log exception, msg='%s'\n", msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 env->ExceptionClear();
192 }
193
194 if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
195 /*
Narayan Kamath83a24af2017-04-12 11:50:10 +0100196 * It's an Error: Reraise the exception and ask the runtime to abort.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 */
Andreas Gampe58383ba2017-06-12 10:43:05 -0700198
199 // Try to get the exception string. Sometimes logcat isn't available,
200 // so try to add it to the abort message.
201 std::string exc_msg = "(Unknown exception message)";
202 {
203 ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(excep));
204 jmethodID method_id = env->GetMethodID(exc_class.get(),
205 "toString",
206 "()Ljava/lang/String;");
207 ScopedLocalRef<jstring> jstr(
208 env,
209 reinterpret_cast<jstring>(
210 env->CallObjectMethod(excep, method_id)));
211 env->ExceptionClear(); // Just for good measure.
212 if (jstr.get() != nullptr) {
213 ScopedUtfChars jstr_utf(env, jstr.get());
214 exc_msg = jstr_utf.c_str();
215 }
216 }
217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 env->Throw(excep);
Narayan Kamathcfd0f9b2017-04-18 17:48:39 +0100219 ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
220 env->ExceptionDescribe();
Andreas Gampe58383ba2017-06-12 10:43:05 -0700221
222 std::string error_msg = base::StringPrintf(
223 "java.lang.Error thrown during binder transaction: %s",
224 exc_msg.c_str());
225 env->FatalError(error_msg.c_str());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 }
227
228bail:
229 /* discard local refs created for us by VM */
230 env->DeleteLocalRef(tagstr);
231 env->DeleteLocalRef(msgstr);
232}
233
234class JavaBBinderHolder;
235
236class JavaBBinder : public BBinder
237{
238public:
239 JavaBBinder(JNIEnv* env, jobject object)
240 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
241 {
Steve Block71f2cf12011-10-20 11:56:00 +0100242 ALOGV("Creating JavaBBinder %p\n", this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 android_atomic_inc(&gNumLocalRefs);
244 incRefsCreated(env);
245 }
246
247 bool checkSubclass(const void* subclassID) const
248 {
249 return subclassID == &gBinderOffsets;
250 }
251
252 jobject object() const
253 {
254 return mObject;
255 }
256
257protected:
258 virtual ~JavaBBinder()
259 {
Steve Block71f2cf12011-10-20 11:56:00 +0100260 ALOGV("Destroying JavaBBinder %p\n", this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 android_atomic_dec(&gNumLocalRefs);
262 JNIEnv* env = javavm_to_jnienv(mVM);
263 env->DeleteGlobalRef(mObject);
264 }
265
266 virtual status_t onTransact(
267 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
268 {
269 JNIEnv* env = javavm_to_jnienv(mVM);
270
Steve Block71f2cf12011-10-20 11:56:00 +0100271 ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700273 IPCThreadState* thread_state = IPCThreadState::self();
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700274 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 //printf("Transact from %p to Java code sending: ", this);
277 //data.print();
278 //printf("\n");
279 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000280 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700281
Mathieu Chartier98671c32014-08-20 10:04:08 -0700282 if (env->ExceptionCheck()) {
283 jthrowable excep = env->ExceptionOccurred();
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100284 report_exception(env, excep,
285 "*** Uncaught remote exception! "
286 "(Exceptions are not yet supported across processes.)");
287 res = JNI_FALSE;
288
289 /* clean up JNI local ref -- we don't return to Java code */
290 env->DeleteLocalRef(excep);
291 }
292
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700293 // Check if the strict mode state changed while processing the
294 // call. The Binder state will be restored by the underlying
295 // Binder system in IPCThreadState, however we need to take care
296 // of the parallel Java state as well.
297 if (thread_state->getStrictModePolicy() != strict_policy_before) {
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700298 set_dalvik_blockguard_policy(env, strict_policy_before);
299 }
300
Mathieu Chartier98671c32014-08-20 10:04:08 -0700301 if (env->ExceptionCheck()) {
302 jthrowable excep = env->ExceptionOccurred();
303 report_exception(env, excep,
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100304 "*** Uncaught exception in onBinderStrictModePolicyChange");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 /* clean up JNI local ref -- we don't return to Java code */
Mathieu Chartier98671c32014-08-20 10:04:08 -0700306 env->DeleteLocalRef(excep);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 }
308
Dianne Hackborna53de062012-05-08 18:53:51 -0700309 // Need to always call through the native implementation of
310 // SYSPROPS_TRANSACTION.
311 if (code == SYSPROPS_TRANSACTION) {
312 BBinder::onTransact(code, data, reply, flags);
313 }
314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 //aout << "onTransact to Java code; result=" << res << endl
316 // << "Transact from " << this << " to Java code returning "
317 // << reply << ": " << *reply << endl;
318 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
319 }
320
321 virtual status_t dump(int fd, const Vector<String16>& args)
322 {
323 return 0;
324 }
325
326private:
327 JavaVM* const mVM;
328 jobject const mObject;
329};
330
331// ----------------------------------------------------------------------------
332
333class JavaBBinderHolder : public RefBase
334{
335public:
Christopher Tate0b414482011-02-17 13:00:38 -0800336 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 {
338 AutoMutex _l(mLock);
339 sp<JavaBBinder> b = mBinder.promote();
340 if (b == NULL) {
Christopher Tate0b414482011-02-17 13:00:38 -0800341 b = new JavaBBinder(env, obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 mBinder = b;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700343 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
Christopher Tate0b414482011-02-17 13:00:38 -0800344 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 }
346
347 return b;
348 }
349
350 sp<JavaBBinder> getExisting()
351 {
352 AutoMutex _l(mLock);
353 return mBinder.promote();
354 }
355
356private:
357 Mutex mLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 wp<JavaBBinder> mBinder;
359};
360
361// ----------------------------------------------------------------------------
362
Christopher Tate0b414482011-02-17 13:00:38 -0800363// Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
364// death recipient references passed in through JNI with the permanent corresponding
365// JavaDeathRecipient objects.
366
367class JavaDeathRecipient;
368
369class DeathRecipientList : public RefBase {
370 List< sp<JavaDeathRecipient> > mList;
371 Mutex mLock;
372
373public:
Christopher Tate79dd31f2011-03-04 17:45:00 -0800374 DeathRecipientList();
Christopher Tate0b414482011-02-17 13:00:38 -0800375 ~DeathRecipientList();
376
377 void add(const sp<JavaDeathRecipient>& recipient);
378 void remove(const sp<JavaDeathRecipient>& recipient);
379 sp<JavaDeathRecipient> find(jobject recipient);
Christopher Tate090c08f2015-05-19 18:16:58 -0700380
381 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
Christopher Tate0b414482011-02-17 13:00:38 -0800382};
383
384// ----------------------------------------------------------------------------
385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386class JavaDeathRecipient : public IBinder::DeathRecipient
387{
388public:
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800389 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
Christopher Tate86284c62011-08-17 15:19:29 -0700390 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
391 mObjectWeak(NULL), mList(list)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 {
Christopher Tate0b414482011-02-17 13:00:38 -0800393 // These objects manage their own lifetimes so are responsible for final bookkeeping.
394 // The list holds a strong reference to this object.
Christopher Tate79dd31f2011-03-04 17:45:00 -0800395 LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800396 list->add(this);
Christopher Tate0b414482011-02-17 13:00:38 -0800397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 android_atomic_inc(&gNumDeathRefs);
399 incRefsCreated(env);
400 }
401
402 void binderDied(const wp<IBinder>& who)
403 {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800404 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
Christopher Tate86284c62011-08-17 15:19:29 -0700405 if (mObject != NULL) {
406 JNIEnv* env = javavm_to_jnienv(mVM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407
Christopher Tate86284c62011-08-17 15:19:29 -0700408 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
409 gBinderProxyOffsets.mSendDeathNotice, mObject);
Mathieu Chartier98671c32014-08-20 10:04:08 -0700410 if (env->ExceptionCheck()) {
411 jthrowable excep = env->ExceptionOccurred();
Christopher Tate86284c62011-08-17 15:19:29 -0700412 report_exception(env, excep,
413 "*** Uncaught exception returned from death notification!");
414 }
415
Christopher Tate090c08f2015-05-19 18:16:58 -0700416 // Serialize with our containing DeathRecipientList so that we can't
417 // delete the global ref on mObject while the list is being iterated.
418 sp<DeathRecipientList> list = mList.promote();
419 if (list != NULL) {
420 AutoMutex _l(list->lock());
421
422 // Demote from strong ref to weak after binderDied() has been delivered,
423 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
424 mObjectWeak = env->NewWeakGlobalRef(mObject);
425 env->DeleteGlobalRef(mObject);
426 mObject = NULL;
427 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 }
430
431 void clearReference()
432 {
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800433 sp<DeathRecipientList> list = mList.promote();
434 if (list != NULL) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800435 LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800436 list->remove(this);
Christopher Tate79dd31f2011-03-04 17:45:00 -0800437 } else {
438 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800439 }
Christopher Tate0b414482011-02-17 13:00:38 -0800440 }
441
442 bool matches(jobject obj) {
Christopher Tate86284c62011-08-17 15:19:29 -0700443 bool result;
Christopher Tate0b414482011-02-17 13:00:38 -0800444 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate86284c62011-08-17 15:19:29 -0700445
446 if (mObject != NULL) {
447 result = env->IsSameObject(obj, mObject);
448 } else {
449 jobject me = env->NewLocalRef(mObjectWeak);
450 result = env->IsSameObject(obj, me);
451 env->DeleteLocalRef(me);
452 }
453 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 }
455
Christopher Tateac5e3502011-08-25 15:48:09 -0700456 void warnIfStillLive() {
457 if (mObject != NULL) {
458 // Okay, something is wrong -- we have a hard reference to a live death
459 // recipient on the VM side, but the list is being torn down.
460 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate0d4a7922011-08-30 12:09:43 -0700461 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
462 ScopedLocalRef<jstring> nameRef(env,
463 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
464 ScopedUtfChars nameUtf(env, nameRef.get());
465 if (nameUtf.c_str() != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +0000466 ALOGW("BinderProxy is being destroyed but the application did not call "
Christopher Tate0d4a7922011-08-30 12:09:43 -0700467 "unlinkToDeath to unlink all of its death recipients beforehand. "
468 "Releasing leaked death recipient: %s", nameUtf.c_str());
469 } else {
Steve Block8564c8d2012-01-05 23:22:43 +0000470 ALOGW("BinderProxy being destroyed; unable to get DR object name");
Christopher Tate0d4a7922011-08-30 12:09:43 -0700471 env->ExceptionClear();
472 }
Christopher Tateac5e3502011-08-25 15:48:09 -0700473 }
474 }
475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476protected:
477 virtual ~JavaDeathRecipient()
478 {
Steve Block6215d3f2012-01-04 20:05:49 +0000479 //ALOGI("Removing death ref: recipient=%p\n", mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 android_atomic_dec(&gNumDeathRefs);
481 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate86284c62011-08-17 15:19:29 -0700482 if (mObject != NULL) {
483 env->DeleteGlobalRef(mObject);
484 } else {
485 env->DeleteWeakGlobalRef(mObjectWeak);
486 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 }
488
489private:
Christopher Tate86284c62011-08-17 15:19:29 -0700490 JavaVM* const mVM;
491 jobject mObject;
492 jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied()
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800493 wp<DeathRecipientList> mList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494};
495
496// ----------------------------------------------------------------------------
497
Christopher Tate79dd31f2011-03-04 17:45:00 -0800498DeathRecipientList::DeathRecipientList() {
499 LOGDEATH("New DRL @ %p", this);
500}
501
Christopher Tate0b414482011-02-17 13:00:38 -0800502DeathRecipientList::~DeathRecipientList() {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800503 LOGDEATH("Destroy DRL @ %p", this);
Christopher Tate0b414482011-02-17 13:00:38 -0800504 AutoMutex _l(mLock);
505
506 // Should never happen -- the JavaDeathRecipient objects that have added themselves
507 // to the list are holding references on the list object. Only when they are torn
508 // down can the list header be destroyed.
509 if (mList.size() > 0) {
Christopher Tateac5e3502011-08-25 15:48:09 -0700510 List< sp<JavaDeathRecipient> >::iterator iter;
511 for (iter = mList.begin(); iter != mList.end(); iter++) {
512 (*iter)->warnIfStillLive();
513 }
Christopher Tate0b414482011-02-17 13:00:38 -0800514 }
515}
516
517void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
518 AutoMutex _l(mLock);
519
Christopher Tate79dd31f2011-03-04 17:45:00 -0800520 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
Christopher Tate0b414482011-02-17 13:00:38 -0800521 mList.push_back(recipient);
522}
523
524void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
525 AutoMutex _l(mLock);
526
527 List< sp<JavaDeathRecipient> >::iterator iter;
528 for (iter = mList.begin(); iter != mList.end(); iter++) {
529 if (*iter == recipient) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800530 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
Christopher Tate0b414482011-02-17 13:00:38 -0800531 mList.erase(iter);
532 return;
533 }
534 }
535}
536
537sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
538 AutoMutex _l(mLock);
539
540 List< sp<JavaDeathRecipient> >::iterator iter;
541 for (iter = mList.begin(); iter != mList.end(); iter++) {
542 if ((*iter)->matches(recipient)) {
543 return *iter;
544 }
545 }
546 return NULL;
547}
548
Christopher Tate090c08f2015-05-19 18:16:58 -0700549Mutex& DeathRecipientList::lock() {
550 return mLock;
551}
552
Christopher Tate0b414482011-02-17 13:00:38 -0800553// ----------------------------------------------------------------------------
554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555namespace android {
556
557static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
558{
559 android_atomic_dec(&gNumProxyRefs);
560 JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
561 env->DeleteGlobalRef((jobject)obj);
562}
563
564static Mutex mProxyLock;
565
566jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
567{
568 if (val == NULL) return NULL;
569
570 if (val->checkSubclass(&gBinderOffsets)) {
571 // One of our own!
572 jobject object = static_cast<JavaBBinder*>(val.get())->object();
Christopher Tate86284c62011-08-17 15:19:29 -0700573 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 return object;
575 }
576
577 // For the rest of the function we will hold this lock, to serialize
Christopher Tate10c3a282016-02-26 17:48:08 -0800578 // looking/creation/destruction of Java proxies for native Binder proxies.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 AutoMutex _l(mProxyLock);
580
581 // Someone else's... do we know about it?
582 jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
583 if (object != NULL) {
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700584 jobject res = jniGetReferent(env, object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 if (res != NULL) {
Steve Block71f2cf12011-10-20 11:56:00 +0100586 ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 return res;
588 }
Christopher Tate86284c62011-08-17 15:19:29 -0700589 LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 android_atomic_dec(&gNumProxyRefs);
591 val->detachObject(&gBinderProxyOffsets);
592 env->DeleteGlobalRef(object);
593 }
594
595 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
596 if (object != NULL) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800597 LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 // The proxy holds a reference to the native object.
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000599 env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800600 val->incStrong((void*)javaObjectForIBinder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601
602 // The native object needs to hold a weak reference back to the
603 // proxy, so we can retrieve the same proxy if it is still active.
604 jobject refObject = env->NewGlobalRef(
605 env->GetObjectField(object, gBinderProxyOffsets.mSelf));
606 val->attachObject(&gBinderProxyOffsets, refObject,
607 jnienv_to_javavm(env), proxy_cleanup);
608
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800609 // Also remember the death recipients registered on this proxy
610 sp<DeathRecipientList> drl = new DeathRecipientList;
611 drl->incStrong((void*)javaObjectForIBinder);
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000612 env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 // Note that a new object reference has been created.
615 android_atomic_inc(&gNumProxyRefs);
616 incRefsCreated(env);
617 }
618
619 return object;
620}
621
622sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
623{
624 if (obj == NULL) return NULL;
625
626 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
627 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000628 env->GetLongField(obj, gBinderOffsets.mObject);
Christopher Tate0b414482011-02-17 13:00:38 -0800629 return jbh != NULL ? jbh->get(env, obj) : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 }
631
632 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
633 return (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000634 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 }
636
Steve Block8564c8d2012-01-05 23:22:43 +0000637 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638 return NULL;
639}
640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
642{
643 return env->NewObject(
644 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
645}
646
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800647void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
648{
649 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
650 // to sync our state back to it. See the comments in StrictMode.java.
651 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
652 gStrictModeCallbackOffsets.mCallback,
653 strict_policy);
654}
655
656void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
Dianne Hackborne5c42622015-05-19 16:04:04 -0700657 bool canThrowRemoteException, int parcelSize)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658{
659 switch (err) {
660 case UNKNOWN_ERROR:
661 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
662 break;
663 case NO_MEMORY:
664 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
665 break;
666 case INVALID_OPERATION:
667 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
668 break;
669 case BAD_VALUE:
670 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
671 break;
672 case BAD_INDEX:
673 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
674 break;
675 case BAD_TYPE:
676 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
677 break;
678 case NAME_NOT_FOUND:
679 jniThrowException(env, "java/util/NoSuchElementException", NULL);
680 break;
681 case PERMISSION_DENIED:
682 jniThrowException(env, "java/lang/SecurityException", NULL);
683 break;
684 case NOT_ENOUGH_DATA:
685 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
686 break;
687 case NO_INIT:
688 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
689 break;
690 case ALREADY_EXISTS:
691 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
692 break;
693 case DEAD_OBJECT:
Jeff Brown0bde66a2011-11-07 12:50:08 -0800694 // DeadObjectException is a checked exception, only throw from certain methods.
695 jniThrowException(env, canThrowRemoteException
696 ? "android/os/DeadObjectException"
697 : "java/lang/RuntimeException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698 break;
699 case UNKNOWN_TRANSACTION:
700 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
701 break;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700702 case FAILED_TRANSACTION: {
703 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
Christopher Tate02ca7a72015-06-24 18:16:42 -0700704 const char* exceptionToThrow;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700705 char msg[128];
Jeff Brown0bde66a2011-11-07 12:50:08 -0800706 // TransactionTooLargeException is a checked exception, only throw from certain methods.
707 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
708 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
709 // for other reasons also, such as if the transaction is malformed or
710 // refers to an FD that has been closed. We should change the driver
711 // to enable us to distinguish these cases in the future.
Christopher Tate02ca7a72015-06-24 18:16:42 -0700712 if (canThrowRemoteException && parcelSize > 200*1024) {
713 // bona fide large payload
714 exceptionToThrow = "android/os/TransactionTooLargeException";
715 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
716 } else {
717 // Heuristic: a payload smaller than this threshold "shouldn't" be too
718 // big, so it's probably some other, more subtle problem. In practice
Christopher Tateffd58642015-06-29 11:00:15 -0700719 // it seems to always mean that the remote process died while the binder
Christopher Tate02ca7a72015-06-24 18:16:42 -0700720 // transaction was already in flight.
Christopher Tateffd58642015-06-29 11:00:15 -0700721 exceptionToThrow = (canThrowRemoteException)
722 ? "android/os/DeadObjectException"
723 : "java/lang/RuntimeException";
Christopher Tate02ca7a72015-06-24 18:16:42 -0700724 snprintf(msg, sizeof(msg)-1,
725 "Transaction failed on small parcel; remote process probably died");
726 }
727 jniThrowException(env, exceptionToThrow, msg);
Dianne Hackborne5c42622015-05-19 16:04:04 -0700728 } break;
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400729 case FDS_NOT_ALLOWED:
730 jniThrowException(env, "java/lang/RuntimeException",
731 "Not allowed to write file descriptors here");
732 break;
Christopher Wileya94fc522015-11-22 14:21:25 -0800733 case UNEXPECTED_NULL:
734 jniThrowNullPointerException(env, NULL);
735 break;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700736 case -EBADF:
737 jniThrowException(env, "java/lang/RuntimeException",
738 "Bad file descriptor");
739 break;
740 case -ENFILE:
741 jniThrowException(env, "java/lang/RuntimeException",
742 "File table overflow");
743 break;
744 case -EMFILE:
745 jniThrowException(env, "java/lang/RuntimeException",
746 "Too many open files");
747 break;
748 case -EFBIG:
749 jniThrowException(env, "java/lang/RuntimeException",
750 "File too large");
751 break;
752 case -ENOSPC:
753 jniThrowException(env, "java/lang/RuntimeException",
754 "No space left on device");
755 break;
756 case -ESPIPE:
757 jniThrowException(env, "java/lang/RuntimeException",
758 "Illegal seek");
759 break;
760 case -EROFS:
761 jniThrowException(env, "java/lang/RuntimeException",
762 "Read-only file system");
763 break;
764 case -EMLINK:
765 jniThrowException(env, "java/lang/RuntimeException",
766 "Too many links");
767 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 default:
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700769 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800770 String8 msg;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700771 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800772 // RemoteException is a checked exception, only throw from certain methods.
773 jniThrowException(env, canThrowRemoteException
774 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
775 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 }
777}
778
779}
780
781// ----------------------------------------------------------------------------
782
783static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
784{
785 return IPCThreadState::self()->getCallingPid();
786}
787
788static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
789{
790 return IPCThreadState::self()->getCallingUid();
791}
792
793static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
794{
795 return IPCThreadState::self()->clearCallingIdentity();
796}
797
798static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
799{
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700800 // XXX temporary sanity check to debug crashes.
801 int uid = (int)(token>>32);
802 if (uid > 0 && uid < 999) {
803 // In Android currently there are no uids in this range.
804 char buf[128];
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700805 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700806 jniThrowException(env, "java/lang/IllegalStateException", buf);
807 return;
808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 IPCThreadState::self()->restoreCallingIdentity(token);
810}
811
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700812static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
813{
814 IPCThreadState::self()->setStrictModePolicy(policyMask);
815}
816
817static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
818{
819 return IPCThreadState::self()->getStrictModePolicy();
820}
821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
823{
824 IPCThreadState::self()->flushCommands();
825}
826
Christopher Tate0b414482011-02-17 13:00:38 -0800827static void android_os_Binder_init(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828{
Christopher Tate0b414482011-02-17 13:00:38 -0800829 JavaBBinderHolder* jbh = new JavaBBinderHolder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 if (jbh == NULL) {
831 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
832 return;
833 }
Steve Block71f2cf12011-10-20 11:56:00 +0100834 ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
Christopher Tate0b414482011-02-17 13:00:38 -0800835 jbh->incStrong((void*)android_os_Binder_init);
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000836 env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837}
838
Christopher Tate0b414482011-02-17 13:00:38 -0800839static void android_os_Binder_destroy(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840{
841 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000842 env->GetLongField(obj, gBinderOffsets.mObject);
Jeff Brown582763a2010-03-24 18:56:57 -0700843 if (jbh != NULL) {
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000844 env->SetLongField(obj, gBinderOffsets.mObject, 0);
Steve Block71f2cf12011-10-20 11:56:00 +0100845 ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
Christopher Tate0b414482011-02-17 13:00:38 -0800846 jbh->decStrong((void*)android_os_Binder_init);
Jeff Brown582763a2010-03-24 18:56:57 -0700847 } else {
848 // Encountering an uninitialized binder is harmless. All it means is that
849 // the Binder was only partially initialized when its finalizer ran and called
850 // destroy(). The Binder could be partially initialized for several reasons.
851 // For example, a Binder subclass constructor might have thrown an exception before
852 // it could delegate to its superclass's constructor. Consequently init() would
853 // not have been called and the holder pointer would remain NULL.
Steve Block71f2cf12011-10-20 11:56:00 +0100854 ALOGV("Java Binder %p: ignoring uninitialized binder", obj);
Jeff Brown582763a2010-03-24 18:56:57 -0700855 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856}
857
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700858static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
859{
860 return IPCThreadState::self()->blockUntilThreadAvailable();
861}
862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863// ----------------------------------------------------------------------------
864
865static const JNINativeMethod gBinderMethods[] = {
866 /* name, signature, funcPtr */
867 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
868 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
869 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
870 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700871 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
872 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
874 { "init", "()V", (void*)android_os_Binder_init },
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700875 { "destroy", "()V", (void*)android_os_Binder_destroy },
876 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877};
878
879const char* const kBinderPathName = "android/os/Binder";
880
881static int int_register_android_os_Binder(JNIEnv* env)
882{
Andreas Gampe987f79f2014-11-18 17:29:46 -0800883 jclass clazz = FindClassOrDie(env, kBinderPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884
Andreas Gampe987f79f2014-11-18 17:29:46 -0800885 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
886 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
887 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800889 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 env, kBinderPathName,
891 gBinderMethods, NELEM(gBinderMethods));
892}
893
894// ****************************************************************************
895// ****************************************************************************
896// ****************************************************************************
897
898namespace android {
899
900jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
901{
902 return gNumLocalRefs;
903}
904
905jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
906{
907 return gNumProxyRefs;
908}
909
910jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
911{
912 return gNumDeathRefs;
913}
914
915}
916
917// ****************************************************************************
918// ****************************************************************************
919// ****************************************************************************
920
921static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
922{
923 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
924 return javaObjectForIBinder(env, b);
925}
926
927static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
928{
929 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
930 android::IPCThreadState::self()->joinThreadPool();
931}
932
Dianne Hackborn887f3552009-12-07 17:59:37 -0800933static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
934 jobject clazz, jboolean disable)
935{
936 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
937}
938
Tim Murrayeef4a3d2016-04-19 14:14:20 -0700939static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
940 jobject clazz, jint maxThreads)
941{
942 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
943}
944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
946{
Steve Block71f2cf12011-10-20 11:56:00 +0100947 ALOGV("Gc has executed, clearing binder ops");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 android_atomic_and(0, &gNumRefsCreated);
949}
950
951// ----------------------------------------------------------------------------
952
953static const JNINativeMethod gBinderInternalMethods[] = {
954 /* name, signature, funcPtr */
955 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
956 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
Dianne Hackborn887f3552009-12-07 17:59:37 -0800957 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
Tim Murrayeef4a3d2016-04-19 14:14:20 -0700958 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
960};
961
962const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
963
964static int int_register_android_os_BinderInternal(JNIEnv* env)
965{
Andreas Gampe987f79f2014-11-18 17:29:46 -0800966 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967
Andreas Gampe987f79f2014-11-18 17:29:46 -0800968 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
969 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800971 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800972 env, kBinderInternalPathName,
973 gBinderInternalMethods, NELEM(gBinderInternalMethods));
974}
975
976// ****************************************************************************
977// ****************************************************************************
978// ****************************************************************************
979
980static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
981{
982 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000983 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 if (target == NULL) {
985 return JNI_FALSE;
986 }
987 status_t err = target->pingBinder();
988 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
989}
990
991static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
992{
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000993 IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 if (target != NULL) {
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -0700995 const String16& desc = target->getInterfaceDescriptor();
Dan Albert66987492014-11-20 11:41:21 -0800996 return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
997 desc.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 }
999 jniThrowException(env, "java/lang/RuntimeException",
1000 "No binder found for object");
1001 return NULL;
1002}
1003
1004static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1005{
1006 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001007 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 if (target == NULL) {
1009 return JNI_FALSE;
1010 }
1011 bool alive = target->isBinderAlive();
1012 return alive ? JNI_TRUE : JNI_FALSE;
1013}
1014
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001015static int getprocname(pid_t pid, char *buf, size_t len) {
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001016 char filename[32];
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001017 FILE *f;
1018
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001019 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001020 f = fopen(filename, "r");
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001021 if (!f) {
1022 *buf = '\0';
1023 return 1;
1024 }
1025 if (!fgets(buf, len, f)) {
1026 *buf = '\0';
1027 fclose(f);
1028 return 2;
1029 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001030 fclose(f);
1031 return 0;
1032}
1033
1034static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1035 jint len = strlen(str);
1036 int space_needed = 1 + sizeof(len) + len;
1037 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001038 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001039 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001040 return false;
1041 }
1042 **pos = EVENT_TYPE_STRING;
1043 (*pos)++;
1044 memcpy(*pos, &len, sizeof(len));
1045 *pos += sizeof(len);
1046 memcpy(*pos, str, len);
1047 *pos += len;
1048 return true;
1049}
1050
1051static bool push_eventlog_int(char** pos, const char* end, jint val) {
1052 int space_needed = 1 + sizeof(val);
1053 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001054 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001055 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001056 return false;
1057 }
1058 **pos = EVENT_TYPE_INT;
1059 (*pos)++;
1060 memcpy(*pos, &val, sizeof(val));
1061 *pos += sizeof(val);
1062 return true;
1063}
1064
1065// From frameworks/base/core/java/android/content/EventLogTags.logtags:
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001066
1067static const bool kEnableBinderSample = false;
1068
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001069#define LOGTAG_BINDER_OPERATION 52004
1070
1071static void conditionally_log_binder_call(int64_t start_millis,
1072 IBinder* target, jint code) {
1073 int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1074
1075 int sample_percent;
1076 if (duration_ms >= 500) {
1077 sample_percent = 100;
1078 } else {
1079 sample_percent = 100 * duration_ms / 500;
1080 if (sample_percent == 0) {
1081 return;
1082 }
1083 if (sample_percent < (random() % 100 + 1)) {
1084 return;
1085 }
1086 }
1087
1088 char process_name[40];
1089 getprocname(getpid(), process_name, sizeof(process_name));
1090 String8 desc(target->getInterfaceDescriptor());
1091
1092 char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1093 buf[0] = EVENT_TYPE_LIST;
1094 buf[1] = 5;
1095 char* pos = &buf[2];
1096 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n
1097 if (!push_eventlog_string(&pos, end, desc.string())) return;
1098 if (!push_eventlog_int(&pos, end, code)) return;
1099 if (!push_eventlog_int(&pos, end, duration_ms)) return;
1100 if (!push_eventlog_string(&pos, end, process_name)) return;
1101 if (!push_eventlog_int(&pos, end, sample_percent)) return;
1102 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently.
1103 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1104}
1105
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001106// We only measure binder call durations to potentially log them if
Elliott Hughes06451fe2014-08-18 10:26:52 -07001107// we're on the main thread.
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001108static bool should_time_binder_calls() {
Elliott Hughes06451fe2014-08-18 10:26:52 -07001109 return (getpid() == gettid());
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001110}
1111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001113 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114{
1115 if (dataObj == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001116 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 return JNI_FALSE;
1118 }
1119
1120 Parcel* data = parcelForJavaObject(env, dataObj);
1121 if (data == NULL) {
1122 return JNI_FALSE;
1123 }
1124 Parcel* reply = parcelForJavaObject(env, replyObj);
1125 if (reply == NULL && replyObj != NULL) {
1126 return JNI_FALSE;
1127 }
1128
1129 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001130 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 if (target == NULL) {
1132 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1133 return JNI_FALSE;
1134 }
1135
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001136 ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 target, obj, code);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001138
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001139
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001140 bool time_binder_calls;
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001141 int64_t start_millis;
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001142 if (kEnableBinderSample) {
1143 // Only log the binder call duration for things on the Java-level main thread.
1144 // But if we don't
1145 time_binder_calls = should_time_binder_calls();
1146
1147 if (time_binder_calls) {
1148 start_millis = uptimeMillis();
1149 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001150 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 //printf("Transact from Java code to %p sending: ", target); data->print();
1153 status_t err = target->transact(code, *data, reply, flags);
1154 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001155
1156 if (kEnableBinderSample) {
1157 if (time_binder_calls) {
1158 conditionally_log_binder_call(start_millis, target, code);
1159 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001160 }
1161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 if (err == NO_ERROR) {
1163 return JNI_TRUE;
1164 } else if (err == UNKNOWN_TRANSACTION) {
1165 return JNI_FALSE;
1166 }
1167
Dianne Hackborne5c42622015-05-19 16:04:04 -07001168 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 return JNI_FALSE;
1170}
1171
1172static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001173 jobject recipient, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174{
1175 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001176 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 return;
1178 }
1179
1180 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001181 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 if (target == NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001183 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 assert(false);
1185 }
1186
Christopher Tate79dd31f2011-03-04 17:45:00 -08001187 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188
1189 if (!target->localBinder()) {
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001190 DeathRecipientList* list = (DeathRecipientList*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001191 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001192 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
Christopher Tate0b414482011-02-17 13:00:38 -08001193 status_t err = target->linkToDeath(jdr, NULL, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 if (err != NO_ERROR) {
1195 // Failure adding the death recipient, so clear its reference
1196 // now.
1197 jdr->clearReference();
Jeff Brown0bde66a2011-11-07 12:50:08 -08001198 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 }
1200 }
1201}
1202
1203static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1204 jobject recipient, jint flags)
1205{
1206 jboolean res = JNI_FALSE;
1207 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001208 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 return res;
1210 }
1211
1212 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001213 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 if (target == NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001215 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 return JNI_FALSE;
1217 }
1218
Christopher Tate79dd31f2011-03-04 17:45:00 -08001219 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220
1221 if (!target->localBinder()) {
Christopher Tate0b414482011-02-17 13:00:38 -08001222 status_t err = NAME_NOT_FOUND;
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001223
1224 // If we find the matching recipient, proceed to unlink using that
1225 DeathRecipientList* list = (DeathRecipientList*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001226 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001227 sp<JavaDeathRecipient> origJDR = list->find(recipient);
Christopher Tate79dd31f2011-03-04 17:45:00 -08001228 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
Christopher Tate0b414482011-02-17 13:00:38 -08001229 if (origJDR != NULL) {
1230 wp<IBinder::DeathRecipient> dr;
1231 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1232 if (err == NO_ERROR && dr != NULL) {
1233 sp<IBinder::DeathRecipient> sdr = dr.promote();
1234 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1235 if (jdr != NULL) {
1236 jdr->clearReference();
1237 }
1238 }
1239 }
1240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 if (err == NO_ERROR || err == DEAD_OBJECT) {
1242 res = JNI_TRUE;
1243 } else {
1244 jniThrowException(env, "java/util/NoSuchElementException",
1245 "Death link does not exist");
1246 }
1247 }
1248
1249 return res;
1250}
1251
1252static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
1253{
Christopher Tate10c3a282016-02-26 17:48:08 -08001254 // Don't race with construction/initialization
1255 AutoMutex _l(mProxyLock);
1256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001257 IBinder* b = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001258 env->GetLongField(obj, gBinderProxyOffsets.mObject);
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001259 DeathRecipientList* drl = (DeathRecipientList*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001260 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
Christopher Tate0b414482011-02-17 13:00:38 -08001261
Christopher Tate79dd31f2011-03-04 17:45:00 -08001262 LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
Christopher Tate10c3a282016-02-26 17:48:08 -08001263 if (b != nullptr) {
1264 env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
1265 env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
1266 drl->decStrong((void*)javaObjectForIBinder);
1267 b->decStrong((void*)javaObjectForIBinder);
1268 }
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001269
1270 IPCThreadState::self()->flushCommands();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271}
1272
1273// ----------------------------------------------------------------------------
1274
1275static const JNINativeMethod gBinderProxyMethods[] = {
1276 /* name, signature, funcPtr */
1277 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1278 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1279 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001280 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1282 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1283 {"destroy", "()V", (void*)android_os_BinderProxy_destroy},
1284};
1285
1286const char* const kBinderProxyPathName = "android/os/BinderProxy";
1287
1288static int int_register_android_os_BinderProxy(JNIEnv* env)
1289{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001290 jclass clazz = FindClassOrDie(env, "java/lang/Error");
1291 gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292
Andreas Gampe987f79f2014-11-18 17:29:46 -08001293 clazz = FindClassOrDie(env, kBinderProxyPathName);
1294 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1295 gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
1296 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1297 "(Landroid/os/IBinder$DeathRecipient;)V");
Elliott Hughes69a017b2011-04-08 14:10:28 -07001298
Andreas Gampe987f79f2014-11-18 17:29:46 -08001299 gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
1300 gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
1301 "Ljava/lang/ref/WeakReference;");
1302 gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303
Andreas Gampe987f79f2014-11-18 17:29:46 -08001304 clazz = FindClassOrDie(env, "java/lang/Class");
1305 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
Christopher Tate0d4a7922011-08-30 12:09:43 -07001306
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001307 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 env, kBinderProxyPathName,
1309 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1310}
1311
1312// ****************************************************************************
1313// ****************************************************************************
1314// ****************************************************************************
1315
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001316int register_android_os_Binder(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317{
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001318 if (int_register_android_os_Binder(env) < 0)
1319 return -1;
1320 if (int_register_android_os_BinderInternal(env) < 0)
1321 return -1;
1322 if (int_register_android_os_BinderProxy(env) < 0)
1323 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324
Andreas Gampe987f79f2014-11-18 17:29:46 -08001325 jclass clazz = FindClassOrDie(env, "android/util/Log");
1326 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1327 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1328 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329
Andreas Gampe987f79f2014-11-18 17:29:46 -08001330 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1331 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1332 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1333 "(Ljava/io/FileDescriptor;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334
Andreas Gampe987f79f2014-11-18 17:29:46 -08001335 clazz = FindClassOrDie(env, "android/os/StrictMode");
1336 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1337 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1338 "onBinderStrictModePolicyChange", "(I)V");
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 return 0;
1341}