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