Loading core/java/android/content/ContentProvider.java +59 −19 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading @@ -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); Loading @@ -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); } } Loading @@ -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); Loading @@ -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); Loading Loading @@ -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++) { Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); } } Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading Loading @@ -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 Loading core/java/android/content/LoggingContentInterface.java 0 → 100644 +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; } } core/java/android/util/ArrayMap.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)"); } } Loading core/java/com/android/internal/util/ArrayUtils.java +26 −0 Original line number Original line Diff line number Diff line Loading @@ -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); } } } } Loading
core/java/android/content/ContentProvider.java +59 −19 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading @@ -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); Loading @@ -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); } } Loading @@ -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); Loading @@ -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); Loading Loading @@ -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++) { Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); } } Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading Loading @@ -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 Loading
core/java/android/content/LoggingContentInterface.java 0 → 100644 +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; } }
core/java/android/util/ArrayMap.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)"); } } Loading
core/java/com/android/internal/util/ArrayUtils.java +26 −0 Original line number Original line Diff line number Diff line Loading @@ -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); } } } }