summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2022-02-02 16:21:40 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2022-02-02 16:21:40 +0000
commit4dbefbccd54c80e653f41e5a85655eb81ab4aec2 (patch)
treef55c138c493eda59af0de8f59843246e85134851
parentf30f967e5a1c5434f228bf12e13279d51088de9d (diff)
parent7d4245bc616f62c7dc96eb2243b8c90fa2ee184d (diff)
Merge "Support "Parcel.propagateAllowBlocking" for AIDL" am: bcefef7a8c am: 7d4245bc61
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1964223 Change-Id: I77917e4f9e7c29f93817bdc2fb96e051c4abfaa9
-rw-r--r--core/api/current.txt1
-rw-r--r--core/api/test-current.txt3
-rw-r--r--core/java/android/os/BinderProxy.java13
-rw-r--r--core/java/android/os/Parcel.java67
4 files changed, 81 insertions, 3 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index d400f98aab12..6a72017c9610 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -30358,6 +30358,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 18ceb2598766..88ab380893b3 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1707,8 +1707,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 2a2cbb996751..71c63ffd841c 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -516,12 +516,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.
@@ -568,7 +571,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 004c02091d75..13d1d96fadc8 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.
*/
@@ -3036,7 +3092,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;
}
/**
@@ -4988,6 +5052,7 @@ public final class Parcel {
}
private void freeBuffer() {
+ mFlags = 0;
resetSqaushingState();
if (mOwnsNativeParcelObject) {
nativeFreeBuffer(mNativePtr);