summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2017-11-09 18:13:43 -0700
committerJeff Sharkey <jsharkey@android.com>2017-11-09 18:32:37 -0700
commit5918948db7c5058af30b143e7336090ef8dac202 (patch)
tree4bee06d1b6d4d9533ffd0bec408c311874e1782b /core/java
parent903ed1b6f9947ac919e9d110d4b82d25a3ff0de0 (diff)
Allow blocking calls when protected against ANRs.
ContentProviderClient has a nice setDetectNotResponding() method that detects hanging calls to remote providers, and it can trigger an ANR to kill the app and release the blocked thread. We typically don't want to perform blocking calls from the system server, but we're okay allowing them on CPCs that are using setDetectNotResponding() to watch for hung clients. Test: builds, boots Bug: 69128093 Change-Id: I223aaf1d0cef0f8dee28f800d9e3c101d7449952
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/content/ContentProviderClient.java13
-rw-r--r--core/java/android/os/Binder.java13
2 files changed, 26 insertions, 0 deletions
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index f8c139feaae3..2d490a03bd76 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -22,6 +22,7 @@ import android.content.res.AssetFileDescriptor;
import android.database.CrossProcessCursorWrapper;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.DeadObjectException;
@@ -102,8 +103,16 @@ public class ContentProviderClient implements AutoCloseable {
if (sAnrHandler == null) {
sAnrHandler = new Handler(Looper.getMainLooper(), null, true /* async */);
}
+
+ // If the remote process hangs, we're going to kill it, so we're
+ // technically okay doing blocking calls.
+ Binder.allowBlocking(mContentProvider.asBinder());
} else {
mAnrRunnable = null;
+
+ // If we're no longer watching for hangs, revert back to default
+ // blocking behavior.
+ Binder.defaultBlocking(mContentProvider.asBinder());
}
}
}
@@ -511,6 +520,10 @@ public class ContentProviderClient implements AutoCloseable {
private boolean closeInternal() {
mCloseGuard.close();
if (mClosed.compareAndSet(false, true)) {
+ // We can't do ANR checks after we cease to exist! Reset any
+ // blocking behavior changes we might have made.
+ setDetectNotResponding(0);
+
if (mStable) {
return mContentResolver.releaseProvider(mContentProvider);
} else {
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 2bfb0138b7dd..b5bcd02c1a18 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -193,6 +193,19 @@ public class Binder implements IBinder {
}
/**
+ * Reset the given interface back to the default blocking behavior,
+ * reverting any changes made by {@link #allowBlocking(IBinder)}.
+ *
+ * @hide
+ */
+ public static IBinder defaultBlocking(IBinder binder) {
+ if (binder instanceof BinderProxy) {
+ ((BinderProxy) binder).mWarnOnBlocking = sWarnOnBlocking;
+ }
+ return binder;
+ }
+
+ /**
* Inherit the current {@link #allowBlocking(IBinder)} value from one given
* interface to another.
*