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

Commit e2e03913 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android Git Automerger
Browse files

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

* commit 'dd79ae6b':
  Add infrastructure for accessing "unstable" content providers.
parents dfca63f3 dd79ae6b
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