blob: fe7e508872ab067dd07f569fa01dfc4c8a8c9ef1 [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{
700 if (val == NULL) return NULL;
701
702 if (val->checkSubclass(&gBinderOffsets)) {
Hans Boehm29f388f2017-10-03 18:01:20 -0700703 // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 jobject object = static_cast<JavaBBinder*>(val.get())->object();
Christopher Tate86284c62011-08-17 15:19:29 -0700705 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800706 return object;
707 }
708
Martijn Coenend3ef4bf2018-07-05 14:58:59 +0200709 BinderProxyNativeData* nativeData = new BinderProxyNativeData();
710 nativeData->mOrgue = new DeathRecipientList;
711 nativeData->mObject = val;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712
Hans Boehm29f388f2017-10-03 18:01:20 -0700713 jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
714 gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
715 if (env->ExceptionCheck()) {
Hans Boehm03477cb2018-02-15 16:12:51 -0800716 // In the exception case, getInstance still took ownership of nativeData.
Hans Boehm29f388f2017-10-03 18:01:20 -0700717 return NULL;
718 }
719 BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
720 if (actualNativeData == nativeData) {
Martijn Coenend3ef4bf2018-07-05 14:58:59 +0200721 // Created a new Proxy
722 uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
723 uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
724 if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
725 // Multiple threads can get here, make sure only one of them gets to
726 // update the warn counter.
727 if (gProxiesWarned.compare_exchange_strong(numLastWarned,
728 numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
729 ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
730 }
Hans Boehm29f388f2017-10-03 18:01:20 -0700731 }
732 } else {
Martijn Coenend3ef4bf2018-07-05 14:58:59 +0200733 delete nativeData;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 }
735
736 return object;
737}
738
739sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
740{
741 if (obj == NULL) return NULL;
742
Hans Boehm29f388f2017-10-03 18:01:20 -0700743 // Instance of Binder?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
745 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000746 env->GetLongField(obj, gBinderOffsets.mObject);
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700747 return jbh->get(env, obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 }
749
Hans Boehm29f388f2017-10-03 18:01:20 -0700750 // Instance of BinderProxy?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700752 return getBPNativeData(env, obj)->mObject;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 }
754
Steve Block8564c8d2012-01-05 23:22:43 +0000755 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 return NULL;
757}
758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
760{
761 return env->NewObject(
762 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
763}
764
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -0800765void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
766{
767 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
768 // to sync our state back to it. See the comments in StrictMode.java.
769 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
770 gStrictModeCallbackOffsets.mCallback,
771 strict_policy);
772}
773
774void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
Dianne Hackborne5c42622015-05-19 16:04:04 -0700775 bool canThrowRemoteException, int parcelSize)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776{
777 switch (err) {
778 case UNKNOWN_ERROR:
779 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
780 break;
781 case NO_MEMORY:
782 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
783 break;
784 case INVALID_OPERATION:
785 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
786 break;
787 case BAD_VALUE:
788 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
789 break;
790 case BAD_INDEX:
791 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
792 break;
793 case BAD_TYPE:
794 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
795 break;
796 case NAME_NOT_FOUND:
797 jniThrowException(env, "java/util/NoSuchElementException", NULL);
798 break;
799 case PERMISSION_DENIED:
800 jniThrowException(env, "java/lang/SecurityException", NULL);
801 break;
802 case NOT_ENOUGH_DATA:
803 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
804 break;
805 case NO_INIT:
806 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
807 break;
808 case ALREADY_EXISTS:
809 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
810 break;
811 case DEAD_OBJECT:
Jeff Brown0bde66a2011-11-07 12:50:08 -0800812 // DeadObjectException is a checked exception, only throw from certain methods.
813 jniThrowException(env, canThrowRemoteException
814 ? "android/os/DeadObjectException"
815 : "java/lang/RuntimeException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 break;
817 case UNKNOWN_TRANSACTION:
818 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
819 break;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700820 case FAILED_TRANSACTION: {
821 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
Christopher Tate02ca7a72015-06-24 18:16:42 -0700822 const char* exceptionToThrow;
Dianne Hackborne5c42622015-05-19 16:04:04 -0700823 char msg[128];
Jeff Brown0bde66a2011-11-07 12:50:08 -0800824 // TransactionTooLargeException is a checked exception, only throw from certain methods.
825 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
826 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
827 // for other reasons also, such as if the transaction is malformed or
828 // refers to an FD that has been closed. We should change the driver
829 // to enable us to distinguish these cases in the future.
Christopher Tate02ca7a72015-06-24 18:16:42 -0700830 if (canThrowRemoteException && parcelSize > 200*1024) {
831 // bona fide large payload
832 exceptionToThrow = "android/os/TransactionTooLargeException";
833 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
834 } else {
835 // Heuristic: a payload smaller than this threshold "shouldn't" be too
836 // big, so it's probably some other, more subtle problem. In practice
Christopher Tateffd58642015-06-29 11:00:15 -0700837 // it seems to always mean that the remote process died while the binder
Christopher Tate02ca7a72015-06-24 18:16:42 -0700838 // transaction was already in flight.
Christopher Tateffd58642015-06-29 11:00:15 -0700839 exceptionToThrow = (canThrowRemoteException)
840 ? "android/os/DeadObjectException"
841 : "java/lang/RuntimeException";
Christopher Tate02ca7a72015-06-24 18:16:42 -0700842 snprintf(msg, sizeof(msg)-1,
843 "Transaction failed on small parcel; remote process probably died");
844 }
845 jniThrowException(env, exceptionToThrow, msg);
Dianne Hackborne5c42622015-05-19 16:04:04 -0700846 } break;
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400847 case FDS_NOT_ALLOWED:
848 jniThrowException(env, "java/lang/RuntimeException",
849 "Not allowed to write file descriptors here");
850 break;
Christopher Wileya94fc522015-11-22 14:21:25 -0800851 case UNEXPECTED_NULL:
852 jniThrowNullPointerException(env, NULL);
853 break;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700854 case -EBADF:
855 jniThrowException(env, "java/lang/RuntimeException",
856 "Bad file descriptor");
857 break;
858 case -ENFILE:
859 jniThrowException(env, "java/lang/RuntimeException",
860 "File table overflow");
861 break;
862 case -EMFILE:
863 jniThrowException(env, "java/lang/RuntimeException",
864 "Too many open files");
865 break;
866 case -EFBIG:
867 jniThrowException(env, "java/lang/RuntimeException",
868 "File too large");
869 break;
870 case -ENOSPC:
871 jniThrowException(env, "java/lang/RuntimeException",
872 "No space left on device");
873 break;
874 case -ESPIPE:
875 jniThrowException(env, "java/lang/RuntimeException",
876 "Illegal seek");
877 break;
878 case -EROFS:
879 jniThrowException(env, "java/lang/RuntimeException",
880 "Read-only file system");
881 break;
882 case -EMLINK:
883 jniThrowException(env, "java/lang/RuntimeException",
884 "Too many links");
885 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 default:
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700887 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800888 String8 msg;
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700889 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
Jeff Brown0bde66a2011-11-07 12:50:08 -0800890 // RemoteException is a checked exception, only throw from certain methods.
891 jniThrowException(env, canThrowRemoteException
892 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
893 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 }
895}
896
897}
898
899// ----------------------------------------------------------------------------
900
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100901static jint android_os_Binder_getCallingPid()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902{
903 return IPCThreadState::self()->getCallingPid();
904}
905
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100906static jint android_os_Binder_getCallingUid()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907{
908 return IPCThreadState::self()->getCallingUid();
909}
910
Nikita Ioffea929cf02019-01-03 13:35:22 +0000911static jboolean android_os_Binder_isHandlingTransaction()
912{
913 return IPCThreadState::self()->isServingCall();
914}
915
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100916static jlong android_os_Binder_clearCallingIdentity()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917{
918 return IPCThreadState::self()->clearCallingIdentity();
919}
920
921static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
922{
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700923 // XXX temporary sanity check to debug crashes.
924 int uid = (int)(token>>32);
925 if (uid > 0 && uid < 999) {
926 // In Android currently there are no uids in this range.
927 char buf[128];
Mark Salyzyncfd91e72014-04-17 15:40:01 -0700928 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
Dianne Hackborncf3004a2011-03-14 14:24:04 -0700929 jniThrowException(env, "java/lang/IllegalStateException", buf);
930 return;
931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 IPCThreadState::self()->restoreCallingIdentity(token);
933}
934
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100935static void android_os_Binder_setThreadStrictModePolicy(jint policyMask)
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700936{
937 IPCThreadState::self()->setStrictModePolicy(policyMask);
938}
939
Olivier Gaillardd8c3df52018-10-23 09:58:42 +0100940static jint android_os_Binder_getThreadStrictModePolicy()
Brad Fitzpatrick727de402010-07-07 16:06:39 -0700941{
942 return IPCThreadState::self()->getStrictModePolicy();
943}
944
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000945static jlong android_os_Binder_setCallingWorkSourceUid(jint workSource)
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100946{
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000947 return IPCThreadState::self()->setCallingWorkSourceUid(workSource);
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100948}
949
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000950static jlong android_os_Binder_getCallingWorkSourceUid()
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100951{
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000952 return IPCThreadState::self()->getCallingWorkSourceUid();
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100953}
954
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000955static jlong android_os_Binder_clearCallingWorkSource()
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100956{
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000957 return IPCThreadState::self()->clearCallingWorkSource();
958}
959
Olivier Gaillarda16b83c2018-12-11 23:09:05 +0000960static void android_os_Binder_restoreCallingWorkSource(jlong token)
Olivier Gaillardd542b1c2018-11-14 15:24:35 +0000961{
962 IPCThreadState::self()->restoreCallingWorkSource(token);
Olivier Gaillarde4ff3972018-08-16 14:01:58 +0100963}
964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
966{
967 IPCThreadState::self()->flushCommands();
968}
969
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700970static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971{
Christopher Tate0b414482011-02-17 13:00:38 -0800972 JavaBBinderHolder* jbh = new JavaBBinderHolder();
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700973 return (jlong) jbh;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974}
975
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700976static void Binder_destroy(void* rawJbh)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977{
Hans Boehm5e5b13f2017-09-28 18:16:50 -0700978 JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh;
979 ALOGV("Java Binder: deleting holder %p", jbh);
980 delete jbh;
981}
982
983JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) {
984 return (jlong) Binder_destroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985}
986
Wale Ogunwaled7fdd022015-04-13 16:22:38 -0700987static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
988{
989 return IPCThreadState::self()->blockUntilThreadAvailable();
990}
991
Jon Spivack9e45fde2019-10-09 17:23:00 -0700992static jobject android_os_Binder_waitForService(
993 JNIEnv *env,
994 jclass /* clazzObj */,
995 jstring serviceNameObj) {
996
997 const jchar* serviceName = env->GetStringCritical(serviceNameObj, nullptr);
998 if (!serviceName) {
999 signalExceptionForError(env, nullptr, BAD_VALUE, true /*canThrowRemoteException*/);
1000 return nullptr;
1001 }
1002 String16 nameCopy = String16(reinterpret_cast<const char16_t *>(serviceName),
1003 env->GetStringLength(serviceNameObj));
1004 env->ReleaseStringCritical(serviceNameObj, serviceName);
1005
1006 auto sm = android::defaultServiceManager();
1007 sp<IBinder> service = sm->waitForService(nameCopy);
1008
1009 if (!service) {
1010 signalExceptionForError(env, nullptr, NAME_NOT_FOUND, true /*canThrowRemoteException*/);
1011 return nullptr;
1012 }
1013
1014 return javaObjectForIBinder(env, service);
1015}
1016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017// ----------------------------------------------------------------------------
1018
1019static const JNINativeMethod gBinderMethods[] = {
1020 /* name, signature, funcPtr */
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001021 // @CriticalNative
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001023 // @CriticalNative
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001025 // @CriticalNative
Nikita Ioffea929cf02019-01-03 13:35:22 +00001026 { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction },
1027 // @CriticalNative
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
1029 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001030 // @CriticalNative
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001031 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
Olivier Gaillardd8c3df52018-10-23 09:58:42 +01001032 // @CriticalNative
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001033 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
Olivier Gaillarde4ff3972018-08-16 14:01:58 +01001034 // @CriticalNative
Olivier Gaillardd542b1c2018-11-14 15:24:35 +00001035 { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
Olivier Gaillarde4ff3972018-08-16 14:01:58 +01001036 // @CriticalNative
Olivier Gaillardd542b1c2018-11-14 15:24:35 +00001037 { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
Olivier Gaillarde4ff3972018-08-16 14:01:58 +01001038 // @CriticalNative
Olivier Gaillardd542b1c2018-11-14 15:24:35 +00001039 { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
1040 { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001042 { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
1043 { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
Jon Spivack9e45fde2019-10-09 17:23:00 -07001044 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable },
1045 { "waitForService", "(Ljava/lang/String;)Landroid/os/IBinder;", (void*)android_os_Binder_waitForService }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046};
1047
1048const char* const kBinderPathName = "android/os/Binder";
1049
1050static int int_register_android_os_Binder(JNIEnv* env)
1051{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001052 jclass clazz = FindClassOrDie(env, kBinderPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053
Andreas Gampe987f79f2014-11-18 17:29:46 -08001054 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1055 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
Steven Morelande52bb7d2018-10-10 11:24:58 -07001056 gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
1057 "()Ljava/lang/String;");
Andreas Gampe987f79f2014-11-18 17:29:46 -08001058 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001059
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001060 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 env, kBinderPathName,
1062 gBinderMethods, NELEM(gBinderMethods));
1063}
1064
1065// ****************************************************************************
1066// ****************************************************************************
1067// ****************************************************************************
1068
1069namespace android {
1070
1071jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
1072{
Hans Boehm29f388f2017-10-03 18:01:20 -07001073 return gNumLocalRefsCreated - gNumLocalRefsDeleted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074}
1075
1076jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
1077{
Martijn Coenend3ef4bf2018-07-05 14:58:59 +02001078 return gNumProxies.load();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079}
1080
1081jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
1082{
Hans Boehm29f388f2017-10-03 18:01:20 -07001083 return gNumDeathRefsCreated - gNumDeathRefsDeleted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084}
1085
1086}
1087
1088// ****************************************************************************
1089// ****************************************************************************
1090// ****************************************************************************
1091
1092static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
1093{
1094 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1095 return javaObjectForIBinder(env, b);
1096}
1097
1098static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
1099{
1100 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1101 android::IPCThreadState::self()->joinThreadPool();
1102}
1103
Dianne Hackborn887f3552009-12-07 17:59:37 -08001104static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
1105 jobject clazz, jboolean disable)
1106{
1107 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
1108}
1109
Tim Murrayeef4a3d2016-04-19 14:14:20 -07001110static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
1111 jobject clazz, jint maxThreads)
1112{
1113 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
1114}
1115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
1117{
Hans Boehm29f388f2017-10-03 18:01:20 -07001118 ALOGV("Gc has executed, updating Refs count at GC");
1119 gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120}
1121
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001122static void android_os_BinderInternal_proxyLimitcallback(int uid)
1123{
1124 JNIEnv *env = AndroidRuntime::getJNIEnv();
1125 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1126 gBinderInternalOffsets.mProxyLimitCallback,
1127 uid);
Martijn Coenendfa390e2018-06-05 11:02:23 +02001128
1129 if (env->ExceptionCheck()) {
1130 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1131 report_exception(env, excep.get(),
1132 "*** Uncaught exception in binderProxyLimitCallbackFromNative");
1133 }
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001134}
1135
1136static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
1137 jboolean enable)
1138{
1139 BpBinder::setCountByUidEnabled((bool) enable);
1140}
1141
1142static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
1143{
1144 Vector<uint32_t> uids, counts;
1145 BpBinder::getCountByUid(uids, counts);
1146 jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
1147 gSparseIntArrayOffsets.constructor);
1148 for (size_t i = 0; i < uids.size(); i++) {
1149 env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
1150 static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
1151 }
1152 return sparseIntArray;
1153}
1154
1155static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
1156 return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
1157}
1158
1159static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
1160 jint high, jint low)
1161{
1162 BpBinder::setBinderProxyCountWatermarks(high, low);
1163}
1164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165// ----------------------------------------------------------------------------
1166
1167static const JNINativeMethod gBinderInternalMethods[] = {
1168 /* name, signature, funcPtr */
1169 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
1170 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
Dianne Hackborn887f3552009-12-07 17:59:37 -08001171 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
Tim Murrayeef4a3d2016-04-19 14:14:20 -07001172 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001173 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
1174 { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
1175 { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
1176 { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
1177 { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001178};
1179
1180const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
1181
1182static int int_register_android_os_BinderInternal(JNIEnv* env)
1183{
Andreas Gampe987f79f2014-11-18 17:29:46 -08001184 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185
Andreas Gampe987f79f2014-11-18 17:29:46 -08001186 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1187 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
Michael Wachenschwanz55182462017-08-14 23:10:13 -07001188 gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
1189
1190 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
1191 gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
1192 gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
1193 "<init>", "()V");
1194 gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
1195 "(II)V");
1196
1197 BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001198
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001199 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 env, kBinderInternalPathName,
1201 gBinderInternalMethods, NELEM(gBinderInternalMethods));
1202}
1203
1204// ****************************************************************************
1205// ****************************************************************************
1206// ****************************************************************************
1207
1208static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
1209{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001210 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 if (target == NULL) {
1212 return JNI_FALSE;
1213 }
1214 status_t err = target->pingBinder();
1215 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1216}
1217
1218static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
1219{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001220 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 if (target != NULL) {
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001222 const String16& desc = target->getInterfaceDescriptor();
Dan Albert66987492014-11-20 11:41:21 -08001223 return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
1224 desc.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 }
1226 jniThrowException(env, "java/lang/RuntimeException",
1227 "No binder found for object");
1228 return NULL;
1229}
1230
1231static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1232{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001233 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 if (target == NULL) {
1235 return JNI_FALSE;
1236 }
1237 bool alive = target->isBinderAlive();
1238 return alive ? JNI_TRUE : JNI_FALSE;
1239}
1240
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001241static int getprocname(pid_t pid, char *buf, size_t len) {
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001242 char filename[32];
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001243 FILE *f;
1244
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001245 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
Nick Kralevich4b3a08c2019-01-28 10:39:10 -08001246 f = fopen(filename, "re");
Sungmin Choiec3d44c2012-12-21 14:24:33 +09001247 if (!f) {
1248 *buf = '\0';
1249 return 1;
1250 }
1251 if (!fgets(buf, len, f)) {
1252 *buf = '\0';
1253 fclose(f);
1254 return 2;
1255 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001256 fclose(f);
1257 return 0;
1258}
1259
1260static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1261 jint len = strlen(str);
1262 int space_needed = 1 + sizeof(len) + len;
1263 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001264 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001265 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001266 return false;
1267 }
1268 **pos = EVENT_TYPE_STRING;
1269 (*pos)++;
1270 memcpy(*pos, &len, sizeof(len));
1271 *pos += sizeof(len);
1272 memcpy(*pos, str, len);
1273 *pos += len;
1274 return true;
1275}
1276
1277static bool push_eventlog_int(char** pos, const char* end, jint val) {
1278 int space_needed = 1 + sizeof(val);
1279 if (end - *pos < space_needed) {
Mark Salyzyn5b6da1a2014-04-17 17:25:36 -07001280 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d",
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001281 end - *pos, space_needed);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001282 return false;
1283 }
1284 **pos = EVENT_TYPE_INT;
1285 (*pos)++;
1286 memcpy(*pos, &val, sizeof(val));
1287 *pos += sizeof(val);
1288 return true;
1289}
1290
1291// From frameworks/base/core/java/android/content/EventLogTags.logtags:
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001292
1293static const bool kEnableBinderSample = false;
1294
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001295#define LOGTAG_BINDER_OPERATION 52004
1296
1297static void conditionally_log_binder_call(int64_t start_millis,
1298 IBinder* target, jint code) {
1299 int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1300
1301 int sample_percent;
1302 if (duration_ms >= 500) {
1303 sample_percent = 100;
1304 } else {
1305 sample_percent = 100 * duration_ms / 500;
1306 if (sample_percent == 0) {
1307 return;
1308 }
1309 if (sample_percent < (random() % 100 + 1)) {
1310 return;
1311 }
1312 }
1313
1314 char process_name[40];
1315 getprocname(getpid(), process_name, sizeof(process_name));
1316 String8 desc(target->getInterfaceDescriptor());
1317
1318 char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1319 buf[0] = EVENT_TYPE_LIST;
1320 buf[1] = 5;
1321 char* pos = &buf[2];
1322 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n
1323 if (!push_eventlog_string(&pos, end, desc.string())) return;
1324 if (!push_eventlog_int(&pos, end, code)) return;
1325 if (!push_eventlog_int(&pos, end, duration_ms)) return;
1326 if (!push_eventlog_string(&pos, end, process_name)) return;
1327 if (!push_eventlog_int(&pos, end, sample_percent)) return;
1328 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently.
1329 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1330}
1331
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001332// We only measure binder call durations to potentially log them if
Elliott Hughes06451fe2014-08-18 10:26:52 -07001333// we're on the main thread.
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001334static bool should_time_binder_calls() {
Elliott Hughes06451fe2014-08-18 10:26:52 -07001335 return (getpid() == gettid());
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001336}
1337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001339 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340{
1341 if (dataObj == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001342 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 return JNI_FALSE;
1344 }
1345
1346 Parcel* data = parcelForJavaObject(env, dataObj);
1347 if (data == NULL) {
1348 return JNI_FALSE;
1349 }
1350 Parcel* reply = parcelForJavaObject(env, replyObj);
1351 if (reply == NULL && replyObj != NULL) {
1352 return JNI_FALSE;
1353 }
1354
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001355 IBinder* target = getBPNativeData(env, obj)->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 if (target == NULL) {
1357 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1358 return JNI_FALSE;
1359 }
1360
Mark Salyzyncfd91e72014-04-17 15:40:01 -07001361 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 -08001362 target, obj, code);
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001363
Brad Fitzpatrickad8fd282010-03-25 02:01:32 -07001364
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001365 bool time_binder_calls;
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001366 int64_t start_millis;
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001367 if (kEnableBinderSample) {
1368 // Only log the binder call duration for things on the Java-level main thread.
1369 // But if we don't
1370 time_binder_calls = should_time_binder_calls();
1371
1372 if (time_binder_calls) {
1373 start_millis = uptimeMillis();
1374 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001375 }
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 //printf("Transact from Java code to %p sending: ", target); data->print();
1378 status_t err = target->transact(code, *data, reply, flags);
1379 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
Andreas Gampe0f0b4912014-11-12 08:03:48 -08001380
1381 if (kEnableBinderSample) {
1382 if (time_binder_calls) {
1383 conditionally_log_binder_call(start_millis, target, code);
1384 }
Brad Fitzpatrick2c5da312010-03-24 16:14:09 -07001385 }
1386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 if (err == NO_ERROR) {
1388 return JNI_TRUE;
1389 } else if (err == UNKNOWN_TRANSACTION) {
1390 return JNI_FALSE;
1391 }
1392
Dianne Hackborne5c42622015-05-19 16:04:04 -07001393 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 return JNI_FALSE;
1395}
1396
1397static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
Jeff Brown0bde66a2011-11-07 12:50:08 -08001398 jobject recipient, jint flags) // throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399{
1400 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001401 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 return;
1403 }
1404
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001405 BinderProxyNativeData *nd = getBPNativeData(env, obj);
1406 IBinder* target = nd->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407
Christopher Tate79dd31f2011-03-04 17:45:00 -08001408 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001409
1410 if (!target->localBinder()) {
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001411 DeathRecipientList* list = nd->mOrgue.get();
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001412 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
Christopher Tate0b414482011-02-17 13:00:38 -08001413 status_t err = target->linkToDeath(jdr, NULL, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 if (err != NO_ERROR) {
1415 // Failure adding the death recipient, so clear its reference
1416 // now.
1417 jdr->clearReference();
Jeff Brown0bde66a2011-11-07 12:50:08 -08001418 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 }
1420 }
1421}
1422
1423static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1424 jobject recipient, jint flags)
1425{
1426 jboolean res = JNI_FALSE;
1427 if (recipient == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -07001428 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 return res;
1430 }
1431
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001432 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1433 IBinder* target = nd->mObject.get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 if (target == NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001435 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 return JNI_FALSE;
1437 }
1438
Christopher Tate79dd31f2011-03-04 17:45:00 -08001439 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440
1441 if (!target->localBinder()) {
Christopher Tate0b414482011-02-17 13:00:38 -08001442 status_t err = NAME_NOT_FOUND;
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001443
1444 // If we find the matching recipient, proceed to unlink using that
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001445 DeathRecipientList* list = nd->mOrgue.get();
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001446 sp<JavaDeathRecipient> origJDR = list->find(recipient);
Christopher Tate79dd31f2011-03-04 17:45:00 -08001447 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
Christopher Tate0b414482011-02-17 13:00:38 -08001448 if (origJDR != NULL) {
1449 wp<IBinder::DeathRecipient> dr;
1450 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1451 if (err == NO_ERROR && dr != NULL) {
1452 sp<IBinder::DeathRecipient> sdr = dr.promote();
1453 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1454 if (jdr != NULL) {
1455 jdr->clearReference();
1456 }
1457 }
1458 }
1459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 if (err == NO_ERROR || err == DEAD_OBJECT) {
1461 res = JNI_TRUE;
1462 } else {
1463 jniThrowException(env, "java/util/NoSuchElementException",
1464 "Death link does not exist");
1465 }
1466 }
1467
1468 return res;
1469}
1470
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001471static void BinderProxy_destroy(void* rawNativeData)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472{
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001473 BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
1474 LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
1475 nativeData->mObject.get(), nativeData->mOrgue.get());
Hans Boehm29f388f2017-10-03 18:01:20 -07001476 delete nativeData;
Christopher Tatebd8b6f22011-03-01 11:55:27 -08001477 IPCThreadState::self()->flushCommands();
Hans Boehm29f388f2017-10-03 18:01:20 -07001478 --gNumProxies;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479}
1480
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001481JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
1482 return (jlong) BinderProxy_destroy;
1483}
1484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485// ----------------------------------------------------------------------------
1486
1487static const JNINativeMethod gBinderProxyMethods[] = {
1488 /* name, signature, funcPtr */
1489 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1490 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1491 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
Dianne Hackborn017c6a22014-09-25 17:41:34 -07001492 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1494 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001495 {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496};
1497
1498const char* const kBinderProxyPathName = "android/os/BinderProxy";
1499
1500static int int_register_android_os_BinderProxy(JNIEnv* env)
1501{
Andreas Gampe9ff9c402019-07-08 08:31:27 -07001502 gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));
1503 gErrorOffsets.mOutOfMemory =
1504 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));
1505 gErrorOffsets.mStackOverflow =
1506 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507
Andreas Gampe9ff9c402019-07-08 08:31:27 -07001508 jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
Andreas Gampe987f79f2014-11-18 17:29:46 -08001509 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
Hans Boehm29f388f2017-10-03 18:01:20 -07001510 gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
1511 "(JJ)Landroid/os/BinderProxy;");
Andreas Gampe987f79f2014-11-18 17:29:46 -08001512 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1513 "(Landroid/os/IBinder$DeathRecipient;)V");
Hans Boehm5e5b13f2017-09-28 18:16:50 -07001514 gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515
Andreas Gampe987f79f2014-11-18 17:29:46 -08001516 clazz = FindClassOrDie(env, "java/lang/Class");
1517 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
Christopher Tate0d4a7922011-08-30 12:09:43 -07001518
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001519 return RegisterMethodsOrDie(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 env, kBinderProxyPathName,
1521 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1522}
1523
1524// ****************************************************************************
1525// ****************************************************************************
1526// ****************************************************************************
1527
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001528int register_android_os_Binder(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529{
Jeff Sharkeyd84e1ce2012-03-06 18:26:19 -08001530 if (int_register_android_os_Binder(env) < 0)
1531 return -1;
1532 if (int_register_android_os_BinderInternal(env) < 0)
1533 return -1;
1534 if (int_register_android_os_BinderProxy(env) < 0)
1535 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536
Andreas Gampe987f79f2014-11-18 17:29:46 -08001537 jclass clazz = FindClassOrDie(env, "android/util/Log");
1538 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1539 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1540 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541
Andreas Gampe987f79f2014-11-18 17:29:46 -08001542 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1543 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1544 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1545 "(Ljava/io/FileDescriptor;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546
Andreas Gampe987f79f2014-11-18 17:29:46 -08001547 clazz = FindClassOrDie(env, "android/os/StrictMode");
1548 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1549 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1550 "onBinderStrictModePolicyChange", "(I)V");
Brad Fitzpatrick727de402010-07-07 16:06:39 -07001551
Andreas Gampe1cd76f52017-09-08 17:44:05 -07001552 clazz = FindClassOrDie(env, "java/lang/Thread");
1553 gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1554 gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
1555 "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
1556 gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
1557 "()Ljava/lang/Thread;");
1558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 return 0;
1560}