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