1 /*
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
20 #include "android_os_Parcel.h"
21 #include "android_util_Binder.h"
22
23 #include <atomic>
24 #include <fcntl.h>
25 #include <inttypes.h>
26 #include <mutex>
27 #include <stdio.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31
32 #include <android-base/stringprintf.h>
33 #include <binder/BpBinder.h>
34 #include <binder/IInterface.h>
35 #include <binder/IPCThreadState.h>
36 #include <binder/IServiceManager.h>
37 #include <binder/Parcel.h>
38 #include <binder/ProcessState.h>
39 #include <binder/Stability.h>
40 #include <binderthreadstate/CallerUtils.h>
41 #include <cutils/atomic.h>
42 #include <log/log.h>
43 #include <utils/KeyedVector.h>
44 #include <utils/List.h>
45 #include <utils/Log.h>
46 #include <utils/String8.h>
47 #include <utils/SystemClock.h>
48 #include <utils/threads.h>
49
50 #include <nativehelper/JNIHelp.h>
51 #include <nativehelper/ScopedLocalRef.h>
52 #include <nativehelper/ScopedUtfChars.h>
53
54 #include "core_jni_helpers.h"
55
56 //#undef ALOGV
57 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
58
59 #define DEBUG_DEATH 0
60 #if DEBUG_DEATH
61 #define LOGDEATH ALOGD
62 #else
63 #define LOGDEATH ALOGV
64 #endif
65
66 using namespace android;
67
68 // ----------------------------------------------------------------------------
69
70 static struct bindernative_offsets_t
71 {
72 // Class state.
73 jclass mClass;
74 jmethodID mExecTransact;
75 jmethodID mGetInterfaceDescriptor;
76
77 // Object state.
78 jfieldID mObject;
79
80 } gBinderOffsets;
81
82 // ----------------------------------------------------------------------------
83
84 static struct binderinternal_offsets_t
85 {
86 // Class state.
87 jclass mClass;
88 jmethodID mForceGc;
89 jmethodID mProxyLimitCallback;
90
91 } gBinderInternalOffsets;
92
93 static struct sparseintarray_offsets_t
94 {
95 jclass classObject;
96 jmethodID constructor;
97 jmethodID put;
98 } gSparseIntArrayOffsets;
99
100 // ----------------------------------------------------------------------------
101
102 static struct error_offsets_t
103 {
104 jclass mError;
105 jclass mOutOfMemory;
106 jclass mStackOverflow;
107 } gErrorOffsets;
108
109 // ----------------------------------------------------------------------------
110
111 static struct binderproxy_offsets_t
112 {
113 // Class state.
114 jclass mClass;
115 jmethodID mGetInstance;
116 jmethodID mSendDeathNotice;
117
118 // Object state.
119 jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
120 } gBinderProxyOffsets;
121
122 static struct class_offsets_t
123 {
124 jmethodID mGetName;
125 } gClassOffsets;
126
127 // ----------------------------------------------------------------------------
128
129 static struct log_offsets_t
130 {
131 // Class state.
132 jclass mClass;
133 jmethodID mLogE;
134 } gLogOffsets;
135
136 static struct parcel_file_descriptor_offsets_t
137 {
138 jclass mClass;
139 jmethodID mConstructor;
140 } gParcelFileDescriptorOffsets;
141
142 static struct strict_mode_callback_offsets_t
143 {
144 jclass mClass;
145 jmethodID mCallback;
146 } gStrictModeCallbackOffsets;
147
148 static struct thread_dispatch_offsets_t
149 {
150 // Class state.
151 jclass mClass;
152 jmethodID mDispatchUncaughtException;
153 jmethodID mCurrentThread;
154 } gThreadDispatchOffsets;
155
156 // ****************************************************************************
157 // ****************************************************************************
158 // ****************************************************************************
159
160 static constexpr int32_t PROXY_WARN_INTERVAL = 5000;
161 static constexpr uint32_t GC_INTERVAL = 1000;
162
163 static std::atomic<uint32_t> gNumProxies(0);
164 static std::atomic<uint32_t> gProxiesWarned(0);
165
166 // Number of GlobalRefs held by JavaBBinders.
167 static std::atomic<uint32_t> gNumLocalRefsCreated(0);
168 static std::atomic<uint32_t> gNumLocalRefsDeleted(0);
169 // Number of GlobalRefs held by JavaDeathRecipients.
170 static std::atomic<uint32_t> gNumDeathRefsCreated(0);
171 static std::atomic<uint32_t> gNumDeathRefsDeleted(0);
172
173 // We collected after creating this many refs.
174 static std::atomic<uint32_t> gCollectedAtRefs(0);
175
176 // Garbage collect if we've allocated at least GC_INTERVAL refs since the last time.
177 // TODO: Consider removing this completely. We should no longer be generating GlobalRefs
178 // that are reclaimed as a result of GC action.
179 __attribute__((no_sanitize("unsigned-integer-overflow")))
gcIfManyNewRefs(JNIEnv * env)180 static void gcIfManyNewRefs(JNIEnv* env)
181 {
182 uint32_t totalRefs = gNumLocalRefsCreated.load(std::memory_order_relaxed)
183 + gNumDeathRefsCreated.load(std::memory_order_relaxed);
184 uint32_t collectedAtRefs = gCollectedAtRefs.load(memory_order_relaxed);
185 // A bound on the number of threads that can have incremented gNum...RefsCreated before the
186 // following check is executed. Effectively a bound on #threads. Almost any value will do.
187 static constexpr uint32_t MAX_RACING = 100000;
188
189 if (totalRefs - (collectedAtRefs + GC_INTERVAL) /* modular arithmetic! */ < MAX_RACING) {
190 // Recently passed next GC interval.
191 if (gCollectedAtRefs.compare_exchange_strong(collectedAtRefs,
192 collectedAtRefs + GC_INTERVAL, std::memory_order_relaxed)) {
193 ALOGV("Binder forcing GC at %u created refs", totalRefs);
194 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
195 gBinderInternalOffsets.mForceGc);
196 } // otherwise somebody else beat us to it.
197 } else {
198 ALOGV("Now have %d binder ops", totalRefs - collectedAtRefs);
199 }
200 }
201
jnienv_to_javavm(JNIEnv * env)202 static JavaVM* jnienv_to_javavm(JNIEnv* env)
203 {
204 JavaVM* vm;
205 return env->GetJavaVM(&vm) >= 0 ? vm : NULL;
206 }
207
javavm_to_jnienv(JavaVM * vm)208 static JNIEnv* javavm_to_jnienv(JavaVM* vm)
209 {
210 JNIEnv* env;
211 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
212 }
213
GetErrorTypeName(JNIEnv * env,jthrowable error)214 static const char* GetErrorTypeName(JNIEnv* env, jthrowable error) {
215 if (env->IsInstanceOf(error, gErrorOffsets.mOutOfMemory)) {
216 return "OutOfMemoryError";
217 }
218 if (env->IsInstanceOf(error, gErrorOffsets.mStackOverflow)) {
219 return "StackOverflowError";
220 }
221 return nullptr;
222 }
223
224 // Report a java.lang.Error (or subclass). This will terminate the runtime by
225 // calling FatalError with a message derived from the given error.
report_java_lang_error_fatal_error(JNIEnv * env,jthrowable error,const char * msg)226 static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
227 const char* msg)
228 {
229 // Report an error: reraise the exception and ask the runtime to abort.
230
231 // Try to get the exception string. Sometimes logcat isn't available,
232 // so try to add it to the abort message.
233 std::string exc_msg;
234 {
235 ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
236 jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
237 "()Ljava/lang/String;");
238 ScopedLocalRef<jstring> jstr(
239 env,
240 reinterpret_cast<jstring>(
241 env->CallObjectMethod(error, method_id)));
242 ScopedLocalRef<jthrowable> new_error(env, nullptr);
243 bool got_jstr = false;
244 if (env->ExceptionCheck()) {
245 new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
246 env->ExceptionClear();
247 }
248 if (jstr.get() != nullptr) {
249 ScopedUtfChars jstr_utf(env, jstr.get());
250 if (jstr_utf.c_str() != nullptr) {
251 exc_msg = jstr_utf.c_str();
252 got_jstr = true;
253 } else {
254 new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
255 env->ExceptionClear();
256 }
257 }
258 if (!got_jstr) {
259 exc_msg = "(Unknown exception message)";
260 const char* orig_type = GetErrorTypeName(env, error);
261 if (orig_type != nullptr) {
262 exc_msg = base::StringPrintf("%s (Error was %s)", exc_msg.c_str(), orig_type);
263 }
264 const char* new_type =
265 new_error == nullptr ? nullptr : GetErrorTypeName(env, new_error.get());
266 if (new_type != nullptr) {
267 exc_msg = base::StringPrintf("%s (toString() error was %s)",
268 exc_msg.c_str(),
269 new_type);
270 }
271 }
272 }
273
274 env->Throw(error);
275 ALOGE("java.lang.Error thrown during binder transaction (stack trace follows) : ");
276 env->ExceptionDescribe();
277
278 std::string error_msg = base::StringPrintf(
279 "java.lang.Error thrown during binder transaction: %s",
280 exc_msg.c_str());
281 env->FatalError(error_msg.c_str());
282 }
283
284 // Report a java.lang.Error (or subclass). This will terminate the runtime, either by
285 // the uncaught exception handler, or explicitly by calling
286 // report_java_lang_error_fatal_error.
report_java_lang_error(JNIEnv * env,jthrowable error,const char * msg)287 static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* msg)
288 {
289 // Try to run the uncaught exception machinery.
290 jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass,
291 gThreadDispatchOffsets.mCurrentThread);
292 if (thread != nullptr) {
293 env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException,
294 error);
295 // Should not return here, unless more errors occured.
296 }
297 // Some error occurred that meant that either dispatchUncaughtException could not be
298 // called or that it had an error itself (as this should be unreachable under normal
299 // conditions). As the binder code cannot handle Errors, attempt to log the error and
300 // abort.
301 env->ExceptionClear();
302 report_java_lang_error_fatal_error(env, error, msg);
303 }
304
report_exception(JNIEnv * env,jthrowable excep,const char * msg)305 static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
306 {
307 env->ExceptionClear();
308
309 ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
310 ScopedLocalRef<jstring> msgstr(env);
311 if (tagstr != nullptr) {
312 msgstr.reset(env->NewStringUTF(msg));
313 }
314
315 if ((tagstr != nullptr) && (msgstr != nullptr)) {
316 env->CallStaticIntMethod(gLogOffsets.mClass, gLogOffsets.mLogE,
317 tagstr.get(), msgstr.get(), excep);
318 if (env->ExceptionCheck()) {
319 // Attempting to log the failure has failed.
320 ALOGW("Failed trying to log exception, msg='%s'\n", msg);
321 env->ExceptionClear();
322 }
323 } else {
324 env->ExceptionClear(); /* assume exception (OOM?) was thrown */
325 ALOGE("Unable to call Log.e()\n");
326 ALOGE("%s", msg);
327 }
328
329 if (env->IsInstanceOf(excep, gErrorOffsets.mError)) {
330 report_java_lang_error(env, excep, msg);
331 }
332 }
333
334 class JavaBBinderHolder;
335
336 class JavaBBinder : public BBinder
337 {
338 public:
JavaBBinder(JNIEnv * env,jobject object)339 JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
340 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
341 {
342 ALOGV("Creating JavaBBinder %p\n", this);
343 gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
344 gcIfManyNewRefs(env);
345 }
346
checkSubclass(const void * subclassID) const347 bool checkSubclass(const void* subclassID) const
348 {
349 return subclassID == &gBinderOffsets;
350 }
351
object() const352 jobject object() const
353 {
354 return mObject;
355 }
356
357 protected:
~JavaBBinder()358 virtual ~JavaBBinder()
359 {
360 ALOGV("Destroying JavaBBinder %p\n", this);
361 gNumLocalRefsDeleted.fetch_add(1, memory_order_relaxed);
362 JNIEnv* env = javavm_to_jnienv(mVM);
363 env->DeleteGlobalRef(mObject);
364 }
365
getInterfaceDescriptor() const366 const String16& getInterfaceDescriptor() const override
367 {
368 call_once(mPopulateDescriptor, [this] {
369 JNIEnv* env = javavm_to_jnienv(mVM);
370
371 ALOGV("getInterfaceDescriptor() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
372
373 jstring descriptor = (jstring)env->CallObjectMethod(mObject, gBinderOffsets.mGetInterfaceDescriptor);
374
375 if (descriptor == nullptr) {
376 return;
377 }
378
379 static_assert(sizeof(jchar) == sizeof(char16_t), "");
380 const jchar* descriptorChars = env->GetStringChars(descriptor, nullptr);
381 const char16_t* rawDescriptor = reinterpret_cast<const char16_t*>(descriptorChars);
382 jsize rawDescriptorLen = env->GetStringLength(descriptor);
383 mDescriptor = String16(rawDescriptor, rawDescriptorLen);
384 env->ReleaseStringChars(descriptor, descriptorChars);
385 });
386
387 return mDescriptor;
388 }
389
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags=0)390 status_t onTransact(
391 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
392 {
393 JNIEnv* env = javavm_to_jnienv(mVM);
394
395 ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
396
397 IPCThreadState* thread_state = IPCThreadState::self();
398 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
399
400 //printf("Transact from %p to Java code sending: ", this);
401 //data.print();
402 //printf("\n");
403 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
404 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
405
406 if (env->ExceptionCheck()) {
407 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
408 report_exception(env, excep.get(),
409 "*** Uncaught remote exception! "
410 "(Exceptions are not yet supported across processes.)");
411 res = JNI_FALSE;
412 }
413
414 // Check if the strict mode state changed while processing the
415 // call. The Binder state will be restored by the underlying
416 // Binder system in IPCThreadState, however we need to take care
417 // of the parallel Java state as well.
418 if (thread_state->getStrictModePolicy() != strict_policy_before) {
419 set_dalvik_blockguard_policy(env, strict_policy_before);
420 }
421
422 if (env->ExceptionCheck()) {
423 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
424 report_exception(env, excep.get(),
425 "*** Uncaught exception in onBinderStrictModePolicyChange");
426 }
427
428 // Need to always call through the native implementation of
429 // SYSPROPS_TRANSACTION.
430 if (code == SYSPROPS_TRANSACTION) {
431 BBinder::onTransact(code, data, reply, flags);
432 }
433
434 //aout << "onTransact to Java code; result=" << res << endl
435 // << "Transact from " << this << " to Java code returning "
436 // << reply << ": " << *reply << endl;
437 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
438 }
439
dump(int fd,const Vector<String16> & args)440 status_t dump(int fd, const Vector<String16>& args) override
441 {
442 return 0;
443 }
444
445 private:
446 JavaVM* const mVM;
447 jobject const mObject; // GlobalRef to Java Binder
448
449 mutable std::once_flag mPopulateDescriptor;
450 mutable String16 mDescriptor;
451 };
452
453 // ----------------------------------------------------------------------------
454
455 class JavaBBinderHolder
456 {
457 public:
get(JNIEnv * env,jobject obj)458 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
459 {
460 AutoMutex _l(mLock);
461 sp<JavaBBinder> b = mBinder.promote();
462 if (b == NULL) {
463 b = new JavaBBinder(env, obj);
464 if (mVintf) {
465 ::android::internal::Stability::markVintf(b.get());
466 }
467 if (mExtension != nullptr) {
468 b.get()->setExtension(mExtension);
469 }
470 mBinder = b;
471 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
472 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
473 }
474
475 return b;
476 }
477
getExisting()478 sp<JavaBBinder> getExisting()
479 {
480 AutoMutex _l(mLock);
481 return mBinder.promote();
482 }
483
markVintf()484 void markVintf() {
485 mVintf = true;
486 }
487
getExtension()488 sp<IBinder> getExtension() {
489 AutoMutex _l(mLock);
490 sp<JavaBBinder> b = mBinder.promote();
491 if (b != nullptr) {
492 return b.get()->getExtension();
493 }
494 return mExtension;
495 }
496
setExtension(const sp<IBinder> & extension)497 void setExtension(const sp<IBinder>& extension) {
498 AutoMutex _l(mLock);
499 mExtension = extension;
500 sp<JavaBBinder> b = mBinder.promote();
501 if (b != nullptr) {
502 b.get()->setExtension(mExtension);
503 }
504 }
505
506 private:
507 Mutex mLock;
508 wp<JavaBBinder> mBinder;
509
510 // in the future, we might condense this into int32_t stability, or if there
511 // is too much binder state here, we can think about making JavaBBinder an
512 // sp here (avoid recreating it)
513 bool mVintf = false;
514
515 sp<IBinder> mExtension;
516 };
517
518 // ----------------------------------------------------------------------------
519
520 // Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject
521 // death recipient references passed in through JNI with the permanent corresponding
522 // JavaDeathRecipient objects.
523
524 class JavaDeathRecipient;
525
526 class DeathRecipientList : public RefBase {
527 List< sp<JavaDeathRecipient> > mList;
528 Mutex mLock;
529
530 public:
531 DeathRecipientList();
532 ~DeathRecipientList();
533
534 void add(const sp<JavaDeathRecipient>& recipient);
535 void remove(const sp<JavaDeathRecipient>& recipient);
536 sp<JavaDeathRecipient> find(jobject recipient);
537
538 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death
539 };
540
541 // ----------------------------------------------------------------------------
542
543 class JavaDeathRecipient : public IBinder::DeathRecipient
544 {
545 public:
JavaDeathRecipient(JNIEnv * env,jobject object,const sp<DeathRecipientList> & list)546 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
547 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
548 mObjectWeak(NULL), mList(list)
549 {
550 // These objects manage their own lifetimes so are responsible for final bookkeeping.
551 // The list holds a strong reference to this object.
552 LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
553 list->add(this);
554
555 gNumDeathRefsCreated.fetch_add(1, std::memory_order_relaxed);
556 gcIfManyNewRefs(env);
557 }
558
binderDied(const wp<IBinder> & who)559 void binderDied(const wp<IBinder>& who)
560 {
561 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
562 if (mObject != NULL) {
563 JNIEnv* env = javavm_to_jnienv(mVM);
564 ScopedLocalRef<jobject> jBinderProxy(env, javaObjectForIBinder(env, who.promote()));
565 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
566 gBinderProxyOffsets.mSendDeathNotice, mObject,
567 jBinderProxy.get());
568 if (env->ExceptionCheck()) {
569 jthrowable excep = env->ExceptionOccurred();
570 report_exception(env, excep,
571 "*** Uncaught exception returned from death notification!");
572 }
573
574 // Serialize with our containing DeathRecipientList so that we can't
575 // delete the global ref on mObject while the list is being iterated.
576 sp<DeathRecipientList> list = mList.promote();
577 if (list != NULL) {
578 AutoMutex _l(list->lock());
579
580 // Demote from strong ref to weak after binderDied() has been delivered,
581 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
582 mObjectWeak = env->NewWeakGlobalRef(mObject);
583 env->DeleteGlobalRef(mObject);
584 mObject = NULL;
585 }
586 }
587 }
588
clearReference()589 void clearReference()
590 {
591 sp<DeathRecipientList> list = mList.promote();
592 if (list != NULL) {
593 LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
594 list->remove(this);
595 } else {
596 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
597 }
598 }
599
matches(jobject obj)600 bool matches(jobject obj) {
601 bool result;
602 JNIEnv* env = javavm_to_jnienv(mVM);
603
604 if (mObject != NULL) {
605 result = env->IsSameObject(obj, mObject);
606 } else {
607 ScopedLocalRef<jobject> me(env, env->NewLocalRef(mObjectWeak));
608 result = env->IsSameObject(obj, me.get());
609 }
610 return result;
611 }
612
warnIfStillLive()613 void warnIfStillLive() {
614 if (mObject != NULL) {
615 // Okay, something is wrong -- we have a hard reference to a live death
616 // recipient on the VM side, but the list is being torn down.
617 JNIEnv* env = javavm_to_jnienv(mVM);
618 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject));
619 ScopedLocalRef<jstring> nameRef(env,
620 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName));
621 ScopedUtfChars nameUtf(env, nameRef.get());
622 if (nameUtf.c_str() != NULL) {
623 ALOGW("BinderProxy is being destroyed but the application did not call "
624 "unlinkToDeath to unlink all of its death recipients beforehand. "
625 "Releasing leaked death recipient: %s", nameUtf.c_str());
626 } else {
627 ALOGW("BinderProxy being destroyed; unable to get DR object name");
628 env->ExceptionClear();
629 }
630 }
631 }
632
633 protected:
~JavaDeathRecipient()634 virtual ~JavaDeathRecipient()
635 {
636 //ALOGI("Removing death ref: recipient=%p\n", mObject);
637 gNumDeathRefsDeleted.fetch_add(1, std::memory_order_relaxed);
638 JNIEnv* env = javavm_to_jnienv(mVM);
639 if (mObject != NULL) {
640 env->DeleteGlobalRef(mObject);
641 } else {
642 env->DeleteWeakGlobalRef(mObjectWeak);
643 }
644 }
645
646 private:
647 JavaVM* const mVM;
648 jobject mObject; // Initial strong ref to Java-side DeathRecipient. Cleared on binderDied().
649 jweak mObjectWeak; // Weak ref to the same Java-side DeathRecipient after binderDied().
650 wp<DeathRecipientList> mList;
651 };
652
653 // ----------------------------------------------------------------------------
654
DeathRecipientList()655 DeathRecipientList::DeathRecipientList() {
656 LOGDEATH("New DRL @ %p", this);
657 }
658
~DeathRecipientList()659 DeathRecipientList::~DeathRecipientList() {
660 LOGDEATH("Destroy DRL @ %p", this);
661 AutoMutex _l(mLock);
662
663 // Should never happen -- the JavaDeathRecipient objects that have added themselves
664 // to the list are holding references on the list object. Only when they are torn
665 // down can the list header be destroyed.
666 if (mList.size() > 0) {
667 List< sp<JavaDeathRecipient> >::iterator iter;
668 for (iter = mList.begin(); iter != mList.end(); iter++) {
669 (*iter)->warnIfStillLive();
670 }
671 }
672 }
673
add(const sp<JavaDeathRecipient> & recipient)674 void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
675 AutoMutex _l(mLock);
676
677 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
678 mList.push_back(recipient);
679 }
680
remove(const sp<JavaDeathRecipient> & recipient)681 void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
682 AutoMutex _l(mLock);
683
684 List< sp<JavaDeathRecipient> >::iterator iter;
685 for (iter = mList.begin(); iter != mList.end(); iter++) {
686 if (*iter == recipient) {
687 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
688 mList.erase(iter);
689 return;
690 }
691 }
692 }
693
find(jobject recipient)694 sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
695 AutoMutex _l(mLock);
696
697 List< sp<JavaDeathRecipient> >::iterator iter;
698 for (iter = mList.begin(); iter != mList.end(); iter++) {
699 if ((*iter)->matches(recipient)) {
700 return *iter;
701 }
702 }
703 return NULL;
704 }
705
lock()706 Mutex& DeathRecipientList::lock() {
707 return mLock;
708 }
709
710 // ----------------------------------------------------------------------------
711
712 namespace android {
713
714 // We aggregate native pointer fields for BinderProxy in a single object to allow
715 // management with a single NativeAllocationRegistry, and to reduce the number of JNI
716 // Java field accesses. This costs us some extra indirections here.
717 struct BinderProxyNativeData {
718 // Both fields are constant and not null once javaObjectForIBinder returns this as
719 // part of a BinderProxy.
720
721 // The native IBinder proxied by this BinderProxy.
722 sp<IBinder> mObject;
723
724 // Death recipients for mObject. Reference counted only because DeathRecipients
725 // hold a weak reference that can be temporarily promoted.
726 sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
727 };
728
getBPNativeData(JNIEnv * env,jobject obj)729 BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
730 return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
731 }
732
733 // If the argument is a JavaBBinder, return the Java object that was used to create it.
734 // Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
735 // same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
javaObjectForIBinder(JNIEnv * env,const sp<IBinder> & val)736 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
737 {
738 // N.B. This function is called from a @FastNative JNI method, so don't take locks around
739 // calls to Java code or block the calling thread for a long time for any reason.
740
741 if (val == NULL) return NULL;
742
743 if (val->checkSubclass(&gBinderOffsets)) {
744 // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
745 jobject object = static_cast<JavaBBinder*>(val.get())->object();
746 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
747 return object;
748 }
749
750 BinderProxyNativeData* nativeData = new BinderProxyNativeData();
751 nativeData->mOrgue = new DeathRecipientList;
752 nativeData->mObject = val;
753
754 jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
755 gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
756 if (env->ExceptionCheck()) {
757 // In the exception case, getInstance still took ownership of nativeData.
758 return NULL;
759 }
760 BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
761 if (actualNativeData == nativeData) {
762 // Created a new Proxy
763 uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
764 uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
765 if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
766 // Multiple threads can get here, make sure only one of them gets to
767 // update the warn counter.
768 if (gProxiesWarned.compare_exchange_strong(numLastWarned,
769 numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
770 ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
771 }
772 }
773 } else {
774 delete nativeData;
775 }
776
777 return object;
778 }
779
ibinderForJavaObject(JNIEnv * env,jobject obj)780 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
781 {
782 if (obj == NULL) return NULL;
783
784 // Instance of Binder?
785 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
786 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
787 env->GetLongField(obj, gBinderOffsets.mObject);
788 return jbh->get(env, obj);
789 }
790
791 // Instance of BinderProxy?
792 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
793 return getBPNativeData(env, obj)->mObject;
794 }
795
796 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
797 return NULL;
798 }
799
newParcelFileDescriptor(JNIEnv * env,jobject fileDesc)800 jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
801 {
802 return env->NewObject(
803 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc);
804 }
805
set_dalvik_blockguard_policy(JNIEnv * env,jint strict_policy)806 void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy)
807 {
808 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange
809 // to sync our state back to it. See the comments in StrictMode.java.
810 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass,
811 gStrictModeCallbackOffsets.mCallback,
812 strict_policy);
813 }
814
signalExceptionForError(JNIEnv * env,jobject obj,status_t err,bool canThrowRemoteException,int parcelSize)815 void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
816 bool canThrowRemoteException, int parcelSize)
817 {
818 switch (err) {
819 case UNKNOWN_ERROR:
820 jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
821 break;
822 case NO_MEMORY:
823 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
824 break;
825 case INVALID_OPERATION:
826 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
827 break;
828 case BAD_VALUE:
829 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
830 break;
831 case BAD_INDEX:
832 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
833 break;
834 case BAD_TYPE:
835 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
836 break;
837 case NAME_NOT_FOUND:
838 jniThrowException(env, "java/util/NoSuchElementException", NULL);
839 break;
840 case PERMISSION_DENIED:
841 jniThrowException(env, "java/lang/SecurityException", NULL);
842 break;
843 case NOT_ENOUGH_DATA:
844 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data");
845 break;
846 case NO_INIT:
847 jniThrowException(env, "java/lang/RuntimeException", "Not initialized");
848 break;
849 case ALREADY_EXISTS:
850 jniThrowException(env, "java/lang/RuntimeException", "Item already exists");
851 break;
852 case DEAD_OBJECT:
853 // DeadObjectException is a checked exception, only throw from certain methods.
854 jniThrowException(env, canThrowRemoteException
855 ? "android/os/DeadObjectException"
856 : "java/lang/RuntimeException", NULL);
857 break;
858 case UNKNOWN_TRANSACTION:
859 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code");
860 break;
861 case FAILED_TRANSACTION: {
862 ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
863 const char* exceptionToThrow;
864 char msg[128];
865 // TransactionTooLargeException is a checked exception, only throw from certain methods.
866 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
867 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY
868 // for other reasons also, such as if the transaction is malformed or
869 // refers to an FD that has been closed. We should change the driver
870 // to enable us to distinguish these cases in the future.
871 if (canThrowRemoteException && parcelSize > 200*1024) {
872 // bona fide large payload
873 exceptionToThrow = "android/os/TransactionTooLargeException";
874 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
875 } else {
876 // Heuristic: a payload smaller than this threshold "shouldn't" be too
877 // big, so it's probably some other, more subtle problem. In practice
878 // it seems to always mean that the remote process died while the binder
879 // transaction was already in flight.
880 exceptionToThrow = (canThrowRemoteException)
881 ? "android/os/DeadObjectException"
882 : "java/lang/RuntimeException";
883 snprintf(msg, sizeof(msg)-1,
884 "Transaction failed on small parcel; remote process probably died");
885 }
886 jniThrowException(env, exceptionToThrow, msg);
887 } break;
888 case FDS_NOT_ALLOWED:
889 jniThrowException(env, "java/lang/RuntimeException",
890 "Not allowed to write file descriptors here");
891 break;
892 case UNEXPECTED_NULL:
893 jniThrowNullPointerException(env, NULL);
894 break;
895 case -EBADF:
896 jniThrowException(env, "java/lang/RuntimeException",
897 "Bad file descriptor");
898 break;
899 case -ENFILE:
900 jniThrowException(env, "java/lang/RuntimeException",
901 "File table overflow");
902 break;
903 case -EMFILE:
904 jniThrowException(env, "java/lang/RuntimeException",
905 "Too many open files");
906 break;
907 case -EFBIG:
908 jniThrowException(env, "java/lang/RuntimeException",
909 "File too large");
910 break;
911 case -ENOSPC:
912 jniThrowException(env, "java/lang/RuntimeException",
913 "No space left on device");
914 break;
915 case -ESPIPE:
916 jniThrowException(env, "java/lang/RuntimeException",
917 "Illegal seek");
918 break;
919 case -EROFS:
920 jniThrowException(env, "java/lang/RuntimeException",
921 "Read-only file system");
922 break;
923 case -EMLINK:
924 jniThrowException(env, "java/lang/RuntimeException",
925 "Too many links");
926 break;
927 default:
928 ALOGE("Unknown binder error code. 0x%" PRIx32, err);
929 String8 msg;
930 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err);
931 // RemoteException is a checked exception, only throw from certain methods.
932 jniThrowException(env, canThrowRemoteException
933 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string());
934 break;
935 }
936 }
937
938 }
939
940 // ----------------------------------------------------------------------------
941
android_os_Binder_getCallingPid()942 static jint android_os_Binder_getCallingPid()
943 {
944 return IPCThreadState::self()->getCallingPid();
945 }
946
android_os_Binder_getCallingUid()947 static jint android_os_Binder_getCallingUid()
948 {
949 return IPCThreadState::self()->getCallingUid();
950 }
951
android_os_Binder_isHandlingTransaction()952 static jboolean android_os_Binder_isHandlingTransaction()
953 {
954 return getCurrentServingCall() == BinderCallType::BINDER;
955 }
956
android_os_Binder_clearCallingIdentity()957 static jlong android_os_Binder_clearCallingIdentity()
958 {
959 return IPCThreadState::self()->clearCallingIdentity();
960 }
961
android_os_Binder_restoreCallingIdentity(JNIEnv * env,jobject clazz,jlong token)962 static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
963 {
964 // XXX temporary sanity check to debug crashes.
965 int uid = (int)(token>>32);
966 if (uid > 0 && uid < 999) {
967 // In Android currently there are no uids in this range.
968 char buf[128];
969 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token);
970 jniThrowException(env, "java/lang/IllegalStateException", buf);
971 return;
972 }
973 IPCThreadState::self()->restoreCallingIdentity(token);
974 }
975
android_os_Binder_setThreadStrictModePolicy(jint policyMask)976 static void android_os_Binder_setThreadStrictModePolicy(jint policyMask)
977 {
978 IPCThreadState::self()->setStrictModePolicy(policyMask);
979 }
980
android_os_Binder_getThreadStrictModePolicy()981 static jint android_os_Binder_getThreadStrictModePolicy()
982 {
983 return IPCThreadState::self()->getStrictModePolicy();
984 }
985
android_os_Binder_setCallingWorkSourceUid(jint workSource)986 static jlong android_os_Binder_setCallingWorkSourceUid(jint workSource)
987 {
988 return IPCThreadState::self()->setCallingWorkSourceUid(workSource);
989 }
990
android_os_Binder_getCallingWorkSourceUid()991 static jlong android_os_Binder_getCallingWorkSourceUid()
992 {
993 return IPCThreadState::self()->getCallingWorkSourceUid();
994 }
995
android_os_Binder_clearCallingWorkSource()996 static jlong android_os_Binder_clearCallingWorkSource()
997 {
998 return IPCThreadState::self()->clearCallingWorkSource();
999 }
1000
android_os_Binder_restoreCallingWorkSource(jlong token)1001 static void android_os_Binder_restoreCallingWorkSource(jlong token)
1002 {
1003 IPCThreadState::self()->restoreCallingWorkSource(token);
1004 }
1005
android_os_Binder_markVintfStability(JNIEnv * env,jobject clazz)1006 static void android_os_Binder_markVintfStability(JNIEnv* env, jobject clazz) {
1007 JavaBBinderHolder* jbh =
1008 (JavaBBinderHolder*) env->GetLongField(clazz, gBinderOffsets.mObject);
1009 jbh->markVintf();
1010 }
1011
android_os_Binder_flushPendingCommands(JNIEnv * env,jobject clazz)1012 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
1013 {
1014 IPCThreadState::self()->flushCommands();
1015 }
1016
android_os_Binder_getNativeBBinderHolder(JNIEnv * env,jobject clazz)1017 static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
1018 {
1019 JavaBBinderHolder* jbh = new JavaBBinderHolder();
1020 return (jlong) jbh;
1021 }
1022
Binder_destroy(void * rawJbh)1023 static void Binder_destroy(void* rawJbh)
1024 {
1025 JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh;
1026 ALOGV("Java Binder: deleting holder %p", jbh);
1027 delete jbh;
1028 }
1029
android_os_Binder_getNativeFinalizer(JNIEnv *,jclass)1030 JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) {
1031 return (jlong) Binder_destroy;
1032 }
1033
android_os_Binder_blockUntilThreadAvailable(JNIEnv * env,jobject clazz)1034 static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
1035 {
1036 return IPCThreadState::self()->blockUntilThreadAvailable();
1037 }
1038
android_os_Binder_getExtension(JNIEnv * env,jobject obj)1039 static jobject android_os_Binder_getExtension(JNIEnv* env, jobject obj) {
1040 JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
1041 return javaObjectForIBinder(env, jbh->getExtension());
1042 }
1043
android_os_Binder_setExtension(JNIEnv * env,jobject obj,jobject extensionObject)1044 static void android_os_Binder_setExtension(JNIEnv* env, jobject obj, jobject extensionObject) {
1045 JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
1046 sp<IBinder> extension = ibinderForJavaObject(env, extensionObject);
1047 jbh->setExtension(extension);
1048 }
1049
1050 // ----------------------------------------------------------------------------
1051
1052 static const JNINativeMethod gBinderMethods[] = {
1053 /* name, signature, funcPtr */
1054 // @CriticalNative
1055 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
1056 // @CriticalNative
1057 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
1058 // @CriticalNative
1059 { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction },
1060 // @CriticalNative
1061 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
1062 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
1063 // @CriticalNative
1064 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
1065 // @CriticalNative
1066 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
1067 // @CriticalNative
1068 { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
1069 // @CriticalNative
1070 { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
1071 // @CriticalNative
1072 { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
1073 { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
1074 { "markVintfStability", "()V", (void*)android_os_Binder_markVintfStability},
1075 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
1076 { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
1077 { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
1078 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable },
1079 { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension },
1080 { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
1081 };
1082
1083 const char* const kBinderPathName = "android/os/Binder";
1084
int_register_android_os_Binder(JNIEnv * env)1085 static int int_register_android_os_Binder(JNIEnv* env)
1086 {
1087 jclass clazz = FindClassOrDie(env, kBinderPathName);
1088
1089 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1090 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
1091 gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
1092 "()Ljava/lang/String;");
1093 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
1094
1095 return RegisterMethodsOrDie(
1096 env, kBinderPathName,
1097 gBinderMethods, NELEM(gBinderMethods));
1098 }
1099
1100 // ****************************************************************************
1101 // ****************************************************************************
1102 // ****************************************************************************
1103
1104 namespace android {
1105
android_os_Debug_getLocalObjectCount(JNIEnv * env,jobject clazz)1106 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
1107 {
1108 return gNumLocalRefsCreated - gNumLocalRefsDeleted;
1109 }
1110
android_os_Debug_getProxyObjectCount(JNIEnv * env,jobject clazz)1111 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
1112 {
1113 return gNumProxies.load();
1114 }
1115
android_os_Debug_getDeathObjectCount(JNIEnv * env,jobject clazz)1116 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
1117 {
1118 return gNumDeathRefsCreated - gNumDeathRefsDeleted;
1119 }
1120
1121 }
1122
1123 // ****************************************************************************
1124 // ****************************************************************************
1125 // ****************************************************************************
1126
android_os_BinderInternal_getContextObject(JNIEnv * env,jobject clazz)1127 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
1128 {
1129 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1130 return javaObjectForIBinder(env, b);
1131 }
1132
android_os_BinderInternal_joinThreadPool(JNIEnv * env,jobject clazz)1133 static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
1134 {
1135 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1136 android::IPCThreadState::self()->joinThreadPool();
1137 }
1138
android_os_BinderInternal_disableBackgroundScheduling(JNIEnv * env,jobject clazz,jboolean disable)1139 static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
1140 jobject clazz, jboolean disable)
1141 {
1142 IPCThreadState::disableBackgroundScheduling(disable ? true : false);
1143 }
1144
android_os_BinderInternal_setMaxThreads(JNIEnv * env,jobject clazz,jint maxThreads)1145 static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
1146 jobject clazz, jint maxThreads)
1147 {
1148 ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
1149 }
1150
android_os_BinderInternal_handleGc(JNIEnv * env,jobject clazz)1151 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
1152 {
1153 ALOGV("Gc has executed, updating Refs count at GC");
1154 gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
1155 }
1156
android_os_BinderInternal_proxyLimitcallback(int uid)1157 static void android_os_BinderInternal_proxyLimitcallback(int uid)
1158 {
1159 JNIEnv *env = AndroidRuntime::getJNIEnv();
1160 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
1161 gBinderInternalOffsets.mProxyLimitCallback,
1162 uid);
1163
1164 if (env->ExceptionCheck()) {
1165 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
1166 report_exception(env, excep.get(),
1167 "*** Uncaught exception in binderProxyLimitCallbackFromNative");
1168 }
1169 }
1170
android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv * env,jobject clazz,jboolean enable)1171 static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
1172 jboolean enable)
1173 {
1174 BpBinder::setCountByUidEnabled((bool) enable);
1175 }
1176
android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv * env,jclass clazz)1177 static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
1178 {
1179 Vector<uint32_t> uids, counts;
1180 BpBinder::getCountByUid(uids, counts);
1181 jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
1182 gSparseIntArrayOffsets.constructor);
1183 for (size_t i = 0; i < uids.size(); i++) {
1184 env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
1185 static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
1186 }
1187 return sparseIntArray;
1188 }
1189
android_os_BinderInternal_getBinderProxyCount(JNIEnv * env,jobject clazz,jint uid)1190 static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
1191 return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
1192 }
1193
android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv * env,jobject clazz,jint high,jint low)1194 static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
1195 jint high, jint low)
1196 {
1197 BpBinder::setBinderProxyCountWatermarks(high, low);
1198 }
1199
1200 // ----------------------------------------------------------------------------
1201
1202 static const JNINativeMethod gBinderInternalMethods[] = {
1203 /* name, signature, funcPtr */
1204 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
1205 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
1206 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
1207 { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
1208 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
1209 { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
1210 { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
1211 { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
1212 { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
1213 };
1214
1215 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
1216
int_register_android_os_BinderInternal(JNIEnv * env)1217 static int int_register_android_os_BinderInternal(JNIEnv* env)
1218 {
1219 jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
1220
1221 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1222 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
1223 gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
1224
1225 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
1226 gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
1227 gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
1228 "<init>", "()V");
1229 gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
1230 "(II)V");
1231
1232 BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
1233
1234 return RegisterMethodsOrDie(
1235 env, kBinderInternalPathName,
1236 gBinderInternalMethods, NELEM(gBinderInternalMethods));
1237 }
1238
1239 // ****************************************************************************
1240 // ****************************************************************************
1241 // ****************************************************************************
1242
android_os_BinderProxy_pingBinder(JNIEnv * env,jobject obj)1243 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
1244 {
1245 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1246 if (target == NULL) {
1247 return JNI_FALSE;
1248 }
1249 status_t err = target->pingBinder();
1250 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1251 }
1252
android_os_BinderProxy_getInterfaceDescriptor(JNIEnv * env,jobject obj)1253 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
1254 {
1255 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1256 if (target != NULL) {
1257 const String16& desc = target->getInterfaceDescriptor();
1258 return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
1259 desc.size());
1260 }
1261 jniThrowException(env, "java/lang/RuntimeException",
1262 "No binder found for object");
1263 return NULL;
1264 }
1265
android_os_BinderProxy_isBinderAlive(JNIEnv * env,jobject obj)1266 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
1267 {
1268 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1269 if (target == NULL) {
1270 return JNI_FALSE;
1271 }
1272 bool alive = target->isBinderAlive();
1273 return alive ? JNI_TRUE : JNI_FALSE;
1274 }
1275
getprocname(pid_t pid,char * buf,size_t len)1276 static int getprocname(pid_t pid, char *buf, size_t len) {
1277 char filename[32];
1278 FILE *f;
1279
1280 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
1281 f = fopen(filename, "re");
1282 if (!f) {
1283 *buf = '\0';
1284 return 1;
1285 }
1286 if (!fgets(buf, len, f)) {
1287 *buf = '\0';
1288 fclose(f);
1289 return 2;
1290 }
1291 fclose(f);
1292 return 0;
1293 }
1294
push_eventlog_string(char ** pos,const char * end,const char * str)1295 static bool push_eventlog_string(char** pos, const char* end, const char* str) {
1296 jint len = strlen(str);
1297 int space_needed = 1 + sizeof(len) + len;
1298 if (end - *pos < space_needed) {
1299 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d",
1300 end - *pos, space_needed);
1301 return false;
1302 }
1303 **pos = EVENT_TYPE_STRING;
1304 (*pos)++;
1305 memcpy(*pos, &len, sizeof(len));
1306 *pos += sizeof(len);
1307 memcpy(*pos, str, len);
1308 *pos += len;
1309 return true;
1310 }
1311
push_eventlog_int(char ** pos,const char * end,jint val)1312 static bool push_eventlog_int(char** pos, const char* end, jint val) {
1313 int space_needed = 1 + sizeof(val);
1314 if (end - *pos < space_needed) {
1315 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d",
1316 end - *pos, space_needed);
1317 return false;
1318 }
1319 **pos = EVENT_TYPE_INT;
1320 (*pos)++;
1321 memcpy(*pos, &val, sizeof(val));
1322 *pos += sizeof(val);
1323 return true;
1324 }
1325
1326 // From frameworks/base/core/java/android/content/EventLogTags.logtags:
1327
1328 static const bool kEnableBinderSample = false;
1329
1330 #define LOGTAG_BINDER_OPERATION 52004
1331
conditionally_log_binder_call(int64_t start_millis,IBinder * target,jint code)1332 static void conditionally_log_binder_call(int64_t start_millis,
1333 IBinder* target, jint code) {
1334 int duration_ms = static_cast<int>(uptimeMillis() - start_millis);
1335
1336 int sample_percent;
1337 if (duration_ms >= 500) {
1338 sample_percent = 100;
1339 } else {
1340 sample_percent = 100 * duration_ms / 500;
1341 if (sample_percent == 0) {
1342 return;
1343 }
1344 if (sample_percent < (random() % 100 + 1)) {
1345 return;
1346 }
1347 }
1348
1349 char process_name[40];
1350 getprocname(getpid(), process_name, sizeof(process_name));
1351 String8 desc(target->getInterfaceDescriptor());
1352
1353 char buf[LOGGER_ENTRY_MAX_PAYLOAD];
1354 buf[0] = EVENT_TYPE_LIST;
1355 buf[1] = 5;
1356 char* pos = &buf[2];
1357 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n
1358 if (!push_eventlog_string(&pos, end, desc.string())) return;
1359 if (!push_eventlog_int(&pos, end, code)) return;
1360 if (!push_eventlog_int(&pos, end, duration_ms)) return;
1361 if (!push_eventlog_string(&pos, end, process_name)) return;
1362 if (!push_eventlog_int(&pos, end, sample_percent)) return;
1363 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently.
1364 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf);
1365 }
1366
1367 // We only measure binder call durations to potentially log them if
1368 // we're on the main thread.
should_time_binder_calls()1369 static bool should_time_binder_calls() {
1370 return (getpid() == gettid());
1371 }
1372
android_os_BinderProxy_transact(JNIEnv * env,jobject obj,jint code,jobject dataObj,jobject replyObj,jint flags)1373 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1374 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1375 {
1376 if (dataObj == NULL) {
1377 jniThrowNullPointerException(env, NULL);
1378 return JNI_FALSE;
1379 }
1380
1381 Parcel* data = parcelForJavaObject(env, dataObj);
1382 if (data == NULL) {
1383 return JNI_FALSE;
1384 }
1385 Parcel* reply = parcelForJavaObject(env, replyObj);
1386 if (reply == NULL && replyObj != NULL) {
1387 return JNI_FALSE;
1388 }
1389
1390 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1391 if (target == NULL) {
1392 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1393 return JNI_FALSE;
1394 }
1395
1396 ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
1397 target, obj, code);
1398
1399
1400 bool time_binder_calls;
1401 int64_t start_millis;
1402 if (kEnableBinderSample) {
1403 // Only log the binder call duration for things on the Java-level main thread.
1404 // But if we don't
1405 time_binder_calls = should_time_binder_calls();
1406
1407 if (time_binder_calls) {
1408 start_millis = uptimeMillis();
1409 }
1410 }
1411
1412 //printf("Transact from Java code to %p sending: ", target); data->print();
1413 status_t err = target->transact(code, *data, reply, flags);
1414 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1415
1416 if (kEnableBinderSample) {
1417 if (time_binder_calls) {
1418 conditionally_log_binder_call(start_millis, target, code);
1419 }
1420 }
1421
1422 if (err == NO_ERROR) {
1423 return JNI_TRUE;
1424 } else if (err == UNKNOWN_TRANSACTION) {
1425 return JNI_FALSE;
1426 }
1427
1428 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
1429 return JNI_FALSE;
1430 }
1431
android_os_BinderProxy_linkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1432 static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
1433 jobject recipient, jint flags) // throws RemoteException
1434 {
1435 if (recipient == NULL) {
1436 jniThrowNullPointerException(env, NULL);
1437 return;
1438 }
1439
1440 BinderProxyNativeData *nd = getBPNativeData(env, obj);
1441 IBinder* target = nd->mObject.get();
1442
1443 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
1444
1445 if (!target->localBinder()) {
1446 DeathRecipientList* list = nd->mOrgue.get();
1447 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
1448 status_t err = target->linkToDeath(jdr, NULL, flags);
1449 if (err != NO_ERROR) {
1450 // Failure adding the death recipient, so clear its reference
1451 // now.
1452 jdr->clearReference();
1453 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1454 }
1455 }
1456 }
1457
android_os_BinderProxy_unlinkToDeath(JNIEnv * env,jobject obj,jobject recipient,jint flags)1458 static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
1459 jobject recipient, jint flags)
1460 {
1461 jboolean res = JNI_FALSE;
1462 if (recipient == NULL) {
1463 jniThrowNullPointerException(env, NULL);
1464 return res;
1465 }
1466
1467 BinderProxyNativeData* nd = getBPNativeData(env, obj);
1468 IBinder* target = nd->mObject.get();
1469 if (target == NULL) {
1470 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
1471 return JNI_FALSE;
1472 }
1473
1474 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
1475
1476 if (!target->localBinder()) {
1477 status_t err = NAME_NOT_FOUND;
1478
1479 // If we find the matching recipient, proceed to unlink using that
1480 DeathRecipientList* list = nd->mOrgue.get();
1481 sp<JavaDeathRecipient> origJDR = list->find(recipient);
1482 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
1483 if (origJDR != NULL) {
1484 wp<IBinder::DeathRecipient> dr;
1485 err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
1486 if (err == NO_ERROR && dr != NULL) {
1487 sp<IBinder::DeathRecipient> sdr = dr.promote();
1488 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
1489 if (jdr != NULL) {
1490 jdr->clearReference();
1491 }
1492 }
1493 }
1494
1495 if (err == NO_ERROR || err == DEAD_OBJECT) {
1496 res = JNI_TRUE;
1497 } else {
1498 jniThrowException(env, "java/util/NoSuchElementException",
1499 "Death link does not exist");
1500 }
1501 }
1502
1503 return res;
1504 }
1505
BinderProxy_destroy(void * rawNativeData)1506 static void BinderProxy_destroy(void* rawNativeData)
1507 {
1508 BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
1509 LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
1510 nativeData->mObject.get(), nativeData->mOrgue.get());
1511 delete nativeData;
1512 IPCThreadState::self()->flushCommands();
1513 --gNumProxies;
1514 }
1515
android_os_BinderProxy_getNativeFinalizer(JNIEnv *,jclass)1516 JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
1517 return (jlong) BinderProxy_destroy;
1518 }
1519
android_os_BinderProxy_getExtension(JNIEnv * env,jobject obj)1520 static jobject android_os_BinderProxy_getExtension(JNIEnv* env, jobject obj) {
1521 IBinder* binder = getBPNativeData(env, obj)->mObject.get();
1522 if (binder == nullptr) {
1523 jniThrowException(env, "java/lang/IllegalStateException", "Native IBinder is null");
1524 return nullptr;
1525 }
1526 sp<IBinder> extension;
1527 status_t err = binder->getExtension(&extension);
1528 if (err != OK) {
1529 signalExceptionForError(env, obj, err, true /* canThrowRemoteException */);
1530 return nullptr;
1531 }
1532 return javaObjectForIBinder(env, extension);
1533 }
1534
1535 // ----------------------------------------------------------------------------
1536
1537 static const JNINativeMethod gBinderProxyMethods[] = {
1538 /* name, signature, funcPtr */
1539 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1540 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1541 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
1542 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
1543 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1544 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1545 {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
1546 {"getExtension", "()Landroid/os/IBinder;", (void*)android_os_BinderProxy_getExtension},
1547 };
1548
1549 const char* const kBinderProxyPathName = "android/os/BinderProxy";
1550
int_register_android_os_BinderProxy(JNIEnv * env)1551 static int int_register_android_os_BinderProxy(JNIEnv* env)
1552 {
1553 gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));
1554 gErrorOffsets.mOutOfMemory =
1555 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));
1556 gErrorOffsets.mStackOverflow =
1557 MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));
1558
1559 jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
1560 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1561 gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
1562 "(JJ)Landroid/os/BinderProxy;");
1563 gBinderProxyOffsets.mSendDeathNotice =
1564 GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
1565 "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
1566 gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
1567
1568 clazz = FindClassOrDie(env, "java/lang/Class");
1569 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
1570
1571 return RegisterMethodsOrDie(
1572 env, kBinderProxyPathName,
1573 gBinderProxyMethods, NELEM(gBinderProxyMethods));
1574 }
1575
1576 // ****************************************************************************
1577 // ****************************************************************************
1578 // ****************************************************************************
1579
register_android_os_Binder(JNIEnv * env)1580 int register_android_os_Binder(JNIEnv* env)
1581 {
1582 if (int_register_android_os_Binder(env) < 0)
1583 return -1;
1584 if (int_register_android_os_BinderInternal(env) < 0)
1585 return -1;
1586 if (int_register_android_os_BinderProxy(env) < 0)
1587 return -1;
1588
1589 jclass clazz = FindClassOrDie(env, "android/util/Log");
1590 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1591 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
1592 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
1593
1594 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
1595 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1596 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
1597 "(Ljava/io/FileDescriptor;)V");
1598
1599 clazz = FindClassOrDie(env, "android/os/StrictMode");
1600 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1601 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
1602 "onBinderStrictModePolicyChange", "(I)V");
1603
1604 clazz = FindClassOrDie(env, "java/lang/Thread");
1605 gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
1606 gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
1607 "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
1608 gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
1609 "()Ljava/lang/Thread;");
1610
1611 return 0;
1612 }
1613