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