Loading api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -15132,6 +15132,7 @@ package android.os { public class RemoteException extends android.util.AndroidException { ctor public RemoteException(); ctor public RemoteException(java.lang.String); } public class ResultReceiver implements android.os.Parcelable { Loading Loading @@ -15226,6 +15227,10 @@ package android.os { method public abstract void released(); } public class TransactionTooLargeException extends android.os.RemoteException { ctor public TransactionTooLargeException(); } public class Vibrator { method public void cancel(); method public boolean hasVibrator(); core/java/android/os/RemoteException.java +4 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,8 @@ public class RemoteException extends AndroidException { public RemoteException() { super(); } public RemoteException(String message) { super(message); } } core/java/android/os/TransactionTooLargeException.java 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.os; import android.os.RemoteException; /** * The Binder transaction failed because it was too large. * <p> * During a remote procedure call, the arguments and the return value of the call * are transferred as {@link Parcel} objects stored in the Binder transaction buffer. * If the arguments or the return value are too large to fit in the transaction buffer, * then the call will fail and {@link TransactionTooLargeException} will be thrown. * </p><p> * The Binder transaction buffer has a limited fixed size, currently 1Mb, which * is shared by all transactions in progress for the process. Consequently this * exception can be thrown when there are many transactions in progress even when * most of the individual transactions are of moderate size. * </p><p> * There are two possible outcomes when a remote procedure call throws * {@link TransactionTooLargeException}. Either the client was unable to send * its request to the service (most likely if the arguments were too large to fit in * the transaction buffer), or the service was unable to send its response back * to the client (most likely if the return value was too large to fit * in the transaction buffer). It is not possible to tell which of these outcomes * actually occurred. The client should assume that a partial failure occurred. * </p><p> * The key to avoiding {@link TransactionTooLargeException} is to keep all * transactions relatively small. Try to minimize the amount of memory needed to create * a {@link Parcel} for the arguments and the return value of the remote procedure call. * Avoid transferring huge arrays of strings or large bitmaps. * If possible, try to break up big requests into smaller pieces. * </p><p> * If you are implementing a service, it may help to impose size or complexity * contraints on the queries that clients can perform. For example, if the result set * could become large, then don't allow the client to request more than a few records * at a time. Alternately, instead of returning all of the available data all at once, * return the essential information first and make the client ask for additional information * later as needed. * </p> */ public class TransactionTooLargeException extends RemoteException { public TransactionTooLargeException() { super(); } } core/jni/android_util_Binder.cpp +26 −8 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include <binder/ProcessState.h> #include <binder/IServiceManager.h> #include <utils/threads.h> #include <utils/String8.h> #include <ScopedUtfChars.h> #include <ScopedLocalRef.h> Loading Loading @@ -651,7 +652,8 @@ jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc) gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc); } void signalExceptionForError(JNIEnv* env, jobject obj, status_t err) static void signalExceptionForError(JNIEnv* env, jobject obj, status_t err, bool canThrowRemoteException = false) { switch (err) { case UNKNOWN_ERROR: Loading Loading @@ -688,14 +690,25 @@ void signalExceptionForError(JNIEnv* env, jobject obj, status_t err) jniThrowException(env, "java/lang/RuntimeException", "Item already exists"); break; case DEAD_OBJECT: jniThrowException(env, "android/os/DeadObjectException", NULL); // DeadObjectException is a checked exception, only throw from certain methods. jniThrowException(env, canThrowRemoteException ? "android/os/DeadObjectException" : "java/lang/RuntimeException", NULL); break; case UNKNOWN_TRANSACTION: jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code"); break; case FAILED_TRANSACTION: LOGE("!!! FAILED BINDER TRANSACTION !!!"); //jniThrowException(env, "java/lang/OutOfMemoryError", "Binder transaction too large"); // TransactionTooLargeException is a checked exception, only throw from certain methods. // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION // but it is not the only one. The Binder driver can return BR_FAILED_REPLY // for other reasons also, such as if the transaction is malformed or // refers to an FD that has been closed. We should change the driver // to enable us to distinguish these cases in the future. jniThrowException(env, canThrowRemoteException ? "android/os/TransactionTooLargeException" : "java/lang/RuntimeException", NULL); break; case FDS_NOT_ALLOWED: jniThrowException(env, "java/lang/RuntimeException", Loading @@ -703,6 +716,12 @@ void signalExceptionForError(JNIEnv* env, jobject obj, status_t err) break; default: LOGE("Unknown binder error code. 0x%x", err); String8 msg; msg.appendFormat("Unknown binder error code. 0x%x", err); // RemoteException is a checked exception, only throw from certain methods. jniThrowException(env, canThrowRemoteException ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string()); break; } } Loading Loading @@ -1036,8 +1055,7 @@ static bool should_time_binder_calls() { } static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException { if (dataObj == NULL) { jniThrowNullPointerException(env, NULL); Loading Loading @@ -1084,12 +1102,12 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, return JNI_FALSE; } signalExceptionForError(env, obj, err); signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); return JNI_FALSE; } static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, jobject recipient, jint flags) jobject recipient, jint flags) // throws RemoteException { if (recipient == NULL) { jniThrowNullPointerException(env, NULL); Loading @@ -1114,7 +1132,7 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, // Failure adding the death recipient, so clear its reference // now. jdr->clearReference(); signalExceptionForError(env, obj, err); signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); } } } Loading Loading
api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -15132,6 +15132,7 @@ package android.os { public class RemoteException extends android.util.AndroidException { ctor public RemoteException(); ctor public RemoteException(java.lang.String); } public class ResultReceiver implements android.os.Parcelable { Loading Loading @@ -15226,6 +15227,10 @@ package android.os { method public abstract void released(); } public class TransactionTooLargeException extends android.os.RemoteException { ctor public TransactionTooLargeException(); } public class Vibrator { method public void cancel(); method public boolean hasVibrator();
core/java/android/os/RemoteException.java +4 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,8 @@ public class RemoteException extends AndroidException { public RemoteException() { super(); } public RemoteException(String message) { super(message); } }
core/java/android/os/TransactionTooLargeException.java 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.os; import android.os.RemoteException; /** * The Binder transaction failed because it was too large. * <p> * During a remote procedure call, the arguments and the return value of the call * are transferred as {@link Parcel} objects stored in the Binder transaction buffer. * If the arguments or the return value are too large to fit in the transaction buffer, * then the call will fail and {@link TransactionTooLargeException} will be thrown. * </p><p> * The Binder transaction buffer has a limited fixed size, currently 1Mb, which * is shared by all transactions in progress for the process. Consequently this * exception can be thrown when there are many transactions in progress even when * most of the individual transactions are of moderate size. * </p><p> * There are two possible outcomes when a remote procedure call throws * {@link TransactionTooLargeException}. Either the client was unable to send * its request to the service (most likely if the arguments were too large to fit in * the transaction buffer), or the service was unable to send its response back * to the client (most likely if the return value was too large to fit * in the transaction buffer). It is not possible to tell which of these outcomes * actually occurred. The client should assume that a partial failure occurred. * </p><p> * The key to avoiding {@link TransactionTooLargeException} is to keep all * transactions relatively small. Try to minimize the amount of memory needed to create * a {@link Parcel} for the arguments and the return value of the remote procedure call. * Avoid transferring huge arrays of strings or large bitmaps. * If possible, try to break up big requests into smaller pieces. * </p><p> * If you are implementing a service, it may help to impose size or complexity * contraints on the queries that clients can perform. For example, if the result set * could become large, then don't allow the client to request more than a few records * at a time. Alternately, instead of returning all of the available data all at once, * return the essential information first and make the client ask for additional information * later as needed. * </p> */ public class TransactionTooLargeException extends RemoteException { public TransactionTooLargeException() { super(); } }
core/jni/android_util_Binder.cpp +26 −8 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include <binder/ProcessState.h> #include <binder/IServiceManager.h> #include <utils/threads.h> #include <utils/String8.h> #include <ScopedUtfChars.h> #include <ScopedLocalRef.h> Loading Loading @@ -651,7 +652,8 @@ jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc) gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDesc); } void signalExceptionForError(JNIEnv* env, jobject obj, status_t err) static void signalExceptionForError(JNIEnv* env, jobject obj, status_t err, bool canThrowRemoteException = false) { switch (err) { case UNKNOWN_ERROR: Loading Loading @@ -688,14 +690,25 @@ void signalExceptionForError(JNIEnv* env, jobject obj, status_t err) jniThrowException(env, "java/lang/RuntimeException", "Item already exists"); break; case DEAD_OBJECT: jniThrowException(env, "android/os/DeadObjectException", NULL); // DeadObjectException is a checked exception, only throw from certain methods. jniThrowException(env, canThrowRemoteException ? "android/os/DeadObjectException" : "java/lang/RuntimeException", NULL); break; case UNKNOWN_TRANSACTION: jniThrowException(env, "java/lang/RuntimeException", "Unknown transaction code"); break; case FAILED_TRANSACTION: LOGE("!!! FAILED BINDER TRANSACTION !!!"); //jniThrowException(env, "java/lang/OutOfMemoryError", "Binder transaction too large"); // TransactionTooLargeException is a checked exception, only throw from certain methods. // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION // but it is not the only one. The Binder driver can return BR_FAILED_REPLY // for other reasons also, such as if the transaction is malformed or // refers to an FD that has been closed. We should change the driver // to enable us to distinguish these cases in the future. jniThrowException(env, canThrowRemoteException ? "android/os/TransactionTooLargeException" : "java/lang/RuntimeException", NULL); break; case FDS_NOT_ALLOWED: jniThrowException(env, "java/lang/RuntimeException", Loading @@ -703,6 +716,12 @@ void signalExceptionForError(JNIEnv* env, jobject obj, status_t err) break; default: LOGE("Unknown binder error code. 0x%x", err); String8 msg; msg.appendFormat("Unknown binder error code. 0x%x", err); // RemoteException is a checked exception, only throw from certain methods. jniThrowException(env, canThrowRemoteException ? "android/os/RemoteException" : "java/lang/RuntimeException", msg.string()); break; } } Loading Loading @@ -1036,8 +1055,7 @@ static bool should_time_binder_calls() { } static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException { if (dataObj == NULL) { jniThrowNullPointerException(env, NULL); Loading Loading @@ -1084,12 +1102,12 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, return JNI_FALSE; } signalExceptionForError(env, obj, err); signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); return JNI_FALSE; } static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, jobject recipient, jint flags) jobject recipient, jint flags) // throws RemoteException { if (recipient == NULL) { jniThrowNullPointerException(env, NULL); Loading @@ -1114,7 +1132,7 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, // Failure adding the death recipient, so clear its reference // now. jdr->clearReference(); signalExceptionForError(env, obj, err); signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); } } } Loading