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