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_util_Binder.h" 21 #include "JNIHelp.h" 22 23 #include <fcntl.h> 24 #include <stdio.h> 25 #include <sys/stat.h> 26 #include <sys/types.h> 27 #include <unistd.h> 28 29 #include <utils/Atomic.h> 30 #include <binder/IInterface.h> 31 #include <binder/IPCThreadState.h> 32 #include <utils/Log.h> 33 #include <utils/SystemClock.h> 34 #include <utils/List.h> 35 #include <utils/KeyedVector.h> 36 #include <cutils/logger.h> 37 #include <binder/Parcel.h> 38 #include <binder/ProcessState.h> 39 #include <binder/IServiceManager.h> 40 #include <utils/threads.h> 41 #include <utils/String8.h> 42 43 #include <ScopedUtfChars.h> 44 #include <ScopedLocalRef.h> 45 46 #include <android_runtime/AndroidRuntime.h> 47 48 //#undef LOGV 49 //#define LOGV(...) fprintf(stderr, __VA_ARGS__) 50 51 #define DEBUG_DEATH 0 52 #if DEBUG_DEATH 53 #define LOGDEATH LOGD 54 #else 55 #define LOGDEATH LOGV 56 #endif 57 58 using namespace android; 59 60 // ---------------------------------------------------------------------------- 61 62 static struct bindernative_offsets_t 63 { 64 // Class state. 65 jclass mClass; 66 jmethodID mExecTransact; 67 68 // Object state. 69 jfieldID mObject; 70 71 } gBinderOffsets; 72 73 // ---------------------------------------------------------------------------- 74 75 static struct binderinternal_offsets_t 76 { 77 // Class state. 78 jclass mClass; 79 jmethodID mForceGc; 80 81 } gBinderInternalOffsets; 82 83 // ---------------------------------------------------------------------------- 84 85 static struct debug_offsets_t 86 { 87 // Class state. 88 jclass mClass; 89 90 } gDebugOffsets; 91 92 // ---------------------------------------------------------------------------- 93 94 static struct weakreference_offsets_t 95 { 96 // Class state. 97 jclass mClass; 98 jmethodID mGet; 99 100 } gWeakReferenceOffsets; 101 102 static struct error_offsets_t 103 { 104 jclass mClass; 105 } gErrorOffsets; 106 107 // ---------------------------------------------------------------------------- 108 109 static struct binderproxy_offsets_t 110 { 111 // Class state. 112 jclass mClass; 113 jmethodID mConstructor; 114 jmethodID mSendDeathNotice; 115 116 // Object state. 117 jfieldID mObject; 118 jfieldID mSelf; 119 jfieldID mOrgue; 120 121 } gBinderProxyOffsets; 122 123 static struct class_offsets_t 124 { 125 jmethodID mGetName; 126 } gClassOffsets; 127 128 // ---------------------------------------------------------------------------- 129 130 static struct parcel_offsets_t 131 { 132 jfieldID mObject; 133 jfieldID mOwnObject; 134 } gParcelOffsets; 135 136 static struct log_offsets_t 137 { 138 // Class state. 139 jclass mClass; 140 jmethodID mLogE; 141 } gLogOffsets; 142 143 static struct parcel_file_descriptor_offsets_t 144 { 145 jclass mClass; 146 jmethodID mConstructor; 147 } gParcelFileDescriptorOffsets; 148 149 static struct strict_mode_callback_offsets_t 150 { 151 jclass mClass; 152 jmethodID mCallback; 153 } gStrictModeCallbackOffsets; 154 155 // **************************************************************************** 156 // **************************************************************************** 157 // **************************************************************************** 158 159 static volatile int32_t gNumRefsCreated = 0; 160 static volatile int32_t gNumProxyRefs = 0; 161 static volatile int32_t gNumLocalRefs = 0; 162 static volatile int32_t gNumDeathRefs = 0; 163 164 static void incRefsCreated(JNIEnv* env) 165 { 166 int old = android_atomic_inc(&gNumRefsCreated); 167 if (old == 200) { 168 android_atomic_and(0, &gNumRefsCreated); 169 env->CallStaticVoidMethod(gBinderInternalOffsets.mClass, 170 gBinderInternalOffsets.mForceGc); 171 } else { 172 LOGV("Now have %d binder ops", old); 173 } 174 } 175 176 static JavaVM* jnienv_to_javavm(JNIEnv* env) 177 { 178 JavaVM* vm; 179 return env->GetJavaVM(&vm) >= 0 ? vm : NULL; 180 } 181 182 static JNIEnv* javavm_to_jnienv(JavaVM* vm) 183 { 184 JNIEnv* env; 185 return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; 186 } 187 188 static void report_exception(JNIEnv* env, jthrowable excep, const char* msg) 189 { 190 env->ExceptionClear(); 191 192 jstring tagstr = env->NewStringUTF(LOG_TAG); 193 jstring msgstr = env->NewStringUTF(msg); 194 195 if ((tagstr == NULL) || (msgstr == NULL)) { 196 env->ExceptionClear(); /* assume exception (OOM?) was thrown */ 197 LOGE("Unable to call Log.e()\n"); 198 LOGE("%s", msg); 199 goto bail; 200 } 201 202 env->CallStaticIntMethod( 203 gLogOffsets.mClass, gLogOffsets.mLogE, tagstr, msgstr, excep); 204 if (env->ExceptionCheck()) { 205 /* attempting to log the failure has failed */ 206 LOGW("Failed trying to log exception, msg='%s'\n", msg); 207 env->ExceptionClear(); 208 } 209 210 if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) { 211 /* 212 * It's an Error: Reraise the exception, detach this thread, and 213 * wait for the fireworks. Die even more blatantly after a minute 214 * if the gentler attempt doesn't do the trick. 215 * 216 * The GetJavaVM function isn't on the "approved" list of JNI calls 217 * that can be made while an exception is pending, so we want to 218 * get the VM ptr, throw the exception, and then detach the thread. 219 */ 220 JavaVM* vm = jnienv_to_javavm(env); 221 env->Throw(excep); 222 vm->DetachCurrentThread(); 223 sleep(60); 224 LOGE("Forcefully exiting"); 225 exit(1); 226 *((int *) 1) = 1; 227 } 228 229 bail: 230 /* discard local refs created for us by VM */ 231 env->DeleteLocalRef(tagstr); 232 env->DeleteLocalRef(msgstr); 233 } 234 235 static void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy) 236 { 237 // Call back into android.os.StrictMode#onBinderStrictModePolicyChange 238 // to sync our state back to it. See the comments in StrictMode.java. 239 env->CallStaticVoidMethod(gStrictModeCallbackOffsets.mClass, 240 gStrictModeCallbackOffsets.mCallback, 241 strict_policy); 242 } 243 244 class JavaBBinderHolder; 245 246 class JavaBBinder : public BBinder 247 { 248 public: 249 JavaBBinder(JNIEnv* env, jobject object) 250 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)) 251 { 252 LOGV("Creating JavaBBinder %p\n", this); 253 android_atomic_inc(&gNumLocalRefs); 254 incRefsCreated(env); 255 } 256 257 bool checkSubclass(const void* subclassID) const 258 { 259 return subclassID == &gBinderOffsets; 260 } 261 262 jobject object() const 263 { 264 return mObject; 265 } 266 267 protected: 268 virtual ~JavaBBinder() 269 { 270 LOGV("Destroying JavaBBinder %p\n", this); 271 android_atomic_dec(&gNumLocalRefs); 272 JNIEnv* env = javavm_to_jnienv(mVM); 273 env->DeleteGlobalRef(mObject); 274 } 275 276 virtual status_t onTransact( 277 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) 278 { 279 JNIEnv* env = javavm_to_jnienv(mVM); 280 281 LOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM); 282 283 IPCThreadState* thread_state = IPCThreadState::self(); 284 const int strict_policy_before = thread_state->getStrictModePolicy(); 285 thread_state->setLastTransactionBinderFlags(flags); 286 287 //printf("Transact from %p to Java code sending: ", this); 288 //data.print(); 289 //printf("\n"); 290 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, 291 code, (int32_t)&data, (int32_t)reply, flags); 292 jthrowable excep = env->ExceptionOccurred(); 293 294 if (excep) { 295 report_exception(env, excep, 296 "*** Uncaught remote exception! " 297 "(Exceptions are not yet supported across processes.)"); 298 res = JNI_FALSE; 299 300 /* clean up JNI local ref -- we don't return to Java code */ 301 env->DeleteLocalRef(excep); 302 } 303 304 // Restore the Java binder thread's state if it changed while 305 // processing a call (as it would if the Parcel's header had a 306 // new policy mask and Parcel.enforceInterface() changed 307 // it...) 308 const int strict_policy_after = thread_state->getStrictModePolicy(); 309 if (strict_policy_after != strict_policy_before) { 310 // Our thread-local... 311 thread_state->setStrictModePolicy(strict_policy_before); 312 // And the Java-level thread-local... 313 set_dalvik_blockguard_policy(env, strict_policy_before); 314 } 315 316 jthrowable excep2 = env->ExceptionOccurred(); 317 if (excep2) { 318 report_exception(env, excep2, 319 "*** Uncaught exception in onBinderStrictModePolicyChange"); 320 /* clean up JNI local ref -- we don't return to Java code */ 321 env->DeleteLocalRef(excep2); 322 } 323 324 //aout << "onTransact to Java code; result=" << res << endl 325 // << "Transact from " << this << " to Java code returning " 326 // << reply << ": " << *reply << endl; 327 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; 328 } 329 330 virtual status_t dump(int fd, const Vector<String16>& args) 331 { 332 return 0; 333 } 334 335 private: 336 JavaVM* const mVM; 337 jobject const mObject; 338 }; 339 340 // ---------------------------------------------------------------------------- 341 342 class JavaBBinderHolder : public RefBase 343 { 344 public: 345 sp<JavaBBinder> get(JNIEnv* env, jobject obj) 346 { 347 AutoMutex _l(mLock); 348 sp<JavaBBinder> b = mBinder.promote(); 349 if (b == NULL) { 350 b = new JavaBBinder(env, obj); 351 mBinder = b; 352 LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n", 353 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount()); 354 } 355 356 return b; 357 } 358 359 sp<JavaBBinder> getExisting() 360 { 361 AutoMutex _l(mLock); 362 return mBinder.promote(); 363 } 364 365 private: 366 Mutex mLock; 367 wp<JavaBBinder> mBinder; 368 }; 369 370 // ---------------------------------------------------------------------------- 371 372 // Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject 373 // death recipient references passed in through JNI with the permanent corresponding 374 // JavaDeathRecipient objects. 375 376 class JavaDeathRecipient; 377 378 class DeathRecipientList : public RefBase { 379 List< sp<JavaDeathRecipient> > mList; 380 Mutex mLock; 381 382 public: 383 DeathRecipientList(); 384 ~DeathRecipientList(); 385 386 void add(const sp<JavaDeathRecipient>& recipient); 387 void remove(const sp<JavaDeathRecipient>& recipient); 388 sp<JavaDeathRecipient> find(jobject recipient); 389 }; 390 391 // ---------------------------------------------------------------------------- 392 393 class JavaDeathRecipient : public IBinder::DeathRecipient 394 { 395 public: 396 JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list) 397 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), 398 mObjectWeak(NULL), mList(list) 399 { 400 // These objects manage their own lifetimes so are responsible for final bookkeeping. 401 // The list holds a strong reference to this object. 402 LOGDEATH("Adding JDR %p to DRL %p", this, list.get()); 403 list->add(this); 404 405 android_atomic_inc(&gNumDeathRefs); 406 incRefsCreated(env); 407 } 408 409 void binderDied(const wp<IBinder>& who) 410 { 411 LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this); 412 if (mObject != NULL) { 413 JNIEnv* env = javavm_to_jnienv(mVM); 414 415 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass, 416 gBinderProxyOffsets.mSendDeathNotice, mObject); 417 jthrowable excep = env->ExceptionOccurred(); 418 if (excep) { 419 report_exception(env, excep, 420 "*** Uncaught exception returned from death notification!"); 421 } 422 423 // Demote from strong ref to weak after binderDied() has been delivered, 424 // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed. 425 mObjectWeak = env->NewWeakGlobalRef(mObject); 426 env->DeleteGlobalRef(mObject); 427 mObject = NULL; 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 LOGW("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 LOGW("BinderProxy being destroyed; unable to get DR object name"); 471 env->ExceptionClear(); 472 } 473 } 474 } 475 476 protected: 477 virtual ~JavaDeathRecipient() 478 { 479 //LOGI("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 489 private: 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 498 DeathRecipientList::DeathRecipientList() { 499 LOGDEATH("New DRL @ %p", this); 500 } 501 502 DeathRecipientList::~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 517 void 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 524 void 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 537 sp<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 549 // ---------------------------------------------------------------------------- 550 551 namespace android { 552 553 static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie) 554 { 555 android_atomic_dec(&gNumProxyRefs); 556 JNIEnv* env = javavm_to_jnienv((JavaVM*)cleanupCookie); 557 env->DeleteGlobalRef((jobject)obj); 558 } 559 560 static Mutex mProxyLock; 561 562 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) 563 { 564 if (val == NULL) return NULL; 565 566 if (val->checkSubclass(&gBinderOffsets)) { 567 // One of our own! 568 jobject object = static_cast<JavaBBinder*>(val.get())->object(); 569 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object); 570 return object; 571 } 572 573 // For the rest of the function we will hold this lock, to serialize 574 // looking/creation of Java proxies for native Binder proxies. 575 AutoMutex _l(mProxyLock); 576 577 // Someone else's... do we know about it? 578 jobject object = (jobject)val->findObject(&gBinderProxyOffsets); 579 if (object != NULL) { 580 jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet); 581 if (res != NULL) { 582 LOGV("objectForBinder %p: found existing %p!\n", val.get(), res); 583 return res; 584 } 585 LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get()); 586 android_atomic_dec(&gNumProxyRefs); 587 val->detachObject(&gBinderProxyOffsets); 588 env->DeleteGlobalRef(object); 589 } 590 591 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); 592 if (object != NULL) { 593 LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object); 594 // The proxy holds a reference to the native object. 595 env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); 596 val->incStrong(object); 597 598 // The native object needs to hold a weak reference back to the 599 // proxy, so we can retrieve the same proxy if it is still active. 600 jobject refObject = env->NewGlobalRef( 601 env->GetObjectField(object, gBinderProxyOffsets.mSelf)); 602 val->attachObject(&gBinderProxyOffsets, refObject, 603 jnienv_to_javavm(env), proxy_cleanup); 604 605 // Also remember the death recipients registered on this proxy 606 sp<DeathRecipientList> drl = new DeathRecipientList; 607 drl->incStrong((void*)javaObjectForIBinder); 608 env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get())); 609 610 // Note that a new object reference has been created. 611 android_atomic_inc(&gNumProxyRefs); 612 incRefsCreated(env); 613 } 614 615 return object; 616 } 617 618 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) 619 { 620 if (obj == NULL) return NULL; 621 622 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { 623 JavaBBinderHolder* jbh = (JavaBBinderHolder*) 624 env->GetIntField(obj, gBinderOffsets.mObject); 625 return jbh != NULL ? jbh->get(env, obj) : NULL; 626 } 627 628 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { 629 return (IBinder*) 630 env->GetIntField(obj, gBinderProxyOffsets.mObject); 631 } 632 633 LOGW("ibinderForJavaObject: %p is not a Binder object", obj); 634 return NULL; 635 } 636 637 Parcel* parcelForJavaObject(JNIEnv* env, jobject obj) 638 { 639 if (obj) { 640 Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mObject); 641 if (p != NULL) { 642 return p; 643 } 644 jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!"); 645 } 646 return NULL; 647 } 648 649 jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc) 650 { 651 return env->NewObject( 652 gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc); 653 } 654 655 static void signalExceptionForError(JNIEnv* env, jobject obj, status_t err, 656 bool canThrowRemoteException = false) 657 { 658 switch (err) { 659 case UNKNOWN_ERROR: 660 jniThrowException(env, "java/lang/RuntimeException", "Unknown error"); 661 break; 662 case NO_MEMORY: 663 jniThrowException(env, "java/lang/OutOfMemoryError", NULL); 664 break; 665 case INVALID_OPERATION: 666 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL); 667 break; 668 case BAD_VALUE: 669 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 670 break; 671 case BAD_INDEX: 672 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL); 673 break; 674 case BAD_TYPE: 675 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 676 break; 677 case NAME_NOT_FOUND: 678 jniThrowException(env, "java/util/NoSuchElementException", NULL); 679 break; 680 case PERMISSION_DENIED: 681 jniThrowException(env, "java/lang/SecurityException", NULL); 682 break; 683 case NOT_ENOUGH_DATA: 684 jniThrowException(env, "android/os/ParcelFormatException", "Not enough data"); 685 break; 686 case NO_INIT: 687 jniThrowException(env, "java/lang/RuntimeException", "Not initialized"); 688 break; 689 case ALREADY_EXISTS: 690 jniThrowException(env, "java/lang/RuntimeException", "Item already exists"); 691 break; 692 case DEAD_OBJECT: 693 // DeadObjectException is a checked exception, only throw from certain methods. 694 jniThrowException(env, canThrowRemoteException 695 ? "android/os/DeadObjectException" 696 : "java/lang/RuntimeException", NULL); 697 break; 698 case UNKNOWN_TRANSACTION: 699 jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code"); 700 break; 701 case FAILED_TRANSACTION: 702 LOGE("!!! FAILED BINDER TRANSACTION !!!"); 703 // TransactionTooLargeException is a checked exception, only throw from certain methods. 704 // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION 705 // but it is not the only one. The Binder driver can return BR_FAILED_REPLY 706 // for other reasons also, such as if the transaction is malformed or 707 // refers to an FD that has been closed. We should change the driver 708 // to enable us to distinguish these cases in the future. 709 jniThrowException(env, canThrowRemoteException 710 ? "android/os/TransactionTooLargeException" 711 : "java/lang/RuntimeException", NULL); 712 break; 713 case FDS_NOT_ALLOWED: 714 jniThrowException(env, "java/lang/RuntimeException", 715 "Not allowed to write file descriptors here"); 716 break; 717 default: 718 LOGE("Unknown binder error code. 0x%x", err); 719 String8 msg; 720 msg.appendFormat("Unknown binder error code. 0x%x", err); 721 // RemoteException is a checked exception, only throw from certain methods. 722 jniThrowException(env, canThrowRemoteException 723 ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string()); 724 break; 725 } 726 } 727 728 } 729 730 // ---------------------------------------------------------------------------- 731 732 static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz) 733 { 734 return IPCThreadState::self()->getCallingPid(); 735 } 736 737 static jint android_os_Binder_getCallingUid(JNIEnv* env, jobject clazz) 738 { 739 return IPCThreadState::self()->getCallingUid(); 740 } 741 742 static jlong android_os_Binder_clearCallingIdentity(JNIEnv* env, jobject clazz) 743 { 744 return IPCThreadState::self()->clearCallingIdentity(); 745 } 746 747 static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token) 748 { 749 // XXX temporary sanity check to debug crashes. 750 int uid = (int)(token>>32); 751 if (uid > 0 && uid < 999) { 752 // In Android currently there are no uids in this range. 753 char buf[128]; 754 sprintf(buf, "Restoring bad calling ident: 0x%Lx", token); 755 jniThrowException(env, "java/lang/IllegalStateException", buf); 756 return; 757 } 758 IPCThreadState::self()->restoreCallingIdentity(token); 759 } 760 761 static void android_os_Binder_setThreadStrictModePolicy(JNIEnv* env, jobject clazz, jint policyMask) 762 { 763 IPCThreadState::self()->setStrictModePolicy(policyMask); 764 } 765 766 static jint android_os_Binder_getThreadStrictModePolicy(JNIEnv* env, jobject clazz) 767 { 768 return IPCThreadState::self()->getStrictModePolicy(); 769 } 770 771 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz) 772 { 773 IPCThreadState::self()->flushCommands(); 774 } 775 776 static void android_os_Binder_init(JNIEnv* env, jobject obj) 777 { 778 JavaBBinderHolder* jbh = new JavaBBinderHolder(); 779 if (jbh == NULL) { 780 jniThrowException(env, "java/lang/OutOfMemoryError", NULL); 781 return; 782 } 783 LOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh); 784 jbh->incStrong((void*)android_os_Binder_init); 785 env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh); 786 } 787 788 static void android_os_Binder_destroy(JNIEnv* env, jobject obj) 789 { 790 JavaBBinderHolder* jbh = (JavaBBinderHolder*) 791 env->GetIntField(obj, gBinderOffsets.mObject); 792 if (jbh != NULL) { 793 env->SetIntField(obj, gBinderOffsets.mObject, 0); 794 LOGV("Java Binder %p: removing ref on holder %p", obj, jbh); 795 jbh->decStrong((void*)android_os_Binder_init); 796 } else { 797 // Encountering an uninitialized binder is harmless. All it means is that 798 // the Binder was only partially initialized when its finalizer ran and called 799 // destroy(). The Binder could be partially initialized for several reasons. 800 // For example, a Binder subclass constructor might have thrown an exception before 801 // it could delegate to its superclass's constructor. Consequently init() would 802 // not have been called and the holder pointer would remain NULL. 803 LOGV("Java Binder %p: ignoring uninitialized binder", obj); 804 } 805 } 806 807 // ---------------------------------------------------------------------------- 808 809 static const JNINativeMethod gBinderMethods[] = { 810 /* name, signature, funcPtr */ 811 { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid }, 812 { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid }, 813 { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity }, 814 { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity }, 815 { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy }, 816 { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy }, 817 { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands }, 818 { "init", "()V", (void*)android_os_Binder_init }, 819 { "destroy", "()V", (void*)android_os_Binder_destroy } 820 }; 821 822 const char* const kBinderPathName = "android/os/Binder"; 823 824 static int int_register_android_os_Binder(JNIEnv* env) 825 { 826 jclass clazz; 827 828 clazz = env->FindClass(kBinderPathName); 829 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder"); 830 831 gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 832 gBinderOffsets.mExecTransact 833 = env->GetMethodID(clazz, "execTransact", "(IIII)Z"); 834 assert(gBinderOffsets.mExecTransact); 835 836 gBinderOffsets.mObject 837 = env->GetFieldID(clazz, "mObject", "I"); 838 assert(gBinderOffsets.mObject); 839 840 return AndroidRuntime::registerNativeMethods( 841 env, kBinderPathName, 842 gBinderMethods, NELEM(gBinderMethods)); 843 } 844 845 // **************************************************************************** 846 // **************************************************************************** 847 // **************************************************************************** 848 849 namespace android { 850 851 jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz) 852 { 853 return gNumLocalRefs; 854 } 855 856 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz) 857 { 858 return gNumProxyRefs; 859 } 860 861 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz) 862 { 863 return gNumDeathRefs; 864 } 865 866 } 867 868 // **************************************************************************** 869 // **************************************************************************** 870 // **************************************************************************** 871 872 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) 873 { 874 sp<IBinder> b = ProcessState::self()->getContextObject(NULL); 875 return javaObjectForIBinder(env, b); 876 } 877 878 static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz) 879 { 880 sp<IBinder> b = ProcessState::self()->getContextObject(NULL); 881 android::IPCThreadState::self()->joinThreadPool(); 882 } 883 884 static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env, 885 jobject clazz, jboolean disable) 886 { 887 IPCThreadState::disableBackgroundScheduling(disable ? true : false); 888 } 889 890 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz) 891 { 892 LOGV("Gc has executed, clearing binder ops"); 893 android_atomic_and(0, &gNumRefsCreated); 894 } 895 896 // ---------------------------------------------------------------------------- 897 898 static const JNINativeMethod gBinderInternalMethods[] = { 899 /* name, signature, funcPtr */ 900 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject }, 901 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool }, 902 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling }, 903 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc } 904 }; 905 906 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal"; 907 908 static int int_register_android_os_BinderInternal(JNIEnv* env) 909 { 910 jclass clazz; 911 912 clazz = env->FindClass(kBinderInternalPathName); 913 LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal"); 914 915 gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 916 gBinderInternalOffsets.mForceGc 917 = env->GetStaticMethodID(clazz, "forceBinderGc", "()V"); 918 assert(gBinderInternalOffsets.mForceGc); 919 920 return AndroidRuntime::registerNativeMethods( 921 env, kBinderInternalPathName, 922 gBinderInternalMethods, NELEM(gBinderInternalMethods)); 923 } 924 925 // **************************************************************************** 926 // **************************************************************************** 927 // **************************************************************************** 928 929 static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj) 930 { 931 IBinder* target = (IBinder*) 932 env->GetIntField(obj, gBinderProxyOffsets.mObject); 933 if (target == NULL) { 934 return JNI_FALSE; 935 } 936 status_t err = target->pingBinder(); 937 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE; 938 } 939 940 static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj) 941 { 942 IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); 943 if (target != NULL) { 944 const String16& desc = target->getInterfaceDescriptor(); 945 return env->NewString(desc.string(), desc.size()); 946 } 947 jniThrowException(env, "java/lang/RuntimeException", 948 "No binder found for object"); 949 return NULL; 950 } 951 952 static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj) 953 { 954 IBinder* target = (IBinder*) 955 env->GetIntField(obj, gBinderProxyOffsets.mObject); 956 if (target == NULL) { 957 return JNI_FALSE; 958 } 959 bool alive = target->isBinderAlive(); 960 return alive ? JNI_TRUE : JNI_FALSE; 961 } 962 963 static int getprocname(pid_t pid, char *buf, size_t len) { 964 char filename[20]; 965 FILE *f; 966 967 sprintf(filename, "/proc/%d/cmdline", pid); 968 f = fopen(filename, "r"); 969 if (!f) { *buf = '\0'; return 1; } 970 if (!fgets(buf, len, f)) { *buf = '\0'; return 2; } 971 fclose(f); 972 return 0; 973 } 974 975 static bool push_eventlog_string(char** pos, const char* end, const char* str) { 976 jint len = strlen(str); 977 int space_needed = 1 + sizeof(len) + len; 978 if (end - *pos < space_needed) { 979 LOGW("not enough space for string. remain=%d; needed=%d", 980 (end - *pos), space_needed); 981 return false; 982 } 983 **pos = EVENT_TYPE_STRING; 984 (*pos)++; 985 memcpy(*pos, &len, sizeof(len)); 986 *pos += sizeof(len); 987 memcpy(*pos, str, len); 988 *pos += len; 989 return true; 990 } 991 992 static bool push_eventlog_int(char** pos, const char* end, jint val) { 993 int space_needed = 1 + sizeof(val); 994 if (end - *pos < space_needed) { 995 LOGW("not enough space for int. remain=%d; needed=%d", 996 (end - *pos), space_needed); 997 return false; 998 } 999 **pos = EVENT_TYPE_INT; 1000 (*pos)++; 1001 memcpy(*pos, &val, sizeof(val)); 1002 *pos += sizeof(val); 1003 return true; 1004 } 1005 1006 // From frameworks/base/core/java/android/content/EventLogTags.logtags: 1007 #define LOGTAG_BINDER_OPERATION 52004 1008 1009 static void conditionally_log_binder_call(int64_t start_millis, 1010 IBinder* target, jint code) { 1011 int duration_ms = static_cast<int>(uptimeMillis() - start_millis); 1012 1013 int sample_percent; 1014 if (duration_ms >= 500) { 1015 sample_percent = 100; 1016 } else { 1017 sample_percent = 100 * duration_ms / 500; 1018 if (sample_percent == 0) { 1019 return; 1020 } 1021 if (sample_percent < (random() % 100 + 1)) { 1022 return; 1023 } 1024 } 1025 1026 char process_name[40]; 1027 getprocname(getpid(), process_name, sizeof(process_name)); 1028 String8 desc(target->getInterfaceDescriptor()); 1029 1030 char buf[LOGGER_ENTRY_MAX_PAYLOAD]; 1031 buf[0] = EVENT_TYPE_LIST; 1032 buf[1] = 5; 1033 char* pos = &buf[2]; 1034 char* end = &buf[LOGGER_ENTRY_MAX_PAYLOAD - 1]; // leave room for final \n 1035 if (!push_eventlog_string(&pos, end, desc.string())) return; 1036 if (!push_eventlog_int(&pos, end, code)) return; 1037 if (!push_eventlog_int(&pos, end, duration_ms)) return; 1038 if (!push_eventlog_string(&pos, end, process_name)) return; 1039 if (!push_eventlog_int(&pos, end, sample_percent)) return; 1040 *(pos++) = '\n'; // conventional with EVENT_TYPE_LIST apparently. 1041 android_bWriteLog(LOGTAG_BINDER_OPERATION, buf, pos - buf); 1042 } 1043 1044 // We only measure binder call durations to potentially log them if 1045 // we're on the main thread. Unfortunately sim-eng doesn't seem to 1046 // have gettid, so we just ignore this and don't log if we can't 1047 // get the thread id. 1048 static bool should_time_binder_calls() { 1049 #ifdef HAVE_GETTID 1050 return (getpid() == androidGetTid()); 1051 #else 1052 #warning no gettid(), so not logging Binder calls... 1053 return false; 1054 #endif 1055 } 1056 1057 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, 1058 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException 1059 { 1060 if (dataObj == NULL) { 1061 jniThrowNullPointerException(env, NULL); 1062 return JNI_FALSE; 1063 } 1064 1065 Parcel* data = parcelForJavaObject(env, dataObj); 1066 if (data == NULL) { 1067 return JNI_FALSE; 1068 } 1069 Parcel* reply = parcelForJavaObject(env, replyObj); 1070 if (reply == NULL && replyObj != NULL) { 1071 return JNI_FALSE; 1072 } 1073 1074 IBinder* target = (IBinder*) 1075 env->GetIntField(obj, gBinderProxyOffsets.mObject); 1076 if (target == NULL) { 1077 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); 1078 return JNI_FALSE; 1079 } 1080 1081 LOGV("Java code calling transact on %p in Java object %p with code %d\n", 1082 target, obj, code); 1083 1084 // Only log the binder call duration for things on the Java-level main thread. 1085 // But if we don't 1086 const bool time_binder_calls = should_time_binder_calls(); 1087 1088 int64_t start_millis; 1089 if (time_binder_calls) { 1090 start_millis = uptimeMillis(); 1091 } 1092 //printf("Transact from Java code to %p sending: ", target); data->print(); 1093 status_t err = target->transact(code, *data, reply, flags); 1094 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); 1095 if (time_binder_calls) { 1096 conditionally_log_binder_call(start_millis, target, code); 1097 } 1098 1099 if (err == NO_ERROR) { 1100 return JNI_TRUE; 1101 } else if (err == UNKNOWN_TRANSACTION) { 1102 return JNI_FALSE; 1103 } 1104 1105 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); 1106 return JNI_FALSE; 1107 } 1108 1109 static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, 1110 jobject recipient, jint flags) // throws RemoteException 1111 { 1112 if (recipient == NULL) { 1113 jniThrowNullPointerException(env, NULL); 1114 return; 1115 } 1116 1117 IBinder* target = (IBinder*) 1118 env->GetIntField(obj, gBinderProxyOffsets.mObject); 1119 if (target == NULL) { 1120 LOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); 1121 assert(false); 1122 } 1123 1124 LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient); 1125 1126 if (!target->localBinder()) { 1127 DeathRecipientList* list = (DeathRecipientList*) 1128 env->GetIntField(obj, gBinderProxyOffsets.mOrgue); 1129 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list); 1130 status_t err = target->linkToDeath(jdr, NULL, flags); 1131 if (err != NO_ERROR) { 1132 // Failure adding the death recipient, so clear its reference 1133 // now. 1134 jdr->clearReference(); 1135 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); 1136 } 1137 } 1138 } 1139 1140 static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, 1141 jobject recipient, jint flags) 1142 { 1143 jboolean res = JNI_FALSE; 1144 if (recipient == NULL) { 1145 jniThrowNullPointerException(env, NULL); 1146 return res; 1147 } 1148 1149 IBinder* target = (IBinder*) 1150 env->GetIntField(obj, gBinderProxyOffsets.mObject); 1151 if (target == NULL) { 1152 LOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); 1153 return JNI_FALSE; 1154 } 1155 1156 LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient); 1157 1158 if (!target->localBinder()) { 1159 status_t err = NAME_NOT_FOUND; 1160 1161 // If we find the matching recipient, proceed to unlink using that 1162 DeathRecipientList* list = (DeathRecipientList*) 1163 env->GetIntField(obj, gBinderProxyOffsets.mOrgue); 1164 sp<JavaDeathRecipient> origJDR = list->find(recipient); 1165 LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get()); 1166 if (origJDR != NULL) { 1167 wp<IBinder::DeathRecipient> dr; 1168 err = target->unlinkToDeath(origJDR, NULL, flags, &dr); 1169 if (err == NO_ERROR && dr != NULL) { 1170 sp<IBinder::DeathRecipient> sdr = dr.promote(); 1171 JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get()); 1172 if (jdr != NULL) { 1173 jdr->clearReference(); 1174 } 1175 } 1176 } 1177 1178 if (err == NO_ERROR || err == DEAD_OBJECT) { 1179 res = JNI_TRUE; 1180 } else { 1181 jniThrowException(env, "java/util/NoSuchElementException", 1182 "Death link does not exist"); 1183 } 1184 } 1185 1186 return res; 1187 } 1188 1189 static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj) 1190 { 1191 IBinder* b = (IBinder*) 1192 env->GetIntField(obj, gBinderProxyOffsets.mObject); 1193 DeathRecipientList* drl = (DeathRecipientList*) 1194 env->GetIntField(obj, gBinderProxyOffsets.mOrgue); 1195 1196 LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl); 1197 env->SetIntField(obj, gBinderProxyOffsets.mObject, 0); 1198 env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0); 1199 drl->decStrong((void*)javaObjectForIBinder); 1200 b->decStrong(obj); 1201 1202 IPCThreadState::self()->flushCommands(); 1203 } 1204 1205 // ---------------------------------------------------------------------------- 1206 1207 static const JNINativeMethod gBinderProxyMethods[] = { 1208 /* name, signature, funcPtr */ 1209 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder}, 1210 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive}, 1211 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor}, 1212 {"transact", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact}, 1213 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath}, 1214 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath}, 1215 {"destroy", "()V", (void*)android_os_BinderProxy_destroy}, 1216 }; 1217 1218 const char* const kBinderProxyPathName = "android/os/BinderProxy"; 1219 1220 static int int_register_android_os_BinderProxy(JNIEnv* env) 1221 { 1222 jclass clazz; 1223 1224 clazz = env->FindClass("java/lang/ref/WeakReference"); 1225 LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference"); 1226 gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 1227 gWeakReferenceOffsets.mGet 1228 = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;"); 1229 assert(gWeakReferenceOffsets.mGet); 1230 1231 clazz = env->FindClass("java/lang/Error"); 1232 LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error"); 1233 gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 1234 1235 clazz = env->FindClass(kBinderProxyPathName); 1236 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy"); 1237 1238 gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 1239 gBinderProxyOffsets.mConstructor 1240 = env->GetMethodID(clazz, "<init>", "()V"); 1241 assert(gBinderProxyOffsets.mConstructor); 1242 gBinderProxyOffsets.mSendDeathNotice 1243 = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V"); 1244 assert(gBinderProxyOffsets.mSendDeathNotice); 1245 1246 gBinderProxyOffsets.mObject 1247 = env->GetFieldID(clazz, "mObject", "I"); 1248 assert(gBinderProxyOffsets.mObject); 1249 gBinderProxyOffsets.mSelf 1250 = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;"); 1251 assert(gBinderProxyOffsets.mSelf); 1252 gBinderProxyOffsets.mOrgue 1253 = env->GetFieldID(clazz, "mOrgue", "I"); 1254 assert(gBinderProxyOffsets.mOrgue); 1255 1256 clazz = env->FindClass("java/lang/Class"); 1257 LOG_FATAL_IF(clazz == NULL, "Unable to find java.lang.Class"); 1258 gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;"); 1259 assert(gClassOffsets.mGetName); 1260 1261 return AndroidRuntime::registerNativeMethods( 1262 env, kBinderProxyPathName, 1263 gBinderProxyMethods, NELEM(gBinderProxyMethods)); 1264 } 1265 1266 // **************************************************************************** 1267 // **************************************************************************** 1268 // **************************************************************************** 1269 1270 static jint android_os_Parcel_dataSize(JNIEnv* env, jobject clazz) 1271 { 1272 Parcel* parcel = parcelForJavaObject(env, clazz); 1273 return parcel ? parcel->dataSize() : 0; 1274 } 1275 1276 static jint android_os_Parcel_dataAvail(JNIEnv* env, jobject clazz) 1277 { 1278 Parcel* parcel = parcelForJavaObject(env, clazz); 1279 return parcel ? parcel->dataAvail() : 0; 1280 } 1281 1282 static jint android_os_Parcel_dataPosition(JNIEnv* env, jobject clazz) 1283 { 1284 Parcel* parcel = parcelForJavaObject(env, clazz); 1285 return parcel ? parcel->dataPosition() : 0; 1286 } 1287 1288 static jint android_os_Parcel_dataCapacity(JNIEnv* env, jobject clazz) 1289 { 1290 Parcel* parcel = parcelForJavaObject(env, clazz); 1291 return parcel ? parcel->dataCapacity() : 0; 1292 } 1293 1294 static void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size) 1295 { 1296 Parcel* parcel = parcelForJavaObject(env, clazz); 1297 if (parcel != NULL) { 1298 const status_t err = parcel->setDataSize(size); 1299 if (err != NO_ERROR) { 1300 signalExceptionForError(env, clazz, err); 1301 } 1302 } 1303 } 1304 1305 static void android_os_Parcel_setDataPosition(JNIEnv* env, jobject clazz, jint pos) 1306 { 1307 Parcel* parcel = parcelForJavaObject(env, clazz); 1308 if (parcel != NULL) { 1309 parcel->setDataPosition(pos); 1310 } 1311 } 1312 1313 static void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint size) 1314 { 1315 Parcel* parcel = parcelForJavaObject(env, clazz); 1316 if (parcel != NULL) { 1317 const status_t err = parcel->setDataCapacity(size); 1318 if (err != NO_ERROR) { 1319 signalExceptionForError(env, clazz, err); 1320 } 1321 } 1322 } 1323 1324 static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds) 1325 { 1326 Parcel* parcel = parcelForJavaObject(env, clazz); 1327 jboolean ret = JNI_TRUE; 1328 if (parcel != NULL) { 1329 ret = (jboolean)parcel->pushAllowFds(allowFds); 1330 } 1331 return ret; 1332 } 1333 1334 static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jobject clazz, jboolean lastValue) 1335 { 1336 Parcel* parcel = parcelForJavaObject(env, clazz); 1337 if (parcel != NULL) { 1338 parcel->restoreAllowFds((bool)lastValue); 1339 } 1340 } 1341 1342 static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz, 1343 jobject data, jint offset, 1344 jint length) 1345 { 1346 Parcel* parcel = parcelForJavaObject(env, clazz); 1347 if (parcel == NULL) { 1348 return; 1349 } 1350 1351 const status_t err = parcel->writeInt32(length); 1352 if (err != NO_ERROR) { 1353 signalExceptionForError(env, clazz, err); 1354 return; 1355 } 1356 1357 void* dest = parcel->writeInplace(length); 1358 if (dest == NULL) { 1359 signalExceptionForError(env, clazz, NO_MEMORY); 1360 return; 1361 } 1362 1363 jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0); 1364 if (ar) { 1365 memcpy(dest, ar + offset, length); 1366 env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0); 1367 } 1368 } 1369 1370 1371 static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val) 1372 { 1373 Parcel* parcel = parcelForJavaObject(env, clazz); 1374 if (parcel != NULL) { 1375 const status_t err = parcel->writeInt32(val); 1376 if (err != NO_ERROR) { 1377 signalExceptionForError(env, clazz, err); 1378 } 1379 } 1380 } 1381 1382 static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val) 1383 { 1384 Parcel* parcel = parcelForJavaObject(env, clazz); 1385 if (parcel != NULL) { 1386 const status_t err = parcel->writeInt64(val); 1387 if (err != NO_ERROR) { 1388 signalExceptionForError(env, clazz, err); 1389 } 1390 } 1391 } 1392 1393 static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val) 1394 { 1395 Parcel* parcel = parcelForJavaObject(env, clazz); 1396 if (parcel != NULL) { 1397 const status_t err = parcel->writeFloat(val); 1398 if (err != NO_ERROR) { 1399 signalExceptionForError(env, clazz, err); 1400 } 1401 } 1402 } 1403 1404 static void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble val) 1405 { 1406 Parcel* parcel = parcelForJavaObject(env, clazz); 1407 if (parcel != NULL) { 1408 const status_t err = parcel->writeDouble(val); 1409 if (err != NO_ERROR) { 1410 signalExceptionForError(env, clazz, err); 1411 } 1412 } 1413 } 1414 1415 static void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring val) 1416 { 1417 Parcel* parcel = parcelForJavaObject(env, clazz); 1418 if (parcel != NULL) { 1419 status_t err = NO_MEMORY; 1420 if (val) { 1421 const jchar* str = env->GetStringCritical(val, 0); 1422 if (str) { 1423 err = parcel->writeString16(str, env->GetStringLength(val)); 1424 env->ReleaseStringCritical(val, str); 1425 } 1426 } else { 1427 err = parcel->writeString16(NULL, 0); 1428 } 1429 if (err != NO_ERROR) { 1430 signalExceptionForError(env, clazz, err); 1431 } 1432 } 1433 } 1434 1435 static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object) 1436 { 1437 Parcel* parcel = parcelForJavaObject(env, clazz); 1438 if (parcel != NULL) { 1439 const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); 1440 if (err != NO_ERROR) { 1441 signalExceptionForError(env, clazz, err); 1442 } 1443 } 1444 } 1445 1446 static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jobject object) 1447 { 1448 Parcel* parcel = parcelForJavaObject(env, clazz); 1449 if (parcel != NULL) { 1450 const status_t err = 1451 parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object)); 1452 if (err != NO_ERROR) { 1453 signalExceptionForError(env, clazz, err); 1454 } 1455 } 1456 } 1457 1458 static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jobject clazz) 1459 { 1460 jbyteArray ret = NULL; 1461 1462 Parcel* parcel = parcelForJavaObject(env, clazz); 1463 if (parcel != NULL) { 1464 int32_t len = parcel->readInt32(); 1465 1466 // sanity check the stored length against the true data size 1467 if (len >= 0 && len <= (int32_t)parcel->dataAvail()) { 1468 ret = env->NewByteArray(len); 1469 1470 if (ret != NULL) { 1471 jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0); 1472 if (a2) { 1473 const void* data = parcel->readInplace(len); 1474 memcpy(a2, data, len); 1475 env->ReleasePrimitiveArrayCritical(ret, a2, 0); 1476 } 1477 } 1478 } 1479 } 1480 1481 return ret; 1482 } 1483 1484 static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz) 1485 { 1486 Parcel* parcel = parcelForJavaObject(env, clazz); 1487 if (parcel != NULL) { 1488 return parcel->readInt32(); 1489 } 1490 return 0; 1491 } 1492 1493 static jlong android_os_Parcel_readLong(JNIEnv* env, jobject clazz) 1494 { 1495 Parcel* parcel = parcelForJavaObject(env, clazz); 1496 if (parcel != NULL) { 1497 return parcel->readInt64(); 1498 } 1499 return 0; 1500 } 1501 1502 static jfloat android_os_Parcel_readFloat(JNIEnv* env, jobject clazz) 1503 { 1504 Parcel* parcel = parcelForJavaObject(env, clazz); 1505 if (parcel != NULL) { 1506 return parcel->readFloat(); 1507 } 1508 return 0; 1509 } 1510 1511 static jdouble android_os_Parcel_readDouble(JNIEnv* env, jobject clazz) 1512 { 1513 Parcel* parcel = parcelForJavaObject(env, clazz); 1514 if (parcel != NULL) { 1515 return parcel->readDouble(); 1516 } 1517 return 0; 1518 } 1519 1520 static jstring android_os_Parcel_readString(JNIEnv* env, jobject clazz) 1521 { 1522 Parcel* parcel = parcelForJavaObject(env, clazz); 1523 if (parcel != NULL) { 1524 size_t len; 1525 const char16_t* str = parcel->readString16Inplace(&len); 1526 if (str) { 1527 return env->NewString(str, len); 1528 } 1529 return NULL; 1530 } 1531 return NULL; 1532 } 1533 1534 static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz) 1535 { 1536 Parcel* parcel = parcelForJavaObject(env, clazz); 1537 if (parcel != NULL) { 1538 return javaObjectForIBinder(env, parcel->readStrongBinder()); 1539 } 1540 return NULL; 1541 } 1542 1543 static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jobject clazz) 1544 { 1545 Parcel* parcel = parcelForJavaObject(env, clazz); 1546 if (parcel != NULL) { 1547 int fd = parcel->readFileDescriptor(); 1548 if (fd < 0) return NULL; 1549 fd = dup(fd); 1550 if (fd < 0) return NULL; 1551 return jniCreateFileDescriptor(env, fd); 1552 } 1553 return NULL; 1554 } 1555 1556 static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jobject clazz, 1557 jstring name, jint mode) 1558 { 1559 if (name == NULL) { 1560 jniThrowNullPointerException(env, NULL); 1561 return NULL; 1562 } 1563 const jchar* str = env->GetStringCritical(name, 0); 1564 if (str == NULL) { 1565 // Whatever, whatever. 1566 jniThrowException(env, "java/lang/IllegalStateException", NULL); 1567 return NULL; 1568 } 1569 String8 name8(str, env->GetStringLength(name)); 1570 env->ReleaseStringCritical(name, str); 1571 int flags=0; 1572 switch (mode&0x30000000) { 1573 case 0: 1574 case 0x10000000: 1575 flags = O_RDONLY; 1576 break; 1577 case 0x20000000: 1578 flags = O_WRONLY; 1579 break; 1580 case 0x30000000: 1581 flags = O_RDWR; 1582 break; 1583 } 1584 1585 if (mode&0x08000000) flags |= O_CREAT; 1586 if (mode&0x04000000) flags |= O_TRUNC; 1587 if (mode&0x02000000) flags |= O_APPEND; 1588 1589 int realMode = S_IRWXU|S_IRWXG; 1590 if (mode&0x00000001) realMode |= S_IROTH; 1591 if (mode&0x00000002) realMode |= S_IWOTH; 1592 1593 int fd = open(name8.string(), flags, realMode); 1594 if (fd < 0) { 1595 jniThrowException(env, "java/io/FileNotFoundException", strerror(errno)); 1596 return NULL; 1597 } 1598 jobject object = jniCreateFileDescriptor(env, fd); 1599 if (object == NULL) { 1600 close(fd); 1601 } 1602 return object; 1603 } 1604 1605 static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jobject clazz, jobject orig) 1606 { 1607 if (orig == NULL) { 1608 jniThrowNullPointerException(env, NULL); 1609 return NULL; 1610 } 1611 int origfd = jniGetFDFromFileDescriptor(env, orig); 1612 if (origfd < 0) { 1613 jniThrowException(env, "java/lang/IllegalArgumentException", "bad FileDescriptor"); 1614 return NULL; 1615 } 1616 1617 int fd = dup(origfd); 1618 if (fd < 0) { 1619 jniThrowIOException(env, errno); 1620 return NULL; 1621 } 1622 jobject object = jniCreateFileDescriptor(env, fd); 1623 if (object == NULL) { 1624 close(fd); 1625 } 1626 return object; 1627 } 1628 1629 static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jobject object) 1630 { 1631 if (object == NULL) { 1632 jniThrowNullPointerException(env, NULL); 1633 return; 1634 } 1635 int fd = jniGetFDFromFileDescriptor(env, object); 1636 if (fd >= 0) { 1637 jniSetFileDescriptorOfFD(env, object, -1); 1638 //LOGI("Closing ParcelFileDescriptor %d\n", fd); 1639 close(fd); 1640 } 1641 } 1642 1643 static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jobject object) 1644 { 1645 if (object == NULL) { 1646 jniThrowNullPointerException(env, NULL); 1647 return; 1648 } 1649 int fd = jniGetFDFromFileDescriptor(env, object); 1650 if (fd >= 0) { 1651 jniSetFileDescriptorOfFD(env, object, -1); 1652 } 1653 } 1654 1655 static void android_os_Parcel_freeBuffer(JNIEnv* env, jobject clazz) 1656 { 1657 int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject); 1658 if (own) { 1659 Parcel* parcel = parcelForJavaObject(env, clazz); 1660 if (parcel != NULL) { 1661 //LOGI("Parcel.freeBuffer() called for C++ Parcel %p\n", parcel); 1662 parcel->freeData(); 1663 } 1664 } 1665 } 1666 1667 static void android_os_Parcel_init(JNIEnv* env, jobject clazz, jint parcelInt) 1668 { 1669 Parcel* parcel = (Parcel*)parcelInt; 1670 int own = 0; 1671 if (!parcel) { 1672 //LOGI("Initializing obj %p: creating new Parcel\n", clazz); 1673 own = 1; 1674 parcel = new Parcel; 1675 } else { 1676 //LOGI("Initializing obj %p: given existing Parcel %p\n", clazz, parcel); 1677 } 1678 if (parcel == NULL) { 1679 jniThrowException(env, "java/lang/OutOfMemoryError", NULL); 1680 return; 1681 } 1682 //LOGI("Initializing obj %p from C++ Parcel %p, own=%d\n", clazz, parcel, own); 1683 env->SetIntField(clazz, gParcelOffsets.mOwnObject, own); 1684 env->SetIntField(clazz, gParcelOffsets.mObject, (int)parcel); 1685 } 1686 1687 static void android_os_Parcel_destroy(JNIEnv* env, jobject clazz) 1688 { 1689 int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject); 1690 if (own) { 1691 Parcel* parcel = parcelForJavaObject(env, clazz); 1692 env->SetIntField(clazz, gParcelOffsets.mObject, 0); 1693 //LOGI("Destroying obj %p: deleting C++ Parcel %p\n", clazz, parcel); 1694 delete parcel; 1695 } else { 1696 env->SetIntField(clazz, gParcelOffsets.mObject, 0); 1697 //LOGI("Destroying obj %p: leaving C++ Parcel %p\n", clazz); 1698 } 1699 } 1700 1701 static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jobject clazz) 1702 { 1703 Parcel* parcel = parcelForJavaObject(env, clazz); 1704 if (parcel == NULL) { 1705 return NULL; 1706 } 1707 1708 // do not marshall if there are binder objects in the parcel 1709 if (parcel->objectsCount()) 1710 { 1711 jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects."); 1712 return NULL; 1713 } 1714 1715 jbyteArray ret = env->NewByteArray(parcel->dataSize()); 1716 1717 if (ret != NULL) 1718 { 1719 jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0); 1720 if (array != NULL) 1721 { 1722 memcpy(array, parcel->data(), parcel->dataSize()); 1723 env->ReleasePrimitiveArrayCritical(ret, array, 0); 1724 } 1725 } 1726 1727 return ret; 1728 } 1729 1730 static void android_os_Parcel_unmarshall(JNIEnv* env, jobject clazz, jbyteArray data, jint offset, jint length) 1731 { 1732 Parcel* parcel = parcelForJavaObject(env, clazz); 1733 if (parcel == NULL || length < 0) { 1734 return; 1735 } 1736 1737 jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0); 1738 if (array) 1739 { 1740 parcel->setDataSize(length); 1741 parcel->setDataPosition(0); 1742 1743 void* raw = parcel->writeInplace(length); 1744 memcpy(raw, (array + offset), length); 1745 1746 env->ReleasePrimitiveArrayCritical(data, array, 0); 1747 } 1748 } 1749 1750 static void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject parcel, jint offset, jint length) 1751 { 1752 Parcel* thisParcel = parcelForJavaObject(env, clazz); 1753 if (thisParcel == NULL) { 1754 return; 1755 } 1756 Parcel* otherParcel = parcelForJavaObject(env, parcel); 1757 if (otherParcel == NULL) { 1758 return; 1759 } 1760 1761 status_t err = thisParcel->appendFrom(otherParcel, offset, length); 1762 if (err != NO_ERROR) { 1763 signalExceptionForError(env, clazz, err); 1764 } 1765 } 1766 1767 static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz) 1768 { 1769 jboolean ret = JNI_FALSE; 1770 Parcel* parcel = parcelForJavaObject(env, clazz); 1771 if (parcel != NULL) { 1772 if (parcel->hasFileDescriptors()) { 1773 ret = JNI_TRUE; 1774 } 1775 } 1776 return ret; 1777 } 1778 1779 static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, jstring name) 1780 { 1781 Parcel* parcel = parcelForJavaObject(env, clazz); 1782 if (parcel != NULL) { 1783 // In the current implementation, the token is just the serialized interface name that 1784 // the caller expects to be invoking 1785 const jchar* str = env->GetStringCritical(name, 0); 1786 if (str != NULL) { 1787 parcel->writeInterfaceToken(String16(str, env->GetStringLength(name))); 1788 env->ReleaseStringCritical(name, str); 1789 } 1790 } 1791 } 1792 1793 static void android_os_Parcel_enforceInterface(JNIEnv* env, jobject clazz, jstring name) 1794 { 1795 jboolean ret = JNI_FALSE; 1796 1797 Parcel* parcel = parcelForJavaObject(env, clazz); 1798 if (parcel != NULL) { 1799 const jchar* str = env->GetStringCritical(name, 0); 1800 if (str) { 1801 IPCThreadState* threadState = IPCThreadState::self(); 1802 const int32_t oldPolicy = threadState->getStrictModePolicy(); 1803 const bool isValid = parcel->enforceInterface( 1804 String16(str, env->GetStringLength(name)), 1805 threadState); 1806 env->ReleaseStringCritical(name, str); 1807 if (isValid) { 1808 const int32_t newPolicy = threadState->getStrictModePolicy(); 1809 if (oldPolicy != newPolicy) { 1810 // Need to keep the Java-level thread-local strict 1811 // mode policy in sync for the libcore 1812 // enforcements, which involves an upcall back 1813 // into Java. (We can't modify the 1814 // Parcel.enforceInterface signature, as it's 1815 // pseudo-public, and used via AIDL 1816 // auto-generation...) 1817 set_dalvik_blockguard_policy(env, newPolicy); 1818 } 1819 return; // everything was correct -> return silently 1820 } 1821 } 1822 } 1823 1824 // all error conditions wind up here 1825 jniThrowException(env, "java/lang/SecurityException", 1826 "Binder invocation to an incorrect interface"); 1827 } 1828 1829 // ---------------------------------------------------------------------------- 1830 1831 static const JNINativeMethod gParcelMethods[] = { 1832 {"dataSize", "()I", (void*)android_os_Parcel_dataSize}, 1833 {"dataAvail", "()I", (void*)android_os_Parcel_dataAvail}, 1834 {"dataPosition", "()I", (void*)android_os_Parcel_dataPosition}, 1835 {"dataCapacity", "()I", (void*)android_os_Parcel_dataCapacity}, 1836 {"setDataSize", "(I)V", (void*)android_os_Parcel_setDataSize}, 1837 {"setDataPosition", "(I)V", (void*)android_os_Parcel_setDataPosition}, 1838 {"setDataCapacity", "(I)V", (void*)android_os_Parcel_setDataCapacity}, 1839 {"pushAllowFds", "(Z)Z", (void*)android_os_Parcel_pushAllowFds}, 1840 {"restoreAllowFds", "(Z)V", (void*)android_os_Parcel_restoreAllowFds}, 1841 {"writeNative", "([BII)V", (void*)android_os_Parcel_writeNative}, 1842 {"writeInt", "(I)V", (void*)android_os_Parcel_writeInt}, 1843 {"writeLong", "(J)V", (void*)android_os_Parcel_writeLong}, 1844 {"writeFloat", "(F)V", (void*)android_os_Parcel_writeFloat}, 1845 {"writeDouble", "(D)V", (void*)android_os_Parcel_writeDouble}, 1846 {"writeString", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeString}, 1847 {"writeStrongBinder", "(Landroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, 1848 {"writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor}, 1849 {"createByteArray", "()[B", (void*)android_os_Parcel_createByteArray}, 1850 {"readInt", "()I", (void*)android_os_Parcel_readInt}, 1851 {"readLong", "()J", (void*)android_os_Parcel_readLong}, 1852 {"readFloat", "()F", (void*)android_os_Parcel_readFloat}, 1853 {"readDouble", "()D", (void*)android_os_Parcel_readDouble}, 1854 {"readString", "()Ljava/lang/String;", (void*)android_os_Parcel_readString}, 1855 {"readStrongBinder", "()Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, 1856 {"internalReadFileDescriptor", "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor}, 1857 {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor}, 1858 {"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor}, 1859 {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor}, 1860 {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor}, 1861 {"freeBuffer", "()V", (void*)android_os_Parcel_freeBuffer}, 1862 {"init", "(I)V", (void*)android_os_Parcel_init}, 1863 {"destroy", "()V", (void*)android_os_Parcel_destroy}, 1864 {"marshall", "()[B", (void*)android_os_Parcel_marshall}, 1865 {"unmarshall", "([BII)V", (void*)android_os_Parcel_unmarshall}, 1866 {"appendFrom", "(Landroid/os/Parcel;II)V", (void*)android_os_Parcel_appendFrom}, 1867 {"hasFileDescriptors", "()Z", (void*)android_os_Parcel_hasFileDescriptors}, 1868 {"writeInterfaceToken", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken}, 1869 {"enforceInterface", "(Ljava/lang/String;)V", (void*)android_os_Parcel_enforceInterface}, 1870 }; 1871 1872 const char* const kParcelPathName = "android/os/Parcel"; 1873 1874 static int int_register_android_os_Parcel(JNIEnv* env) 1875 { 1876 jclass clazz; 1877 1878 clazz = env->FindClass("android/util/Log"); 1879 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.util.Log"); 1880 gLogOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 1881 gLogOffsets.mLogE = env->GetStaticMethodID( 1882 clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I"); 1883 assert(gLogOffsets.mLogE); 1884 1885 clazz = env->FindClass("android/os/ParcelFileDescriptor"); 1886 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor"); 1887 gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 1888 gParcelFileDescriptorOffsets.mConstructor 1889 = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V"); 1890 1891 clazz = env->FindClass(kParcelPathName); 1892 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel"); 1893 1894 gParcelOffsets.mObject 1895 = env->GetFieldID(clazz, "mObject", "I"); 1896 gParcelOffsets.mOwnObject 1897 = env->GetFieldID(clazz, "mOwnObject", "I"); 1898 1899 clazz = env->FindClass("android/os/StrictMode"); 1900 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.StrictMode"); 1901 gStrictModeCallbackOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 1902 gStrictModeCallbackOffsets.mCallback = env->GetStaticMethodID( 1903 clazz, "onBinderStrictModePolicyChange", "(I)V"); 1904 LOG_FATAL_IF(gStrictModeCallbackOffsets.mCallback == NULL, 1905 "Unable to find strict mode callback."); 1906 1907 return AndroidRuntime::registerNativeMethods( 1908 env, kParcelPathName, 1909 gParcelMethods, NELEM(gParcelMethods)); 1910 } 1911 1912 int register_android_os_Binder(JNIEnv* env) 1913 { 1914 if (int_register_android_os_Binder(env) < 0) 1915 return -1; 1916 if (int_register_android_os_BinderInternal(env) < 0) 1917 return -1; 1918 if (int_register_android_os_BinderProxy(env) < 0) 1919 return -1; 1920 if (int_register_android_os_Parcel(env) < 0) 1921 return -1; 1922 return 0; 1923 } 1924