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