Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5918948d authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

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
parent 903ed1b6
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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 {
+13 −0
Original line number Diff line number Diff line
@@ -192,6 +192,19 @@ public class Binder implements IBinder {
        return binder;
    }

    /**
     * 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.