blob: 22323931e94cea37e52b09a3fbd9d12806116b34 [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{
Andreas Gampe9ff9c402019-07-08 08:31:27 -0700102 jclass mError;
103 jclass mOutOfMemory;
104 jclass mStackOverflow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105} gErrorOffsets;
106
107// ----------------------------------------------------------------------------
108
109static struct binderproxy_offsets_t
110{
111 // Class state.
112 jclass mClass;
Hans Boehm29f388f2017-10-03 18:01:20 -0700113 jmethodID mGetInstance;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 jmethodID mSendDeathNotice;
115
116 // Object state.
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700117 jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118} gBinderProxyOffsets;
119
Christopher Tate0d4a7922011-08-30 12:09:43 -0700120static struct class_offsets_t
121{
122 jmethodID mGetName;
123} gClassOffsets;
124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125// ----------------------------------------------------------------------------
126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127static struct log_offsets_t
128{
129 // Class state.
130 jclass mClass;
131 jmethodID mLogE;
132} gLogOffsets;
133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134static struct parcel_file_descriptor_offsets_t
135{
136 jclass mClass;
137 jmethodID mConstructor;
138} gParcelFileDescriptorOffsets;
139
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700140static struct strict_mode_callback_offsets_t
141{
142 jclass mClass;
143 jmethodID mCallback;
144} gStrictModeCallbackOffsets;
145
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700146static struct thread_dispatch_offsets_t
147{
148 // Class state.
149 jclass mClass;
150 jmethodID mDispatchUncaughtException;
151 jmethodID mCurrentThread;
152} gThreadDispatchOffsets;
153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154// ****************************************************************************
155// ****************************************************************************
156// ****************************************************************************
157
Hans Boehm29f388f2017-10-03 18:01:20 -0700158static constexpr int32_t PROXY_WARN_INTERVAL = 5000;
159static constexpr uint32_t GC_INTERVAL = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160
Martijn Coenend3ef4bf2018-07-05 14:58:59 +0200161static std::atomic<uint32_t> gNumProxies(0);
162static std::atomic<uint32_t> gProxiesWarned(0);
Hans Boehm29f388f2017-10-03 18:01:20 -0700163
164// Number of GlobalRefs held by JavaBBinders.
165static std::atomic<uint32_t> gNumLocalRefsCreated(0);
166static std::atomic<uint32_t> gNumLocalRefsDeleted(0);
167// Number of GlobalRefs held by JavaDeathRecipients.
168static std::atomic<uint32_t> gNumDeathRefsCreated(0);
169static std::atomic<uint32_t> gNumDeathRefsDeleted(0);
170
171// We collected after creating this many refs.
172static std::atomic<uint32_t> gCollectedAtRefs(0);
173
174// Garbage collect if we've allocated at least GC_INTERVAL refs since the last time.
175// TODO: Consider removing this completely. We should no longer be generating GlobalRefs
176// that are reclaimed as a result of GC action.
Ivan Lozano2ea71352017-11-02 14:10:57 -0700177__attribute__((no_sanitize("unsigned-integer-overflow")))
Hans Boehm29f388f2017-10-03 18:01:20 -0700178static void gcIfManyNewRefs(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179{
Hans Boehm29f388f2017-10-03 18:01:20 -0700180 uint32_t totalRefs = gNumLocalRefsCreated.load(std::memory_order_relaxed)
181 + gNumDeathRefsCreated.load(std::memory_order_relaxed);
182 uint32_t collectedAtRefs = gCollectedAtRefs.load(memory_order_relaxed);
183 // A bound on the number of threads that can have incremented gNum...RefsCreated before the
184 // following check is executed. Effectively a bound on #threads. Almost any value will do.
185 static constexpr uint32_t MAX_RACING = 100000;
186
187 if (totalRefs - (collectedAtRefs + GC_INTERVAL) /* modular arithmetic! */ < MAX_RACING) {
188 // Recently passed next GC interval.
189 if (gCollectedAtRefs.compare_exchange_strong(collectedAtRefs,
190 collectedAtRefs + GC_INTERVAL, std::memory_order_relaxed)) {
191 ALOGV("Binder forcing GC at %u created refs", totalRefs);
192 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
193 gBinderInternalOffsets.mForceGc);
194 } // otherwise somebody else beat us to it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 } else {
Hans Boehm29f388f2017-10-03 18:01:20 -0700196 ALOGV("Now have %d binder ops", totalRefs - collectedAtRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 }
198}
199
200static JavaVM* jnienv_to_javavm(JNIEnv* env)
201{
202 JavaVM* vm;
203 return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
204}
205
206static JNIEnv* javavm_to_jnienv(JavaVM* vm)
207{
208 JNIEnv* env;
209 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
210}
211
Andreas Gampe9ff9c402019-07-08 08:31:27 -0700212static const char* GetErrorTypeName(JNIEnv* env, jthrowable error) {
213 if (env->IsInstanceOf(error, gErrorOffsets.mOutOfMemory)) {
214 return "OutOfMemoryError";
215 }
216 if (env->IsInstanceOf(error, gErrorOffsets.mStackOverflow)) {
217 return "StackOverflowError";
218 }
219 return nullptr;
220}
221
Andreas Gampe625e0002017-09-08 17:44:05 -0700222// Report a java.lang.Error (or subclass). This will terminate the runtime by
223// calling FatalError with a message derived from the given error.
224static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
225 const char* msg)
226{
227 // Report an error: reraise the exception and ask the runtime to abort.
228
229 // Try to get the exception string. Sometimes logcat isn't available,
230 // so try to add it to the abort message.
Andreas Gampe9ff9c402019-07-08 08:31:27 -0700231 std::string exc_msg;
Andreas Gampe625e0002017-09-08 17:44:05 -0700232 {
233 ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
234 jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
235 "()Ljava/lang/String;");
236 ScopedLocalRef<jstring> jstr(
237 env,
238 reinterpret_cast<jstring>(
239 env->CallObjectMethod(error, method_id)));
Andreas Gampe9ff9c402019-07-08 08:31:27 -0700240 ScopedLocalRef<jthrowable> new_error(env, nullptr);
241 bool got_jstr = false;
242 if (env->ExceptionCheck()) {
243 new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
244 env->ExceptionClear();
245 }
Andreas Gampe625e0002017-09-08 17:44:05 -0700246 if (jstr.get() != nullptr) {
247 ScopedUtfChars jstr_utf(env, jstr.get());
248 if (jstr_utf.c_str() != nullptr) {
249 exc_msg = jstr_utf.c_str();
Andreas Gampe9ff9c402019-07-08 08:31:27 -0700250 got_jstr = true;
Andreas Gampe625e0002017-09-08 17:44:05 -0700251 } else {
Andreas Gampe9ff9c402019-07-08 08:31:27 -0700252 new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
Andreas Gampe625e0002017-09-08 17:44:05 -0700253 env->ExceptionClear();
254 }
255 }
Andreas Gampe9ff9c402019-07-08 08:31:27 -0700256 if (!got_jstr) {
257 exc_msg = "(Unknown exception message)";
258 const char* orig_type = GetErrorTypeName(env, error);
259 if (orig_type != nullptr) {
260 exc_msg = base::StringPrintf("%s (Error was %s)", exc_msg.c_str(), orig_type);
261 }
262 const char* new_type =
263 new_error == nullptr ? nullptr : GetErrorTypeName(env, new_error.get());
264 if (new_type != nullptr) {
265 exc_msg = base::StringPrintf("%s (toString() error was %s)",
266 exc_msg.c_str(),
267 new_type);
268 }
269 }
Andreas Gampe625e0002017-09-08 17:44:05 -0700270 }
271
272 env->Throw(error);
273 ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
274 env->ExceptionDescribe();
275
276 std::string error_msg = base::StringPrintf(
277 "java.lang.Error thrown during binder transaction: %s",
278 exc_msg.c_str());
279 env->FatalError(error_msg.c_str());
280}
281
282// Report a java.lang.Error (or subclass). This will terminate the runtime, either by
283// the uncaught exception handler, or explicitly by calling
284// report_java_lang_error_fatal_error.
285static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* msg)
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700286{
287 // Try to run the uncaught exception machinery.
288 jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass,
289 gThreadDispatchOffsets.mCurrentThread);
290 if (thread != nullptr) {
291 env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException,
292 error);
293 // Should not return here, unless more errors occured.
294 }
295 // Some error occurred that meant that either dispatchUncaughtException could not be
296 // called or that it had an error itself (as this should be unreachable under normal
Andreas Gampe625e0002017-09-08 17:44:05 -0700297 // conditions). As the binder code cannot handle Errors, attempt to log the error and
298 // abort.
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700299 env->ExceptionClear();
Andreas Gampe625e0002017-09-08 17:44:05 -0700300 report_java_lang_error_fatal_error(env, error, msg);
Andreas Gampe1cd76f52017-09-08 17:44:05 -0700301}
302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
304{
305 env->ExceptionClear();
306
Andreas Gampe625e0002017-09-08 17:44:05 -0700307 ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
Andreas Gampe8571ec32017-09-21 10:55:59 -0700308 ScopedLocalRef<jstring> msgstr(env);
Andreas Gampe625e0002017-09-08 17:44:05 -0700309 if (tagstr != nullptr) {
310 msgstr.reset(env->NewStringUTF(msg));
Mathieu Chartiercf6775e2014-08-06 13:39:17 -0700311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312
Andreas Gampe625e0002017-09-08 17:44:05 -0700313 if ((tagstr != nullptr) && (msgstr != nullptr)) {
314 env->CallStaticIntMethod(gLogOffsets.mClass, gLogOffsets.mLogE,
315 tagstr.get(), msgstr.get(), excep);
316 if (env->ExceptionCheck()) {
317 // Attempting to log the failure has failed.
318 ALOGW("Failed trying to log exception, msg='%s'\n", msg);
319 env->ExceptionClear();
320 }
321 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 env->ExceptionClear(); /* assume exception (OOM?) was thrown */
Steve Block3762c312012-01-06 19:20:56 +0000323 ALOGE("Unable to call Log.e()\n");
324 ALOGE("%s", msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 }
326
Andreas Gampe9ff9c402019-07-08 08:31:27 -0700327 if (env->IsInstanceOf(excep, gErrorOffsets.mError)) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700328 report_java_lang_error(env, excep, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330}
331
332class JavaBBinderHolder;
333
334class JavaBBinder : public BBinder
335{
336public:
Hans Boehm29f388f2017-10-03 18:01:20 -0700337 JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
339 {
Steve Block71f2cf12011-10-20 11:56:00 +0100340 ALOGV("Creating JavaBBinder %p\n", this);
Hans Boehm29f388f2017-10-03 18:01:20 -0700341 gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
342 gcIfManyNewRefs(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 }
344
345 bool checkSubclass(const void* subclassID) const
346 {
347 return subclassID == &gBinderOffsets;
348 }
349
350 jobject object() const
351 {
352 return mObject;
353 }
354
355protected:
356 virtual ~JavaBBinder()
357 {
Steve Block71f2cf12011-10-20 11:56:00 +0100358 ALOGV("Destroying JavaBBinder %p\n", this);
Hans Boehm29f388f2017-10-03 18:01:20 -0700359 gNumLocalRefsDeleted.fetch_add(1, memory_order_relaxed);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 JNIEnv* env = javavm_to_jnienv(mVM);
361 env->DeleteGlobalRef(mObject);
362 }
363
Steven Morelande52bb7d2018-10-10 11:24:58 -0700364 const String16& getInterfaceDescriptor() const override
365 {
366 call_once(mPopulateDescriptor, [this] {
367 JNIEnv* env = javavm_to_jnienv(mVM);
368
369 ALOGV("getInterfaceDescriptor() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
370
371 jstring descriptor = (jstring)env->CallObjectMethod(mObject, gBinderOffsets.mGetInterfaceDescriptor);
372
373 if (descriptor == nullptr) {
374 return;
375 }
376
377 static_assert(sizeof(jchar) == sizeof(char16_t), "");
378 const jchar* descriptorChars = env->GetStringChars(descriptor, nullptr);
379 const char16_t* rawDescriptor = reinterpret_cast<const char16_t*>(descriptorChars);
380 jsize rawDescriptorLen = env->GetStringLength(descriptor);
381 mDescriptor = String16(rawDescriptor, rawDescriptorLen);
382 env->ReleaseStringChars(descriptor, descriptorChars);
383 });
384
385 return mDescriptor;
386 }
387
388 status_t onTransact(
389 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 {
391 JNIEnv* env = javavm_to_jnienv(mVM);
392
Steve Block71f2cf12011-10-20 11:56:00 +0100393 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 -0800394
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700395 IPCThreadState* thread_state = IPCThreadState::self();
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700396 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 //printf("Transact from %p to Java code sending: ", this);
399 //data.print();
400 //printf("\n");
401 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000402 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700403
Mathieu Chartier98671c32014-08-20 10:04:08 -0700404 if (env->ExceptionCheck()) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700405 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
406 report_exception(env, excep.get(),
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100407 "*** Uncaught remote exception! "
408 "(Exceptions are not yet supported across processes.)");
409 res = JNI_FALSE;
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100410 }
411
Dianne Hackbornce92b0d2014-09-30 11:28:18 -0700412 // Check if the strict mode state changed while processing the
413 // call. The Binder state will be restored by the underlying
414 // Binder system in IPCThreadState, however we need to take care
415 // of the parallel Java state as well.
416 if (thread_state->getStrictModePolicy() != strict_policy_before) {
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700417 set_dalvik_blockguard_policy(env, strict_policy_before);
418 }
419
Mathieu Chartier98671c32014-08-20 10:04:08 -0700420 if (env->ExceptionCheck()) {
Andreas Gampe625e0002017-09-08 17:44:05 -0700421 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
422 report_exception(env, excep.get(),
Bjorn Bringert9013ccd2011-04-26 19:10:58 +0100423 "*** Uncaught exception in onBinderStrictModePolicyChange");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 }
425
Dianne Hackborna53de062012-05-08 18:53:51 -0700426 // Need to always call through the native implementation of
427 // SYSPROPS_TRANSACTION.
428 if (code == SYSPROPS_TRANSACTION) {
429 BBinder::onTransact(code, data, reply, flags);
430 }
431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 //aout << "onTransact to Java code; result=" << res << endl
433 // << "Transact from " << this << " to Java code returning "
434 // << reply << ": " << *reply << endl;
435 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
436 }
437
Steven Morelande52bb7d2018-10-10 11:24:58 -0700438 status_t dump(int fd, const Vector<String16>& args) override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 {
440 return 0;
441 }
442
443private:
444 JavaVM* const mVM;
Hans Boehm29f388f2017-10-03 18:01:20 -0700445 jobject const mObject; // GlobalRef to Java Binder
Steven Morelande52bb7d2018-10-10 11:24:58 -0700446
447 mutable std::once_flag mPopulateDescriptor;
448 mutable String16 mDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449};
450
451// ----------------------------------------------------------------------------
452
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700453class JavaBBinderHolder
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454{
455public:
Christopher Tate0b414482011-02-17 13:00:38 -0800456 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 {
458 AutoMutex _l(mLock);
459 sp<JavaBBinder> b = mBinder.promote();
460 if (b == NULL) {
Christopher Tate0b414482011-02-17 13:00:38 -0800461 b = new JavaBBinder(env, obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 mBinder = b;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700463 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
Christopher Tate0b414482011-02-17 13:00:38 -0800464 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 }
466
467 return b;
468 }
469
470 sp<JavaBBinder> getExisting()
471 {
472 AutoMutex _l(mLock);
473 return mBinder.promote();
474 }
475
476private:
477 Mutex mLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 wp<JavaBBinder> mBinder;
479};
480
481// ----------------------------------------------------------------------------
482
Christopher Tate0b414482011-02-17 13:00:38 -0800483// Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
484// death recipient references passed in through JNI with the permanent corresponding
485// JavaDeathRecipient objects.
486
487class JavaDeathRecipient;
488
489class DeathRecipientList : public RefBase {
490 List< sp<JavaDeathRecipient> > mList;
491 Mutex mLock;
492
493public:
Christopher Tate79dd31f2011-03-04 17:45:00 -0800494 DeathRecipientList();
Christopher Tate0b414482011-02-17 13:00:38 -0800495 ~DeathRecipientList();
496
497 void add(const sp<JavaDeathRecipient>& recipient);
498 void remove(const sp<JavaDeathRecipient>& recipient);
499 sp<JavaDeathRecipient> find(jobject recipient);
Christopher Tate090c08f2015-05-19 18:16:58 -0700500
501 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
Christopher Tate0b414482011-02-17 13:00:38 -0800502};
503
504// ----------------------------------------------------------------------------
505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506class JavaDeathRecipient : public IBinder::DeathRecipient
507{
508public:
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800509 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
Christopher Tate86284c62011-08-17 15:19:29 -0700510 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
511 mObjectWeak(NULL), mList(list)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 {
Christopher Tate0b414482011-02-17 13:00:38 -0800513 // These objects manage their own lifetimes so are responsible for final bookkeeping.
514 // The list holds a strong reference to this object.
Christopher Tate79dd31f2011-03-04 17:45:00 -0800515 LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800516 list->add(this);
Christopher Tate0b414482011-02-17 13:00:38 -0800517
Hans Boehm29f388f2017-10-03 18:01:20 -0700518 gNumDeathRefsCreated.fetch_add(1, std::memory_order_relaxed);
519 gcIfManyNewRefs(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 }
521
522 void binderDied(const wp<IBinder>& who)
523 {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800524 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
Christopher Tate86284c62011-08-17 15:19:29 -0700525 if (mObject != NULL) {
526 JNIEnv* env = javavm_to_jnienv(mVM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527
Christopher Tate86284c62011-08-17 15:19:29 -0700528 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
529 gBinderProxyOffsets.mSendDeathNotice, mObject);
Mathieu Chartier98671c32014-08-20 10:04:08 -0700530 if (env->ExceptionCheck()) {
531 jthrowable excep = env->ExceptionOccurred();
Christopher Tate86284c62011-08-17 15:19:29 -0700532 report_exception(env, excep,
533 "*** Uncaught exception returned from death notification!");
534 }
535
Christopher Tate090c08f2015-05-19 18:16:58 -0700536 // Serialize with our containing DeathRecipientList so that we can't
537 // delete the global ref on mObject while the list is being iterated.
538 sp<DeathRecipientList> list = mList.promote();
539 if (list != NULL) {
540 AutoMutex _l(list->lock());
541
542 // Demote from strong ref to weak after binderDied() has been delivered,
543 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
544 mObjectWeak = env->NewWeakGlobalRef(mObject);
545 env->DeleteGlobalRef(mObject);
546 mObject = NULL;
547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 }
550
551 void clearReference()
552 {
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800553 sp<DeathRecipientList> list = mList.promote();
554 if (list != NULL) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800555 LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800556 list->remove(this);
Christopher Tate79dd31f2011-03-04 17:45:00 -0800557 } else {
558 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800559 }
Christopher Tate0b414482011-02-17 13:00:38 -0800560 }
561
562 bool matches(jobject obj) {
Christopher Tate86284c62011-08-17 15:19:29 -0700563 bool result;
Christopher Tate0b414482011-02-17 13:00:38 -0800564 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate86284c62011-08-17 15:19:29 -0700565
566 if (mObject != NULL) {
567 result = env->IsSameObject(obj, mObject);
568 } else {
Andreas Gampe625e0002017-09-08 17:44:05 -0700569 ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
570 result = env->IsSameObject(obj, me.get());
Christopher Tate86284c62011-08-17 15:19:29 -0700571 }
572 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 }
574
Christopher Tateac5e3502011-08-25 15:48:09 -0700575 void warnIfStillLive() {
576 if (mObject != NULL) {
577 // Okay, something is wrong -- we have a hard reference to a live death
578 // recipient on the VM side, but the list is being torn down.
579 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate0d4a7922011-08-30 12:09:43 -0700580 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
581 ScopedLocalRef<jstring> nameRef(env,
582 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
583 ScopedUtfChars nameUtf(env, nameRef.get());
584 if (nameUtf.c_str() != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +0000585 ALOGW("BinderProxy is being destroyed but the application did not call "
Christopher Tate0d4a7922011-08-30 12:09:43 -0700586 "unlinkToDeath to unlink all of its death recipients beforehand. "
587 "Releasing leaked death recipient: %s", nameUtf.c_str());
588 } else {
Steve Block8564c8d2012-01-05 23:22:43 +0000589 ALOGW("BinderProxy being destroyed; unable to get DR object name");
Christopher Tate0d4a7922011-08-30 12:09:43 -0700590 env->ExceptionClear();
591 }
Christopher Tateac5e3502011-08-25 15:48:09 -0700592 }
593 }
594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595protected:
596 virtual ~JavaDeathRecipient()
597 {
Steve Block6215d3f2012-01-04 20:05:49 +0000598 //ALOGI("Removing death ref: recipient=%p\n", mObject);
Hans Boehm29f388f2017-10-03 18:01:20 -0700599 gNumDeathRefsDeleted.fetch_add(1, std::memory_order_relaxed);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 JNIEnv* env = javavm_to_jnienv(mVM);
Christopher Tate86284c62011-08-17 15:19:29 -0700601 if (mObject != NULL) {
602 env->DeleteGlobalRef(mObject);
603 } else {
604 env->DeleteWeakGlobalRef(mObjectWeak);
605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 }
607
608private:
Christopher Tate86284c62011-08-17 15:19:29 -0700609 JavaVM* const mVM;
Hans Boehmeb6d62c2017-09-20 15:59:12 -0700610 jobject mObject; // Initial strong ref to Java-side DeathRecipient. Cleared on binderDied().
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700611 jweak mObjectWeak; // Weak ref to the same Java-side DeathRecipient after binderDied().
Christopher Tatebd8b6f22011-03-01 11:55:27 -0800612 wp<DeathRecipientList> mList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613};
614
615// ----------------------------------------------------------------------------
616
Christopher Tate79dd31f2011-03-04 17:45:00 -0800617DeathRecipientList::DeathRecipientList() {
618 LOGDEATH("New DRL @ %p", this);
619}
620
Christopher Tate0b414482011-02-17 13:00:38 -0800621DeathRecipientList::~DeathRecipientList() {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800622 LOGDEATH("Destroy DRL @ %p", this);
Christopher Tate0b414482011-02-17 13:00:38 -0800623 AutoMutex _l(mLock);
624
625 // Should never happen -- the JavaDeathRecipient objects that have added themselves
626 // to the list are holding references on the list object. Only when they are torn
627 // down can the list header be destroyed.
628 if (mList.size() > 0) {
Christopher Tateac5e3502011-08-25 15:48:09 -0700629 List< sp<JavaDeathRecipient> >::iterator iter;
630 for (iter = mList.begin(); iter != mList.end(); iter++) {
631 (*iter)->warnIfStillLive();
632 }
Christopher Tate0b414482011-02-17 13:00:38 -0800633 }
634}
635
636void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
637 AutoMutex _l(mLock);
638
Christopher Tate79dd31f2011-03-04 17:45:00 -0800639 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
Christopher Tate0b414482011-02-17 13:00:38 -0800640 mList.push_back(recipient);
641}
642
643void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
644 AutoMutex _l(mLock);
645
646 List< sp<JavaDeathRecipient> >::iterator iter;
647 for (iter = mList.begin(); iter != mList.end(); iter++) {
648 if (*iter == recipient) {
Christopher Tate79dd31f2011-03-04 17:45:00 -0800649 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
Christopher Tate0b414482011-02-17 13:00:38 -0800650 mList.erase(iter);
651 return;
652 }
653 }
654}
655
656sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
657 AutoMutex _l(mLock);
658
659 List< sp<JavaDeathRecipient> >::iterator iter;
660 for (iter = mList.begin(); iter != mList.end(); iter++) {
661 if ((*iter)->matches(recipient)) {
662 return *iter;
663 }
664 }
665 return NULL;
666}
667
Christopher Tate090c08f2015-05-19 18:16:58 -0700668Mutex& DeathRecipientList::lock() {
669 return mLock;
670}
671
Christopher Tate0b414482011-02-17 13:00:38 -0800672// ----------------------------------------------------------------------------
673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674namespace android {
675
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700676// We aggregate native pointer fields for BinderProxy in a single object to allow
677// management with a single NativeAllocationRegistry, and to reduce the number of JNI
678// Java field accesses. This costs us some extra indirections here.
679struct BinderProxyNativeData {
Hans Boehm29f388f2017-10-03 18:01:20 -0700680 // Both fields are constant and not null once javaObjectForIBinder returns this as
681 // part of a BinderProxy.
682
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700683 // The native IBinder proxied by this BinderProxy.
Hans Boehm29f388f2017-10-03 18:01:20 -0700684 sp<IBinder> mObject;
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700685
686 // Death recipients for mObject. Reference counted only because DeathRecipients
687 // hold a weak reference that can be temporarily promoted.
Hans Boehm29f388f2017-10-03 18:01:20 -0700688 sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700689};
690
691BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
692 return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
693}
694
Hans Boehm29f388f2017-10-03 18:01:20 -0700695// If the argument is a JavaBBinder, return the Java object that was used to create it.
696// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
697// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
699{
Daniel Colascione012ab8e2019-10-07 14:18:09 -0700700 // N.B. This function is called from a @FastNative JNI method, so don't take locks around
701 // calls to Java code or block the calling thread for a long time for any reason.
702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 if (val == NULL) return NULL;
704
705 if (val->checkSubclass(&gBinderOffsets)) {
Hans Boehm29f388f2017-10-03 18:01:20 -0700706 // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 jobject object = static_cast<JavaBBinder*>(val.get())->object();
Christopher Tate86284c62011-08-17 15:19:29 -0700708 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800709 return object;
710 }
711
Martijn Coenend3ef4bf2018-07-05 14:58:59 +0200712 BinderProxyNativeData* nativeData = new BinderProxyNativeData();
713 nativeData->mOrgue = new DeathRecipientList;
714 nativeData->mObject = val;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715
Hans Boehm29f388f2017-10-03 18:01:20 -0700716 jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
717 gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
718 if (env->ExceptionCheck()) {
Hans Boehm03477cb2018-02-15 16:12:51 -0800719 // In the exception case, getInstance still took ownership of nativeData.
Hans Boehm29f388f2017-10-03 18:01:20 -0700720 return NULL;
721 }
722 BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
723 if (actualNativeData == nativeData) {
Martijn Coenend3ef4bf2018-07-05 14:58:59 +0200724 // Created a new Proxy
725 uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
726 uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
727 if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
728 // Multiple threads can get here, make sure only one of them gets to
729 // update the warn counter.
730 if (gProxiesWarned.compare_exchange_strong(numLastWarned,
731 numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
732 ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
733 }
Hans Boehm29f388f2017-10-03 18:01:20 -0700734 }
735 } else {
Martijn Coenend3ef4bf2018-07-05 14:58:59 +0200736 delete nativeData;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 }
738
739 return object;
740}
741
742sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
743{
744 if (obj == NULL) return NULL;
745
Hans Boehm29f388f2017-10-03 18:01:20 -0700746 // Instance of Binder?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
748 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000749 env->GetLongField(obj, gBinderOffsets.mObject);
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700750 return jbh->get(env, obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 }
752
Hans Boehm29f388f2017-10-03 18:01:20 -0700753 // Instance of BinderProxy?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700755 return getBPNativeData(env, obj)->mObject;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 }
757
Steve Block8564c8d2012-01-05 23:22:43 +0000758 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759 return NULL;
760}
761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
763{
764 return env->NewObject(
765 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
766}
767
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800768void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
769{
770 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
771 // to sync our state back to it. See the comments in StrictMode.java.
772 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
773 gStrictModeCallbackOffsets.mCallback,
774 strict_policy);
775}
776
777void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
Dianne Hackborne5c42622015-05-19 16:04:04 -0700778 bool canThrowRemoteException, int parcelSize)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779{
780 switch (err) {
781 case UNKNOWN_ERROR:
782 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
783 break;
784 case NO_MEMORY:
785 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
786 break;
787 case INVALID_OPERATION:
788 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
789 break;
790 case BAD_VALUE:
791 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
792 break;
793 case BAD_INDEX:
794 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
795 break;
796 case BAD_TYPE:
797 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
798 break;
799 case NAME_NOT_FOUND:
800 jniThrowException(env, "java/util/NoSuchElementException", NULL);
801 break;
802 case PERMISSION_DENIED:
803 jniThrowException(env, "java/lang/SecurityException", NULL);
804 break;
805 case NOT_ENOUGH_DATA:
806 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
807 break;
808 case NO_INIT:
809 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
810 break;
811 case ALREADY_EXISTS:
812 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
813 break;
814 case DEAD_OBJECT:
Jeff Brown0bde66a2011-11-07 12:50:08 -0800815 // DeadObjectException is a checked exception, only throw from certain methods.
816 jniThrowException(env, canThrowRemoteException
817 ? "android/os/DeadObjectException"
818 : "java/lang/RuntimeException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 break;
820 case UNKNOWN_TRANSACTION:
821 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
822 break;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700823 case FAILED_TRANSACTION: {
824 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
Christopher Tate02ca7a72015-06-24 18:16:42 -0700825 const char* exceptionToThrow;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700826 char msg[128];
Jeff Brown0bde66a2011-11-07 12:50:08 -0800827 // TransactionTooLargeException is a checked exception, only throw from certain methods.
828 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
829 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
830 // for other reasons also, such as if the transaction is malformed or
831 // refers to an FD that has been closed. We should change the driver
832 // to enable us to distinguish these cases in the future.
Christopher Tate02ca7a72015-06-24 18:16:42 -0700833 if (canThrowRemoteException && parcelSize > 200*1024) {
834 // bona fide large payload
835 exceptionToThrow = "android/os/TransactionTooLargeException";
836 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
837 } else {
838 // Heuristic: a payload smaller than this threshold "shouldn't" be too
839 // big, so it's probably some other, more subtle problem. In practice
Christopher Tateffd58642015-06-29 11:00:15 -0700840 // it seems to always mean that the remote process died while the binder
Christopher Tate02ca7a72015-06-24 18:16:42 -0700841 // transaction was already in flight.
Christopher Tateffd58642015-06-29 11:00:15 -0700842 exceptionToThrow = (canThrowRemoteException)
843 ? "android/os/DeadObjectException"
844 : "java/lang/RuntimeException";
Christopher Tate02ca7a72015-06-24 18:16:42 -0700845 snprintf(msg, sizeof(msg)-1,
846 "Transaction failed on small parcel; remote process probably died");
847 }
848 jniThrowException(env, exceptionToThrow, msg);
Dianne Hackborne5c42622015-05-19 16:04:04 -0700849 } break;
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400850 case FDS_NOT_ALLOWED:
851 jniThrowException(env, "java/lang/RuntimeException",
852 "Not allowed to write file descriptors here");
853 break;
Christopher Wileya94fc522015-11-22 14:21:25 -0800854 case UNEXPECTED_NULL:
855 jniThrowNullPointerException(env, NULL);
856 break;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700857 case -EBADF:
858 jniThrowException(env, "java/lang/RuntimeException",
859 "Bad file descriptor");
860 break;
861 case -ENFILE:
862 jniThrowException(env, "java/lang/RuntimeException",
863 "File table overflow");
864 break;
865 case -EMFILE:
866 jniThrowException(env, "java/lang/RuntimeException",
867 "Too many open files");
868 break;
869 case -EFBIG:
870 jniThrowException(env, "java/lang/RuntimeException",
871 "File too large");
872 break;
873 case -ENOSPC:
874 jniThrowException(env, "java/lang/RuntimeException",
875 "No space left on device");
876 break;
877 case -ESPIPE:
878 jniThrowException(env, "java/lang/RuntimeException",
879 "Illegal seek");
880 break;
881 case -EROFS:
882 jniThrowException(env, "java/lang/RuntimeException",
883 "Read-only file system");
884 break;
885 case -EMLINK:
886 jniThrowException(env, "java/lang/RuntimeException",
887 "Too many links");
888 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 default:
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700890 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800891 String8 msg;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700892 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800893 // RemoteException is a checked exception, only throw from certain methods.
894 jniThrowException(env, canThrowRemoteException
895 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
896 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 }
898}
899
900}
901
902// ----------------------------------------------------------------------------
903
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100904static jint android_os_Binder_getCallingPid()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905{
906 return IPCThreadState::self()->getCallingPid();
907}
908
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100909static jint android_os_Binder_getCallingUid()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910{
911 return IPCThreadState::self()->getCallingUid();
912}
913
Nikita Ioffea929cf02019-01-03 13:35:22 +0000914static jboolean android_os_Binder_isHandlingTransaction()
915{
916 return IPCThreadState::self()->isServingCall();
917}
918
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100919static jlong android_os_Binder_clearCallingIdentity()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920{
921 return IPCThreadState::self()->clearCallingIdentity();
922}
923
924static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
925{
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700926 // XXX temporary sanity check to debug crashes.
927 int uid = (int)(token>>32);
928 if (uid > 0 && uid < 999) {
929 // In Android currently there are no uids in this range.
930 char buf[128];
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700931 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700932 jniThrowException(env, "java/lang/IllegalStateException", buf);
933 return;
934 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 IPCThreadState::self()->restoreCallingIdentity(token);
936}
937
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100938static void android_os_Binder_setThreadStrictModePolicy(jint policyMask)
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700939{
940 IPCThreadState::self()->setStrictModePolicy(policyMask);
941}
942
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100943static jint android_os_Binder_getThreadStrictModePolicy()
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700944{
945 return IPCThreadState::self()->getStrictModePolicy();
946}
947
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000948static jlong android_os_Binder_setCallingWorkSourceUid(jint workSource)
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100949{
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000950 return IPCThreadState::self()->setCallingWorkSourceUid(workSource);
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100951}
952
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000953static jlong android_os_Binder_getCallingWorkSourceUid()
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100954{
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000955 return IPCThreadState::self()->getCallingWorkSourceUid();
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100956}
957
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000958static jlong android_os_Binder_clearCallingWorkSource()
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100959{
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000960 return IPCThreadState::self()->clearCallingWorkSource();
961}
962
Olivier Gaillarda16b83c2018-12-11 23:09:05 +0000963static void android_os_Binder_restoreCallingWorkSource(jlong token)
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000964{
965 IPCThreadState::self()->restoreCallingWorkSource(token);
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100966}
967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
969{
970 IPCThreadState::self()->flushCommands();
971}
972
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700973static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974{
Christopher Tate0b414482011-02-17 13:00:38 -0800975 JavaBBinderHolder* jbh = new JavaBBinderHolder();
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700976 return (jlong) jbh;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977}
978
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700979static void Binder_destroy(void* rawJbh)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980{
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700981 JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh;
982 ALOGV("Java Binder: deleting holder %p", jbh);
983 delete jbh;
984}
985
986JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) {
987 return (jlong) Binder_destroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988}
989
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700990static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
991{
992 return IPCThreadState::self()->blockUntilThreadAvailable();
993}
994
Jon Spivack9e45fde2019-10-09 17:23:00 -0700995static jobject android_os_Binder_waitForService(
996 JNIEnv *env,
997 jclass /* clazzObj */,
998 jstring serviceNameObj) {
999
1000 const jchar* serviceName = env->GetStringCritical(serviceNameObj, nullptr);
1001 if (!serviceName) {
1002 signalExceptionForError(env, nullptr, BAD_VALUE, true /*canThrowRemoteException*/);
1003 return nullptr;
1004 }
1005 String16 nameCopy = String16(reinterpret_cast<const char16_t *>(serviceName),
1006 env->GetStringLength(serviceNameObj));
1007 env->ReleaseStringCritical(serviceNameObj, serviceName);
1008
1009 auto sm = android::defaultServiceManager();
1010 sp<IBinder> service = sm->waitForService(nameCopy);
1011
1012 if (!service) {
1013 signalExceptionForError(env, nullptr, NAME_NOT_FOUND, true /*canThrowRemoteException*/);
1014 return nullptr;
1015 }
1016
1017 return javaObjectForIBinder(env, service);
1018}
1019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020// ----------------------------------------------------------------------------
1021
1022static const JNINativeMethod gBinderMethods[] = {
1023 /* name, signature, funcPtr */
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001024 // @CriticalNative
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001026 // @CriticalNative
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001028 // @CriticalNative
Nikita Ioffea929cf02019-01-03 13:35:22 +00001029 { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction },
1030 // @CriticalNative
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
1032 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001033 // @CriticalNative
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001034 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001035 // @CriticalNative
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001036 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
Olivier Gaillarde4ff3972018-08-16 14:01:58 +01001037 // @CriticalNative
Olivier Gaillardd542b1c2018-11-14 15:24:35 +00001038 { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
Olivier Gaillarde4ff3972018-08-16 14:01:58 +01001039 // @CriticalNative
Olivier Gaillardd542b1c2018-11-14 15:24:35 +00001040 { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
Olivier Gaillarde4ff3972018-08-16 14:01:58 +01001041 // @CriticalNative
Olivier Gaillardd542b1c2018-11-14 15:24:35 +00001042 { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
1043 { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001045 { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
1046 { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
Jon Spivack9e45fde2019-10-09 17:23:00 -07001047 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable },
1048 { "waitForService", "(Ljava/lang/String;)Landroid/os/IBinder;", (void*)android_os_Binder_waitForService }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049};
1050
1051const char* const kBinderPathName = "android/os/Binder";
1052
1053static int int_register_android_os_Binder(JNIEnv* env)
1054{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001055 jclass clazz = FindClassOrDie(env, kBinderPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001056
Andreas Gampe987f79f2014-11-18 17:29:46 -08001057 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1058 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
Steven Morelande52bb7d2018-10-10 11:24:58 -07001059 gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
1060 "()Ljava/lang/String;");
Andreas Gampe987f79f2014-11-18 17:29:46 -08001061 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001063 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 env, kBinderPathName,
1065 gBinderMethods, NELEM(gBinderMethods));
1066}
1067
1068// ****************************************************************************
1069// ****************************************************************************
1070// ****************************************************************************
1071
1072namespace android {
1073
1074jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
1075{
Hans Boehm29f388f2017-10-03 18:01:20 -07001076 return gNumLocalRefsCreated - gNumLocalRefsDeleted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077}
1078
1079jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
1080{
Martijn Coenend3ef4bf2018-07-05 14:58:59 +02001081 return gNumProxies.load();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001082}
1083
1084jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
1085{
Hans Boehm29f388f2017-10-03 18:01:20 -07001086 return gNumDeathRefsCreated - gNumDeathRefsDeleted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001087}
1088
1089}
1090
1091// ****************************************************************************
1092// ****************************************************************************
1093// ****************************************************************************
1094
1095static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
1096{
1097 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1098 return javaObjectForIBinder(env, b);
1099}
1100
1101static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
1102{
1103 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1104 android::IPCThreadState::self()->joinThreadPool();
1105}
1106
Dianne Hackborn887f3552009-12-07 17:59:37 -08001107static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
1108 jobject clazz, jboolean disable)
1109{
1110 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
1111}
1112
Tim Murrayeef4a3d2016-04-19 14:14:20 -07001113static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
1114 jobject clazz, jint maxThreads)
1115{
1116 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
1117}
1118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
1120{
Hans Boehm29f388f2017-10-03 18:01:20 -07001121 ALOGV("Gc has executed, updating Refs count at GC");
1122 gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123}
1124
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001125static void android_os_BinderInternal_proxyLimitcallback(int uid)
1126{
1127 JNIEnv *env = AndroidRuntime::getJNIEnv();
1128 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1129 gBinderInternalOffsets.mProxyLimitCallback,
1130 uid);
Martijn Coenendfa390e2018-06-05 11:02:23 +02001131
1132 if (env->ExceptionCheck()) {
1133 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1134 report_exception(env, excep.get(),
1135 "*** Uncaught exception in binderProxyLimitCallbackFromNative");
1136 }
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001137}
1138
1139static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
1140 jboolean enable)
1141{
1142 BpBinder::setCountByUidEnabled((bool) enable);
1143}
1144
1145static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
1146{
1147 Vector<uint32_t> uids, counts;
1148 BpBinder::getCountByUid(uids, counts);
1149 jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
1150 gSparseIntArrayOffsets.constructor);
1151 for (size_t i = 0; i < uids.size(); i++) {
1152 env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
1153 static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
1154 }
1155 return sparseIntArray;
1156}
1157
1158static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
1159 return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
1160}
1161
1162static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
1163 jint high, jint low)
1164{
1165 BpBinder::setBinderProxyCountWatermarks(high, low);
1166}
1167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168// ----------------------------------------------------------------------------
1169
1170static const JNINativeMethod gBinderInternalMethods[] = {
1171 /* name, signature, funcPtr */
1172 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
1173 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
Dianne Hackborn887f3552009-12-07 17:59:37 -08001174 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
Tim Murrayeef4a3d2016-04-19 14:14:20 -07001175 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001176 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
1177 { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
1178 { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
1179 { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
1180 { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181};
1182
1183const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
1184
1185static int int_register_android_os_BinderInternal(JNIEnv* env)
1186{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001187 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188
Andreas Gampe987f79f2014-11-18 17:29:46 -08001189 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1190 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001191 gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
1192
1193 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
1194 gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
1195 gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
1196 "<init>", "()V");
1197 gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
1198 "(II)V");
1199
1200 BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001202 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 env, kBinderInternalPathName,
1204 gBinderInternalMethods, NELEM(gBinderInternalMethods));
1205}
1206
1207// ****************************************************************************
1208// ****************************************************************************
1209// ****************************************************************************
1210
1211static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
1212{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001213 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 if (target == NULL) {
1215 return JNI_FALSE;
1216 }
1217 status_t err = target->pingBinder();
1218 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1219}
1220
1221static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
1222{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001223 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 if (target != NULL) {
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001225 const String16& desc = target->getInterfaceDescriptor();
Dan Albert66987492014-11-20 11:41:21 -08001226 return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
1227 desc.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001228 }
1229 jniThrowException(env, "java/lang/RuntimeException",
1230 "No binder found for object");
1231 return NULL;
1232}
1233
1234static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1235{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001236 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 if (target == NULL) {
1238 return JNI_FALSE;
1239 }
1240 bool alive = target->isBinderAlive();
1241 return alive ? JNI_TRUE : JNI_FALSE;
1242}
1243
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001244static int getprocname(pid_t pid, char *buf, size_t len) {
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001245 char filename[32];
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001246 FILE *f;
1247
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001248 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
Nick Kralevich4b3a08c2019-01-28 10:39:10 -08001249 f = fopen(filename, "re");
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001250 if (!f) {
1251 *buf = '\0';
1252 return 1;
1253 }
1254 if (!fgets(buf, len, f)) {
1255 *buf = '\0';
1256 fclose(f);
1257 return 2;
1258 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001259 fclose(f);
1260 return 0;
1261}
1262
1263static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1264 jint len = strlen(str);
1265 int space_needed = 1 + sizeof(len) + len;
1266 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001267 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001268 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001269 return false;
1270 }
1271 **pos = EVENT_TYPE_STRING;
1272 (*pos)++;
1273 memcpy(*pos, &len, sizeof(len));
1274 *pos += sizeof(len);
1275 memcpy(*pos, str, len);
1276 *pos += len;
1277 return true;
1278}
1279
1280static bool push_eventlog_int(char** pos, const char* end, jint val) {
1281 int space_needed = 1 + sizeof(val);
1282 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001283 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001284 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001285 return false;
1286 }
1287 **pos = EVENT_TYPE_INT;
1288 (*pos)++;
1289 memcpy(*pos, &val, sizeof(val));
1290 *pos += sizeof(val);
1291 return true;
1292}
1293
1294// From frameworks/base/core/java/android/content/EventLogTags.logtags:
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001295
1296static const bool kEnableBinderSample = false;
1297
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001298#define LOGTAG_BINDER_OPERATION 52004
1299
1300static void conditionally_log_binder_call(int64_t start_millis,
1301 IBinder* target, jint code) {
1302 int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1303
1304 int sample_percent;
1305 if (duration_ms >= 500) {
1306 sample_percent = 100;
1307 } else {
1308 sample_percent = 100 * duration_ms / 500;
1309 if (sample_percent == 0) {
1310 return;
1311 }
1312 if (sample_percent < (random() % 100 + 1)) {
1313 return;
1314 }
1315 }
1316
1317 char process_name[40];
1318 getprocname(getpid(), process_name, sizeof(process_name));
1319 String8 desc(target->getInterfaceDescriptor());
1320
1321 char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1322 buf[0] = EVENT_TYPE_LIST;
1323 buf[1] = 5;
1324 char* pos = &buf[2];
1325 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n
1326 if (!push_eventlog_string(&pos, end, desc.string())) return;
1327 if (!push_eventlog_int(&pos, end, code)) return;
1328 if (!push_eventlog_int(&pos, end, duration_ms)) return;
1329 if (!push_eventlog_string(&pos, end, process_name)) return;
1330 if (!push_eventlog_int(&pos, end, sample_percent)) return;
1331 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently.
1332 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1333}
1334
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001335// We only measure binder call durations to potentially log them if
Elliott Hughes06451fe2014-08-18 10:26:52 -07001336// we're on the main thread.
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001337static bool should_time_binder_calls() {
Elliott Hughes06451fe2014-08-18 10:26:52 -07001338 return (getpid() == gettid());
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001339}
1340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001342 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343{
1344 if (dataObj == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001345 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346 return JNI_FALSE;
1347 }
1348
1349 Parcel* data = parcelForJavaObject(env, dataObj);
1350 if (data == NULL) {
1351 return JNI_FALSE;
1352 }
1353 Parcel* reply = parcelForJavaObject(env, replyObj);
1354 if (reply == NULL && replyObj != NULL) {
1355 return JNI_FALSE;
1356 }
1357
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001358 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359 if (target == NULL) {
1360 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1361 return JNI_FALSE;
1362 }
1363
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001364 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 -08001365 target, obj, code);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001366
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001367
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001368 bool time_binder_calls;
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001369 int64_t start_millis;
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001370 if (kEnableBinderSample) {
1371 // Only log the binder call duration for things on the Java-level main thread.
1372 // But if we don't
1373 time_binder_calls = should_time_binder_calls();
1374
1375 if (time_binder_calls) {
1376 start_millis = uptimeMillis();
1377 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001378 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 //printf("Transact from Java code to %p sending: ", target); data->print();
1381 status_t err = target->transact(code, *data, reply, flags);
1382 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001383
1384 if (kEnableBinderSample) {
1385 if (time_binder_calls) {
1386 conditionally_log_binder_call(start_millis, target, code);
1387 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001388 }
1389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 if (err == NO_ERROR) {
1391 return JNI_TRUE;
1392 } else if (err == UNKNOWN_TRANSACTION) {
1393 return JNI_FALSE;
1394 }
1395
Dianne Hackborne5c42622015-05-19 16:04:04 -07001396 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 return JNI_FALSE;
1398}
1399
1400static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001401 jobject recipient, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402{
1403 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001404 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 return;
1406 }
1407
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001408 BinderProxyNativeData *nd = getBPNativeData(env, obj);
1409 IBinder* target = nd->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410
Christopher Tate79dd31f2011-03-04 17:45:00 -08001411 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412
1413 if (!target->localBinder()) {
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001414 DeathRecipientList* list = nd->mOrgue.get();
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001415 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
Christopher Tate0b414482011-02-17 13:00:38 -08001416 status_t err = target->linkToDeath(jdr, NULL, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 if (err != NO_ERROR) {
1418 // Failure adding the death recipient, so clear its reference
1419 // now.
1420 jdr->clearReference();
Jeff Brown0bde66a2011-11-07 12:50:08 -08001421 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 }
1423 }
1424}
1425
1426static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1427 jobject recipient, jint flags)
1428{
1429 jboolean res = JNI_FALSE;
1430 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001431 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 return res;
1433 }
1434
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001435 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1436 IBinder* target = nd->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001437 if (target == NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001438 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 return JNI_FALSE;
1440 }
1441
Christopher Tate79dd31f2011-03-04 17:45:00 -08001442 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443
1444 if (!target->localBinder()) {
Christopher Tate0b414482011-02-17 13:00:38 -08001445 status_t err = NAME_NOT_FOUND;
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001446
1447 // If we find the matching recipient, proceed to unlink using that
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001448 DeathRecipientList* list = nd->mOrgue.get();
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001449 sp<JavaDeathRecipient> origJDR = list->find(recipient);
Christopher Tate79dd31f2011-03-04 17:45:00 -08001450 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
Christopher Tate0b414482011-02-17 13:00:38 -08001451 if (origJDR != NULL) {
1452 wp<IBinder::DeathRecipient> dr;
1453 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1454 if (err == NO_ERROR && dr != NULL) {
1455 sp<IBinder::DeathRecipient> sdr = dr.promote();
1456 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1457 if (jdr != NULL) {
1458 jdr->clearReference();
1459 }
1460 }
1461 }
1462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 if (err == NO_ERROR || err == DEAD_OBJECT) {
1464 res = JNI_TRUE;
1465 } else {
1466 jniThrowException(env, "java/util/NoSuchElementException",
1467 "Death link does not exist");
1468 }
1469 }
1470
1471 return res;
1472}
1473
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001474static void BinderProxy_destroy(void* rawNativeData)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001476 BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
1477 LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
1478 nativeData->mObject.get(), nativeData->mOrgue.get());
Hans Boehm29f388f2017-10-03 18:01:20 -07001479 delete nativeData;
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001480 IPCThreadState::self()->flushCommands();
Hans Boehm29f388f2017-10-03 18:01:20 -07001481 --gNumProxies;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482}
1483
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001484JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
1485 return (jlong) BinderProxy_destroy;
1486}
1487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488// ----------------------------------------------------------------------------
1489
1490static const JNINativeMethod gBinderProxyMethods[] = {
1491 /* name, signature, funcPtr */
1492 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1493 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1494 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001495 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1497 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001498 {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499};
1500
1501const char* const kBinderProxyPathName = "android/os/BinderProxy";
1502
1503static int int_register_android_os_BinderProxy(JNIEnv* env)
1504{
Andreas Gampe9ff9c402019-07-08 08:31:27 -07001505 gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));
1506 gErrorOffsets.mOutOfMemory =
1507 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));
1508 gErrorOffsets.mStackOverflow =
1509 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510
Andreas Gampe9ff9c402019-07-08 08:31:27 -07001511 jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
Andreas Gampe987f79f2014-11-18 17:29:46 -08001512 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
Hans Boehm29f388f2017-10-03 18:01:20 -07001513 gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
1514 "(JJ)Landroid/os/BinderProxy;");
Andreas Gampe987f79f2014-11-18 17:29:46 -08001515 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1516 "(Landroid/os/IBinder$DeathRecipient;)V");
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001517 gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518
Andreas Gampe987f79f2014-11-18 17:29:46 -08001519 clazz = FindClassOrDie(env, "java/lang/Class");
1520 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
Christopher Tate0d4a7922011-08-30 12:09:43 -07001521
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001522 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 env, kBinderProxyPathName,
1524 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1525}
1526
1527// ****************************************************************************
1528// ****************************************************************************
1529// ****************************************************************************
1530
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001531int register_android_os_Binder(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532{
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001533 if (int_register_android_os_Binder(env) < 0)
1534 return -1;
1535 if (int_register_android_os_BinderInternal(env) < 0)
1536 return -1;
1537 if (int_register_android_os_BinderProxy(env) < 0)
1538 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539
Andreas Gampe987f79f2014-11-18 17:29:46 -08001540 jclass clazz = FindClassOrDie(env, "android/util/Log");
1541 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1542 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1543 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544
Andreas Gampe987f79f2014-11-18 17:29:46 -08001545 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1546 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1547 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1548 "(Ljava/io/FileDescriptor;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549
Andreas Gampe987f79f2014-11-18 17:29:46 -08001550 clazz = FindClassOrDie(env, "android/os/StrictMode");
1551 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1552 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1553 "onBinderStrictModePolicyChange", "(I)V");
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001554
Andreas Gampe1cd76f52017-09-08 17:44:05 -07001555 clazz = FindClassOrDie(env, "java/lang/Thread");
1556 gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1557 gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
1558 "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
1559 gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
1560 "()Ljava/lang/Thread;");
1561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 return 0;
1563}