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

Commit 4ba69239 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Offer API to detect ContentProvider ANRs.

If a system component calls to a remote provider, and that provider
hangs, we end up burning that Binder thread until the remote process
is killed for some unrelated reason.

This change adds an API to detect these hangs, and kill the remote
process after a specific timeout, but only when the caller holds a
permission that lets them kill other apps.

Bug: 117635768
Test: atest android.content.cts.ContentResolverTest
Change-Id: I81b0d993d9d585cdeb5e2559c68052ba6cbbced9
parent e770d22d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1036,6 +1036,10 @@ package android.bluetooth.le {

package android.content {

  public class ContentProviderClient implements java.lang.AutoCloseable android.content.ContentInterface {
    method public void setDetectNotResponding(long);
  }

  public abstract class Context {
    method public boolean bindServiceAsUser(android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle);
    method public abstract android.content.Context createCredentialProtectedStorageContext();
+4 −0
Original line number Diff line number Diff line
@@ -299,6 +299,10 @@ package android.bluetooth {

package android.content {

  public class ContentProviderClient implements java.lang.AutoCloseable android.content.ContentInterface {
    method public void setDetectNotResponding(long);
  }

  public abstract class ContentResolver implements android.content.ContentInterface {
    method public static java.lang.String[] getSyncAdapterPackagesForAuthorityAsUser(java.lang.String, int);
  }
+18 −2
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@

package android.content;

import android.annotation.DurationMillisLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetFileDescriptor;
import android.database.CrossProcessCursorWrapper;
@@ -106,8 +110,20 @@ public class ContentProviderClient implements ContentInterface, AutoCloseable {
        mCloseGuard.open("close");
    }

    /** {@hide} */
    public void setDetectNotResponding(long timeoutMillis) {
    /**
     * Configure this client to automatically detect and kill the remote
     * provider when an "application not responding" event is detected.
     *
     * @param timeoutMillis the duration for which a pending call is allowed
     *            block before the remote provider is considered to be
     *            unresponsive. Set to {@code 0} to allow pending calls to block
     *            indefinitely with no action taken.
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(android.Manifest.permission.REMOVE_TASKS)
    public void setDetectNotResponding(@DurationMillisLong long timeoutMillis) {
        synchronized (ContentProviderClient.class) {
            mAnrTimeout = timeoutMillis;

+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
    <uses-permission android:name="android.permission.REORDER_TASKS" />
    <uses-permission android:name="android.permission.REMOVE_TASKS" />
    <uses-permission android:name="android.permission.SET_ANIMATION_SCALE" />
    <uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />