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

Commit 60cfad80 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Discourage use of "_data" column.

Moving forward, all client file access really needs to be going
through explicit APIs like openFileDescriptor(), since that allows
the provider to better protect its underlying files.

This change also changes several classes to use the AutoClosable
pattern, which enables try-with-resources usage.  Older release()
methods are deprecated in favor of close().

Uniformly apply CloseGuard across several classes, using
AtomicBoolean to avoid double-freeing, and fix several resource
leaks and bugs related to MediaScanner allocation.  Switch
MediaScanner and friends to use public API instead of raw AIDL calls.

Bug: 22958127
Change-Id: Id722379f72c9e4b80d8b72550d7ce90e5e2bc786
parent 6a40ac6c
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -4228,7 +4228,7 @@ package android.app {
    field public static final java.lang.String COLUMN_DESCRIPTION = "description";
    field public static final java.lang.String COLUMN_ID = "_id";
    field public static final java.lang.String COLUMN_LAST_MODIFIED_TIMESTAMP = "last_modified_timestamp";
    field public static final java.lang.String COLUMN_LOCAL_FILENAME = "local_filename";
    field public static final deprecated java.lang.String COLUMN_LOCAL_FILENAME = "local_filename";
    field public static final java.lang.String COLUMN_LOCAL_URI = "local_uri";
    field public static final java.lang.String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
    field public static final java.lang.String COLUMN_MEDIA_TYPE = "media_type";
@@ -7568,11 +7568,12 @@ package android.content {
    method public abstract void writeDataToPipe(android.os.ParcelFileDescriptor, android.net.Uri, java.lang.String, android.os.Bundle, T);
  }
  public class ContentProviderClient {
  public class ContentProviderClient implements java.lang.AutoCloseable {
    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException;
    method public int bulkInsert(android.net.Uri, android.content.ContentValues[]) throws android.os.RemoteException;
    method public android.os.Bundle call(java.lang.String, java.lang.String, android.os.Bundle) throws android.os.RemoteException;
    method public final android.net.Uri canonicalize(android.net.Uri) throws android.os.RemoteException;
    method public void close();
    method public int delete(android.net.Uri, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
    method public android.content.ContentProvider getLocalContentProvider();
    method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String) throws android.os.RemoteException;
@@ -7586,7 +7587,7 @@ package android.content {
    method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException;
    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) throws android.os.RemoteException;
    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal) throws android.os.RemoteException;
    method public boolean release();
    method public deprecated boolean release();
    method public final android.net.Uri uncanonicalize(android.net.Uri) throws android.os.RemoteException;
    method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
  }
@@ -10844,7 +10845,7 @@ package android.drm {
    field public final int statusCode;
  }
  public class DrmManagerClient {
  public class DrmManagerClient implements java.lang.AutoCloseable {
    ctor public DrmManagerClient(android.content.Context);
    method public android.drm.DrmInfo acquireDrmInfo(android.drm.DrmInfoRequest);
    method public int acquireRights(android.drm.DrmInfoRequest);
@@ -10854,6 +10855,7 @@ package android.drm {
    method public int checkRightsStatus(android.net.Uri);
    method public int checkRightsStatus(java.lang.String, int);
    method public int checkRightsStatus(android.net.Uri, int);
    method public void close();
    method public android.drm.DrmConvertedStatus closeConvertSession(int);
    method public android.drm.DrmConvertedStatus convertData(int, byte[]);
    method public java.lang.String[] getAvailableDrmEngines();
@@ -10867,7 +10869,7 @@ package android.drm {
    method public java.lang.String getOriginalMimeType(android.net.Uri);
    method public int openConvertSession(java.lang.String);
    method public int processDrmInfo(android.drm.DrmInfo);
    method public void release();
    method public deprecated void release();
    method public int removeAllRights();
    method public int removeRights(java.lang.String);
    method public int removeRights(android.net.Uri);
+7 −5
Original line number Diff line number Diff line
@@ -4348,7 +4348,7 @@ package android.app {
    field public static final java.lang.String COLUMN_DESCRIPTION = "description";
    field public static final java.lang.String COLUMN_ID = "_id";
    field public static final java.lang.String COLUMN_LAST_MODIFIED_TIMESTAMP = "last_modified_timestamp";
    field public static final java.lang.String COLUMN_LOCAL_FILENAME = "local_filename";
    field public static final deprecated java.lang.String COLUMN_LOCAL_FILENAME = "local_filename";
    field public static final java.lang.String COLUMN_LOCAL_URI = "local_uri";
    field public static final java.lang.String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
    field public static final java.lang.String COLUMN_MEDIA_TYPE = "media_type";
@@ -7811,11 +7811,12 @@ package android.content {
    method public abstract void writeDataToPipe(android.os.ParcelFileDescriptor, android.net.Uri, java.lang.String, android.os.Bundle, T);
  }
  public class ContentProviderClient {
  public class ContentProviderClient implements java.lang.AutoCloseable {
    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException;
    method public int bulkInsert(android.net.Uri, android.content.ContentValues[]) throws android.os.RemoteException;
    method public android.os.Bundle call(java.lang.String, java.lang.String, android.os.Bundle) throws android.os.RemoteException;
    method public final android.net.Uri canonicalize(android.net.Uri) throws android.os.RemoteException;
    method public void close();
    method public int delete(android.net.Uri, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
    method public android.content.ContentProvider getLocalContentProvider();
    method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String) throws android.os.RemoteException;
@@ -7829,7 +7830,7 @@ package android.content {
    method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException;
    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) throws android.os.RemoteException;
    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal) throws android.os.RemoteException;
    method public boolean release();
    method public deprecated boolean release();
    method public final android.net.Uri uncanonicalize(android.net.Uri) throws android.os.RemoteException;
    method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
  }
@@ -11198,7 +11199,7 @@ package android.drm {
    field public final int statusCode;
  }
  public class DrmManagerClient {
  public class DrmManagerClient implements java.lang.AutoCloseable {
    ctor public DrmManagerClient(android.content.Context);
    method public android.drm.DrmInfo acquireDrmInfo(android.drm.DrmInfoRequest);
    method public int acquireRights(android.drm.DrmInfoRequest);
@@ -11208,6 +11209,7 @@ package android.drm {
    method public int checkRightsStatus(android.net.Uri);
    method public int checkRightsStatus(java.lang.String, int);
    method public int checkRightsStatus(android.net.Uri, int);
    method public void close();
    method public android.drm.DrmConvertedStatus closeConvertSession(int);
    method public android.drm.DrmConvertedStatus convertData(int, byte[]);
    method public java.lang.String[] getAvailableDrmEngines();
@@ -11221,7 +11223,7 @@ package android.drm {
    method public java.lang.String getOriginalMimeType(android.net.Uri);
    method public int openConvertSession(java.lang.String);
    method public int processDrmInfo(android.drm.DrmInfo);
    method public void release();
    method public deprecated void release();
    method public int removeAllRights();
    method public int removeRights(java.lang.String);
    method public int removeRights(android.net.Uri);
+7 −5
Original line number Diff line number Diff line
@@ -4228,7 +4228,7 @@ package android.app {
    field public static final java.lang.String COLUMN_DESCRIPTION = "description";
    field public static final java.lang.String COLUMN_ID = "_id";
    field public static final java.lang.String COLUMN_LAST_MODIFIED_TIMESTAMP = "last_modified_timestamp";
    field public static final java.lang.String COLUMN_LOCAL_FILENAME = "local_filename";
    field public static final deprecated java.lang.String COLUMN_LOCAL_FILENAME = "local_filename";
    field public static final java.lang.String COLUMN_LOCAL_URI = "local_uri";
    field public static final java.lang.String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
    field public static final java.lang.String COLUMN_MEDIA_TYPE = "media_type";
@@ -7568,11 +7568,12 @@ package android.content {
    method public abstract void writeDataToPipe(android.os.ParcelFileDescriptor, android.net.Uri, java.lang.String, android.os.Bundle, T);
  }
  public class ContentProviderClient {
  public class ContentProviderClient implements java.lang.AutoCloseable {
    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException;
    method public int bulkInsert(android.net.Uri, android.content.ContentValues[]) throws android.os.RemoteException;
    method public android.os.Bundle call(java.lang.String, java.lang.String, android.os.Bundle) throws android.os.RemoteException;
    method public final android.net.Uri canonicalize(android.net.Uri) throws android.os.RemoteException;
    method public void close();
    method public int delete(android.net.Uri, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
    method public android.content.ContentProvider getLocalContentProvider();
    method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String) throws android.os.RemoteException;
@@ -7586,7 +7587,7 @@ package android.content {
    method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException;
    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) throws android.os.RemoteException;
    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal) throws android.os.RemoteException;
    method public boolean release();
    method public deprecated boolean release();
    method public final android.net.Uri uncanonicalize(android.net.Uri) throws android.os.RemoteException;
    method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
  }
@@ -10844,7 +10845,7 @@ package android.drm {
    field public final int statusCode;
  }
  public class DrmManagerClient {
  public class DrmManagerClient implements java.lang.AutoCloseable {
    ctor public DrmManagerClient(android.content.Context);
    method public android.drm.DrmInfo acquireDrmInfo(android.drm.DrmInfoRequest);
    method public int acquireRights(android.drm.DrmInfoRequest);
@@ -10854,6 +10855,7 @@ package android.drm {
    method public int checkRightsStatus(android.net.Uri);
    method public int checkRightsStatus(java.lang.String, int);
    method public int checkRightsStatus(android.net.Uri, int);
    method public void close();
    method public android.drm.DrmConvertedStatus closeConvertSession(int);
    method public android.drm.DrmConvertedStatus convertData(int, byte[]);
    method public java.lang.String[] getAvailableDrmEngines();
@@ -10867,7 +10869,7 @@ package android.drm {
    method public java.lang.String getOriginalMimeType(android.net.Uri);
    method public int openConvertSession(java.lang.String);
    method public int processDrmInfo(android.drm.DrmInfo);
    method public void release();
    method public deprecated void release();
    method public int removeAllRights();
    method public int removeRights(java.lang.String);
    method public int removeRights(android.net.Uri);
+37 −11
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.database.CursorWrapper;
import android.net.ConnectivityManager;
import android.net.NetworkPolicyManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.Downloads;
@@ -105,8 +106,17 @@ public class DownloadManager {
    public final static String COLUMN_LOCAL_URI = "local_uri";

    /**
     * The pathname of the file where the download is stored.
     * Path to the downloaded file on disk.
     * <p>
     * Note that apps may not have filesystem permissions to directly access
     * this path. Instead of trying to open this path directly, apps should use
     * {@link ContentResolver#openFileDescriptor(Uri, String)} to gain access.
     *
     * @deprecated apps should transition to using
     *             {@link ContentResolver#openFileDescriptor(Uri, String)}
     *             instead.
     */
    @Deprecated
    public final static String COLUMN_LOCAL_FILENAME = "local_filename";

    /**
@@ -908,16 +918,19 @@ public class DownloadManager {
        }
    }

    private ContentResolver mResolver;
    private String mPackageName;
    private final ContentResolver mResolver;
    private final String mPackageName;
    private final int mTargetSdkVersion;

    private Uri mBaseUri = Downloads.Impl.CONTENT_URI;

    /**
     * @hide
     */
    public DownloadManager(ContentResolver resolver, String packageName) {
        mResolver = resolver;
        mPackageName = packageName;
    public DownloadManager(Context context) {
        mResolver = context.getContentResolver();
        mPackageName = context.getPackageName();
        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
    }

    /**
@@ -997,7 +1010,7 @@ public class DownloadManager {
        if (underlyingCursor == null) {
            return null;
        }
        return new CursorTranslator(underlyingCursor, mBaseUri);
        return new CursorTranslator(underlyingCursor, mBaseUri, mTargetSdkVersion);
    }

    /**
@@ -1265,11 +1278,13 @@ public class DownloadManager {
     * underlying data.
     */
    private static class CursorTranslator extends CursorWrapper {
        private Uri mBaseUri;
        private final Uri mBaseUri;
        private final int mTargetSdkVersion;

        public CursorTranslator(Cursor cursor, Uri baseUri) {
        public CursorTranslator(Cursor cursor, Uri baseUri, int targetSdkVersion) {
            super(cursor);
            mBaseUri = baseUri;
            mTargetSdkVersion = targetSdkVersion;
        }

        @Override
@@ -1290,8 +1305,19 @@ public class DownloadManager {

        @Override
        public String getString(int columnIndex) {
            return (getColumnName(columnIndex).equals(COLUMN_LOCAL_URI)) ? getLocalUri() :
                    super.getString(columnIndex);
            final String columnName = getColumnName(columnIndex);
            switch (columnName) {
                case COLUMN_LOCAL_URI:
                    return getLocalUri();
                case COLUMN_LOCAL_FILENAME:
                    if (mTargetSdkVersion >= Build.VERSION_CODES.N) {
                        throw new IllegalArgumentException(
                                "COLUMN_LOCAL_FILENAME is deprecated;"
                                        + " use ContentResolver.openFileDescriptor() instead");
                    }
                default:
                    return super.getString(columnIndex);
            }
        }

        private String getLocalUri() {
+1 −1
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ final class SystemServiceRegistry {
                new CachedServiceFetcher<DownloadManager>() {
            @Override
            public DownloadManager createService(ContextImpl ctx) {
                return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
                return new DownloadManager(ctx);
            }});

        registerService(Context.BATTERY_SERVICE, BatteryManager.class,
Loading