diff options
| author | 2022-02-02 16:45:48 +0000 | |
|---|---|---|
| committer | 2022-02-02 16:45:48 +0000 | |
| commit | 57a7b823d14ec0730a423c2285a79462109474c4 (patch) | |
| tree | f8fc25ce4bf98eeae7d78de767c262998e2415fd | |
| parent | 7096d45f59a05b7ed265ad6189252fb354dad159 (diff) | |
| parent | f1bc977e8dfbda375aab5ef86ffe2ce32a3992b3 (diff) | |
Merge "Support "Parcel.propagateAllowBlocking" for AIDL" am: bcefef7a8c am: 7d4245bc61 am: 4dbefbccd5 am: f1bc977e8d
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1964223
Change-Id: Ie91a206e927a8c857cc3eb556b95bae5d49e89b3
| -rw-r--r-- | core/api/current.txt | 1 | ||||
| -rw-r--r-- | core/api/test-current.txt | 3 | ||||
| -rw-r--r-- | core/java/android/os/BinderProxy.java | 13 | ||||
| -rw-r--r-- | core/java/android/os/Parcel.java | 67 |
4 files changed, 81 insertions, 3 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 74594d07a8b8..40f589d6f169 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -31525,6 +31525,7 @@ package android.os { method public void setDataCapacity(int); method public void setDataPosition(int); method public void setDataSize(int); + method public void setPropagateAllowBlocking(); method public void unmarshall(@NonNull byte[], int, int); method public void writeArray(@Nullable Object[]); method public void writeBinderArray(@Nullable android.os.IBinder[]); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index e2a78c6414d2..82742bc8e437 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1741,8 +1741,11 @@ package android.os { public final class Parcel { method public boolean allowSquashing(); + method public int getFlags(); method public int readExceptionCode(); method public void restoreAllowSquashing(boolean); + field public static final int FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT = 1; // 0x1 + field public static final int FLAG_PROPAGATE_ALLOW_BLOCKING = 2; // 0x2 } public class ParcelFileDescriptor implements java.io.Closeable android.os.Parcelable { diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java index 1b7c00c00f83..63306612fdaf 100644 --- a/core/java/android/os/BinderProxy.java +++ b/core/java/android/os/BinderProxy.java @@ -526,12 +526,15 @@ public final class BinderProxy implements IBinder { public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { Binder.checkParcel(this, code, data, "Unreasonably large binder buffer"); - if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0) + boolean warnOnBlocking = mWarnOnBlocking; // Cache it to reduce volatile access. + + if (warnOnBlocking && ((flags & FLAG_ONEWAY) == 0) && Binder.sWarnOnBlockingOnCurrentThread.get()) { // For now, avoid spamming the log by disabling after we've logged // about this interface at least once mWarnOnBlocking = false; + warnOnBlocking = false; if (Build.IS_USERDEBUG) { // Log this as a WTF on userdebug builds. @@ -578,7 +581,13 @@ public final class BinderProxy implements IBinder { } try { - return transactNative(code, data, reply, flags); + final boolean result = transactNative(code, data, reply, flags); + + if (reply != null && !warnOnBlocking) { + reply.addFlags(Parcel.FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT); + } + + return result; } finally { AppOpsManager.resumeNotedAppOpsCollection(prevCollection); diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 321b3643b45b..9998e1206602 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -18,6 +18,7 @@ package android.os; import static java.util.Objects.requireNonNull; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; @@ -53,6 +54,8 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.io.Serializable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -229,6 +232,25 @@ public final class Parcel { private RuntimeException mStack; + /** @hide */ + @TestApi + public static final int FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT = 1 << 0; + + /** @hide */ + @TestApi + public static final int FLAG_PROPAGATE_ALLOW_BLOCKING = 1 << 1; + + /** @hide */ + @IntDef(flag = true, prefix = { "FLAG_" }, value = { + FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT, + FLAG_PROPAGATE_ALLOW_BLOCKING, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ParcelFlags {} + + @ParcelFlags + private int mFlags; + /** * Whether or not to parcel the stack trace of an exception. This has a performance * impact, so should only be included in specific processes and only on debug builds. @@ -585,6 +607,40 @@ public final class Parcel { nativeMarkForBinder(mNativePtr, binder); } + /** @hide */ + @ParcelFlags + @TestApi + public int getFlags() { + return mFlags; + } + + /** @hide */ + public void setFlags(@ParcelFlags int flags) { + mFlags = flags; + } + + /** @hide */ + public void addFlags(@ParcelFlags int flags) { + mFlags |= flags; + } + + /** @hide */ + private boolean hasFlags(@ParcelFlags int flags) { + return (mFlags & flags) == flags; + } + + /** + * This method is used by the AIDL compiler for system components. Not intended to be + * used by non-system apps. + */ + // Note: Ideally this method should be @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES), + // but we need to make this method public due to the way the aidl compiler is compiled. + // We don't really need to protect it; even if 3p / non-system apps, nothing would happen. + // This would only work when used on a reply parcel by a binder object that's allowed-blocking. + public void setPropagateAllowBlocking() { + addFlags(FLAG_PROPAGATE_ALLOW_BLOCKING); + } + /** * Returns the total amount of data contained in the parcel. */ @@ -3045,7 +3101,15 @@ public final class Parcel { * Read an object from the parcel at the current dataPosition(). */ public final IBinder readStrongBinder() { - return nativeReadStrongBinder(mNativePtr); + final IBinder result = nativeReadStrongBinder(mNativePtr); + + // If it's a reply from a method with @PropagateAllowBlocking, then inherit allow-blocking + // from the object that returned it. + if (result != null && hasFlags( + FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT | FLAG_PROPAGATE_ALLOW_BLOCKING)) { + Binder.allowBlocking(result); + } + return result; } /** @@ -4995,6 +5059,7 @@ public final class Parcel { } private void freeBuffer() { + mFlags = 0; resetSqaushingState(); if (mOwnsNativeParcelObject) { nativeFreeBuffer(mNativePtr); |