blob: 6362bc7187fc3051af123a7a08996e2cec4f26b6 [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 <fcntl.h>
Mark Salyzyncfd91e72014-04-17 15:40:01 -070024#include <inttypes.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025#include <stdio.h>
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -070026#include <sys/stat.h>
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -070027#include <sys/types.h>
Brad Fitzpatrick8f26b322010-03-25 00:25:37 -070028#include <unistd.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Andreas Gampe58383ba2017-06-12 10:43:05 -070030#include <android-base/stringprintf.h>
Mathias Agopian07952722009-05-19 19:08:10 -070031#include <binder/IInterface.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070032#include <binder/IServiceManager.h>
Mathias Agopian07952722009-05-19 19:08:10 -070033#include <binder/IPCThreadState.h>
Mathias Agopian07952722009-05-19 19:08:10 -070034#include <binder/Parcel.h>
Michael Wachenschwanz55182462017-08-14 23:10:13 -070035#include <binder/BpBinder.h>
Mathias Agopian07952722009-05-19 19:08:10 -070036#include <binder/ProcessState.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070037#include <log/log.h>
38#include <utils/Atomic.h>
39#include <utils/KeyedVector.h>
40#include <utils/List.h>
41#include <utils/Log.h>
Jeff Brown0bde66a2011-11-07 12:50:08 -080042#include <utils/String8.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070043#include <utils/SystemClock.h>
44#include <utils/threads.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045
Andreas Gampe625e0002017-09-08 17:44:05 -070046#include <nativehelper/JNIHelp.h>
Steven Moreland2279b252017-07-19 09:50:45 -070047#include <nativehelper/ScopedLocalRef.h>
Andreas Gampe625e0002017-09-08 17:44:05 -070048#include <nativehelper/ScopedUtfChars.h>
Christopher Tateac5e3502011-08-25 15:48:09 -070049
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;
Michael Wachenschwanz55182462017-08-14 23:10:13 -070084 jmethodID mProxyLimitCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085
86} gBinderInternalOffsets;
87
Michael Wachenschwanz55182462017-08-14 23:10:13 -070088static struct sparseintarray_offsets_t
89{
90 jclass classObject;
91 jmethodID constructor;
92 jmethodID put;
93} gSparseIntArrayOffsets;
94
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095// ----------------------------------------------------------------------------
96
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097static struct error_offsets_t
98{
99 jclass mClass;
100} gErrorOffsets;
101
102// ----------------------------------------------------------------------------
103
104static struct binderproxy_offsets_t
105{
106 // Class state.
107 jclass mClass;
108 jmethodID mConstructor;
109 jmethodID mSendDeathNotice;
110
111 // Object state.
112 jfieldID mObject;
113 jfieldID mSelf;
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800114 jfieldID mOrgue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115
116} gBinderProxyOffsets;
117
Christopher Tate0d4a7922011-08-30 12:09:43 -0700118static struct class_offsets_t
119{
120 jmethodID mGetName;
121} gClassOffsets;
122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123// ----------------------------------------------------------------------------
124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125static struct log_offsets_t
126{
127 // Class state.
128 jclass mClass;
129 jmethodID mLogE;
130} gLogOffsets;
131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132static struct parcel_file_descriptor_offsets_t
133{
134 jclass mClass;
135 jmethodID mConstructor;
136} gParcelFileDescriptorOffsets;
137
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700138static struct strict_mode_callback_offsets_t
139{
140 jclass mClass;
141 jmethodID mCallback;
142} gStrictModeCallbackOffsets;
143
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700144static struct thread_dispatch_offsets_t
145{
146 // Class state.
147 jclass mClass;
148 jmethodID mDispatchUncaughtException;
149 jmethodID mCurrentThread;
150} gThreadDispatchOffsets;
151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152// ****************************************************************************
153// ****************************************************************************
154// ****************************************************************************
155
156static volatile int32_t gNumRefsCreated = 0;
157static volatile int32_t gNumProxyRefs = 0;
158static volatile int32_t gNumLocalRefs = 0;
159static volatile int32_t gNumDeathRefs = 0;
160
161static void incRefsCreated(JNIEnv* env)
162{
163 int old = android_atomic_inc(&gNumRefsCreated);
164 if (old == 200) {
165 android_atomic_and(0, &gNumRefsCreated);
166 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
167 gBinderInternalOffsets.mForceGc);
168 } else {
Steve Block71f2cf12011-10-20 11:56:00 +0100169 ALOGV("Now have %d binder ops", old);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 }
171}
172
173static JavaVM* jnienv_to_javavm(JNIEnv* env)
174{
175 JavaVM* vm;
176 return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
177}
178
179static JNIEnv* javavm_to_jnienv(JavaVM* vm)
180{
181 JNIEnv* env;
182 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
183}
184
Andreas Gampe625e0002017-09-08 17:44:05 -0700185// Report a java.lang.Error (or subclass). This will terminate the runtime by
186// calling FatalError with a message derived from the given error.
187static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
188 const char* msg)
189{
190 // Report an error: reraise the exception and ask the runtime to abort.
191
192 // Try to get the exception string. Sometimes logcat isn't available,
193 // so try to add it to the abort message.
194 std::string exc_msg = "(Unknown exception message)";
195 {
196 ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
197 jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
198 "()Ljava/lang/String;");
199 ScopedLocalRef<jstring> jstr(
200 env,
201 reinterpret_cast<jstring>(
202 env->CallObjectMethod(error, method_id)));
203 env->ExceptionClear(); // Just for good measure.
204 if (jstr.get() != nullptr) {
205 ScopedUtfChars jstr_utf(env, jstr.get());
206 if (jstr_utf.c_str() != nullptr) {
207 exc_msg = jstr_utf.c_str();
208 } else {
209 env->ExceptionClear();
210 }
211 }
212 }
213
214 env->Throw(error);
215 ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
216 env->ExceptionDescribe();
217
218 std::string error_msg = base::StringPrintf(
219 "java.lang.Error thrown during binder transaction: %s",
220 exc_msg.c_str());
221 env->FatalError(error_msg.c_str());
222}
223
224// Report a java.lang.Error (or subclass). This will terminate the runtime, either by
225// the uncaught exception handler, or explicitly by calling
226// report_java_lang_error_fatal_error.
227static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* msg)
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700228{
229 // Try to run the uncaught exception machinery.
230 jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass,
231 gThreadDispatchOffsets.mCurrentThread);
232 if (thread != nullptr) {
233 env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException,
234 error);
235 // Should not return here, unless more errors occured.
236 }
237 // Some error occurred that meant that either dispatchUncaughtException could not be
238 // called or that it had an error itself (as this should be unreachable under normal
Andreas Gampe625e0002017-09-08 17:44:05 -0700239 // conditions). As the binder code cannot handle Errors, attempt to log the error and
240 // abort.
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700241 env->ExceptionClear();
Andreas Gampe625e0002017-09-08 17:44:05 -0700242 report_java_lang_error_fatal_error(env, error, msg);
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700243}
244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
246{
247 env->ExceptionClear();
248
Andreas Gampe625e0002017-09-08 17:44:05 -0700249 ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
Andreas Gampe8571ec32017-09-21 10:55:59 -0700250 ScopedLocalRef<jstring> msgstr(env);
Andreas Gampe625e0002017-09-08 17:44:05 -0700251 if (tagstr != nullptr) {
252 msgstr.reset(env->NewStringUTF(msg));
Mathieu Chartiercf6775e2014-08-06 13:39:17 -0700253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254
Andreas Gampe625e0002017-09-08 17:44:05 -0700255 if ((tagstr != nullptr) && (msgstr != nullptr)) {
256 env->CallStaticIntMethod(gLogOffsets.mClass, gLogOffsets.mLogE,
257 tagstr.get(), msgstr.get(), excep);
258 if (env->ExceptionCheck()) {
259 // Attempting to log the failure has failed.
260 ALOGW("Failed trying to log exception, msg='%s'\n", msg);
261 env->ExceptionClear();
262 }
263 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 env->ExceptionClear(); /* assume exception (OOM?) was thrown */
Steve Block3762c312012-01-06 19:20:56 +0000265 ALOGE("Unable to call Log.e()\n");
266 ALOGE("%s", msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 }
268
269 if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700270 report_java_lang_error(env, excep, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272}
273
274class JavaBBinderHolder;
275
276class JavaBBinder : public BBinder
277{
278public:
279 JavaBBinder(JNIEnv* env, jobject object)
280 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
281 {
Steve Block71f2cf12011-10-20 11:56:00 +0100282 ALOGV("Creating JavaBBinder %p\n", this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 android_atomic_inc(&gNumLocalRefs);
284 incRefsCreated(env);
285 }
286
287 bool checkSubclass(const void* subclassID) const
288 {
289 return subclassID == &gBinderOffsets;
290 }
291
292 jobject object() const
293 {
294 return mObject;
295 }
296
297protected:
298 virtual ~JavaBBinder()
299 {
Steve Block71f2cf12011-10-20 11:56:00 +0100300 ALOGV("Destroying JavaBBinder %p\n", this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 android_atomic_dec(&gNumLocalRefs);
302 JNIEnv* env = javavm_to_jnienv(mVM);
303 env->DeleteGlobalRef(mObject);
304 }
305
306 virtual status_t onTransact(
307 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
308 {
309 JNIEnv* env = javavm_to_jnienv(mVM);
310
Steve Block71f2cf12011-10-20 11:56:00 +0100311 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 -0800312
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700313 IPCThreadState* thread_state = IPCThreadState::self();
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700314 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 //printf("Transact from %p to Java code sending: ", this);
317 //data.print();
318 //printf("\n");
319 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000320 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700321
Mathieu Chartier98671c32014-08-20 10:04:08 -0700322 if (env->ExceptionCheck()) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700323 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
324 report_exception(env, excep.get(),
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100325 "*** Uncaught remote exception! "
326 "(Exceptions are not yet supported across processes.)");
327 res = JNI_FALSE;
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100328 }
329
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700330 // Check if the strict mode state changed while processing the
331 // call. The Binder state will be restored by the underlying
332 // Binder system in IPCThreadState, however we need to take care
333 // of the parallel Java state as well.
334 if (thread_state->getStrictModePolicy() != strict_policy_before) {
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700335 set_dalvik_blockguard_policy(env, strict_policy_before);
336 }
337
Mathieu Chartier98671c32014-08-20 10:04:08 -0700338 if (env->ExceptionCheck()) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700339 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
340 report_exception(env, excep.get(),
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100341 "*** Uncaught exception in onBinderStrictModePolicyChange");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 }
343
Dianne Hackborna53de062012-05-08 18:53:51 -0700344 // Need to always call through the native implementation of
345 // SYSPROPS_TRANSACTION.
346 if (code == SYSPROPS_TRANSACTION) {
347 BBinder::onTransact(code, data, reply, flags);
348 }
349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 //aout << "onTransact to Java code; result=" << res << endl
351 // << "Transact from " << this << " to Java code returning "
352 // << reply << ": " << *reply << endl;
353 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
354 }
355
356 virtual status_t dump(int fd, const Vector<String16>& args)
357 {
358 return 0;
359 }
360
361private:
362 JavaVM* const mVM;
363 jobject const mObject;
364};
365
366// ----------------------------------------------------------------------------
367
368class JavaBBinderHolder : public RefBase
369{
370public:
Christopher Tate0b414482011-02-17 13:00:38 -0800371 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 {
373 AutoMutex _l(mLock);
374 sp<JavaBBinder> b = mBinder.promote();
375 if (b == NULL) {
Christopher Tate0b414482011-02-17 13:00:38 -0800376 b = new JavaBBinder(env, obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 mBinder = b;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700378 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
Christopher Tate0b414482011-02-17 13:00:38 -0800379 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 }
381
382 return b;
383 }
384
385 sp<JavaBBinder> getExisting()
386 {
387 AutoMutex _l(mLock);
388 return mBinder.promote();
389 }
390
391private:
392 Mutex mLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 wp<JavaBBinder> mBinder;
394};
395
396// ----------------------------------------------------------------------------
397
Christopher Tate0b414482011-02-17 13:00:38 -0800398// Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
399// death recipient references passed in through JNI with the permanent corresponding
400// JavaDeathRecipient objects.
401
402class JavaDeathRecipient;
403
404class DeathRecipientList : public RefBase {
405 List< sp<JavaDeathRecipient> > mList;
406 Mutex mLock;
407
408public:
Christopher Tate79dd31f2011-03-04 17:45:00 -0800409 DeathRecipientList();
Christopher Tate0b414482011-02-17 13:00:38 -0800410 ~DeathRecipientList();
411
412 void add(const sp<JavaDeathRecipient>& recipient);
413 void remove(const sp<JavaDeathRecipient>& recipient);
414 sp<JavaDeathRecipient> find(jobject recipient);
Christopher Tate090c08f2015-05-19 18:16:58 -0700415
416 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
Christopher Tate0b414482011-02-17 13:00:38 -0800417};
418
419// ----------------------------------------------------------------------------
420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421class JavaDeathRecipient : public IBinder::DeathRecipient
422{
423public:
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800424 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
Christopher Tate86284c62011-08-17 15:19:29 -0700425 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
426 mObjectWeak(NULL), mList(list)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 {
Christopher Tate0b414482011-02-17 13:00:38 -0800428 // These objects manage their own lifetimes so are responsible for final bookkeeping.
429 // The list holds a strong reference to this object.
Christopher Tate79dd31f2011-03-04 17:45:00 -0800430 LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800431 list->add(this);
Christopher Tate0b414482011-02-17 13:00:38 -0800432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 android_atomic_inc(&gNumDeathRefs);
434 incRefsCreated(env);
435 }
436
437 void binderDied(const wp<IBinder>& who)
438 {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800439 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
Christopher Tate86284c62011-08-17 15:19:29 -0700440 if (mObject != NULL) {
441 JNIEnv* env = javavm_to_jnienv(mVM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442
Christopher Tate86284c62011-08-17 15:19:29 -0700443 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
444 gBinderProxyOffsets.mSendDeathNotice, mObject);
Mathieu Chartier98671c32014-08-20 10:04:08 -0700445 if (env->ExceptionCheck()) {
446 jthrowable excep = env->ExceptionOccurred();
Christopher Tate86284c62011-08-17 15:19:29 -0700447 report_exception(env, excep,
448 "*** Uncaught exception returned from death notification!");
449 }
450
Christopher Tate090c08f2015-05-19 18:16:58 -0700451 // Serialize with our containing DeathRecipientList so that we can't
452 // delete the global ref on mObject while the list is being iterated.
453 sp<DeathRecipientList> list = mList.promote();
454 if (list != NULL) {
455 AutoMutex _l(list->lock());
456
457 // Demote from strong ref to weak after binderDied() has been delivered,
458 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
459 mObjectWeak = env->NewWeakGlobalRef(mObject);
460 env->DeleteGlobalRef(mObject);
461 mObject = NULL;
462 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 }
465
466 void clearReference()
467 {
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800468 sp<DeathRecipientList> list = mList.promote();
469 if (list != NULL) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800470 LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800471 list->remove(this);
Christopher Tate79dd31f2011-03-04 17:45:00 -0800472 } else {
473 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800474 }
Christopher Tate0b414482011-02-17 13:00:38 -0800475 }
476
477 bool matches(jobject obj) {
Christopher Tate86284c62011-08-17 15:19:29 -0700478 bool result;
Christopher Tate0b414482011-02-17 13:00:38 -0800479 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate86284c62011-08-17 15:19:29 -0700480
481 if (mObject != NULL) {
482 result = env->IsSameObject(obj, mObject);
483 } else {
Andreas Gampe625e0002017-09-08 17:44:05 -0700484 ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
485 result = env->IsSameObject(obj, me.get());
Christopher Tate86284c62011-08-17 15:19:29 -0700486 }
487 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 }
489
Christopher Tateac5e3502011-08-25 15:48:09 -0700490 void warnIfStillLive() {
491 if (mObject != NULL) {
492 // Okay, something is wrong -- we have a hard reference to a live death
493 // recipient on the VM side, but the list is being torn down.
494 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate0d4a7922011-08-30 12:09:43 -0700495 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
496 ScopedLocalRef<jstring> nameRef(env,
497 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
498 ScopedUtfChars nameUtf(env, nameRef.get());
499 if (nameUtf.c_str() != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +0000500 ALOGW("BinderProxy is being destroyed but the application did not call "
Christopher Tate0d4a7922011-08-30 12:09:43 -0700501 "unlinkToDeath to unlink all of its death recipients beforehand. "
502 "Releasing leaked death recipient: %s", nameUtf.c_str());
503 } else {
Steve Block8564c8d2012-01-05 23:22:43 +0000504 ALOGW("BinderProxy being destroyed; unable to get DR object name");
Christopher Tate0d4a7922011-08-30 12:09:43 -0700505 env->ExceptionClear();
506 }
Christopher Tateac5e3502011-08-25 15:48:09 -0700507 }
508 }
509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510protected:
511 virtual ~JavaDeathRecipient()
512 {
Steve Block6215d3f2012-01-04 20:05:49 +0000513 //ALOGI("Removing death ref: recipient=%p\n", mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 android_atomic_dec(&gNumDeathRefs);
515 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate86284c62011-08-17 15:19:29 -0700516 if (mObject != NULL) {
517 env->DeleteGlobalRef(mObject);
518 } else {
519 env->DeleteWeakGlobalRef(mObjectWeak);
520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 }
522
523private:
Christopher Tate86284c62011-08-17 15:19:29 -0700524 JavaVM* const mVM;
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700525 jobject mObject; // Initial strong ref to Java-side DeathRecipient. Cleared on binderDied().
526 jweak mObjectWeak; // weak ref to the same Java-side DeathRecipient after binderDied().
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800527 wp<DeathRecipientList> mList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528};
529
530// ----------------------------------------------------------------------------
531
Christopher Tate79dd31f2011-03-04 17:45:00 -0800532DeathRecipientList::DeathRecipientList() {
533 LOGDEATH("New DRL @ %p", this);
534}
535
Christopher Tate0b414482011-02-17 13:00:38 -0800536DeathRecipientList::~DeathRecipientList() {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800537 LOGDEATH("Destroy DRL @ %p", this);
Christopher Tate0b414482011-02-17 13:00:38 -0800538 AutoMutex _l(mLock);
539
540 // Should never happen -- the JavaDeathRecipient objects that have added themselves
541 // to the list are holding references on the list object. Only when they are torn
542 // down can the list header be destroyed.
543 if (mList.size() > 0) {
Christopher Tateac5e3502011-08-25 15:48:09 -0700544 List< sp<JavaDeathRecipient> >::iterator iter;
545 for (iter = mList.begin(); iter != mList.end(); iter++) {
546 (*iter)->warnIfStillLive();
547 }
Christopher Tate0b414482011-02-17 13:00:38 -0800548 }
549}
550
551void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
552 AutoMutex _l(mLock);
553
Christopher Tate79dd31f2011-03-04 17:45:00 -0800554 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
Christopher Tate0b414482011-02-17 13:00:38 -0800555 mList.push_back(recipient);
556}
557
558void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
559 AutoMutex _l(mLock);
560
561 List< sp<JavaDeathRecipient> >::iterator iter;
562 for (iter = mList.begin(); iter != mList.end(); iter++) {
563 if (*iter == recipient) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800564 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
Christopher Tate0b414482011-02-17 13:00:38 -0800565 mList.erase(iter);
566 return;
567 }
568 }
569}
570
571sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
572 AutoMutex _l(mLock);
573
574 List< sp<JavaDeathRecipient> >::iterator iter;
575 for (iter = mList.begin(); iter != mList.end(); iter++) {
576 if ((*iter)->matches(recipient)) {
577 return *iter;
578 }
579 }
580 return NULL;
581}
582
Christopher Tate090c08f2015-05-19 18:16:58 -0700583Mutex& DeathRecipientList::lock() {
584 return mLock;
585}
586
Christopher Tate0b414482011-02-17 13:00:38 -0800587// ----------------------------------------------------------------------------
588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589namespace android {
590
591static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
592{
593 android_atomic_dec(&gNumProxyRefs);
594 JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie);
595 env->DeleteGlobalRef((jobject)obj);
596}
597
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700598static Mutex gProxyLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599
600jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
601{
602 if (val == NULL) return NULL;
603
604 if (val->checkSubclass(&gBinderOffsets)) {
605 // One of our own!
606 jobject object = static_cast<JavaBBinder*>(val.get())->object();
Christopher Tate86284c62011-08-17 15:19:29 -0700607 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 return object;
609 }
610
611 // For the rest of the function we will hold this lock, to serialize
Christopher Tate10c3a282016-02-26 17:48:08 -0800612 // looking/creation/destruction of Java proxies for native Binder proxies.
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700613 AutoMutex _l(gProxyLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614
615 // Someone else's... do we know about it?
616 jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
617 if (object != NULL) {
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700618 jobject res = jniGetReferent(env, object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 if (res != NULL) {
Steve Block71f2cf12011-10-20 11:56:00 +0100620 ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 return res;
622 }
Christopher Tate86284c62011-08-17 15:19:29 -0700623 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 -0800624 android_atomic_dec(&gNumProxyRefs);
625 val->detachObject(&gBinderProxyOffsets);
626 env->DeleteGlobalRef(object);
627 }
628
629 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
630 if (object != NULL) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800631 LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632 // The proxy holds a reference to the native object.
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000633 env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800634 val->incStrong((void*)javaObjectForIBinder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635
636 // The native object needs to hold a weak reference back to the
637 // proxy, so we can retrieve the same proxy if it is still active.
638 jobject refObject = env->NewGlobalRef(
639 env->GetObjectField(object, gBinderProxyOffsets.mSelf));
640 val->attachObject(&gBinderProxyOffsets, refObject,
641 jnienv_to_javavm(env), proxy_cleanup);
642
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800643 // Also remember the death recipients registered on this proxy
644 sp<DeathRecipientList> drl = new DeathRecipientList;
645 drl->incStrong((void*)javaObjectForIBinder);
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000646 env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 // Note that a new object reference has been created.
649 android_atomic_inc(&gNumProxyRefs);
650 incRefsCreated(env);
651 }
652
653 return object;
654}
655
656sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
657{
658 if (obj == NULL) return NULL;
659
660 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
661 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000662 env->GetLongField(obj, gBinderOffsets.mObject);
Christopher Tate0b414482011-02-17 13:00:38 -0800663 return jbh != NULL ? jbh->get(env, obj) : NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 }
665
666 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
667 return (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000668 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800669 }
670
Steve Block8564c8d2012-01-05 23:22:43 +0000671 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 return NULL;
673}
674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
676{
677 return env->NewObject(
678 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
679}
680
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800681void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
682{
683 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
684 // to sync our state back to it. See the comments in StrictMode.java.
685 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
686 gStrictModeCallbackOffsets.mCallback,
687 strict_policy);
688}
689
690void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
Dianne Hackborne5c42622015-05-19 16:04:04 -0700691 bool canThrowRemoteException, int parcelSize)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692{
693 switch (err) {
694 case UNKNOWN_ERROR:
695 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
696 break;
697 case NO_MEMORY:
698 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
699 break;
700 case INVALID_OPERATION:
701 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
702 break;
703 case BAD_VALUE:
704 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
705 break;
706 case BAD_INDEX:
707 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
708 break;
709 case BAD_TYPE:
710 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
711 break;
712 case NAME_NOT_FOUND:
713 jniThrowException(env, "java/util/NoSuchElementException", NULL);
714 break;
715 case PERMISSION_DENIED:
716 jniThrowException(env, "java/lang/SecurityException", NULL);
717 break;
718 case NOT_ENOUGH_DATA:
719 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
720 break;
721 case NO_INIT:
722 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
723 break;
724 case ALREADY_EXISTS:
725 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
726 break;
727 case DEAD_OBJECT:
Jeff Brown0bde66a2011-11-07 12:50:08 -0800728 // DeadObjectException is a checked exception, only throw from certain methods.
729 jniThrowException(env, canThrowRemoteException
730 ? "android/os/DeadObjectException"
731 : "java/lang/RuntimeException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 break;
733 case UNKNOWN_TRANSACTION:
734 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
735 break;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700736 case FAILED_TRANSACTION: {
737 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
Christopher Tate02ca7a72015-06-24 18:16:42 -0700738 const char* exceptionToThrow;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700739 char msg[128];
Jeff Brown0bde66a2011-11-07 12:50:08 -0800740 // TransactionTooLargeException is a checked exception, only throw from certain methods.
741 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
742 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
743 // for other reasons also, such as if the transaction is malformed or
744 // refers to an FD that has been closed. We should change the driver
745 // to enable us to distinguish these cases in the future.
Christopher Tate02ca7a72015-06-24 18:16:42 -0700746 if (canThrowRemoteException && parcelSize > 200*1024) {
747 // bona fide large payload
748 exceptionToThrow = "android/os/TransactionTooLargeException";
749 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
750 } else {
751 // Heuristic: a payload smaller than this threshold "shouldn't" be too
752 // big, so it's probably some other, more subtle problem. In practice
Christopher Tateffd58642015-06-29 11:00:15 -0700753 // it seems to always mean that the remote process died while the binder
Christopher Tate02ca7a72015-06-24 18:16:42 -0700754 // transaction was already in flight.
Christopher Tateffd58642015-06-29 11:00:15 -0700755 exceptionToThrow = (canThrowRemoteException)
756 ? "android/os/DeadObjectException"
757 : "java/lang/RuntimeException";
Christopher Tate02ca7a72015-06-24 18:16:42 -0700758 snprintf(msg, sizeof(msg)-1,
759 "Transaction failed on small parcel; remote process probably died");
760 }
761 jniThrowException(env, exceptionToThrow, msg);
Dianne Hackborne5c42622015-05-19 16:04:04 -0700762 } break;
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400763 case FDS_NOT_ALLOWED:
764 jniThrowException(env, "java/lang/RuntimeException",
765 "Not allowed to write file descriptors here");
766 break;
Christopher Wileya94fc522015-11-22 14:21:25 -0800767 case UNEXPECTED_NULL:
768 jniThrowNullPointerException(env, NULL);
769 break;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700770 case -EBADF:
771 jniThrowException(env, "java/lang/RuntimeException",
772 "Bad file descriptor");
773 break;
774 case -ENFILE:
775 jniThrowException(env, "java/lang/RuntimeException",
776 "File table overflow");
777 break;
778 case -EMFILE:
779 jniThrowException(env, "java/lang/RuntimeException",
780 "Too many open files");
781 break;
782 case -EFBIG:
783 jniThrowException(env, "java/lang/RuntimeException",
784 "File too large");
785 break;
786 case -ENOSPC:
787 jniThrowException(env, "java/lang/RuntimeException",
788 "No space left on device");
789 break;
790 case -ESPIPE:
791 jniThrowException(env, "java/lang/RuntimeException",
792 "Illegal seek");
793 break;
794 case -EROFS:
795 jniThrowException(env, "java/lang/RuntimeException",
796 "Read-only file system");
797 break;
798 case -EMLINK:
799 jniThrowException(env, "java/lang/RuntimeException",
800 "Too many links");
801 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 default:
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700803 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800804 String8 msg;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700805 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800806 // RemoteException is a checked exception, only throw from certain methods.
807 jniThrowException(env, canThrowRemoteException
808 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
809 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 }
811}
812
813}
814
815// ----------------------------------------------------------------------------
816
817static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
818{
819 return IPCThreadState::self()->getCallingPid();
820}
821
822static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
823{
824 return IPCThreadState::self()->getCallingUid();
825}
826
827static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
828{
829 return IPCThreadState::self()->clearCallingIdentity();
830}
831
832static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
833{
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700834 // XXX temporary sanity check to debug crashes.
835 int uid = (int)(token>>32);
836 if (uid > 0 && uid < 999) {
837 // In Android currently there are no uids in this range.
838 char buf[128];
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700839 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700840 jniThrowException(env, "java/lang/IllegalStateException", buf);
841 return;
842 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 IPCThreadState::self()->restoreCallingIdentity(token);
844}
845
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700846static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
847{
848 IPCThreadState::self()->setStrictModePolicy(policyMask);
849}
850
851static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
852{
853 return IPCThreadState::self()->getStrictModePolicy();
854}
855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
857{
858 IPCThreadState::self()->flushCommands();
859}
860
Christopher Tate0b414482011-02-17 13:00:38 -0800861static void android_os_Binder_init(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862{
Christopher Tate0b414482011-02-17 13:00:38 -0800863 JavaBBinderHolder* jbh = new JavaBBinderHolder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 if (jbh == NULL) {
865 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
866 return;
867 }
Steve Block71f2cf12011-10-20 11:56:00 +0100868 ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
Christopher Tate0b414482011-02-17 13:00:38 -0800869 jbh->incStrong((void*)android_os_Binder_init);
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000870 env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871}
872
Vladimir Markob25a5322017-06-21 14:40:12 +0100873static void android_os_Binder_destroyBinder(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874{
875 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000876 env->GetLongField(obj, gBinderOffsets.mObject);
Jeff Brown582763a2010-03-24 18:56:57 -0700877 if (jbh != NULL) {
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000878 env->SetLongField(obj, gBinderOffsets.mObject, 0);
Steve Block71f2cf12011-10-20 11:56:00 +0100879 ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
Christopher Tate0b414482011-02-17 13:00:38 -0800880 jbh->decStrong((void*)android_os_Binder_init);
Jeff Brown582763a2010-03-24 18:56:57 -0700881 } else {
882 // Encountering an uninitialized binder is harmless. All it means is that
883 // the Binder was only partially initialized when its finalizer ran and called
Vladimir Markob25a5322017-06-21 14:40:12 +0100884 // destroyBinder(). The Binder could be partially initialized for several reasons.
Jeff Brown582763a2010-03-24 18:56:57 -0700885 // For example, a Binder subclass constructor might have thrown an exception before
886 // it could delegate to its superclass's constructor. Consequently init() would
887 // not have been called and the holder pointer would remain NULL.
Steve Block71f2cf12011-10-20 11:56:00 +0100888 ALOGV("Java Binder %p: ignoring uninitialized binder", obj);
Jeff Brown582763a2010-03-24 18:56:57 -0700889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890}
891
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700892static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
893{
894 return IPCThreadState::self()->blockUntilThreadAvailable();
895}
896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897// ----------------------------------------------------------------------------
898
899static const JNINativeMethod gBinderMethods[] = {
900 /* name, signature, funcPtr */
901 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
902 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
903 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
904 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700905 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
906 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
908 { "init", "()V", (void*)android_os_Binder_init },
Vladimir Markob25a5322017-06-21 14:40:12 +0100909 { "destroyBinder", "()V", (void*)android_os_Binder_destroyBinder },
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700910 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911};
912
913const char* const kBinderPathName = "android/os/Binder";
914
915static int int_register_android_os_Binder(JNIEnv* env)
916{
Andreas Gampe987f79f2014-11-18 17:29:46 -0800917 jclass clazz = FindClassOrDie(env, kBinderPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918
Andreas Gampe987f79f2014-11-18 17:29:46 -0800919 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
920 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
921 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800923 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 env, kBinderPathName,
925 gBinderMethods, NELEM(gBinderMethods));
926}
927
928// ****************************************************************************
929// ****************************************************************************
930// ****************************************************************************
931
932namespace android {
933
934jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
935{
936 return gNumLocalRefs;
937}
938
939jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
940{
941 return gNumProxyRefs;
942}
943
944jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
945{
946 return gNumDeathRefs;
947}
948
949}
950
951// ****************************************************************************
952// ****************************************************************************
953// ****************************************************************************
954
955static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
956{
957 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
958 return javaObjectForIBinder(env, b);
959}
960
961static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
962{
963 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
964 android::IPCThreadState::self()->joinThreadPool();
965}
966
Dianne Hackborn887f3552009-12-07 17:59:37 -0800967static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
968 jobject clazz, jboolean disable)
969{
970 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
971}
972
Tim Murrayeef4a3d2016-04-19 14:14:20 -0700973static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
974 jobject clazz, jint maxThreads)
975{
976 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
977}
978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
980{
Steve Block71f2cf12011-10-20 11:56:00 +0100981 ALOGV("Gc has executed, clearing binder ops");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 android_atomic_and(0, &gNumRefsCreated);
983}
984
Michael Wachenschwanz55182462017-08-14 23:10:13 -0700985static void android_os_BinderInternal_proxyLimitcallback(int uid)
986{
987 JNIEnv *env = AndroidRuntime::getJNIEnv();
988 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
989 gBinderInternalOffsets.mProxyLimitCallback,
990 uid);
991}
992
993static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
994 jboolean enable)
995{
996 BpBinder::setCountByUidEnabled((bool) enable);
997}
998
999static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
1000{
1001 Vector<uint32_t> uids, counts;
1002 BpBinder::getCountByUid(uids, counts);
1003 jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
1004 gSparseIntArrayOffsets.constructor);
1005 for (size_t i = 0; i < uids.size(); i++) {
1006 env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
1007 static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
1008 }
1009 return sparseIntArray;
1010}
1011
1012static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
1013 return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
1014}
1015
1016static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
1017 jint high, jint low)
1018{
1019 BpBinder::setBinderProxyCountWatermarks(high, low);
1020}
1021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022// ----------------------------------------------------------------------------
1023
1024static const JNINativeMethod gBinderInternalMethods[] = {
1025 /* name, signature, funcPtr */
1026 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
1027 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
Dianne Hackborn887f3552009-12-07 17:59:37 -08001028 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
Tim Murrayeef4a3d2016-04-19 14:14:20 -07001029 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001030 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
1031 { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
1032 { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
1033 { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
1034 { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001035};
1036
1037const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
1038
1039static int int_register_android_os_BinderInternal(JNIEnv* env)
1040{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001041 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042
Andreas Gampe987f79f2014-11-18 17:29:46 -08001043 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1044 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001045 gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
1046
1047 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
1048 gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
1049 gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
1050 "<init>", "()V");
1051 gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
1052 "(II)V");
1053
1054 BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001056 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057 env, kBinderInternalPathName,
1058 gBinderInternalMethods, NELEM(gBinderInternalMethods));
1059}
1060
1061// ****************************************************************************
1062// ****************************************************************************
1063// ****************************************************************************
1064
1065static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
1066{
1067 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001068 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 if (target == NULL) {
1070 return JNI_FALSE;
1071 }
1072 status_t err = target->pingBinder();
1073 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1074}
1075
1076static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
1077{
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001078 IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 if (target != NULL) {
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001080 const String16& desc = target->getInterfaceDescriptor();
Dan Albert66987492014-11-20 11:41:21 -08001081 return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
1082 desc.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 }
1084 jniThrowException(env, "java/lang/RuntimeException",
1085 "No binder found for object");
1086 return NULL;
1087}
1088
1089static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1090{
1091 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001092 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093 if (target == NULL) {
1094 return JNI_FALSE;
1095 }
1096 bool alive = target->isBinderAlive();
1097 return alive ? JNI_TRUE : JNI_FALSE;
1098}
1099
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001100static int getprocname(pid_t pid, char *buf, size_t len) {
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001101 char filename[32];
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001102 FILE *f;
1103
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001104 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001105 f = fopen(filename, "r");
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001106 if (!f) {
1107 *buf = '\0';
1108 return 1;
1109 }
1110 if (!fgets(buf, len, f)) {
1111 *buf = '\0';
1112 fclose(f);
1113 return 2;
1114 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001115 fclose(f);
1116 return 0;
1117}
1118
1119static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1120 jint len = strlen(str);
1121 int space_needed = 1 + sizeof(len) + len;
1122 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001123 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001124 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001125 return false;
1126 }
1127 **pos = EVENT_TYPE_STRING;
1128 (*pos)++;
1129 memcpy(*pos, &len, sizeof(len));
1130 *pos += sizeof(len);
1131 memcpy(*pos, str, len);
1132 *pos += len;
1133 return true;
1134}
1135
1136static bool push_eventlog_int(char** pos, const char* end, jint val) {
1137 int space_needed = 1 + sizeof(val);
1138 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001139 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001140 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001141 return false;
1142 }
1143 **pos = EVENT_TYPE_INT;
1144 (*pos)++;
1145 memcpy(*pos, &val, sizeof(val));
1146 *pos += sizeof(val);
1147 return true;
1148}
1149
1150// From frameworks/base/core/java/android/content/EventLogTags.logtags:
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001151
1152static const bool kEnableBinderSample = false;
1153
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001154#define LOGTAG_BINDER_OPERATION 52004
1155
1156static void conditionally_log_binder_call(int64_t start_millis,
1157 IBinder* target, jint code) {
1158 int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1159
1160 int sample_percent;
1161 if (duration_ms >= 500) {
1162 sample_percent = 100;
1163 } else {
1164 sample_percent = 100 * duration_ms / 500;
1165 if (sample_percent == 0) {
1166 return;
1167 }
1168 if (sample_percent < (random() % 100 + 1)) {
1169 return;
1170 }
1171 }
1172
1173 char process_name[40];
1174 getprocname(getpid(), process_name, sizeof(process_name));
1175 String8 desc(target->getInterfaceDescriptor());
1176
1177 char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1178 buf[0] = EVENT_TYPE_LIST;
1179 buf[1] = 5;
1180 char* pos = &buf[2];
1181 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n
1182 if (!push_eventlog_string(&pos, end, desc.string())) return;
1183 if (!push_eventlog_int(&pos, end, code)) return;
1184 if (!push_eventlog_int(&pos, end, duration_ms)) return;
1185 if (!push_eventlog_string(&pos, end, process_name)) return;
1186 if (!push_eventlog_int(&pos, end, sample_percent)) return;
1187 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently.
1188 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1189}
1190
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001191// We only measure binder call durations to potentially log them if
Elliott Hughes06451fe2014-08-18 10:26:52 -07001192// we're on the main thread.
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001193static bool should_time_binder_calls() {
Elliott Hughes06451fe2014-08-18 10:26:52 -07001194 return (getpid() == gettid());
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001195}
1196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001197static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001198 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199{
1200 if (dataObj == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001201 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 return JNI_FALSE;
1203 }
1204
1205 Parcel* data = parcelForJavaObject(env, dataObj);
1206 if (data == NULL) {
1207 return JNI_FALSE;
1208 }
1209 Parcel* reply = parcelForJavaObject(env, replyObj);
1210 if (reply == NULL && replyObj != NULL) {
1211 return JNI_FALSE;
1212 }
1213
1214 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001215 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 if (target == NULL) {
1217 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1218 return JNI_FALSE;
1219 }
1220
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001221 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 -08001222 target, obj, code);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001223
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001224
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001225 bool time_binder_calls;
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001226 int64_t start_millis;
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001227 if (kEnableBinderSample) {
1228 // Only log the binder call duration for things on the Java-level main thread.
1229 // But if we don't
1230 time_binder_calls = should_time_binder_calls();
1231
1232 if (time_binder_calls) {
1233 start_millis = uptimeMillis();
1234 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001235 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 //printf("Transact from Java code to %p sending: ", target); data->print();
1238 status_t err = target->transact(code, *data, reply, flags);
1239 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001240
1241 if (kEnableBinderSample) {
1242 if (time_binder_calls) {
1243 conditionally_log_binder_call(start_millis, target, code);
1244 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001245 }
1246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001247 if (err == NO_ERROR) {
1248 return JNI_TRUE;
1249 } else if (err == UNKNOWN_TRANSACTION) {
1250 return JNI_FALSE;
1251 }
1252
Dianne Hackborne5c42622015-05-19 16:04:04 -07001253 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 return JNI_FALSE;
1255}
1256
1257static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001258 jobject recipient, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259{
1260 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001261 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 return;
1263 }
1264
1265 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001266 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001267 if (target == NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001268 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 assert(false);
1270 }
1271
Christopher Tate79dd31f2011-03-04 17:45:00 -08001272 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273
1274 if (!target->localBinder()) {
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001275 DeathRecipientList* list = (DeathRecipientList*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001276 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001277 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
Christopher Tate0b414482011-02-17 13:00:38 -08001278 status_t err = target->linkToDeath(jdr, NULL, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 if (err != NO_ERROR) {
1280 // Failure adding the death recipient, so clear its reference
1281 // now.
1282 jdr->clearReference();
Jeff Brown0bde66a2011-11-07 12:50:08 -08001283 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 }
1285 }
1286}
1287
1288static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1289 jobject recipient, jint flags)
1290{
1291 jboolean res = JNI_FALSE;
1292 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001293 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 return res;
1295 }
1296
1297 IBinder* target = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001298 env->GetLongField(obj, gBinderProxyOffsets.mObject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001299 if (target == NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001300 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 return JNI_FALSE;
1302 }
1303
Christopher Tate79dd31f2011-03-04 17:45:00 -08001304 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305
1306 if (!target->localBinder()) {
Christopher Tate0b414482011-02-17 13:00:38 -08001307 status_t err = NAME_NOT_FOUND;
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001308
1309 // If we find the matching recipient, proceed to unlink using that
1310 DeathRecipientList* list = (DeathRecipientList*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001311 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001312 sp<JavaDeathRecipient> origJDR = list->find(recipient);
Christopher Tate79dd31f2011-03-04 17:45:00 -08001313 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
Christopher Tate0b414482011-02-17 13:00:38 -08001314 if (origJDR != NULL) {
1315 wp<IBinder::DeathRecipient> dr;
1316 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1317 if (err == NO_ERROR && dr != NULL) {
1318 sp<IBinder::DeathRecipient> sdr = dr.promote();
1319 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1320 if (jdr != NULL) {
1321 jdr->clearReference();
1322 }
1323 }
1324 }
1325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 if (err == NO_ERROR || err == DEAD_OBJECT) {
1327 res = JNI_TRUE;
1328 } else {
1329 jniThrowException(env, "java/util/NoSuchElementException",
1330 "Death link does not exist");
1331 }
1332 }
1333
1334 return res;
1335}
1336
1337static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
1338{
Christopher Tate10c3a282016-02-26 17:48:08 -08001339 // Don't race with construction/initialization
Hans Boehmeb6d62c2017-09-20 15:59:12 -07001340 AutoMutex _l(gProxyLock);
Christopher Tate10c3a282016-02-26 17:48:08 -08001341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 IBinder* b = (IBinder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001343 env->GetLongField(obj, gBinderProxyOffsets.mObject);
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001344 DeathRecipientList* drl = (DeathRecipientList*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +00001345 env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
Christopher Tate0b414482011-02-17 13:00:38 -08001346
Christopher Tate79dd31f2011-03-04 17:45:00 -08001347 LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
Christopher Tate10c3a282016-02-26 17:48:08 -08001348 if (b != nullptr) {
1349 env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
1350 env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
1351 drl->decStrong((void*)javaObjectForIBinder);
1352 b->decStrong((void*)javaObjectForIBinder);
1353 }
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001354
1355 IPCThreadState::self()->flushCommands();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356}
1357
1358// ----------------------------------------------------------------------------
1359
1360static const JNINativeMethod gBinderProxyMethods[] = {
1361 /* name, signature, funcPtr */
1362 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1363 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1364 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001365 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1367 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1368 {"destroy", "()V", (void*)android_os_BinderProxy_destroy},
1369};
1370
1371const char* const kBinderProxyPathName = "android/os/BinderProxy";
1372
1373static int int_register_android_os_BinderProxy(JNIEnv* env)
1374{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001375 jclass clazz = FindClassOrDie(env, "java/lang/Error");
1376 gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377
Andreas Gampe987f79f2014-11-18 17:29:46 -08001378 clazz = FindClassOrDie(env, kBinderProxyPathName);
1379 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1380 gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
1381 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1382 "(Landroid/os/IBinder$DeathRecipient;)V");
Elliott Hughes69a017b2011-04-08 14:10:28 -07001383
Andreas Gampe987f79f2014-11-18 17:29:46 -08001384 gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
1385 gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
1386 "Ljava/lang/ref/WeakReference;");
1387 gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388
Andreas Gampe987f79f2014-11-18 17:29:46 -08001389 clazz = FindClassOrDie(env, "java/lang/Class");
1390 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
Christopher Tate0d4a7922011-08-30 12:09:43 -07001391
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001392 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 env, kBinderProxyPathName,
1394 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1395}
1396
1397// ****************************************************************************
1398// ****************************************************************************
1399// ****************************************************************************
1400
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001401int register_android_os_Binder(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402{
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001403 if (int_register_android_os_Binder(env) < 0)
1404 return -1;
1405 if (int_register_android_os_BinderInternal(env) < 0)
1406 return -1;
1407 if (int_register_android_os_BinderProxy(env) < 0)
1408 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001409
Andreas Gampe987f79f2014-11-18 17:29:46 -08001410 jclass clazz = FindClassOrDie(env, "android/util/Log");
1411 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1412 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1413 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414
Andreas Gampe987f79f2014-11-18 17:29:46 -08001415 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1416 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1417 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1418 "(Ljava/io/FileDescriptor;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419
Andreas Gampe987f79f2014-11-18 17:29:46 -08001420 clazz = FindClassOrDie(env, "android/os/StrictMode");
1421 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1422 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1423 "onBinderStrictModePolicyChange", "(I)V");
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001424
Andreas Gampe1cd76f52017-09-08 17:44:05 -07001425 clazz = FindClassOrDie(env, "java/lang/Thread");
1426 gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1427 gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
1428 "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
1429 gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
1430 "()Ljava/lang/Thread;");
1431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 return 0;
1433}