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

Commit dd79ae6b authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Add infrastructure for accessing "unstable" content providers." into jb-dev

parents 4cbb2c41 652b6d1e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -5118,6 +5118,8 @@ package android.content {
    ctor public ContentResolver(android.content.Context);
    method public final android.content.ContentProviderClient acquireContentProviderClient(android.net.Uri);
    method public final android.content.ContentProviderClient acquireContentProviderClient(java.lang.String);
    method public final android.content.ContentProviderClient acquireUnstableContentProviderClient(android.net.Uri);
    method public final android.content.ContentProviderClient acquireUnstableContentProviderClient(java.lang.String);
    method public static void addPeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle, long);
    method public static java.lang.Object addStatusChangeListener(int, android.content.SyncStatusObserver);
    method public android.content.ContentProviderResult[] applyBatch(java.lang.String, java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException;
+8 −0
Original line number Diff line number Diff line
@@ -4278,6 +4278,14 @@ public final class ActivityThread {
        }
    }

    public final IContentProvider acquireUnstableProvider(Context c, String name) {
        return acquireProvider(c, name);
    }

    public final boolean releaseUnstableProvider(IContentProvider provider) {
        return releaseProvider(provider);
    }

    final void completeRemoveProvider(IContentProvider provider) {
        IBinder jBinder = provider.asBinder();
        String remoteProviderName = null;
+10 −0
Original line number Diff line number Diff line
@@ -1692,6 +1692,16 @@ class ContextImpl extends Context {
            return mMainThread.releaseProvider(provider);
        }

        @Override
        protected IContentProvider acquireUnstableProvider(Context c, String name) {
            return mMainThread.acquireUnstableProvider(c, name);
        }

        @Override
        public boolean releaseUnstableProvider(IContentProvider icp) {
            return mMainThread.releaseUnstableProvider(icp);
        }

        private final ActivityThread mMainThread;
    }
}
+9 −2
Original line number Diff line number Diff line
@@ -37,13 +37,16 @@ import java.util.ArrayList;
public class ContentProviderClient {
    private final IContentProvider mContentProvider;
    private final ContentResolver mContentResolver;
    private final boolean mStable;

    /**
     * @hide
     */
    ContentProviderClient(ContentResolver contentResolver, IContentProvider contentProvider) {
    ContentProviderClient(ContentResolver contentResolver,
            IContentProvider contentProvider, boolean stable) {
        mContentProvider = contentProvider;
        mContentResolver = contentResolver;
        mStable = stable;
    }

    /** See {@link ContentProvider#query ContentProvider.query} */
@@ -141,7 +144,11 @@ public class ContentProviderClient {
     * @return true if this was release, false if it was already released
     */
    public boolean release() {
        if (mStable) {
            return mContentResolver.releaseProvider(mContentProvider);
        } else {
            return mContentResolver.releaseUnstableProvider(mContentProvider);
        }
    }

    /**
+155 −53
Original line number Diff line number Diff line
@@ -198,6 +198,10 @@ public abstract class ContentResolver {
    }
    /** @hide */
    public abstract boolean releaseProvider(IContentProvider icp);
    /** @hide */
    protected abstract IContentProvider acquireUnstableProvider(Context c, String name);
    /** @hide */
    public abstract boolean releaseUnstableProvider(IContentProvider icp);

    /**
     * Return the MIME type of the given content URL.
@@ -588,7 +592,10 @@ public abstract class ContentResolver {
            if ("r".equals(mode)) {
                return openTypedAssetFileDescriptor(uri, "*/*", null);
            } else {
                IContentProvider provider = acquireProvider(uri);
                int n = 0;
                while (true) {
                    n++;
                    IContentProvider provider = acquireUnstableProvider(uri);
                    if (provider == null) {
                        throw new FileNotFoundException("No content provider: " + uri);
                    }
@@ -608,14 +615,25 @@ public abstract class ContentResolver {
                        return new AssetFileDescriptor(pfd, fd.getStartOffset(),
                                fd.getDeclaredLength());
                    } catch (RemoteException e) {
                    // Somewhat pointless, as Activity Manager will kill this
                    // process shortly anyway if the depdendent ContentProvider dies.
                        // The provider died for some reason.  Since we are
                        // acquiring it unstable, its process could have gotten
                        // killed and need to be restarted.  We'll retry a couple
                        // times and if still can't succeed then fail.
                        if (n <= 2) {
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e1) {
                            }
                            continue;
                        }
                        // Whatever, whatever, we'll go away.
                        throw new FileNotFoundException("Dead content provider: " + uri);
                    } catch (FileNotFoundException e) {
                        throw e;
                    } finally {
                        if (provider != null) {
                        releaseProvider(provider);
                            releaseUnstableProvider(provider);
                        }
                    }
                }
            }
@@ -652,7 +670,10 @@ public abstract class ContentResolver {
     */
    public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
            String mimeType, Bundle opts) throws FileNotFoundException {
        IContentProvider provider = acquireProvider(uri);
        int n = 0;
        while (true) {
            n++;
            IContentProvider provider = acquireUnstableProvider(uri);
            if (provider == null) {
                throw new FileNotFoundException("No content provider: " + uri);
            }
@@ -672,12 +693,25 @@ public abstract class ContentResolver {
                return new AssetFileDescriptor(pfd, fd.getStartOffset(),
                        fd.getDeclaredLength());
            } catch (RemoteException e) {
                // The provider died for some reason.  Since we are
                // acquiring it unstable, its process could have gotten
                // killed and need to be restarted.  We'll retry a couple
                // times and if still can't succeed then fail.
                if (n <= 2) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e1) {
                    }
                    continue;
                }
                // Whatever, whatever, we'll go away.
                throw new FileNotFoundException("Dead content provider: " + uri);
            } catch (FileNotFoundException e) {
                throw e;
            } finally {
                if (provider != null) {
                releaseProvider(provider);
                    releaseUnstableProvider(provider);
                }
            }
        }
    }
@@ -1002,6 +1036,34 @@ public abstract class ContentResolver {
        return acquireProvider(mContext, name);
    }

    /**
     * Returns the content provider for the given content URI.
     *
     * @param uri The URI to a content provider
     * @return The ContentProvider for the given URI, or null if no content provider is found.
     * @hide
     */
    public final IContentProvider acquireUnstableProvider(Uri uri) {
        if (!SCHEME_CONTENT.equals(uri.getScheme())) {
            return null;
        }
        String auth = uri.getAuthority();
        if (auth != null) {
            return acquireUnstableProvider(mContext, uri.getAuthority());
        }
        return null;
    }

    /**
     * @hide
     */
    public final IContentProvider acquireUnstableProvider(String name) {
        if (name == null) {
            return null;
        }
        return acquireProvider(mContext, name);
    }

    /**
     * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider}
     * that services the content at uri, starting the provider if necessary. Returns
@@ -1016,7 +1078,7 @@ public abstract class ContentResolver {
    public final ContentProviderClient acquireContentProviderClient(Uri uri) {
        IContentProvider provider = acquireProvider(uri);
        if (provider != null) {
            return new ContentProviderClient(this, provider);
            return new ContentProviderClient(this, provider, true);
        }

        return null;
@@ -1036,7 +1098,47 @@ public abstract class ContentResolver {
    public final ContentProviderClient acquireContentProviderClient(String name) {
        IContentProvider provider = acquireProvider(name);
        if (provider != null) {
            return new ContentProviderClient(this, provider);
            return new ContentProviderClient(this, provider, true);
        }

        return null;
    }

    /**
     * Like {@link #acquireContentProviderClient(Uri)}, but for use when you do
     * not trust the stability of the target content provider.  This turns off
     * the mechanism in the platform clean up processes that are dependent on
     * a content provider if that content provider's process goes away.  Normally
     * you can safely assume that once you have acquired a provider, you can freely
     * use it as needed and it won't disappear, even if your process is in the
     * background.  If using this method, you need to take care to deal with any
     * failures when communicating with the provider, and be sure to close it
     * so that it can be re-opened later.
     */
    public final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) {
        IContentProvider provider = acquireProvider(uri);
        if (provider != null) {
            return new ContentProviderClient(this, provider, false);
        }

        return null;
    }

    /**
     * Like {@link #acquireContentProviderClient(String)}, but for use when you do
     * not trust the stability of the target content provider.  This turns off
     * the mechanism in the platform clean up processes that are dependent on
     * a content provider if that content provider's process goes away.  Normally
     * you can safely assume that once you have acquired a provider, you can freely
     * use it as needed and it won't disappear, even if your process is in the
     * background.  If using this method, you need to take care to deal with any
     * failures when communicating with the provider, and be sure to close it
     * so that it can be re-opened later.
     */
    public final ContentProviderClient acquireUnstableContentProviderClient(String name) {
        IContentProvider provider = acquireProvider(name);
        if (provider != null) {
            return new ContentProviderClient(this, provider, false);
        }

        return null;
@@ -1690,7 +1792,7 @@ public abstract class ContentResolver {
        public void close() throws IOException {
            if(!mReleaseProviderFlag) {
                super.close();
                ContentResolver.this.releaseProvider(mContentProvider);
                ContentResolver.this.releaseUnstableProvider(mContentProvider);
                mReleaseProviderFlag = true;
            }
        }
Loading