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