Merge "Support "Parcel.propagateAllowBlocking" for AIDL" am: bcefef7a8c

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1964223

Change-Id: I25a4150a9b4f621cf636a60f2b7faef35d8a6a95
This commit is contained in:
Treehugger Robot
2022-02-02 16:16:59 +00:00
committed by Automerger Merge Worker
4 changed files with 81 additions and 3 deletions

View File

@@ -30358,6 +30358,7 @@ package android.os {
method public void setDataCapacity(int); method public void setDataCapacity(int);
method public void setDataPosition(int); method public void setDataPosition(int);
method public void setDataSize(int); method public void setDataSize(int);
method public void setPropagateAllowBlocking();
method public void unmarshall(@NonNull byte[], int, int); method public void unmarshall(@NonNull byte[], int, int);
method public void writeArray(@Nullable Object[]); method public void writeArray(@Nullable Object[]);
method public void writeBinderArray(@Nullable android.os.IBinder[]); method public void writeBinderArray(@Nullable android.os.IBinder[]);

View File

@@ -1707,8 +1707,11 @@ package android.os {
public final class Parcel { public final class Parcel {
method public boolean allowSquashing(); method public boolean allowSquashing();
method public int getFlags();
method public int readExceptionCode(); method public int readExceptionCode();
method public void restoreAllowSquashing(boolean); 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 { public class ParcelFileDescriptor implements java.io.Closeable android.os.Parcelable {

View File

@@ -516,12 +516,15 @@ public final class BinderProxy implements IBinder {
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer"); 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()) { && Binder.sWarnOnBlockingOnCurrentThread.get()) {
// For now, avoid spamming the log by disabling after we've logged // For now, avoid spamming the log by disabling after we've logged
// about this interface at least once // about this interface at least once
mWarnOnBlocking = false; mWarnOnBlocking = false;
warnOnBlocking = false;
if (Build.IS_USERDEBUG) { if (Build.IS_USERDEBUG) {
// Log this as a WTF on userdebug builds. // Log this as a WTF on userdebug builds.
@@ -568,7 +571,13 @@ public final class BinderProxy implements IBinder {
} }
try { 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 { } finally {
AppOpsManager.resumeNotedAppOpsCollection(prevCollection); AppOpsManager.resumeNotedAppOpsCollection(prevCollection);

View File

@@ -18,6 +18,7 @@ package android.os;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@@ -53,6 +54,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass; import java.io.ObjectStreamClass;
import java.io.Serializable; import java.io.Serializable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
@@ -229,6 +232,25 @@ public final class Parcel {
private RuntimeException mStack; 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 * 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. * 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); 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. * Returns the total amount of data contained in the parcel.
*/ */
@@ -3036,7 +3092,15 @@ public final class Parcel {
* Read an object from the parcel at the current dataPosition(). * Read an object from the parcel at the current dataPosition().
*/ */
public final IBinder readStrongBinder() { 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;
} }
/** /**
@@ -4988,6 +5052,7 @@ public final class Parcel {
} }
private void freeBuffer() { private void freeBuffer() {
mFlags = 0;
resetSqaushingState(); resetSqaushingState();
if (mOwnsNativeParcelObject) { if (mOwnsNativeParcelObject) {
nativeFreeBuffer(mNativePtr); nativeFreeBuffer(mNativePtr);