1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "JavaBinder" 18 //#define LOG_NDEBUG 0 19 20 #include "android_os_Parcel.h" 21 #include "android_util_Binder.h" 22 23 #include "JNIHelp.h" 24 25 #include <fcntl.h> 26 #include <inttypes.h> 27 #include <stdio.h> 28 #include <sys/stat.h> 29 #include <sys/types.h> 30 #include <unistd.h> 31 32 #include <utils/Atomic.h> 33 #include <binder/IInterface.h> 34 #include <binder/IPCThreadState.h> 35 #include <utils/Log.h> 36 #include <utils/SystemClock.h> 37 #include <utils/List.h> 38 #include <utils/KeyedVector.h> 39 #include <log/logger.h> 40 #include <binder/Parcel.h> 41 #include <binder/ProcessState.h> 42 #include <binder/IServiceManager.h> 43 #include <utils/threads.h> 44 #include <utils/String8.h> 45 46 #include <ScopedUtfChars.h> 47 #include <ScopedLocalRef.h> 48 49 #include "core_jni_helpers.h" 50 51 //#undef ALOGV 52 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__) 53 54 #define DEBUG_DEATH 0 55 #if DEBUG_DEATH 56 #define LOGDEATH ALOGD 57 #else 58 #define LOGDEATH ALOGV 59 #endif 60 61 using namespace android; 62 63 // ---------------------------------------------------------------------------- 64 65 static struct bindernative_offsets_t 66 { 67 // Class state. 68 jclass mClass; 69 jmethodID mExecTransact; 70 71 // Object state. 72 jfieldID mObject; 73 74 } gBinderOffsets; 75 76 // ---------------------------------------------------------------------------- 77 78 static struct binderinternal_offsets_t 79 { 80 // Class state. 81 jclass mClass; 82 jmethodID mForceGc; 83 84 } gBinderInternalOffsets; 85 86 // ---------------------------------------------------------------------------- 87 88 static struct error_offsets_t 89 { 90 jclass mClass; 91 } gErrorOffsets; 92 93 // ---------------------------------------------------------------------------- 94 95 static struct binderproxy_offsets_t 96 { 97 // Class state. 98 jclass mClass; 99 jmethodID mConstructor; 100 jmethodID mSendDeathNotice; 101 102 // Object state. 103 jfieldID mObject; 104 jfieldID mSelf; 105 jfieldID mOrgue; 106 107 } gBinderProxyOffsets; 108 109 static struct class_offsets_t 110 { 111 jmethodID mGetName; 112 } gClassOffsets; 113 114 // ---------------------------------------------------------------------------- 115 116 static struct log_offsets_t 117 { 118 // Class state. 119 jclass mClass; 120 jmethodID mLogE; 121 } gLogOffsets; 122 123 static struct parcel_file_descriptor_offsets_t 124 { 125 jclass mClass; 126 jmethodID mConstructor; 127 } gParcelFileDescriptorOffsets; 128 129 static struct strict_mode_callback_offsets_t 130 { 131 jclass mClass; 132 jmethodID mCallback; 133 } gStrictModeCallbackOffsets; 134 135 // **************************************************************************** 136 // **************************************************************************** 137 // **************************************************************************** 138 139 static volatile int32_t gNumRefsCreated = 0; 140 static volatile int32_t gNumProxyRefs = 0; 141 static volatile int32_t gNumLocalRefs = 0; 142 static volatile int32_t gNumDeathRefs = 0; 143 144 static void incRefsCreated(JNIEnv* env) 145 { 146 int old = android_atomic_inc(&gNumRefsCreated); 147 if (old == 200) { 148 android_atomic_and(0, &gNumRefsCreated); 149 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass, 150 gBinderInternalOffsets.mForceGc); 151 } else { 152 ALOGV("Now have %d binder ops", old); 153 } 154 } 155 156 static JavaVM* jnienv_to_javavm(JNIEnv* env) 157 { 158 JavaVM* vm; 159 return env->GetJavaVM(&vm) >= 0 ? vm : NULL; 160 } 161 162 static JNIEnv* javavm_to_jnienv(JavaVM* vm) 163 { 164 JNIEnv* env; 165 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; 166 } 167 168 static void report_exception(JNIEnv* env, jthrowable excep, const char* msg) 169 { 170 env->ExceptionClear(); 171 172 jstring tagstr = env->NewStringUTF(LOG_TAG); 173 jstring msgstr = NULL; 174 if (tagstr != NULL) { 175 msgstr = env->NewStringUTF(msg); 176 } 177 178 if ((tagstr == NULL) || (msgstr == NULL)) { 179 env->ExceptionClear(); /* assume exception (OOM?) was thrown */ 180 ALOGE("Unable to call Log.e()\n"); 181 ALOGE("%s", msg); 182 goto bail; 183 } 184 185 env->CallStaticIntMethod( 186 gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep); 187 if (env->ExceptionCheck()) { 188 /* attempting to log the failure has failed */ 189 ALOGW("Failed trying to log exception, msg='%s'\n", msg); 190 env->ExceptionClear(); 191 } 192 193 if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) { 194 /* 195 * It's an Error: Reraise the exception, detach this thread, and 196 * wait for the fireworks. Die even more blatantly after a minute 197 * if the gentler attempt doesn't do the trick. 198 * 199 * The GetJavaVM function isn't on the "approved" list of JNI calls 200 * that can be made while an exception is pending, so we want to 201 * get the VM ptr, throw the exception, and then detach the thread. 202 */ 203 env->Throw(excep); 204 env->ExceptionDescribe(); 205 ALOGE("Forcefully exiting"); 206 exit(1); 207 } 208 209 bail: 210 /* discard local refs created for us by VM */ 211 env->DeleteLocalRef(tagstr); 212 env->DeleteLocalRef(msgstr); 213 } 214 215 class JavaBBinderHolder; 216 217 class JavaBBinder : public BBinder 218 { 219 public: 220 JavaBBinder(JNIEnv* env, jobject object) 221 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)) 222 { 223 ALOGV("Creating JavaBBinder %p\n", this); 224 android_atomic_inc(&gNumLocalRefs); 225 incRefsCreated(env); 226 } 227 228 bool checkSubclass(const void* subclassID) const 229 { 230 return subclassID == &gBinderOffsets; 231 } 232 233 jobject object() const 234 { 235 return mObject; 236 } 237 238 protected: 239 virtual ~JavaBBinder() 240 { 241 ALOGV("Destroying JavaBBinder %p\n", this); 242 android_atomic_dec(&gNumLocalRefs); 243 JNIEnv* env = javavm_to_jnienv(mVM); 244 env->DeleteGlobalRef(mObject); 245 } 246 247 virtual status_t onTransact( 248 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) 249 { 250 JNIEnv* env = javavm_to_jnienv(mVM); 251 252 ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM); 253 254 IPCThreadState* thread_state = IPCThreadState::self(); 255 const int32_t strict_policy_before = thread_state->getStrictModePolicy(); 256 257 //printf("Transact from %p to Java code sending: ", this); 258 //data.print(); 259 //printf("\n"); 260 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, 261 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags); 262 263 if (env->ExceptionCheck()) { 264 jthrowable excep = env->ExceptionOccurred(); 265 report_exception(env, excep, 266 "*** Uncaught remote exception! " 267 "(Exceptions are not yet supported across processes.)"); 268 res = JNI_FALSE; 269 270 /* clean up JNI local ref -- we don't return to Java code */ 271 env->DeleteLocalRef(excep); 272 } 273 274 // Check if the strict mode state changed while processing the 275 // call. The Binder state will be restored by the underlying 276 // Binder system in IPCThreadState, however we need to take care 277 // of the parallel Java state as well. 278 if (thread_state->getStrictModePolicy() != strict_policy_before) { 279 set_dalvik_blockguard_policy(env, strict_policy_before); 280 } 281 282 if (env->ExceptionCheck()) { 283 jthrowable excep = env->ExceptionOccurred(); 284 report_exception(env, excep, 285 "*** Uncaught exception in onBinderStrictModePolicyChange"); 286 /* clean up JNI local ref -- we don't return to Java code */ 287 env->DeleteLocalRef(excep); 288 } 289 290 // Need to always call through the native implementation of 291 // SYSPROPS_TRANSACTION. 292 if (code == SYSPROPS_TRANSACTION) { 293 BBinder::onTransact(code, data, reply, flags); 294 } 295 296 //aout << "onTransact to Java code; result=" << res << endl 297 // << "Transact from " << this << " to Java code returning " 298 // << reply << ": " << *reply << endl; 299 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; 300 } 301 302 virtual status_t dump(int fd, const Vector<String16>& args) 303 { 304 return 0; 305 } 306 307 private: 308 JavaVM* const mVM; 309 jobject const mObject; 310 }; 311 312 // ---------------------------------------------------------------------------- 313 314 class JavaBBinderHolder : public RefBase 315 { 316 public: 317 sp<JavaBBinder> get(JNIEnv* env, jobject obj) 318 { 319 AutoMutex _l(mLock); 320 sp<JavaBBinder> b = mBinder.promote(); 321 if (b == NULL) { 322 b = new JavaBBinder(env, obj); 323 mBinder = b; 324 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n", 325 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount()); 326 } 327 328 return b; 329 } 330 331 sp<JavaBBinder> getExisting() 332 { 333 AutoMutex _l(mLock); 334 return mBinder.promote(); 335 } 336 337 private: 338 Mutex mLock; 339 wp<JavaBBinder> mBinder; 340 }; 341 342 // ---------------------------------------------------------------------------- 343 344 // Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject 345 // death recipient references passed in through JNI with the permanent corresponding 346 // JavaDeathRecipient objects. 347 348 class JavaDeathRecipient; 349 350 class DeathRecipientList : public RefBase { 351 List< sp<JavaDeathRecipient> > mList; 352 Mutex mLock; 353 354 public: 355 DeathRecipientList(); 356 ~DeathRecipientList(); 357 358 void add(const sp<JavaDeathRecipient>& recipient); 359 void remove(const sp<JavaDeathRecipient>& recipient); 360 sp<JavaDeathRecipient> find(jobject recipient); 361 362 Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death 363 }; 364 365 // ---------------------------------------------------------------------------- 366 367 class JavaDeathRecipient : public IBinder::DeathRecipient 368 { 369 public: 370 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list) 371 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), 372 mObjectWeak(NULL), mList(list) 373 { 374 // These objects manage their own lifetimes so are responsible for final bookkeeping. 375 // The list holds a strong reference to this object. 376 LOGDEATH("Adding JDR %p to DRL %p", this, list.get()); 377 list->add(this); 378 379 android_atomic_inc(&gNumDeathRefs); 380 incRefsCreated(env); 381 } 382 383 void binderDied(const wp<IBinder>& who) 384 { 385 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this); 386 if (mObject != NULL) { 387 JNIEnv* env = javavm_to_jnienv(mVM); 388 389 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass, 390 gBinderProxyOffsets.mSendDeathNotice, mObject); 391 if (env->ExceptionCheck()) { 392 jthrowable excep = env->ExceptionOccurred(); 393 report_exception(env, excep, 394 "*** Uncaught exception returned from death notification!"); 395 } 396 397 // Serialize with our containing DeathRecipientList so that we can't 398 // delete the global ref on mObject while the list is being iterated. 399 sp<DeathRecipientList> list = mList.promote(); 400 if (list != NULL) { 401 AutoMutex _l(list->lock()); 402 403 // Demote from strong ref to weak after binderDied() has been delivered, 404 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed. 405 mObjectWeak = env->NewWeakGlobalRef(mObject); 406 env->DeleteGlobalRef(mObject); 407 mObject = NULL; 408 } 409 } 410 } 411 412 void clearReference() 413 { 414 sp<DeathRecipientList> list = mList.promote(); 415 if (list != NULL) { 416 LOGDEATH("Removing JDR %p from DRL %p", this, list.get()); 417 list->remove(this); 418 } else { 419 LOGDEATH("clearReference() on JDR %p but DRL wp purged", this); 420 } 421 } 422 423 bool matches(jobject obj) { 424 bool result; 425 JNIEnv* env = javavm_to_jnienv(mVM); 426 427 if (mObject != NULL) { 428 result = env->IsSameObject(obj, mObject); 429 } else { 430 jobject me = env->NewLocalRef(mObjectWeak); 431 result = env->IsSameObject(obj, me); 432 env->DeleteLocalRef(me); 433 } 434 return result; 435 } 436 437 void warnIfStillLive() { 438 if (mObject != NULL) { 439 // Okay, something is wrong -- we have a hard reference to a live death 440 // recipient on the VM side, but the list is being torn down. 441 JNIEnv* env = javavm_to_jnienv(mVM); 442 ScopedLocalRef<jclass> objClassRef(env, env->GetObjectClass(mObject)); 443 ScopedLocalRef<jstring> nameRef(env, 444 (jstring) env->CallObjectMethod(objClassRef.get(), gClassOffsets.mGetName)); 445 ScopedUtfChars nameUtf(env, nameRef.get()); 446 if (nameUtf.c_str() != NULL) { 447 ALOGW("BinderProxy is being destroyed but the application did not call " 448 "unlinkToDeath to unlink all of its death recipients beforehand. " 449 "Releasing leaked death recipient: %s", nameUtf.c_str()); 450 } else { 451 ALOGW("BinderProxy being destroyed; unable to get DR object name"); 452 env->ExceptionClear(); 453 } 454 } 455 } 456 457 protected: 458 virtual ~JavaDeathRecipient() 459 { 460 //ALOGI("Removing death ref: recipient=%p\n", mObject); 461 android_atomic_dec(&gNumDeathRefs); 462 JNIEnv* env = javavm_to_jnienv(mVM); 463 if (mObject != NULL) { 464 env->DeleteGlobalRef(mObject); 465 } else { 466 env->DeleteWeakGlobalRef(mObjectWeak); 467 } 468 } 469 470 private: 471 JavaVM* const mVM; 472 jobject mObject; 473 jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied() 474 wp<DeathRecipientList> mList; 475 }; 476 477 // ---------------------------------------------------------------------------- 478 479 DeathRecipientList::DeathRecipientList() { 480 LOGDEATH("New DRL @ %p", this); 481 } 482 483 DeathRecipientList::~DeathRecipientList() { 484 LOGDEATH("Destroy DRL @ %p", this); 485 AutoMutex _l(mLock); 486 487 // Should never happen -- the JavaDeathRecipient objects that have added themselves 488 // to the list are holding references on the list object. Only when they are torn 489 // down can the list header be destroyed. 490 if (mList.size() > 0) { 491 List< sp<JavaDeathRecipient> >::iterator iter; 492 for (iter = mList.begin(); iter != mList.end(); iter++) { 493 (*iter)->warnIfStillLive(); 494 } 495 } 496 } 497 498 void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) { 499 AutoMutex _l(mLock); 500 501 LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get()); 502 mList.push_back(recipient); 503 } 504 505 void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) { 506 AutoMutex _l(mLock); 507 508 List< sp<JavaDeathRecipient> >::iterator iter; 509 for (iter = mList.begin(); iter != mList.end(); iter++) { 510 if (*iter == recipient) { 511 LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get()); 512 mList.erase(iter); 513 return; 514 } 515 } 516 } 517 518 sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) { 519 AutoMutex _l(mLock); 520 521 List< sp<JavaDeathRecipient> >::iterator iter; 522 for (iter = mList.begin(); iter != mList.end(); iter++) { 523 if ((*iter)->matches(recipient)) { 524 return *iter; 525 } 526 } 527 return NULL; 528 } 529 530 Mutex& DeathRecipientList::lock() { 531 return mLock; 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->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)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->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(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->GetLongField(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->GetLongField(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, int parcelSize) 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 !!! (parcel size = %d)", parcelSize); 685 const char* exceptionToThrow; 686 char msg[128]; 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 if (canThrowRemoteException && parcelSize > 200*1024) { 694 // bona fide large payload 695 exceptionToThrow = "android/os/TransactionTooLargeException"; 696 snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize); 697 } else { 698 // Heuristic: a payload smaller than this threshold "shouldn't" be too 699 // big, so it's probably some other, more subtle problem. In practice 700 // it seems to always mean that the remote process died while the binder 701 // transaction was already in flight. 702 exceptionToThrow = (canThrowRemoteException) 703 ? "android/os/DeadObjectException" 704 : "java/lang/RuntimeException"; 705 snprintf(msg, sizeof(msg)-1, 706 "Transaction failed on small parcel; remote process probably died"); 707 } 708 jniThrowException(env, exceptionToThrow, msg); 709 } break; 710 case FDS_NOT_ALLOWED: 711 jniThrowException(env, "java/lang/RuntimeException", 712 "Not allowed to write file descriptors here"); 713 break; 714 case -EBADF: 715 jniThrowException(env, "java/lang/RuntimeException", 716 "Bad file descriptor"); 717 break; 718 case -ENFILE: 719 jniThrowException(env, "java/lang/RuntimeException", 720 "File table overflow"); 721 break; 722 case -EMFILE: 723 jniThrowException(env, "java/lang/RuntimeException", 724 "Too many open files"); 725 break; 726 case -EFBIG: 727 jniThrowException(env, "java/lang/RuntimeException", 728 "File too large"); 729 break; 730 case -ENOSPC: 731 jniThrowException(env, "java/lang/RuntimeException", 732 "No space left on device"); 733 break; 734 case -ESPIPE: 735 jniThrowException(env, "java/lang/RuntimeException", 736 "Illegal seek"); 737 break; 738 case -EROFS: 739 jniThrowException(env, "java/lang/RuntimeException", 740 "Read-only file system"); 741 break; 742 case -EMLINK: 743 jniThrowException(env, "java/lang/RuntimeException", 744 "Too many links"); 745 break; 746 default: 747 ALOGE("Unknown binder error code. 0x%" PRIx32, err); 748 String8 msg; 749 msg.appendFormat("Unknown binder error code. 0x%" PRIx32, err); 750 // RemoteException is a checked exception, only throw from certain methods. 751 jniThrowException(env, canThrowRemoteException 752 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string()); 753 break; 754 } 755 } 756 757 } 758 759 // ---------------------------------------------------------------------------- 760 761 static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz) 762 { 763 return IPCThreadState::self()->getCallingPid(); 764 } 765 766 static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz) 767 { 768 return IPCThreadState::self()->getCallingUid(); 769 } 770 771 static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz) 772 { 773 return IPCThreadState::self()->clearCallingIdentity(); 774 } 775 776 static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token) 777 { 778 // XXX temporary sanity check to debug crashes. 779 int uid = (int)(token>>32); 780 if (uid > 0 && uid < 999) { 781 // In Android currently there are no uids in this range. 782 char buf[128]; 783 sprintf(buf, "Restoring bad calling ident: 0x%" PRIx64, token); 784 jniThrowException(env, "java/lang/IllegalStateException", buf); 785 return; 786 } 787 IPCThreadState::self()->restoreCallingIdentity(token); 788 } 789 790 static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask) 791 { 792 IPCThreadState::self()->setStrictModePolicy(policyMask); 793 } 794 795 static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz) 796 { 797 return IPCThreadState::self()->getStrictModePolicy(); 798 } 799 800 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz) 801 { 802 IPCThreadState::self()->flushCommands(); 803 } 804 805 static void android_os_Binder_init(JNIEnv* env, jobject obj) 806 { 807 JavaBBinderHolder* jbh = new JavaBBinderHolder(); 808 if (jbh == NULL) { 809 jniThrowException(env, "java/lang/OutOfMemoryError", NULL); 810 return; 811 } 812 ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh); 813 jbh->incStrong((void*)android_os_Binder_init); 814 env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh); 815 } 816 817 static void android_os_Binder_destroy(JNIEnv* env, jobject obj) 818 { 819 JavaBBinderHolder* jbh = (JavaBBinderHolder*) 820 env->GetLongField(obj, gBinderOffsets.mObject); 821 if (jbh != NULL) { 822 env->SetLongField(obj, gBinderOffsets.mObject, 0); 823 ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh); 824 jbh->decStrong((void*)android_os_Binder_init); 825 } else { 826 // Encountering an uninitialized binder is harmless. All it means is that 827 // the Binder was only partially initialized when its finalizer ran and called 828 // destroy(). The Binder could be partially initialized for several reasons. 829 // For example, a Binder subclass constructor might have thrown an exception before 830 // it could delegate to its superclass's constructor. Consequently init() would 831 // not have been called and the holder pointer would remain NULL. 832 ALOGV("Java Binder %p: ignoring uninitialized binder", obj); 833 } 834 } 835 836 static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz) 837 { 838 return IPCThreadState::self()->blockUntilThreadAvailable(); 839 } 840 841 // ---------------------------------------------------------------------------- 842 843 static const JNINativeMethod gBinderMethods[] = { 844 /* name, signature, funcPtr */ 845 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid }, 846 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid }, 847 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity }, 848 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity }, 849 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy }, 850 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy }, 851 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands }, 852 { "init", "()V", (void*)android_os_Binder_init }, 853 { "destroy", "()V", (void*)android_os_Binder_destroy }, 854 { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable } 855 }; 856 857 const char* const kBinderPathName = "android/os/Binder"; 858 859 static int int_register_android_os_Binder(JNIEnv* env) 860 { 861 jclass clazz = FindClassOrDie(env, kBinderPathName); 862 863 gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 864 gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z"); 865 gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J"); 866 867 return RegisterMethodsOrDie( 868 env, kBinderPathName, 869 gBinderMethods, NELEM(gBinderMethods)); 870 } 871 872 // **************************************************************************** 873 // **************************************************************************** 874 // **************************************************************************** 875 876 namespace android { 877 878 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz) 879 { 880 return gNumLocalRefs; 881 } 882 883 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz) 884 { 885 return gNumProxyRefs; 886 } 887 888 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz) 889 { 890 return gNumDeathRefs; 891 } 892 893 } 894 895 // **************************************************************************** 896 // **************************************************************************** 897 // **************************************************************************** 898 899 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) 900 { 901 sp<IBinder> b = ProcessState::self()->getContextObject(NULL); 902 return javaObjectForIBinder(env, b); 903 } 904 905 static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz) 906 { 907 sp<IBinder> b = ProcessState::self()->getContextObject(NULL); 908 android::IPCThreadState::self()->joinThreadPool(); 909 } 910 911 static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env, 912 jobject clazz, jboolean disable) 913 { 914 IPCThreadState::disableBackgroundScheduling(disable ? true : false); 915 } 916 917 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz) 918 { 919 ALOGV("Gc has executed, clearing binder ops"); 920 android_atomic_and(0, &gNumRefsCreated); 921 } 922 923 // ---------------------------------------------------------------------------- 924 925 static const JNINativeMethod gBinderInternalMethods[] = { 926 /* name, signature, funcPtr */ 927 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject }, 928 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool }, 929 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling }, 930 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc } 931 }; 932 933 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal"; 934 935 static int int_register_android_os_BinderInternal(JNIEnv* env) 936 { 937 jclass clazz = FindClassOrDie(env, kBinderInternalPathName); 938 939 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 940 gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V"); 941 942 return RegisterMethodsOrDie( 943 env, kBinderInternalPathName, 944 gBinderInternalMethods, NELEM(gBinderInternalMethods)); 945 } 946 947 // **************************************************************************** 948 // **************************************************************************** 949 // **************************************************************************** 950 951 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj) 952 { 953 IBinder* target = (IBinder*) 954 env->GetLongField(obj, gBinderProxyOffsets.mObject); 955 if (target == NULL) { 956 return JNI_FALSE; 957 } 958 status_t err = target->pingBinder(); 959 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE; 960 } 961 962 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj) 963 { 964 IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); 965 if (target != NULL) { 966 const String16& desc = target->getInterfaceDescriptor(); 967 return env->NewString(reinterpret_cast<const jchar*>(desc.string()), 968 desc.size()); 969 } 970 jniThrowException(env, "java/lang/RuntimeException", 971 "No binder found for object"); 972 return NULL; 973 } 974 975 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj) 976 { 977 IBinder* target = (IBinder*) 978 env->GetLongField(obj, gBinderProxyOffsets.mObject); 979 if (target == NULL) { 980 return JNI_FALSE; 981 } 982 bool alive = target->isBinderAlive(); 983 return alive ? JNI_TRUE : JNI_FALSE; 984 } 985 986 static int getprocname(pid_t pid, char *buf, size_t len) { 987 char filename[32]; 988 FILE *f; 989 990 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid); 991 f = fopen(filename, "r"); 992 if (!f) { 993 *buf = '\0'; 994 return 1; 995 } 996 if (!fgets(buf, len, f)) { 997 *buf = '\0'; 998 fclose(f); 999 return 2; 1000 } 1001 fclose(f); 1002 return 0; 1003 } 1004 1005 static bool push_eventlog_string(char** pos, const char* end, const char* str) { 1006 jint len = strlen(str); 1007 int space_needed = 1 + sizeof(len) + len; 1008 if (end - *pos < space_needed) { 1009 ALOGW("not enough space for string. remain=%" PRIdPTR "; needed=%d", 1010 end - *pos, space_needed); 1011 return false; 1012 } 1013 **pos = EVENT_TYPE_STRING; 1014 (*pos)++; 1015 memcpy(*pos, &len, sizeof(len)); 1016 *pos += sizeof(len); 1017 memcpy(*pos, str, len); 1018 *pos += len; 1019 return true; 1020 } 1021 1022 static bool push_eventlog_int(char** pos, const char* end, jint val) { 1023 int space_needed = 1 + sizeof(val); 1024 if (end - *pos < space_needed) { 1025 ALOGW("not enough space for int. remain=%" PRIdPTR "; needed=%d", 1026 end - *pos, space_needed); 1027 return false; 1028 } 1029 **pos = EVENT_TYPE_INT; 1030 (*pos)++; 1031 memcpy(*pos, &val, sizeof(val)); 1032 *pos += sizeof(val); 1033 return true; 1034 } 1035 1036 // From frameworks/base/core/java/android/content/EventLogTags.logtags: 1037 1038 static const bool kEnableBinderSample = false; 1039 1040 #define LOGTAG_BINDER_OPERATION 52004 1041 1042 static void conditionally_log_binder_call(int64_t start_millis, 1043 IBinder* target, jint code) { 1044 int duration_ms = static_cast<int>(uptimeMillis() - start_millis); 1045 1046 int sample_percent; 1047 if (duration_ms >= 500) { 1048 sample_percent = 100; 1049 } else { 1050 sample_percent = 100 * duration_ms / 500; 1051 if (sample_percent == 0) { 1052 return; 1053 } 1054 if (sample_percent < (random() % 100 + 1)) { 1055 return; 1056 } 1057 } 1058 1059 char process_name[40]; 1060 getprocname(getpid(), process_name, sizeof(process_name)); 1061 String8 desc(target->getInterfaceDescriptor()); 1062 1063 char buf[LOGGER_ENTRY_MAX_PAYLOAD]; 1064 buf[0] = EVENT_TYPE_LIST; 1065 buf[1] = 5; 1066 char* pos = &buf[2]; 1067 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n 1068 if (!push_eventlog_string(&pos, end, desc.string())) return; 1069 if (!push_eventlog_int(&pos, end, code)) return; 1070 if (!push_eventlog_int(&pos, end, duration_ms)) return; 1071 if (!push_eventlog_string(&pos, end, process_name)) return; 1072 if (!push_eventlog_int(&pos, end, sample_percent)) return; 1073 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently. 1074 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf); 1075 } 1076 1077 // We only measure binder call durations to potentially log them if 1078 // we're on the main thread. 1079 static bool should_time_binder_calls() { 1080 return (getpid() == gettid()); 1081 } 1082 1083 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, 1084 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException 1085 { 1086 if (dataObj == NULL) { 1087 jniThrowNullPointerException(env, NULL); 1088 return JNI_FALSE; 1089 } 1090 1091 Parcel* data = parcelForJavaObject(env, dataObj); 1092 if (data == NULL) { 1093 return JNI_FALSE; 1094 } 1095 Parcel* reply = parcelForJavaObject(env, replyObj); 1096 if (reply == NULL && replyObj != NULL) { 1097 return JNI_FALSE; 1098 } 1099 1100 IBinder* target = (IBinder*) 1101 env->GetLongField(obj, gBinderProxyOffsets.mObject); 1102 if (target == NULL) { 1103 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); 1104 return JNI_FALSE; 1105 } 1106 1107 ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n", 1108 target, obj, code); 1109 1110 1111 bool time_binder_calls; 1112 int64_t start_millis; 1113 if (kEnableBinderSample) { 1114 // Only log the binder call duration for things on the Java-level main thread. 1115 // But if we don't 1116 time_binder_calls = should_time_binder_calls(); 1117 1118 if (time_binder_calls) { 1119 start_millis = uptimeMillis(); 1120 } 1121 } 1122 1123 //printf("Transact from Java code to %p sending: ", target); data->print(); 1124 status_t err = target->transact(code, *data, reply, flags); 1125 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); 1126 1127 if (kEnableBinderSample) { 1128 if (time_binder_calls) { 1129 conditionally_log_binder_call(start_millis, target, code); 1130 } 1131 } 1132 1133 if (err == NO_ERROR) { 1134 return JNI_TRUE; 1135 } else if (err == UNKNOWN_TRANSACTION) { 1136 return JNI_FALSE; 1137 } 1138 1139 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize()); 1140 return JNI_FALSE; 1141 } 1142 1143 static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, 1144 jobject recipient, jint flags) // throws RemoteException 1145 { 1146 if (recipient == NULL) { 1147 jniThrowNullPointerException(env, NULL); 1148 return; 1149 } 1150 1151 IBinder* target = (IBinder*) 1152 env->GetLongField(obj, gBinderProxyOffsets.mObject); 1153 if (target == NULL) { 1154 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); 1155 assert(false); 1156 } 1157 1158 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient); 1159 1160 if (!target->localBinder()) { 1161 DeathRecipientList* list = (DeathRecipientList*) 1162 env->GetLongField(obj, gBinderProxyOffsets.mOrgue); 1163 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list); 1164 status_t err = target->linkToDeath(jdr, NULL, flags); 1165 if (err != NO_ERROR) { 1166 // Failure adding the death recipient, so clear its reference 1167 // now. 1168 jdr->clearReference(); 1169 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); 1170 } 1171 } 1172 } 1173 1174 static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, 1175 jobject recipient, jint flags) 1176 { 1177 jboolean res = JNI_FALSE; 1178 if (recipient == NULL) { 1179 jniThrowNullPointerException(env, NULL); 1180 return res; 1181 } 1182 1183 IBinder* target = (IBinder*) 1184 env->GetLongField(obj, gBinderProxyOffsets.mObject); 1185 if (target == NULL) { 1186 ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); 1187 return JNI_FALSE; 1188 } 1189 1190 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient); 1191 1192 if (!target->localBinder()) { 1193 status_t err = NAME_NOT_FOUND; 1194 1195 // If we find the matching recipient, proceed to unlink using that 1196 DeathRecipientList* list = (DeathRecipientList*) 1197 env->GetLongField(obj, gBinderProxyOffsets.mOrgue); 1198 sp<JavaDeathRecipient> origJDR = list->find(recipient); 1199 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get()); 1200 if (origJDR != NULL) { 1201 wp<IBinder::DeathRecipient> dr; 1202 err = target->unlinkToDeath(origJDR, NULL, flags, &dr); 1203 if (err == NO_ERROR && dr != NULL) { 1204 sp<IBinder::DeathRecipient> sdr = dr.promote(); 1205 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get()); 1206 if (jdr != NULL) { 1207 jdr->clearReference(); 1208 } 1209 } 1210 } 1211 1212 if (err == NO_ERROR || err == DEAD_OBJECT) { 1213 res = JNI_TRUE; 1214 } else { 1215 jniThrowException(env, "java/util/NoSuchElementException", 1216 "Death link does not exist"); 1217 } 1218 } 1219 1220 return res; 1221 } 1222 1223 static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj) 1224 { 1225 IBinder* b = (IBinder*) 1226 env->GetLongField(obj, gBinderProxyOffsets.mObject); 1227 DeathRecipientList* drl = (DeathRecipientList*) 1228 env->GetLongField(obj, gBinderProxyOffsets.mOrgue); 1229 1230 LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl); 1231 env->SetLongField(obj, gBinderProxyOffsets.mObject, 0); 1232 env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0); 1233 drl->decStrong((void*)javaObjectForIBinder); 1234 b->decStrong((void*)javaObjectForIBinder); 1235 1236 IPCThreadState::self()->flushCommands(); 1237 } 1238 1239 // ---------------------------------------------------------------------------- 1240 1241 static const JNINativeMethod gBinderProxyMethods[] = { 1242 /* name, signature, funcPtr */ 1243 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder}, 1244 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive}, 1245 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor}, 1246 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact}, 1247 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath}, 1248 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath}, 1249 {"destroy", "()V", (void*)android_os_BinderProxy_destroy}, 1250 }; 1251 1252 const char* const kBinderProxyPathName = "android/os/BinderProxy"; 1253 1254 static int int_register_android_os_BinderProxy(JNIEnv* env) 1255 { 1256 jclass clazz = FindClassOrDie(env, "java/lang/Error"); 1257 gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 1258 1259 clazz = FindClassOrDie(env, kBinderProxyPathName); 1260 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 1261 gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V"); 1262 gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice", 1263 "(Landroid/os/IBinder$DeathRecipient;)V"); 1264 1265 gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J"); 1266 gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf", 1267 "Ljava/lang/ref/WeakReference;"); 1268 gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J"); 1269 1270 clazz = FindClassOrDie(env, "java/lang/Class"); 1271 gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;"); 1272 1273 return RegisterMethodsOrDie( 1274 env, kBinderProxyPathName, 1275 gBinderProxyMethods, NELEM(gBinderProxyMethods)); 1276 } 1277 1278 // **************************************************************************** 1279 // **************************************************************************** 1280 // **************************************************************************** 1281 1282 int register_android_os_Binder(JNIEnv* env) 1283 { 1284 if (int_register_android_os_Binder(env) < 0) 1285 return -1; 1286 if (int_register_android_os_BinderInternal(env) < 0) 1287 return -1; 1288 if (int_register_android_os_BinderProxy(env) < 0) 1289 return -1; 1290 1291 jclass clazz = FindClassOrDie(env, "android/util/Log"); 1292 gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 1293 gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e", 1294 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I"); 1295 1296 clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor"); 1297 gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 1298 gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", 1299 "(Ljava/io/FileDescriptor;)V"); 1300 1301 clazz = FindClassOrDie(env, "android/os/StrictMode"); 1302 gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 1303 gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz, 1304 "onBinderStrictModePolicyChange", "(I)V"); 1305 1306 return 0; 1307 } 1308