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

Commit cb4dd279 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Translate selection arguments that are paths."

parents a30e5c38 bffd2508
Loading
Loading
Loading
Loading
+59 −19
Original line number Original line Diff line number Diff line
@@ -209,9 +209,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
     * @hide
     * @hide
     */
     */
    class Transport extends ContentProviderNative {
    class Transport extends ContentProviderNative {
        AppOpsManager mAppOpsManager = null;
        volatile AppOpsManager mAppOpsManager = null;
        int mReadOp = AppOpsManager.OP_NONE;
        volatile int mReadOp = AppOpsManager.OP_NONE;
        int mWriteOp = AppOpsManager.OP_NONE;
        volatile int mWriteOp = AppOpsManager.OP_NONE;
        volatile ContentInterface mInterface = ContentProvider.this;


        ContentProvider getContentProvider() {
        ContentProvider getContentProvider() {
            return ContentProvider.this;
            return ContentProvider.this;
@@ -245,9 +246,11 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
                Cursor cursor;
                Cursor cursor;
                final String original = setCallingPackage(callingPkg);
                final String original = setCallingPackage(callingPkg);
                try {
                try {
                    cursor = ContentProvider.this.query(
                    cursor = mInterface.query(
                            uri, projection, queryArgs,
                            uri, projection, queryArgs,
                            CancellationSignal.fromTransport(cancellationSignal));
                            CancellationSignal.fromTransport(cancellationSignal));
                } catch (RemoteException e) {
                    throw e.rethrowAsRuntimeException();
                } finally {
                } finally {
                    setCallingPackage(original);
                    setCallingPackage(original);
                }
                }
@@ -261,9 +264,11 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "query");
            Trace.traceBegin(TRACE_TAG_DATABASE, "query");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.query(
                return mInterface.query(
                        uri, projection, queryArgs,
                        uri, projection, queryArgs,
                        CancellationSignal.fromTransport(cancellationSignal));
                        CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -277,7 +282,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            uri = maybeGetUriWithoutUserId(uri);
            uri = maybeGetUriWithoutUserId(uri);
            Trace.traceBegin(TRACE_TAG_DATABASE, "getType");
            Trace.traceBegin(TRACE_TAG_DATABASE, "getType");
            try {
            try {
                return ContentProvider.this.getType(uri);
                return mInterface.getType(uri);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
            }
            }
@@ -299,7 +306,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "insert");
            Trace.traceBegin(TRACE_TAG_DATABASE, "insert");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return maybeAddUserId(ContentProvider.this.insert(uri, initialValues), userId);
                return maybeAddUserId(mInterface.insert(uri, initialValues), userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -316,7 +325,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "bulkInsert");
            Trace.traceBegin(TRACE_TAG_DATABASE, "bulkInsert");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.bulkInsert(uri, initialValues);
                return mInterface.bulkInsert(uri, initialValues);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -357,7 +368,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "applyBatch");
            Trace.traceBegin(TRACE_TAG_DATABASE, "applyBatch");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                ContentProviderResult[] results = ContentProvider.this.applyBatch(authority,
                ContentProviderResult[] results = mInterface.applyBatch(authority,
                        operations);
                        operations);
                if (results != null) {
                if (results != null) {
                    for (int i = 0; i < results.length ; i++) {
                    for (int i = 0; i < results.length ; i++) {
@@ -368,6 +379,8 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
                    }
                    }
                }
                }
                return results;
                return results;
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -384,7 +397,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "delete");
            Trace.traceBegin(TRACE_TAG_DATABASE, "delete");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.delete(uri, selection, selectionArgs);
                return mInterface.delete(uri, selection, selectionArgs);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -402,7 +417,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "update");
            Trace.traceBegin(TRACE_TAG_DATABASE, "update");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.update(uri, values, selection, selectionArgs);
                return mInterface.update(uri, values, selection, selectionArgs);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -419,8 +436,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "openFile");
            Trace.traceBegin(TRACE_TAG_DATABASE, "openFile");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.openFile(
                return mInterface.openFile(
                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -437,8 +456,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "openAssetFile");
            Trace.traceBegin(TRACE_TAG_DATABASE, "openAssetFile");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.openAssetFile(
                return mInterface.openAssetFile(
                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -453,7 +474,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "call");
            Trace.traceBegin(TRACE_TAG_DATABASE, "call");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.call(authority, method, arg, extras);
                return mInterface.call(authority, method, arg, extras);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -467,7 +490,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            uri = maybeGetUriWithoutUserId(uri);
            uri = maybeGetUriWithoutUserId(uri);
            Trace.traceBegin(TRACE_TAG_DATABASE, "getStreamTypes");
            Trace.traceBegin(TRACE_TAG_DATABASE, "getStreamTypes");
            try {
            try {
                return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
                return mInterface.getStreamTypes(uri, mimeTypeFilter);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
            }
            }
@@ -483,8 +508,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "openTypedAssetFile");
            Trace.traceBegin(TRACE_TAG_DATABASE, "openTypedAssetFile");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.openTypedAssetFile(
                return mInterface.openTypedAssetFile(
                        uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
                        uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -507,7 +534,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "canonicalize");
            Trace.traceBegin(TRACE_TAG_DATABASE, "canonicalize");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return maybeAddUserId(ContentProvider.this.canonicalize(uri), userId);
                return maybeAddUserId(mInterface.canonicalize(uri), userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -525,7 +554,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "uncanonicalize");
            Trace.traceBegin(TRACE_TAG_DATABASE, "uncanonicalize");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return maybeAddUserId(ContentProvider.this.uncanonicalize(uri), userId);
                return maybeAddUserId(mInterface.uncanonicalize(uri), userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
                Trace.traceEnd(TRACE_TAG_DATABASE);
@@ -543,7 +574,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            Trace.traceBegin(TRACE_TAG_DATABASE, "refresh");
            Trace.traceBegin(TRACE_TAG_DATABASE, "refresh");
            final String original = setCallingPackage(callingPkg);
            final String original = setCallingPackage(callingPkg);
            try {
            try {
                return ContentProvider.this.refresh(uri, args,
                return mInterface.refresh(uri, args,
                        CancellationSignal.fromTransport(cancellationSignal));
                        CancellationSignal.fromTransport(cancellationSignal));
            } finally {
            } finally {
                setCallingPackage(original);
                setCallingPackage(original);
@@ -986,6 +1017,15 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
        return mTransport.mAppOpsManager;
        return mTransport.mAppOpsManager;
    }
    }


    /** @hide */
    public final void setTransportLoggingEnabled(boolean enabled) {
        if (enabled) {
            mTransport.mInterface = new LoggingContentInterface(getClass().getSimpleName(), this);
        } else {
            mTransport.mInterface = this;
        }
    }

    /**
    /**
     * Implement this to initialize your content provider on startup.
     * Implement this to initialize your content provider on startup.
     * This method is called for all registered content providers on the
     * This method is called for all registered content providers on the
+199 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.content;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * Instance of {@link ContentInterface} that logs all inputs and outputs while
 * delegating to another {@link ContentInterface}.
 *
 * @hide
 */
public class LoggingContentInterface implements ContentInterface {
    private final String tag;
    private final ContentInterface delegate;

    public LoggingContentInterface(String tag, ContentInterface delegate) {
        this.tag = tag;
        this.delegate = delegate;
    }

    private void log(String method, Object res, Object... args) {
        // First, force-unparcel any bundles so we can log them
        for (Object arg : args) {
            if (arg instanceof Bundle) {
                ((Bundle) arg).size();
            }
        }

        final StringBuilder sb = new StringBuilder();
        sb.append("callingUid=").append(Binder.getCallingUid()).append(' ');
        sb.append(method);
        sb.append('(').append(deepToString(args)).append(')');
        if (res instanceof Cursor) {
            sb.append('\n');
            DatabaseUtils.dumpCursor((Cursor) res, sb);
        } else {
            sb.append(" = ").append(deepToString(res));
        }
        Log.v(tag, sb.toString());
    }

    private String deepToString(Object value) {
        if (value != null && value.getClass().isArray()) {
            return Arrays.deepToString((Object[]) value);
        } else {
            return String.valueOf(value);
        }
    }

    @Override
    public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
            @Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal)
            throws RemoteException {
        final Cursor res = delegate.query(uri, projection, queryArgs, cancellationSignal);
        log("query", res, uri, projection, queryArgs, cancellationSignal);
        return res;
    }

    @Override
    public @Nullable String getType(@NonNull Uri uri) throws RemoteException {
        final String res = delegate.getType(uri);
        log("getType", res, uri);
        return res;
    }

    @Override
    public @Nullable String[] getStreamTypes(@NonNull Uri uri, @NonNull String mimeTypeFilter)
            throws RemoteException {
        final String[] res = delegate.getStreamTypes(uri, mimeTypeFilter);
        log("getStreamTypes", res, uri, mimeTypeFilter);
        return res;
    }

    @Override
    public @Nullable Uri canonicalize(@NonNull Uri uri) throws RemoteException {
        final Uri res = delegate.canonicalize(uri);
        log("canonicalize", res, uri);
        return res;
    }

    @Override
    public @Nullable Uri uncanonicalize(@NonNull Uri uri) throws RemoteException {
        final Uri res = delegate.uncanonicalize(uri);
        log("uncanonicalize", res, uri);
        return res;
    }

    @Override
    public boolean refresh(@NonNull Uri uri, @Nullable Bundle args,
            @Nullable CancellationSignal cancellationSignal) throws RemoteException {
        final boolean res = delegate.refresh(uri, args, cancellationSignal);
        log("refresh", res, uri, args, cancellationSignal);
        return res;
    }

    @Override
    public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
            throws RemoteException {
        final Uri res = delegate.insert(uri, initialValues);
        log("insert", res, uri, initialValues);
        return res;
    }

    @Override
    public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] initialValues)
            throws RemoteException {
        final int res = delegate.bulkInsert(uri, initialValues);
        log("bulkInsert", res, uri, initialValues);
        return res;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection,
            @Nullable String[] selectionArgs) throws RemoteException {
        final int res = delegate.delete(uri, selection, selectionArgs);
        log("delete", res, uri, selection, selectionArgs);
        return res;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
            @Nullable String[] selectionArgs) throws RemoteException {
        final int res = delegate.update(uri, values, selection, selectionArgs);
        log("update", res, uri, values, selection, selectionArgs);
        return res;
    }

    @Override
    public @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode,
            @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
        final ParcelFileDescriptor res = delegate.openFile(uri, mode, signal);
        log("openFile", res, uri, mode, signal);
        return res;
    }

    @Override
    public @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode,
            @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
        final AssetFileDescriptor res = delegate.openAssetFile(uri, mode, signal);
        log("openAssetFile", res, uri, mode, signal);
        return res;
    }

    @Override
    public @Nullable AssetFileDescriptor openTypedAssetFile(@NonNull Uri uri,
            @NonNull String mimeTypeFilter, @Nullable Bundle opts,
            @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
        final AssetFileDescriptor res = delegate.openTypedAssetFile(uri, mimeTypeFilter, opts, signal);
        log("openTypedAssetFile", res, uri, mimeTypeFilter, opts, signal);
        return res;
    }

    @Override
    public @NonNull ContentProviderResult[] applyBatch(@NonNull String authority,
            @NonNull ArrayList<ContentProviderOperation> operations)
            throws RemoteException, OperationApplicationException {
        final ContentProviderResult[] res = delegate.applyBatch(authority, operations);
        log("applyBatch", res, authority, operations);
        return res;
    }

    @Override
    public @Nullable Bundle call(@NonNull String authority, @NonNull String method,
            @Nullable String arg, @Nullable Bundle extras) throws RemoteException {
        final Bundle res = delegate.call(authority, method, arg, extras);
        log("call", res, authority, method, arg, extras);
        return res;
    }
}
+4 −1
Original line number Original line Diff line number Diff line
@@ -19,6 +19,9 @@ package android.util;
import libcore.util.EmptyArray;
import libcore.util.EmptyArray;


import android.annotation.UnsupportedAppUsage;
import android.annotation.UnsupportedAppUsage;

import com.android.internal.util.ArrayUtils;

import java.util.Collection;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.Map;
@@ -816,7 +819,7 @@ public final class ArrayMap<K, V> implements Map<K, V> {
            buffer.append('=');
            buffer.append('=');
            Object value = valueAt(i);
            Object value = valueAt(i);
            if (value != this) {
            if (value != this) {
                buffer.append(value);
                buffer.append(ArrayUtils.deepToString(value));
            } else {
            } else {
                buffer.append("(this Map)");
                buffer.append("(this Map)");
            }
            }
+26 −0
Original line number Original line Diff line number Diff line
@@ -712,4 +712,30 @@ public class ArrayUtils {
        }
        }
        return null;
        return null;
    }
    }

    public static String deepToString(Object value) {
        if (value != null && value.getClass().isArray()) {
            if (value.getClass() == boolean[].class) {
                return Arrays.toString((boolean[]) value);
            } else if (value.getClass() == byte[].class) {
                return Arrays.toString((byte[]) value);
            } else if (value.getClass() == char[].class) {
                return Arrays.toString((char[]) value);
            } else if (value.getClass() == double[].class) {
                return Arrays.toString((double[]) value);
            } else if (value.getClass() == float[].class) {
                return Arrays.toString((float[]) value);
            } else if (value.getClass() == int[].class) {
                return Arrays.toString((int[]) value);
            } else if (value.getClass() == long[].class) {
                return Arrays.toString((long[]) value);
            } else if (value.getClass() == short[].class) {
                return Arrays.toString((short[]) value);
            } else {
                return Arrays.deepToString((Object[]) value);
            }
        } else {
            return String.valueOf(value);
        }
    }
}
}