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