blob: 9556333dbf86abf9b27d4e5e1e3ad5c079338be6 [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
Hans Boehm29f388f2017-10-03 18:01:20 -070023#include <atomic>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024#include <fcntl.h>
Mark Salyzyncfd91e72014-04-17 15:40:01 -070025#include <inttypes.h>
Steven Morelande52bb7d2018-10-10 11:24:58 -070026#include <mutex>
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>
Michael Wachenschwanz55182462017-08-14 23:10:13 -070037#include <binder/BpBinder.h>
Mathias Agopian07952722009-05-19 19:08:10 -070038#include <binder/ProcessState.h>
Steven Morelandfb7952f2018-02-23 14:58:50 -080039#include <cutils/atomic.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070040#include <log/log.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070041#include <utils/KeyedVector.h>
42#include <utils/List.h>
43#include <utils/Log.h>
Jeff Brown0bde66a2011-11-07 12:50:08 -080044#include <utils/String8.h>
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070045#include <utils/SystemClock.h>
46#include <utils/threads.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
Andreas Gampe625e0002017-09-08 17:44:05 -070048#include <nativehelper/JNIHelp.h>
Steven Moreland2279b252017-07-19 09:50:45 -070049#include <nativehelper/ScopedLocalRef.h>
Andreas Gampe625e0002017-09-08 17:44:05 -070050#include <nativehelper/ScopedUtfChars.h>
Christopher Tateac5e3502011-08-25 15:48:09 -070051
Andreas Gampe987f79f2014-11-18 17:29:46 -080052#include "core_jni_helpers.h"
53
Steve Block71f2cf12011-10-20 11:56:00 +010054//#undef ALOGV
55//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056
Christopher Tate79dd31f2011-03-04 17:45:00 -080057#define DEBUG_DEATH 0
58#if DEBUG_DEATH
Steve Block5baa3a62011-12-20 16:23:08 +000059#define LOGDEATH ALOGD
Christopher Tate79dd31f2011-03-04 17:45:00 -080060#else
Steve Block71f2cf12011-10-20 11:56:00 +010061#define LOGDEATH ALOGV
Christopher Tate79dd31f2011-03-04 17:45:00 -080062#endif
63
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064using namespace android;
65
66// ----------------------------------------------------------------------------
67
68static struct bindernative_offsets_t
69{
70 // Class state.
71 jclass mClass;
72 jmethodID mExecTransact;
Steven Morelande52bb7d2018-10-10 11:24:58 -070073 jmethodID mGetInterfaceDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
75 // Object state.
76 jfieldID mObject;
77
78} gBinderOffsets;
79
80// ----------------------------------------------------------------------------
81
82static struct binderinternal_offsets_t
83{
84 // Class state.
85 jclass mClass;
86 jmethodID mForceGc;
Michael Wachenschwanz55182462017-08-14 23:10:13 -070087 jmethodID mProxyLimitCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89} gBinderInternalOffsets;
90
Michael Wachenschwanz55182462017-08-14 23:10:13 -070091static struct sparseintarray_offsets_t
92{
93 jclass classObject;
94 jmethodID constructor;
95 jmethodID put;
96} gSparseIntArrayOffsets;
97
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098// ----------------------------------------------------------------------------
99
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100static struct error_offsets_t
101{
102 jclass mClass;
103} gErrorOffsets;
104
105// ----------------------------------------------------------------------------
106
107static struct binderproxy_offsets_t
108{
109 // Class state.
110 jclass mClass;
Hans Boehm29f388f2017-10-03 18:01:20 -0700111 jmethodID mGetInstance;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 jmethodID mSendDeathNotice;
113
114 // Object state.
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700115 jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116} 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
Hans Boehm29f388f2017-10-03 18:01:20 -0700156static constexpr int32_t PROXY_WARN_INTERVAL = 5000;
157static constexpr uint32_t GC_INTERVAL = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158
Hans Boehm29f388f2017-10-03 18:01:20 -0700159// Protected by gProxyLock. We warn if this gets too large.
160static int32_t gNumProxies = 0;
161static int32_t gProxiesWarned = 0;
162
163// Number of GlobalRefs held by JavaBBinders.
164static std::atomic<uint32_t> gNumLocalRefsCreated(0);
165static std::atomic<uint32_t> gNumLocalRefsDeleted(0);
166// Number of GlobalRefs held by JavaDeathRecipients.
167static std::atomic<uint32_t> gNumDeathRefsCreated(0);
168static std::atomic<uint32_t> gNumDeathRefsDeleted(0);
169
170// We collected after creating this many refs.
171static std::atomic<uint32_t> gCollectedAtRefs(0);
172
173// Garbage collect if we've allocated at least GC_INTERVAL refs since the last time.
174// TODO: Consider removing this completely. We should no longer be generating GlobalRefs
175// that are reclaimed as a result of GC action.
Ivan Lozano2ea71352017-11-02 14:10:57 -0700176__attribute__((no_sanitize("unsigned-integer-overflow")))
Hans Boehm29f388f2017-10-03 18:01:20 -0700177static void gcIfManyNewRefs(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178{
Hans Boehm29f388f2017-10-03 18:01:20 -0700179 uint32_t totalRefs = gNumLocalRefsCreated.load(std::memory_order_relaxed)
180 + gNumDeathRefsCreated.load(std::memory_order_relaxed);
181 uint32_t collectedAtRefs = gCollectedAtRefs.load(memory_order_relaxed);
182 // A bound on the number of threads that can have incremented gNum...RefsCreated before the
183 // following check is executed. Effectively a bound on #threads. Almost any value will do.
184 static constexpr uint32_t MAX_RACING = 100000;
185
186 if (totalRefs - (collectedAtRefs + GC_INTERVAL) /* modular arithmetic! */ < MAX_RACING) {
187 // Recently passed next GC interval.
188 if (gCollectedAtRefs.compare_exchange_strong(collectedAtRefs,
189 collectedAtRefs + GC_INTERVAL, std::memory_order_relaxed)) {
190 ALOGV("Binder forcing GC at %u created refs", totalRefs);
191 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
192 gBinderInternalOffsets.mForceGc);
193 } // otherwise somebody else beat us to it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 } else {
Hans Boehm29f388f2017-10-03 18:01:20 -0700195 ALOGV("Now have %d binder ops", totalRefs - collectedAtRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 }
197}
198
199static JavaVM* jnienv_to_javavm(JNIEnv* env)
200{
201 JavaVM* vm;
202 return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
203}
204
205static JNIEnv* javavm_to_jnienv(JavaVM* vm)
206{
207 JNIEnv* env;
208 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
209}
210
Andreas Gampe625e0002017-09-08 17:44:05 -0700211// Report a java.lang.Error (or subclass). This will terminate the runtime by
212// calling FatalError with a message derived from the given error.
213static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
214 const char* msg)
215{
216 // Report an error: reraise the exception and ask the runtime to abort.
217
218 // Try to get the exception string. Sometimes logcat isn't available,
219 // so try to add it to the abort message.
220 std::string exc_msg = "(Unknown exception message)";
221 {
222 ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
223 jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
224 "()Ljava/lang/String;");
225 ScopedLocalRef<jstring> jstr(
226 env,
227 reinterpret_cast<jstring>(
228 env->CallObjectMethod(error, method_id)));
229 env->ExceptionClear(); // Just for good measure.
230 if (jstr.get() != nullptr) {
231 ScopedUtfChars jstr_utf(env, jstr.get());
232 if (jstr_utf.c_str() != nullptr) {
233 exc_msg = jstr_utf.c_str();
234 } else {
235 env->ExceptionClear();
236 }
237 }
238 }
239
240 env->Throw(error);
241 ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
242 env->ExceptionDescribe();
243
244 std::string error_msg = base::StringPrintf(
245 "java.lang.Error thrown during binder transaction: %s",
246 exc_msg.c_str());
247 env->FatalError(error_msg.c_str());
248}
249
250// Report a java.lang.Error (or subclass). This will terminate the runtime, either by
251// the uncaught exception handler, or explicitly by calling
252// report_java_lang_error_fatal_error.
253static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* msg)
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700254{
255 // Try to run the uncaught exception machinery.
256 jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass,
257 gThreadDispatchOffsets.mCurrentThread);
258 if (thread != nullptr) {
259 env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException,
260 error);
261 // Should not return here, unless more errors occured.
262 }
263 // Some error occurred that meant that either dispatchUncaughtException could not be
264 // called or that it had an error itself (as this should be unreachable under normal
Andreas Gampe625e0002017-09-08 17:44:05 -0700265 // conditions). As the binder code cannot handle Errors, attempt to log the error and
266 // abort.
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700267 env->ExceptionClear();
Andreas Gampe625e0002017-09-08 17:44:05 -0700268 report_java_lang_error_fatal_error(env, error, msg);
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700269}
270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
272{
273 env->ExceptionClear();
274
Andreas Gampe625e0002017-09-08 17:44:05 -0700275 ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
Andreas Gampe8571ec32017-09-21 10:55:59 -0700276 ScopedLocalRef<jstring> msgstr(env);
Andreas Gampe625e0002017-09-08 17:44:05 -0700277 if (tagstr != nullptr) {
278 msgstr.reset(env->NewStringUTF(msg));
Mathieu Chartiercf6775e2014-08-06 13:39:17 -0700279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280
Andreas Gampe625e0002017-09-08 17:44:05 -0700281 if ((tagstr != nullptr) && (msgstr != nullptr)) {
282 env->CallStaticIntMethod(gLogOffsets.mClass, gLogOffsets.mLogE,
283 tagstr.get(), msgstr.get(), excep);
284 if (env->ExceptionCheck()) {
285 // Attempting to log the failure has failed.
286 ALOGW("Failed trying to log exception, msg='%s'\n", msg);
287 env->ExceptionClear();
288 }
289 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 env->ExceptionClear(); /* assume exception (OOM?) was thrown */
Steve Block3762c312012-01-06 19:20:56 +0000291 ALOGE("Unable to call Log.e()\n");
292 ALOGE("%s", msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 }
294
295 if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700296 report_java_lang_error(env, excep, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298}
299
300class JavaBBinderHolder;
301
302class JavaBBinder : public BBinder
303{
304public:
Hans Boehm29f388f2017-10-03 18:01:20 -0700305 JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
307 {
Steve Block71f2cf12011-10-20 11:56:00 +0100308 ALOGV("Creating JavaBBinder %p\n", this);
Hans Boehm29f388f2017-10-03 18:01:20 -0700309 gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
310 gcIfManyNewRefs(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 }
312
313 bool checkSubclass(const void* subclassID) const
314 {
315 return subclassID == &gBinderOffsets;
316 }
317
318 jobject object() const
319 {
320 return mObject;
321 }
322
323protected:
324 virtual ~JavaBBinder()
325 {
Steve Block71f2cf12011-10-20 11:56:00 +0100326 ALOGV("Destroying JavaBBinder %p\n", this);
Hans Boehm29f388f2017-10-03 18:01:20 -0700327 gNumLocalRefsDeleted.fetch_add(1, memory_order_relaxed);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 JNIEnv* env = javavm_to_jnienv(mVM);
329 env->DeleteGlobalRef(mObject);
330 }
331
Steven Morelande52bb7d2018-10-10 11:24:58 -0700332 const String16& getInterfaceDescriptor() const override
333 {
334 call_once(mPopulateDescriptor, [this] {
335 JNIEnv* env = javavm_to_jnienv(mVM);
336
337 ALOGV("getInterfaceDescriptor() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
338
339 jstring descriptor = (jstring)env->CallObjectMethod(mObject, gBinderOffsets.mGetInterfaceDescriptor);
340
341 if (descriptor == nullptr) {
342 return;
343 }
344
345 static_assert(sizeof(jchar) == sizeof(char16_t), "");
346 const jchar* descriptorChars = env->GetStringChars(descriptor, nullptr);
347 const char16_t* rawDescriptor = reinterpret_cast<const char16_t*>(descriptorChars);
348 jsize rawDescriptorLen = env->GetStringLength(descriptor);
349 mDescriptor = String16(rawDescriptor, rawDescriptorLen);
350 env->ReleaseStringChars(descriptor, descriptorChars);
351 });
352
353 return mDescriptor;
354 }
355
356 status_t onTransact(
357 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 {
359 JNIEnv* env = javavm_to_jnienv(mVM);
360
Steve Block71f2cf12011-10-20 11:56:00 +0100361 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 -0800362
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700363 IPCThreadState* thread_state = IPCThreadState::self();
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700364 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 //printf("Transact from %p to Java code sending: ", this);
367 //data.print();
368 //printf("\n");
369 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000370 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700371
Mathieu Chartier98671c32014-08-20 10:04:08 -0700372 if (env->ExceptionCheck()) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700373 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
374 report_exception(env, excep.get(),
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100375 "*** Uncaught remote exception! "
376 "(Exceptions are not yet supported across processes.)");
377 res = JNI_FALSE;
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100378 }
379
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700380 // Check if the strict mode state changed while processing the
381 // call. The Binder state will be restored by the underlying
382 // Binder system in IPCThreadState, however we need to take care
383 // of the parallel Java state as well.
384 if (thread_state->getStrictModePolicy() != strict_policy_before) {
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700385 set_dalvik_blockguard_policy(env, strict_policy_before);
386 }
387
Mathieu Chartier98671c32014-08-20 10:04:08 -0700388 if (env->ExceptionCheck()) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700389 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
390 report_exception(env, excep.get(),
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100391 "*** Uncaught exception in onBinderStrictModePolicyChange");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 }
393
Dianne Hackborna53de062012-05-08 18:53:51 -0700394 // Need to always call through the native implementation of
395 // SYSPROPS_TRANSACTION.
396 if (code == SYSPROPS_TRANSACTION) {
397 BBinder::onTransact(code, data, reply, flags);
398 }
399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 //aout << "onTransact to Java code; result=" << res << endl
401 // << "Transact from " << this << " to Java code returning "
402 // << reply << ": " << *reply << endl;
403 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
404 }
405
Steven Morelande52bb7d2018-10-10 11:24:58 -0700406 status_t dump(int fd, const Vector<String16>& args) override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 {
408 return 0;
409 }
410
411private:
412 JavaVM* const mVM;
Hans Boehm29f388f2017-10-03 18:01:20 -0700413 jobject const mObject; // GlobalRef to Java Binder
Steven Morelande52bb7d2018-10-10 11:24:58 -0700414
415 mutable std::once_flag mPopulateDescriptor;
416 mutable String16 mDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417};
418
419// ----------------------------------------------------------------------------
420
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700421class JavaBBinderHolder
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422{
423public:
Christopher Tate0b414482011-02-17 13:00:38 -0800424 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 {
426 AutoMutex _l(mLock);
427 sp<JavaBBinder> b = mBinder.promote();
428 if (b == NULL) {
Christopher Tate0b414482011-02-17 13:00:38 -0800429 b = new JavaBBinder(env, obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 mBinder = b;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700431 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
Christopher Tate0b414482011-02-17 13:00:38 -0800432 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 }
434
435 return b;
436 }
437
438 sp<JavaBBinder> getExisting()
439 {
440 AutoMutex _l(mLock);
441 return mBinder.promote();
442 }
443
444private:
445 Mutex mLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 wp<JavaBBinder> mBinder;
447};
448
449// ----------------------------------------------------------------------------
450
Christopher Tate0b414482011-02-17 13:00:38 -0800451// Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
452// death recipient references passed in through JNI with the permanent corresponding
453// JavaDeathRecipient objects.
454
455class JavaDeathRecipient;
456
457class DeathRecipientList : public RefBase {
458 List< sp<JavaDeathRecipient> > mList;
459 Mutex mLock;
460
461public:
Christopher Tate79dd31f2011-03-04 17:45:00 -0800462 DeathRecipientList();
Christopher Tate0b414482011-02-17 13:00:38 -0800463 ~DeathRecipientList();
464
465 void add(const sp<JavaDeathRecipient>& recipient);
466 void remove(const sp<JavaDeathRecipient>& recipient);
467 sp<JavaDeathRecipient> find(jobject recipient);
Christopher Tate090c08f2015-05-19 18:16:58 -0700468
469 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
Christopher Tate0b414482011-02-17 13:00:38 -0800470};
471
472// ----------------------------------------------------------------------------
473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474class JavaDeathRecipient : public IBinder::DeathRecipient
475{
476public:
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800477 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
Christopher Tate86284c62011-08-17 15:19:29 -0700478 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
479 mObjectWeak(NULL), mList(list)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 {
Christopher Tate0b414482011-02-17 13:00:38 -0800481 // These objects manage their own lifetimes so are responsible for final bookkeeping.
482 // The list holds a strong reference to this object.
Christopher Tate79dd31f2011-03-04 17:45:00 -0800483 LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800484 list->add(this);
Christopher Tate0b414482011-02-17 13:00:38 -0800485
Hans Boehm29f388f2017-10-03 18:01:20 -0700486 gNumDeathRefsCreated.fetch_add(1, std::memory_order_relaxed);
487 gcIfManyNewRefs(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 }
489
490 void binderDied(const wp<IBinder>& who)
491 {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800492 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
Christopher Tate86284c62011-08-17 15:19:29 -0700493 if (mObject != NULL) {
494 JNIEnv* env = javavm_to_jnienv(mVM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495
Christopher Tate86284c62011-08-17 15:19:29 -0700496 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
497 gBinderProxyOffsets.mSendDeathNotice, mObject);
Mathieu Chartier98671c32014-08-20 10:04:08 -0700498 if (env->ExceptionCheck()) {
499 jthrowable excep = env->ExceptionOccurred();
Christopher Tate86284c62011-08-17 15:19:29 -0700500 report_exception(env, excep,
501 "*** Uncaught exception returned from death notification!");
502 }
503
Christopher Tate090c08f2015-05-19 18:16:58 -0700504 // Serialize with our containing DeathRecipientList so that we can't
505 // delete the global ref on mObject while the list is being iterated.
506 sp<DeathRecipientList> list = mList.promote();
507 if (list != NULL) {
508 AutoMutex _l(list->lock());
509
510 // Demote from strong ref to weak after binderDied() has been delivered,
511 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
512 mObjectWeak = env->NewWeakGlobalRef(mObject);
513 env->DeleteGlobalRef(mObject);
514 mObject = NULL;
515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 }
518
519 void clearReference()
520 {
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800521 sp<DeathRecipientList> list = mList.promote();
522 if (list != NULL) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800523 LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800524 list->remove(this);
Christopher Tate79dd31f2011-03-04 17:45:00 -0800525 } else {
526 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800527 }
Christopher Tate0b414482011-02-17 13:00:38 -0800528 }
529
530 bool matches(jobject obj) {
Christopher Tate86284c62011-08-17 15:19:29 -0700531 bool result;
Christopher Tate0b414482011-02-17 13:00:38 -0800532 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate86284c62011-08-17 15:19:29 -0700533
534 if (mObject != NULL) {
535 result = env->IsSameObject(obj, mObject);
536 } else {
Andreas Gampe625e0002017-09-08 17:44:05 -0700537 ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
538 result = env->IsSameObject(obj, me.get());
Christopher Tate86284c62011-08-17 15:19:29 -0700539 }
540 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 }
542
Christopher Tateac5e3502011-08-25 15:48:09 -0700543 void warnIfStillLive() {
544 if (mObject != NULL) {
545 // Okay, something is wrong -- we have a hard reference to a live death
546 // recipient on the VM side, but the list is being torn down.
547 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate0d4a7922011-08-30 12:09:43 -0700548 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
549 ScopedLocalRef<jstring> nameRef(env,
550 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
551 ScopedUtfChars nameUtf(env, nameRef.get());
552 if (nameUtf.c_str() != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +0000553 ALOGW("BinderProxy is being destroyed but the application did not call "
Christopher Tate0d4a7922011-08-30 12:09:43 -0700554 "unlinkToDeath to unlink all of its death recipients beforehand. "
555 "Releasing leaked death recipient: %s", nameUtf.c_str());
556 } else {
Steve Block8564c8d2012-01-05 23:22:43 +0000557 ALOGW("BinderProxy being destroyed; unable to get DR object name");
Christopher Tate0d4a7922011-08-30 12:09:43 -0700558 env->ExceptionClear();
559 }
Christopher Tateac5e3502011-08-25 15:48:09 -0700560 }
561 }
562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563protected:
564 virtual ~JavaDeathRecipient()
565 {
Steve Block6215d3f2012-01-04 20:05:49 +0000566 //ALOGI("Removing death ref: recipient=%p\n", mObject);
Hans Boehm29f388f2017-10-03 18:01:20 -0700567 gNumDeathRefsDeleted.fetch_add(1, std::memory_order_relaxed);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate86284c62011-08-17 15:19:29 -0700569 if (mObject != NULL) {
570 env->DeleteGlobalRef(mObject);
571 } else {
572 env->DeleteWeakGlobalRef(mObjectWeak);
573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 }
575
576private:
Christopher Tate86284c62011-08-17 15:19:29 -0700577 JavaVM* const mVM;
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700578 jobject mObject; // Initial strong ref to Java-side DeathRecipient. Cleared on binderDied().
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700579 jweak mObjectWeak; // Weak ref to the same Java-side DeathRecipient after binderDied().
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800580 wp<DeathRecipientList> mList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581};
582
583// ----------------------------------------------------------------------------
584
Christopher Tate79dd31f2011-03-04 17:45:00 -0800585DeathRecipientList::DeathRecipientList() {
586 LOGDEATH("New DRL @ %p", this);
587}
588
Christopher Tate0b414482011-02-17 13:00:38 -0800589DeathRecipientList::~DeathRecipientList() {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800590 LOGDEATH("Destroy DRL @ %p", this);
Christopher Tate0b414482011-02-17 13:00:38 -0800591 AutoMutex _l(mLock);
592
593 // Should never happen -- the JavaDeathRecipient objects that have added themselves
594 // to the list are holding references on the list object. Only when they are torn
595 // down can the list header be destroyed.
596 if (mList.size() > 0) {
Christopher Tateac5e3502011-08-25 15:48:09 -0700597 List< sp<JavaDeathRecipient> >::iterator iter;
598 for (iter = mList.begin(); iter != mList.end(); iter++) {
599 (*iter)->warnIfStillLive();
600 }
Christopher Tate0b414482011-02-17 13:00:38 -0800601 }
602}
603
604void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
605 AutoMutex _l(mLock);
606
Christopher Tate79dd31f2011-03-04 17:45:00 -0800607 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
Christopher Tate0b414482011-02-17 13:00:38 -0800608 mList.push_back(recipient);
609}
610
611void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
612 AutoMutex _l(mLock);
613
614 List< sp<JavaDeathRecipient> >::iterator iter;
615 for (iter = mList.begin(); iter != mList.end(); iter++) {
616 if (*iter == recipient) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800617 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
Christopher Tate0b414482011-02-17 13:00:38 -0800618 mList.erase(iter);
619 return;
620 }
621 }
622}
623
624sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
625 AutoMutex _l(mLock);
626
627 List< sp<JavaDeathRecipient> >::iterator iter;
628 for (iter = mList.begin(); iter != mList.end(); iter++) {
629 if ((*iter)->matches(recipient)) {
630 return *iter;
631 }
632 }
633 return NULL;
634}
635
Christopher Tate090c08f2015-05-19 18:16:58 -0700636Mutex& DeathRecipientList::lock() {
637 return mLock;
638}
639
Christopher Tate0b414482011-02-17 13:00:38 -0800640// ----------------------------------------------------------------------------
641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800642namespace android {
643
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700644// We aggregate native pointer fields for BinderProxy in a single object to allow
645// management with a single NativeAllocationRegistry, and to reduce the number of JNI
646// Java field accesses. This costs us some extra indirections here.
647struct BinderProxyNativeData {
Hans Boehm29f388f2017-10-03 18:01:20 -0700648 // Both fields are constant and not null once javaObjectForIBinder returns this as
649 // part of a BinderProxy.
650
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700651 // The native IBinder proxied by this BinderProxy.
Hans Boehm29f388f2017-10-03 18:01:20 -0700652 sp<IBinder> mObject;
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700653
654 // Death recipients for mObject. Reference counted only because DeathRecipients
655 // hold a weak reference that can be temporarily promoted.
Hans Boehm29f388f2017-10-03 18:01:20 -0700656 sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700657};
658
659BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
660 return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
661}
662
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700663static Mutex gProxyLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664
Hans Boehm29f388f2017-10-03 18:01:20 -0700665// We may cache a single BinderProxyNativeData node to avoid repeat allocation.
666// All fields are null. Protected by gProxyLock.
667static BinderProxyNativeData *gNativeDataCache;
668
669// If the argument is a JavaBBinder, return the Java object that was used to create it.
670// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
671// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
673{
674 if (val == NULL) return NULL;
675
676 if (val->checkSubclass(&gBinderOffsets)) {
Hans Boehm29f388f2017-10-03 18:01:20 -0700677 // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 jobject object = static_cast<JavaBBinder*>(val.get())->object();
Christopher Tate86284c62011-08-17 15:19:29 -0700679 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 return object;
681 }
682
683 // For the rest of the function we will hold this lock, to serialize
Christopher Tate10c3a282016-02-26 17:48:08 -0800684 // looking/creation/destruction of Java proxies for native Binder proxies.
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700685 AutoMutex _l(gProxyLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686
Hans Boehm29f388f2017-10-03 18:01:20 -0700687 BinderProxyNativeData* nativeData = gNativeDataCache;
688 if (nativeData == nullptr) {
689 nativeData = new BinderProxyNativeData();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 }
Hans Boehm29f388f2017-10-03 18:01:20 -0700691 // gNativeDataCache is now logically empty.
692 jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
693 gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
694 if (env->ExceptionCheck()) {
Hans Boehm03477cb2018-02-15 16:12:51 -0800695 // In the exception case, getInstance still took ownership of nativeData.
696 gNativeDataCache = nullptr;
Hans Boehm29f388f2017-10-03 18:01:20 -0700697 return NULL;
698 }
699 BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
700 if (actualNativeData == nativeData) {
701 // New BinderProxy; we still have exclusive access.
702 nativeData->mOrgue = new DeathRecipientList;
703 nativeData->mObject = val;
704 gNativeDataCache = nullptr;
705 ++gNumProxies;
Martijn Coenen5183c0e2018-02-07 10:25:39 +0100706 if (gNumProxies >= gProxiesWarned + PROXY_WARN_INTERVAL) {
Hans Boehm29f388f2017-10-03 18:01:20 -0700707 ALOGW("Unexpectedly many live BinderProxies: %d\n", gNumProxies);
708 gProxiesWarned = gNumProxies;
709 }
710 } else {
711 // nativeData wasn't used. Reuse it the next time.
712 gNativeDataCache = nativeData;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713 }
714
715 return object;
716}
717
718sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
719{
720 if (obj == NULL) return NULL;
721
Hans Boehm29f388f2017-10-03 18:01:20 -0700722 // Instance of Binder?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
724 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000725 env->GetLongField(obj, gBinderOffsets.mObject);
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700726 return jbh->get(env, obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 }
728
Hans Boehm29f388f2017-10-03 18:01:20 -0700729 // Instance of BinderProxy?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700731 return getBPNativeData(env, obj)->mObject;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 }
733
Steve Block8564c8d2012-01-05 23:22:43 +0000734 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 return NULL;
736}
737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
739{
740 return env->NewObject(
741 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
742}
743
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800744void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
745{
746 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
747 // to sync our state back to it. See the comments in StrictMode.java.
748 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
749 gStrictModeCallbackOffsets.mCallback,
750 strict_policy);
751}
752
753void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
Dianne Hackborne5c42622015-05-19 16:04:04 -0700754 bool canThrowRemoteException, int parcelSize)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755{
756 switch (err) {
757 case UNKNOWN_ERROR:
758 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
759 break;
760 case NO_MEMORY:
761 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
762 break;
763 case INVALID_OPERATION:
764 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
765 break;
766 case BAD_VALUE:
767 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
768 break;
769 case BAD_INDEX:
770 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
771 break;
772 case BAD_TYPE:
773 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
774 break;
775 case NAME_NOT_FOUND:
776 jniThrowException(env, "java/util/NoSuchElementException", NULL);
777 break;
778 case PERMISSION_DENIED:
779 jniThrowException(env, "java/lang/SecurityException", NULL);
780 break;
781 case NOT_ENOUGH_DATA:
782 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
783 break;
784 case NO_INIT:
785 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
786 break;
787 case ALREADY_EXISTS:
788 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
789 break;
790 case DEAD_OBJECT:
Jeff Brown0bde66a2011-11-07 12:50:08 -0800791 // DeadObjectException is a checked exception, only throw from certain methods.
792 jniThrowException(env, canThrowRemoteException
793 ? "android/os/DeadObjectException"
794 : "java/lang/RuntimeException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 break;
796 case UNKNOWN_TRANSACTION:
797 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
798 break;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700799 case FAILED_TRANSACTION: {
800 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
Christopher Tate02ca7a72015-06-24 18:16:42 -0700801 const char* exceptionToThrow;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700802 char msg[128];
Jeff Brown0bde66a2011-11-07 12:50:08 -0800803 // TransactionTooLargeException is a checked exception, only throw from certain methods.
804 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
805 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
806 // for other reasons also, such as if the transaction is malformed or
807 // refers to an FD that has been closed. We should change the driver
808 // to enable us to distinguish these cases in the future.
Christopher Tate02ca7a72015-06-24 18:16:42 -0700809 if (canThrowRemoteException && parcelSize > 200*1024) {
810 // bona fide large payload
811 exceptionToThrow = "android/os/TransactionTooLargeException";
812 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
813 } else {
814 // Heuristic: a payload smaller than this threshold "shouldn't" be too
815 // big, so it's probably some other, more subtle problem. In practice
Christopher Tateffd58642015-06-29 11:00:15 -0700816 // it seems to always mean that the remote process died while the binder
Christopher Tate02ca7a72015-06-24 18:16:42 -0700817 // transaction was already in flight.
Christopher Tateffd58642015-06-29 11:00:15 -0700818 exceptionToThrow = (canThrowRemoteException)
819 ? "android/os/DeadObjectException"
820 : "java/lang/RuntimeException";
Christopher Tate02ca7a72015-06-24 18:16:42 -0700821 snprintf(msg, sizeof(msg)-1,
822 "Transaction failed on small parcel; remote process probably died");
823 }
824 jniThrowException(env, exceptionToThrow, msg);
Dianne Hackborne5c42622015-05-19 16:04:04 -0700825 } break;
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400826 case FDS_NOT_ALLOWED:
827 jniThrowException(env, "java/lang/RuntimeException",
828 "Not allowed to write file descriptors here");
829 break;
Christopher Wileya94fc522015-11-22 14:21:25 -0800830 case UNEXPECTED_NULL:
831 jniThrowNullPointerException(env, NULL);
832 break;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700833 case -EBADF:
834 jniThrowException(env, "java/lang/RuntimeException",
835 "Bad file descriptor");
836 break;
837 case -ENFILE:
838 jniThrowException(env, "java/lang/RuntimeException",
839 "File table overflow");
840 break;
841 case -EMFILE:
842 jniThrowException(env, "java/lang/RuntimeException",
843 "Too many open files");
844 break;
845 case -EFBIG:
846 jniThrowException(env, "java/lang/RuntimeException",
847 "File too large");
848 break;
849 case -ENOSPC:
850 jniThrowException(env, "java/lang/RuntimeException",
851 "No space left on device");
852 break;
853 case -ESPIPE:
854 jniThrowException(env, "java/lang/RuntimeException",
855 "Illegal seek");
856 break;
857 case -EROFS:
858 jniThrowException(env, "java/lang/RuntimeException",
859 "Read-only file system");
860 break;
861 case -EMLINK:
862 jniThrowException(env, "java/lang/RuntimeException",
863 "Too many links");
864 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 default:
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700866 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800867 String8 msg;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700868 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800869 // RemoteException is a checked exception, only throw from certain methods.
870 jniThrowException(env, canThrowRemoteException
871 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
872 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 }
874}
875
876}
877
878// ----------------------------------------------------------------------------
879
880static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
881{
882 return IPCThreadState::self()->getCallingPid();
883}
884
885static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz)
886{
887 return IPCThreadState::self()->getCallingUid();
888}
889
890static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz)
891{
892 return IPCThreadState::self()->clearCallingIdentity();
893}
894
895static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
896{
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700897 // XXX temporary sanity check to debug crashes.
898 int uid = (int)(token>>32);
899 if (uid > 0 && uid < 999) {
900 // In Android currently there are no uids in this range.
901 char buf[128];
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700902 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700903 jniThrowException(env, "java/lang/IllegalStateException", buf);
904 return;
905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 IPCThreadState::self()->restoreCallingIdentity(token);
907}
908
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700909static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask)
910{
911 IPCThreadState::self()->setStrictModePolicy(policyMask);
912}
913
914static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz)
915{
916 return IPCThreadState::self()->getStrictModePolicy();
917}
918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
920{
921 IPCThreadState::self()->flushCommands();
922}
923
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700924static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925{
Christopher Tate0b414482011-02-17 13:00:38 -0800926 JavaBBinderHolder* jbh = new JavaBBinderHolder();
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700927 return (jlong) jbh;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928}
929
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700930static void Binder_destroy(void* rawJbh)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931{
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700932 JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh;
933 ALOGV("Java Binder: deleting holder %p", jbh);
934 delete jbh;
935}
936
937JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) {
938 return (jlong) Binder_destroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939}
940
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700941static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
942{
943 return IPCThreadState::self()->blockUntilThreadAvailable();
944}
945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946// ----------------------------------------------------------------------------
947
948static const JNINativeMethod gBinderMethods[] = {
949 /* name, signature, funcPtr */
950 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
951 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
952 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
953 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700954 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
955 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700957 { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
958 { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700959 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960};
961
962const char* const kBinderPathName = "android/os/Binder";
963
964static int int_register_android_os_Binder(JNIEnv* env)
965{
Andreas Gampe987f79f2014-11-18 17:29:46 -0800966 jclass clazz = FindClassOrDie(env, kBinderPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967
Andreas Gampe987f79f2014-11-18 17:29:46 -0800968 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
969 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
Steven Morelande52bb7d2018-10-10 11:24:58 -0700970 gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
971 "()Ljava/lang/String;");
Andreas Gampe987f79f2014-11-18 17:29:46 -0800972 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800974 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 env, kBinderPathName,
976 gBinderMethods, NELEM(gBinderMethods));
977}
978
979// ****************************************************************************
980// ****************************************************************************
981// ****************************************************************************
982
983namespace android {
984
985jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
986{
Hans Boehm29f388f2017-10-03 18:01:20 -0700987 return gNumLocalRefsCreated - gNumLocalRefsDeleted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988}
989
990jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
991{
Hans Boehm29f388f2017-10-03 18:01:20 -0700992 AutoMutex _l(gProxyLock);
993 return gNumProxies;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994}
995
996jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
997{
Hans Boehm29f388f2017-10-03 18:01:20 -0700998 return gNumDeathRefsCreated - gNumDeathRefsDeleted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999}
1000
1001}
1002
1003// ****************************************************************************
1004// ****************************************************************************
1005// ****************************************************************************
1006
1007static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
1008{
1009 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1010 return javaObjectForIBinder(env, b);
1011}
1012
1013static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
1014{
1015 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1016 android::IPCThreadState::self()->joinThreadPool();
1017}
1018
Dianne Hackborn887f3552009-12-07 17:59:37 -08001019static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
1020 jobject clazz, jboolean disable)
1021{
1022 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
1023}
1024
Tim Murrayeef4a3d2016-04-19 14:14:20 -07001025static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
1026 jobject clazz, jint maxThreads)
1027{
1028 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
1029}
1030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
1032{
Hans Boehm29f388f2017-10-03 18:01:20 -07001033 ALOGV("Gc has executed, updating Refs count at GC");
1034 gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001035}
1036
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001037static void android_os_BinderInternal_proxyLimitcallback(int uid)
1038{
1039 JNIEnv *env = AndroidRuntime::getJNIEnv();
1040 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1041 gBinderInternalOffsets.mProxyLimitCallback,
1042 uid);
Martijn Coenendfa390e2018-06-05 11:02:23 +02001043
1044 if (env->ExceptionCheck()) {
1045 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1046 report_exception(env, excep.get(),
1047 "*** Uncaught exception in binderProxyLimitCallbackFromNative");
1048 }
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001049}
1050
1051static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
1052 jboolean enable)
1053{
1054 BpBinder::setCountByUidEnabled((bool) enable);
1055}
1056
1057static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
1058{
1059 Vector<uint32_t> uids, counts;
1060 BpBinder::getCountByUid(uids, counts);
1061 jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
1062 gSparseIntArrayOffsets.constructor);
1063 for (size_t i = 0; i < uids.size(); i++) {
1064 env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
1065 static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
1066 }
1067 return sparseIntArray;
1068}
1069
1070static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
1071 return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
1072}
1073
1074static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
1075 jint high, jint low)
1076{
1077 BpBinder::setBinderProxyCountWatermarks(high, low);
1078}
1079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001080// ----------------------------------------------------------------------------
1081
1082static const JNINativeMethod gBinderInternalMethods[] = {
1083 /* name, signature, funcPtr */
1084 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
1085 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
Dianne Hackborn887f3552009-12-07 17:59:37 -08001086 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
Tim Murrayeef4a3d2016-04-19 14:14:20 -07001087 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001088 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
1089 { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
1090 { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
1091 { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
1092 { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093};
1094
1095const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
1096
1097static int int_register_android_os_BinderInternal(JNIEnv* env)
1098{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001099 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100
Andreas Gampe987f79f2014-11-18 17:29:46 -08001101 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1102 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001103 gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
1104
1105 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
1106 gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
1107 gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
1108 "<init>", "()V");
1109 gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
1110 "(II)V");
1111
1112 BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001114 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 env, kBinderInternalPathName,
1116 gBinderInternalMethods, NELEM(gBinderInternalMethods));
1117}
1118
1119// ****************************************************************************
1120// ****************************************************************************
1121// ****************************************************************************
1122
1123static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
1124{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001125 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 if (target == NULL) {
1127 return JNI_FALSE;
1128 }
1129 status_t err = target->pingBinder();
1130 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1131}
1132
1133static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
1134{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001135 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 if (target != NULL) {
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001137 const String16& desc = target->getInterfaceDescriptor();
Dan Albert66987492014-11-20 11:41:21 -08001138 return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
1139 desc.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 }
1141 jniThrowException(env, "java/lang/RuntimeException",
1142 "No binder found for object");
1143 return NULL;
1144}
1145
1146static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1147{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001148 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 if (target == NULL) {
1150 return JNI_FALSE;
1151 }
1152 bool alive = target->isBinderAlive();
1153 return alive ? JNI_TRUE : JNI_FALSE;
1154}
1155
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001156static int getprocname(pid_t pid, char *buf, size_t len) {
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001157 char filename[32];
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001158 FILE *f;
1159
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001160 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
Nick Kralevich4b3a08c2019-01-28 10:39:10 -08001161 f = fopen(filename, "re");
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001162 if (!f) {
1163 *buf = '\0';
1164 return 1;
1165 }
1166 if (!fgets(buf, len, f)) {
1167 *buf = '\0';
1168 fclose(f);
1169 return 2;
1170 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001171 fclose(f);
1172 return 0;
1173}
1174
1175static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1176 jint len = strlen(str);
1177 int space_needed = 1 + sizeof(len) + len;
1178 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001179 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001180 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001181 return false;
1182 }
1183 **pos = EVENT_TYPE_STRING;
1184 (*pos)++;
1185 memcpy(*pos, &len, sizeof(len));
1186 *pos += sizeof(len);
1187 memcpy(*pos, str, len);
1188 *pos += len;
1189 return true;
1190}
1191
1192static bool push_eventlog_int(char** pos, const char* end, jint val) {
1193 int space_needed = 1 + sizeof(val);
1194 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001195 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001196 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001197 return false;
1198 }
1199 **pos = EVENT_TYPE_INT;
1200 (*pos)++;
1201 memcpy(*pos, &val, sizeof(val));
1202 *pos += sizeof(val);
1203 return true;
1204}
1205
1206// From frameworks/base/core/java/android/content/EventLogTags.logtags:
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001207
1208static const bool kEnableBinderSample = false;
1209
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001210#define LOGTAG_BINDER_OPERATION 52004
1211
1212static void conditionally_log_binder_call(int64_t start_millis,
1213 IBinder* target, jint code) {
1214 int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1215
1216 int sample_percent;
1217 if (duration_ms >= 500) {
1218 sample_percent = 100;
1219 } else {
1220 sample_percent = 100 * duration_ms / 500;
1221 if (sample_percent == 0) {
1222 return;
1223 }
1224 if (sample_percent < (random() % 100 + 1)) {
1225 return;
1226 }
1227 }
1228
1229 char process_name[40];
1230 getprocname(getpid(), process_name, sizeof(process_name));
1231 String8 desc(target->getInterfaceDescriptor());
1232
1233 char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1234 buf[0] = EVENT_TYPE_LIST;
1235 buf[1] = 5;
1236 char* pos = &buf[2];
1237 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n
1238 if (!push_eventlog_string(&pos, end, desc.string())) return;
1239 if (!push_eventlog_int(&pos, end, code)) return;
1240 if (!push_eventlog_int(&pos, end, duration_ms)) return;
1241 if (!push_eventlog_string(&pos, end, process_name)) return;
1242 if (!push_eventlog_int(&pos, end, sample_percent)) return;
1243 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently.
1244 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1245}
1246
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001247// We only measure binder call durations to potentially log them if
Elliott Hughes06451fe2014-08-18 10:26:52 -07001248// we're on the main thread.
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001249static bool should_time_binder_calls() {
Elliott Hughes06451fe2014-08-18 10:26:52 -07001250 return (getpid() == gettid());
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001251}
1252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001254 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255{
1256 if (dataObj == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001257 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 return JNI_FALSE;
1259 }
1260
1261 Parcel* data = parcelForJavaObject(env, dataObj);
1262 if (data == NULL) {
1263 return JNI_FALSE;
1264 }
1265 Parcel* reply = parcelForJavaObject(env, replyObj);
1266 if (reply == NULL && replyObj != NULL) {
1267 return JNI_FALSE;
1268 }
1269
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001270 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 if (target == NULL) {
1272 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1273 return JNI_FALSE;
1274 }
1275
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001276 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 -08001277 target, obj, code);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001278
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001279
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001280 bool time_binder_calls;
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001281 int64_t start_millis;
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001282 if (kEnableBinderSample) {
1283 // Only log the binder call duration for things on the Java-level main thread.
1284 // But if we don't
1285 time_binder_calls = should_time_binder_calls();
1286
1287 if (time_binder_calls) {
1288 start_millis = uptimeMillis();
1289 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001290 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 //printf("Transact from Java code to %p sending: ", target); data->print();
1293 status_t err = target->transact(code, *data, reply, flags);
1294 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001295
1296 if (kEnableBinderSample) {
1297 if (time_binder_calls) {
1298 conditionally_log_binder_call(start_millis, target, code);
1299 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001300 }
1301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 if (err == NO_ERROR) {
1303 return JNI_TRUE;
1304 } else if (err == UNKNOWN_TRANSACTION) {
1305 return JNI_FALSE;
1306 }
1307
Dianne Hackborne5c42622015-05-19 16:04:04 -07001308 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 return JNI_FALSE;
1310}
1311
1312static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001313 jobject recipient, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314{
1315 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001316 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 return;
1318 }
1319
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001320 BinderProxyNativeData *nd = getBPNativeData(env, obj);
1321 IBinder* target = nd->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322
Christopher Tate79dd31f2011-03-04 17:45:00 -08001323 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324
1325 if (!target->localBinder()) {
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001326 DeathRecipientList* list = nd->mOrgue.get();
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001327 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
Christopher Tate0b414482011-02-17 13:00:38 -08001328 status_t err = target->linkToDeath(jdr, NULL, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 if (err != NO_ERROR) {
1330 // Failure adding the death recipient, so clear its reference
1331 // now.
1332 jdr->clearReference();
Jeff Brown0bde66a2011-11-07 12:50:08 -08001333 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 }
1335 }
1336}
1337
1338static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1339 jobject recipient, jint flags)
1340{
1341 jboolean res = JNI_FALSE;
1342 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001343 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 return res;
1345 }
1346
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001347 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1348 IBinder* target = nd->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 if (target == NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001350 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 return JNI_FALSE;
1352 }
1353
Christopher Tate79dd31f2011-03-04 17:45:00 -08001354 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355
1356 if (!target->localBinder()) {
Christopher Tate0b414482011-02-17 13:00:38 -08001357 status_t err = NAME_NOT_FOUND;
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001358
1359 // If we find the matching recipient, proceed to unlink using that
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001360 DeathRecipientList* list = nd->mOrgue.get();
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001361 sp<JavaDeathRecipient> origJDR = list->find(recipient);
Christopher Tate79dd31f2011-03-04 17:45:00 -08001362 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
Christopher Tate0b414482011-02-17 13:00:38 -08001363 if (origJDR != NULL) {
1364 wp<IBinder::DeathRecipient> dr;
1365 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1366 if (err == NO_ERROR && dr != NULL) {
1367 sp<IBinder::DeathRecipient> sdr = dr.promote();
1368 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1369 if (jdr != NULL) {
1370 jdr->clearReference();
1371 }
1372 }
1373 }
1374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 if (err == NO_ERROR || err == DEAD_OBJECT) {
1376 res = JNI_TRUE;
1377 } else {
1378 jniThrowException(env, "java/util/NoSuchElementException",
1379 "Death link does not exist");
1380 }
1381 }
1382
1383 return res;
1384}
1385
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001386static void BinderProxy_destroy(void* rawNativeData)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387{
Christopher Tate10c3a282016-02-26 17:48:08 -08001388 // Don't race with construction/initialization
Hans Boehmeb6d62c2017-09-20 15:59:12 -07001389 AutoMutex _l(gProxyLock);
Christopher Tate10c3a282016-02-26 17:48:08 -08001390
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001391 BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
1392 LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
1393 nativeData->mObject.get(), nativeData->mOrgue.get());
Hans Boehm29f388f2017-10-03 18:01:20 -07001394 delete nativeData;
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001395 IPCThreadState::self()->flushCommands();
Hans Boehm29f388f2017-10-03 18:01:20 -07001396 --gNumProxies;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397}
1398
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001399JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
1400 return (jlong) BinderProxy_destroy;
1401}
1402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403// ----------------------------------------------------------------------------
1404
1405static const JNINativeMethod gBinderProxyMethods[] = {
1406 /* name, signature, funcPtr */
1407 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1408 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1409 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001410 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1412 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001413 {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414};
1415
1416const char* const kBinderProxyPathName = "android/os/BinderProxy";
1417
1418static int int_register_android_os_BinderProxy(JNIEnv* env)
1419{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001420 jclass clazz = FindClassOrDie(env, "java/lang/Error");
1421 gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422
Andreas Gampe987f79f2014-11-18 17:29:46 -08001423 clazz = FindClassOrDie(env, kBinderProxyPathName);
1424 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
Hans Boehm29f388f2017-10-03 18:01:20 -07001425 gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
1426 "(JJ)Landroid/os/BinderProxy;");
Andreas Gampe987f79f2014-11-18 17:29:46 -08001427 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1428 "(Landroid/os/IBinder$DeathRecipient;)V");
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001429 gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430
Andreas Gampe987f79f2014-11-18 17:29:46 -08001431 clazz = FindClassOrDie(env, "java/lang/Class");
1432 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
Christopher Tate0d4a7922011-08-30 12:09:43 -07001433
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001434 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 env, kBinderProxyPathName,
1436 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1437}
1438
1439// ****************************************************************************
1440// ****************************************************************************
1441// ****************************************************************************
1442
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001443int register_android_os_Binder(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444{
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001445 if (int_register_android_os_Binder(env) < 0)
1446 return -1;
1447 if (int_register_android_os_BinderInternal(env) < 0)
1448 return -1;
1449 if (int_register_android_os_BinderProxy(env) < 0)
1450 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451
Andreas Gampe987f79f2014-11-18 17:29:46 -08001452 jclass clazz = FindClassOrDie(env, "android/util/Log");
1453 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1454 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1455 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456
Andreas Gampe987f79f2014-11-18 17:29:46 -08001457 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1458 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1459 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1460 "(Ljava/io/FileDescriptor;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461
Andreas Gampe987f79f2014-11-18 17:29:46 -08001462 clazz = FindClassOrDie(env, "android/os/StrictMode");
1463 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1464 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1465 "onBinderStrictModePolicyChange", "(I)V");
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001466
Andreas Gampe1cd76f52017-09-08 17:44:05 -07001467 clazz = FindClassOrDie(env, "java/lang/Thread");
1468 gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1469 gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
1470 "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
1471 gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
1472 "()Ljava/lang/Thread;");
1473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 return 0;
1475}