3838#include < binder/ProcessState.h>
3939#include < binder/IServiceManager.h>
4040#include < utils/threads.h>
41+ #include < utils/String8.h>
4142
4243#include < ScopedUtfChars.h>
4344#include < ScopedLocalRef.h>
@@ -651,7 +652,8 @@ jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc)
651652 gParcelFileDescriptorOffsets .mClass , gParcelFileDescriptorOffsets .mConstructor , fileDesc);
652653}
653654
654- void signalExceptionForError (JNIEnv* env, jobject obj, status_t err)
655+ static void signalExceptionForError (JNIEnv* env, jobject obj, status_t err,
656+ bool canThrowRemoteException = false )
655657{
656658 switch (err) {
657659 case UNKNOWN_ERROR:
@@ -688,21 +690,38 @@ void signalExceptionForError(JNIEnv* env, jobject obj, status_t err)
688690 jniThrowException (env, " java/lang/RuntimeException" , " Item already exists" );
689691 break ;
690692 case DEAD_OBJECT:
691- jniThrowException (env, " android/os/DeadObjectException" , NULL );
693+ // DeadObjectException is a checked exception, only throw from certain methods.
694+ jniThrowException (env, canThrowRemoteException
695+ ? " android/os/DeadObjectException"
696+ : " java/lang/RuntimeException" , NULL );
692697 break ;
693698 case UNKNOWN_TRANSACTION:
694699 jniThrowException (env, " java/lang/RuntimeException" , " Unknown transaction code" );
695700 break ;
696701 case FAILED_TRANSACTION:
697702 LOGE (" !!! FAILED BINDER TRANSACTION !!!" );
698- // jniThrowException(env, "java/lang/OutOfMemoryError", "Binder transaction too large");
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 );
699712 break ;
700713 case FDS_NOT_ALLOWED:
701714 jniThrowException (env, " java/lang/RuntimeException" ,
702715 " Not allowed to write file descriptors here" );
703716 break ;
704717 default :
705718 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 ;
706725 }
707726}
708727
@@ -1036,8 +1055,7 @@ static bool should_time_binder_calls() {
10361055}
10371056
10381057static jboolean android_os_BinderProxy_transact (JNIEnv* env, jobject obj,
1039- jint code, jobject dataObj,
1040- jobject replyObj, jint flags)
1058+ jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
10411059{
10421060 if (dataObj == NULL ) {
10431061 jniThrowNullPointerException (env, NULL );
@@ -1084,12 +1102,12 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
10841102 return JNI_FALSE;
10851103 }
10861104
1087- signalExceptionForError (env, obj, err);
1105+ signalExceptionForError (env, obj, err, true /* canThrowRemoteException */ );
10881106 return JNI_FALSE;
10891107}
10901108
10911109static void android_os_BinderProxy_linkToDeath (JNIEnv* env, jobject obj,
1092- jobject recipient, jint flags)
1110+ jobject recipient, jint flags) // throws RemoteException
10931111{
10941112 if (recipient == NULL ) {
10951113 jniThrowNullPointerException (env, NULL );
@@ -1114,7 +1132,7 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
11141132 // Failure adding the death recipient, so clear its reference
11151133 // now.
11161134 jdr->clearReference ();
1117- signalExceptionForError (env, obj, err);
1135+ signalExceptionForError (env, obj, err, true /* canThrowRemoteException */ );
11181136 }
11191137 }
11201138}
0 commit comments