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