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