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

Commit 715a1c65 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Add async version of getProviderMimeType"

parents f394f378 d55a387f
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -303,8 +303,13 @@ interface IActivityManager {
    boolean isTopActivityImmersive();
    void crashApplication(int uid, int initialPid, in String packageName, int userId,
            in String message, boolean force);
    @UnsupportedAppUsage
    /** @deprecated -- use getProviderMimeTypeAsync */
    @UnsupportedAppUsage(maxTargetSdk = 29, publicAlternatives =
            "Use {@link android.content.ContentResolver#getType} public API instead.")
    String getProviderMimeType(in Uri uri, int userId);

    oneway void getProviderMimeTypeAsync(in Uri uri, int userId, in RemoteCallback resultCallback);

    // Cause the specified process to dump the specified heap.
    boolean dumpHeap(in String process, int userId, boolean managed, boolean mallocInfo,
            boolean runGc, in String path, in ParcelFileDescriptor fd,
+8 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
@@ -299,6 +300,13 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            }
        }

        @Override
        public void getTypeAsync(Uri uri, RemoteCallback callback) {
            final Bundle result = new Bundle();
            result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri));
            callback.sendResult(result);
        }

        @Override
        public Uri insert(String callingPkg, @Nullable String featureId, Uri uri,
                ContentValues initialValues, Bundle extras) {
+25 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.os.ICancellationSignal;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.RemoteCallback;
import android.os.RemoteException;

import java.io.FileNotFoundException;
@@ -146,6 +147,14 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
                    return true;
                }

                case GET_TYPE_ASYNC_TRANSACTION: {
                    data.enforceInterface(IContentProvider.descriptor);
                    Uri url = Uri.CREATOR.createFromParcel(data);
                    RemoteCallback callback = RemoteCallback.CREATOR.createFromParcel(data);
                    getTypeAsync(url, callback);
                    return true;
                }

                case INSERT_TRANSACTION:
                {
                    data.enforceInterface(IContentProvider.descriptor);
@@ -494,6 +503,22 @@ final class ContentProviderProxy implements IContentProvider
        }
    }

    @Override
    /* oneway */ public void getTypeAsync(Uri uri, RemoteCallback callback) throws RemoteException {
        Parcel data = Parcel.obtain();
        try {
            data.writeInterfaceToken(IContentProvider.descriptor);

            uri.writeToParcel(data, 0);
            callback.writeToParcel(data, 0);

            mRemote.transact(IContentProvider.GET_TYPE_ASYNC_TRANSACTION, data, null,
                    IBinder.FLAG_ONEWAY);
        } finally {
            data.recycle();
        }
    }

    @Override
    public Uri insert(String callingPkg, @Nullable String featureId, Uri url,
            ContentValues values, Bundle extras) throws RemoteException
+49 −5
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -67,6 +68,7 @@ import android.util.Log;
import android.util.Size;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.MimeIconUtils;

import dalvik.system.CloseGuard;
@@ -695,6 +697,9 @@ public abstract class ContentResolver implements ContentInterface {
    private static final int SLOW_THRESHOLD_MILLIS = 500;
    private final Random mRandom = new Random();  // guarded by itself

    /** @hide */
    public static final String REMOTE_CALLBACK_RESULT = "result";

    public ContentResolver(@Nullable Context context) {
        this(context, null);
    }
@@ -807,7 +812,10 @@ public abstract class ContentResolver implements ContentInterface {
        IContentProvider provider = acquireExistingProvider(url);
        if (provider != null) {
            try {
                return provider.getType(url);
                final GetTypeResultListener resultListener = new GetTypeResultListener();
                provider.getTypeAsync(url, new RemoteCallback(resultListener));
                resultListener.waitForResult();
                return resultListener.type;
            } catch (RemoteException e) {
                // Arbitrary and not worth documenting, as Activity
                // Manager will kill this process shortly anyway.
@@ -825,17 +833,53 @@ public abstract class ContentResolver implements ContentInterface {
        }

        try {
            String type = ActivityManager.getService().getProviderMimeType(
                    ContentProvider.getUriWithoutUserId(url), resolveUserId(url));
            return type;
            GetTypeResultListener resultListener = new GetTypeResultListener();
            ActivityManager.getService().getProviderMimeTypeAsync(
                    ContentProvider.getUriWithoutUserId(url),
                    resolveUserId(url),
                    new RemoteCallback(resultListener));
            resultListener.waitForResult();
            return resultListener.type;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            // We just failed to send a oneway request to the System Server. Nothing to do.
            return null;
        } catch (java.lang.Exception e) {
            Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")");
            return null;
        }
    }

    private static final int GET_TYPE_TIMEOUT_MILLIS = 3000;

    private static class GetTypeResultListener implements RemoteCallback.OnResultListener {
        @GuardedBy("this")
        public boolean done;

        @GuardedBy("this")
        public String type;

        @Override
        public void onResult(Bundle result) {
            synchronized (this) {
                type = result.getString(REMOTE_CALLBACK_RESULT);
                done = true;
                notifyAll();
            }
        }

        public void waitForResult() {
            synchronized (this) {
                if (!done) {
                    try {
                        wait(GET_TYPE_TIMEOUT_MILLIS);
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }
            }
        }
    }

    /**
     * Query for the possible MIME types for the representations the given
     * content URL can be returned when opened as as stream with
+10 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.IInterface;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallback;
import android.os.RemoteException;

import java.io.FileNotFoundException;
@@ -42,6 +43,14 @@ public interface IContentProvider extends IInterface {
            @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal)
            throws RemoteException;
    public String getType(Uri url) throws RemoteException;

    /**
     * An oneway version of getType. The functionality is exactly the same, except that the
     * call returns immediately, and the resulting type is returned when available via
     * a binder callback.
     */
    void getTypeAsync(Uri uri, RemoteCallback callback) throws RemoteException;

    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
            + "ContentProviderClient#insert(android.net.Uri, android.content.ContentValues)} "
@@ -152,4 +161,5 @@ public interface IContentProvider extends IInterface {
    static final int UNCANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 25;
    static final int REFRESH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 26;
    static final int CHECK_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 27;
    int GET_TYPE_ASYNC_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 28;
}
Loading