16a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana/*
26a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * Copyright (C) 2009 The Android Open Source Project
36a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana *
46a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * Licensed under the Apache License, Version 2.0 (the "License");
56a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * you may not use this file except in compliance with the License.
66a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * You may obtain a copy of the License at
76a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana *
86a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana *      http://www.apache.org/licenses/LICENSE-2.0
96a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana *
106a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * Unless required by applicable law or agreed to in writing, software
116a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * distributed under the License is distributed on an "AS IS" BASIS,
126a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * See the License for the specific language governing permissions and
146a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * limitations under the License.
156a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana */
166a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
17718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanapackage android.content;
18718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
197aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.content.res.AssetFileDescriptor;
20718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport android.database.Cursor;
21718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport android.net.Uri;
2223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport android.os.Bundle;
23a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal;
246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackbornimport android.os.DeadObjectException;
257aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.os.Handler;
26a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.ICancellationSignal;
277aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.os.Looper;
28718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport android.os.ParcelFileDescriptor;
297aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.os.RemoteException;
307aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.util.Log;
317aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
327aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport com.android.internal.annotations.GuardedBy;
33718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
345545f56f7561810187545a1817b6001dd1f9931bJeff Sharkeyimport dalvik.system.CloseGuard;
355545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey
36718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport java.io.FileNotFoundException;
3703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanaimport java.util.ArrayList;
38718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
39718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana/**
40718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * The public interface object used to interact with a {@link ContentProvider}. This is obtained by
41718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * calling {@link ContentResolver#acquireContentProviderClient}. This object must be released
42718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * using {@link #release} in order to indicate to the system that the {@link ContentProvider} is
43718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * no longer needed and can be killed to free up resources.
446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn *
456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * <p>Note that you should generally create a new ContentProviderClient instance
466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * for each thread that will be performing operations.  Unlike
476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link ContentResolver}, the methods here such as {@link #query} and
486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link #openFile} are not thread safe -- you must not call
496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link #release()} on the ContentProviderClient those calls are made from
506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * until you are finished with the data they have returned.
51718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */
52718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanapublic class ContentProviderClient {
537aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private static final String TAG = "ContentProviderClient";
547aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
557aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    @GuardedBy("ContentProviderClient.class")
567aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private static Handler sAnrHandler;
577aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
58718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    private final ContentResolver mContentResolver;
597aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private final IContentProvider mContentProvider;
6035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn    private final String mPackageName;
61652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn    private final boolean mStable;
62718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
635545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey    private final CloseGuard mGuard = CloseGuard.get();
645545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey
657aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private long mAnrTimeout;
667aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private NotRespondingRunnable mAnrRunnable;
677aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
687aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private boolean mReleased;
697aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
707aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    /** {@hide} */
717aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    ContentProviderClient(
727aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            ContentResolver contentResolver, IContentProvider contentProvider, boolean stable) {
73718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana        mContentResolver = contentResolver;
747aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        mContentProvider = contentProvider;
7535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn        mPackageName = contentResolver.mPackageName;
76652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn        mStable = stable;
777aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
785545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        mGuard.open("release");
79718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
80718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
817aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    /** {@hide} */
827aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    public void setDetectNotResponding(long timeoutMillis) {
837aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        synchronized (ContentProviderClient.class) {
847aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            mAnrTimeout = timeoutMillis;
857aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
867aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            if (timeoutMillis > 0) {
877aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                if (mAnrRunnable == null) {
887aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                    mAnrRunnable = new NotRespondingRunnable();
897aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                }
907aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                if (sAnrHandler == null) {
917aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                    sAnrHandler = new Handler(Looper.getMainLooper(), null, true /* async */);
927aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                }
937aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            } else {
947aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                mAnrRunnable = null;
957aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            }
967aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        }
977aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    }
987aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
997aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private void beforeRemote() {
1007aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        if (mAnrRunnable != null) {
1017aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            sAnrHandler.postDelayed(mAnrRunnable, mAnrTimeout);
1027aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        }
1037aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    }
1047aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
1057aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private void afterRemote() {
1067aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        if (mAnrRunnable != null) {
1077aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            sAnrHandler.removeCallbacks(mAnrRunnable);
1087aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        }
1097aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    }
1107aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
11123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#query ContentProvider.query} */
112718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public Cursor query(Uri url, String[] projection, String selection,
113718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            String[] selectionArgs, String sortOrder) throws RemoteException {
114bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey        return query(url, projection, selection,  selectionArgs, sortOrder, null);
11575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    }
11675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
11775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    /** See {@link ContentProvider#query ContentProvider.query} */
1187aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
1197aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            String sortOrder, CancellationSignal cancellationSignal) throws RemoteException {
1207aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
1216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1227aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            ICancellationSignal remoteCancellationSignal = null;
1237aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            if (cancellationSignal != null) {
1247aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                cancellationSignal.throwIfCanceled();
1257aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                remoteCancellationSignal = mContentProvider.createCancellationSignal();
1267aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                cancellationSignal.setRemote(remoteCancellationSignal);
1277aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            }
1287aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            return mContentProvider.query(mPackageName, url, projection, selection, selectionArgs,
12935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn                    sortOrder, remoteCancellationSignal);
1306ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1357aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
1367aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
1376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
138718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
139718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
14023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#getType ContentProvider.getType} */
141718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public String getType(Uri url) throws RemoteException {
1427aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
1436ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.getType(url);
1456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1507aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
1517aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
1526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
153718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
154718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
15523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#getStreamTypes ContentProvider.getStreamTypes} */
15623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
1577aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
1586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.getStreamTypes(url, mimeTypeFilter);
1606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1657aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
1667aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
1676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
16823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
16923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
17038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn    /** See {@link ContentProvider#canonicalize} */
17138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn    public final Uri canonicalize(Uri url) throws RemoteException {
1727aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
17338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn        try {
17438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn            return mContentProvider.canonicalize(mPackageName, url);
17538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn        } catch (DeadObjectException e) {
17638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn            if (!mStable) {
17738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
17838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn            }
17938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn            throw e;
1807aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
1817aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
18238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn        }
18338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn    }
18438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn
18538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn    /** See {@link ContentProvider#uncanonicalize} */
18638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn    public final Uri uncanonicalize(Uri url) throws RemoteException {
1877aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
18838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn        try {
18938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn            return mContentProvider.uncanonicalize(mPackageName, url);
19038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn        } catch (DeadObjectException e) {
19138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn            if (!mStable) {
19238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
19338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn            }
19438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn            throw e;
1957aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
1967aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
19738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn        }
19838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn    }
19938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn
20023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#insert ContentProvider.insert} */
2017aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    public Uri insert(Uri url, ContentValues initialValues) throws RemoteException {
2027aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
2036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
20435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            return mContentProvider.insert(mPackageName, url, initialValues);
2056ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
2066ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
2076ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
2107aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
2117aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
2126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
213718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
214718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
21523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#bulkInsert ContentProvider.bulkInsert} */
216718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
2177aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
2186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
21935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            return mContentProvider.bulkInsert(mPackageName, url, initialValues);
2206ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
2216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
2226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
2257aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
2267aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
2276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
228718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
229718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
23023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#delete ContentProvider.delete} */
231718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public int delete(Uri url, String selection, String[] selectionArgs)
232718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            throws RemoteException {
2337aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
2346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
23535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            return mContentProvider.delete(mPackageName, url, selection, selectionArgs);
2366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
2376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
2386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
2417aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
2427aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
2436ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
244718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
245718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
24623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#update ContentProvider.update} */
247718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public int update(Uri url, ContentValues values, String selection,
248718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            String[] selectionArgs) throws RemoteException {
2497aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
2506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
25135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            return mContentProvider.update(mPackageName, url, values, selection, selectionArgs);
2526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
2536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
2546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
2577aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
2587aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
2596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
260718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
261718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
26223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
26323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * See {@link ContentProvider#openFile ContentProvider.openFile}.  Note that
26423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * this <em>does not</em>
26523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * take care of non-content: URIs such as file:.  It is strongly recommended
26623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * you use the {@link ContentResolver#openFileDescriptor
26723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * ContentResolver.openFileDescriptor} API instead.
26823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
269718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public ParcelFileDescriptor openFile(Uri url, String mode)
270718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            throws RemoteException, FileNotFoundException {
271bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey        return openFile(url, mode, null);
272bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    }
273bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey
274bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    /**
275bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * See {@link ContentProvider#openFile ContentProvider.openFile}.  Note that
276bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * this <em>does not</em>
277bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * take care of non-content: URIs such as file:.  It is strongly recommended
278bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * you use the {@link ContentResolver#openFileDescriptor
279bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * ContentResolver.openFileDescriptor} API instead.
280bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     */
281bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    public ParcelFileDescriptor openFile(Uri url, String mode, CancellationSignal signal)
282bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey            throws RemoteException, FileNotFoundException {
2837aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
2846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
2857aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            ICancellationSignal remoteSignal = null;
2867aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            if (signal != null) {
2877aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                signal.throwIfCanceled();
2887aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                remoteSignal = mContentProvider.createCancellationSignal();
2897aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                signal.setRemote(remoteSignal);
2907aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            }
291ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn            return mContentProvider.openFile(mPackageName, url, mode, remoteSignal, null);
2926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
2936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
2946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
2977aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
2987aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
2996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
300718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
301718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
30223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
30323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * See {@link ContentProvider#openAssetFile ContentProvider.openAssetFile}.
30423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * Note that this <em>does not</em>
30523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * take care of non-content: URIs such as file:.  It is strongly recommended
30623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * you use the {@link ContentResolver#openAssetFileDescriptor
30723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * ContentResolver.openAssetFileDescriptor} API instead.
30823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
309718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public AssetFileDescriptor openAssetFile(Uri url, String mode)
310718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            throws RemoteException, FileNotFoundException {
311bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey        return openAssetFile(url, mode, null);
312bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    }
313bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey
314bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    /**
315bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * See {@link ContentProvider#openAssetFile ContentProvider.openAssetFile}.
316bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * Note that this <em>does not</em>
317bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * take care of non-content: URIs such as file:.  It is strongly recommended
318bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * you use the {@link ContentResolver#openAssetFileDescriptor
319bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     * ContentResolver.openAssetFileDescriptor} API instead.
320bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey     */
321bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    public AssetFileDescriptor openAssetFile(Uri url, String mode, CancellationSignal signal)
322bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey            throws RemoteException, FileNotFoundException {
3237aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
3246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
3257aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            ICancellationSignal remoteSignal = null;
3267aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            if (signal != null) {
3277aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                signal.throwIfCanceled();
3287aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                remoteSignal = mContentProvider.createCancellationSignal();
3297aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                signal.setRemote(remoteSignal);
3307aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            }
331bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey            return mContentProvider.openAssetFile(mPackageName, url, mode, remoteSignal);
3326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
3336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
3346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
3356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
3366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
3377aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
3387aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
3396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
340718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
341718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
34223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
34323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
344bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey            String mimeType, Bundle opts) throws RemoteException, FileNotFoundException {
345bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey        return openTypedAssetFileDescriptor(uri, mimeType, opts, null);
346bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    }
347bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey
348bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    /** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
349bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey    public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
350bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey            String mimeType, Bundle opts, CancellationSignal signal)
35123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            throws RemoteException, FileNotFoundException {
3527aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
3536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
3547aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            ICancellationSignal remoteSignal = null;
3557aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            if (signal != null) {
3567aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                signal.throwIfCanceled();
3577aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                remoteSignal = mContentProvider.createCancellationSignal();
3587aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                signal.setRemote(remoteSignal);
3597aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            }
360bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey            return mContentProvider.openTypedAssetFile(
361bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey                    mPackageName, uri, mimeType, opts, remoteSignal);
3626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
3636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
3646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
3656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
3666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
3677aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
3687aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
3696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
37023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
37123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
37223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#applyBatch ContentProvider.applyBatch} */
37303d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
3748943737692169f564cd34a9c8d471f3a5d438712Fred Quintana            throws RemoteException, OperationApplicationException {
3757aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
3766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
37735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            return mContentProvider.applyBatch(mPackageName, operations);
3786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
3796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
3806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
3816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
3826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
3837aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
3847aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
3856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
3866a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    }
3876a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
3887d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn    /** See {@link ContentProvider#call(String, String, Bundle)} */
3897aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    public Bundle call(String method, String arg, Bundle extras) throws RemoteException {
3907aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        beforeRemote();
3917d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        try {
39235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            return mContentProvider.call(mPackageName, method, arg, extras);
3937d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        } catch (DeadObjectException e) {
3947d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            if (!mStable) {
3957d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
3967d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            }
3977d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            throw e;
3987aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        } finally {
3997aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            afterRemote();
4007d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        }
4017d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn    }
4027d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn
403718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    /**
404718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * Call this to indicate to the system that the associated {@link ContentProvider} is no
405718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * longer needed by this {@link ContentProviderClient}.
406718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * @return true if this was release, false if it was already released
407718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     */
408718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public boolean release() {
4096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        synchronized (this) {
4106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (mReleased) {
4116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                throw new IllegalStateException("Already released");
4126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
4136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            mReleased = true;
4145545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey            mGuard.close();
4156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (mStable) {
4166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                return mContentResolver.releaseProvider(mContentProvider);
4176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            } else {
4186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                return mContentResolver.releaseUnstableProvider(mContentProvider);
4196ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
420652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn        }
421718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
422718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
4235545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey    @Override
4245545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey    protected void finalize() throws Throwable {
4255545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        if (mGuard != null) {
4265545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey            mGuard.warnIfOpen();
4275545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        }
4285545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey    }
4295545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey
430718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    /**
431718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * Get a reference to the {@link ContentProvider} that is associated with this
432718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * client. If the {@link ContentProvider} is running in a different process then
433718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * null will be returned. This can be used if you know you are running in the same
434718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * process as a provider, and want to get direct access to its implementation details.
435718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     *
436718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * @return If the associated {@link ContentProvider} is local, returns it.
437718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * Otherwise returns null.
438718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     */
439718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public ContentProvider getLocalContentProvider() {
440718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana        return ContentProvider.coerceToLocalContentProvider(mContentProvider);
441718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
442aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey
443aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey    /** {@hide} */
4447aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    public static void releaseQuietly(ContentProviderClient client) {
445aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey        if (client != null) {
4463f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey            try {
4473f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey                client.release();
4483f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey            } catch (Exception ignored) {
4493f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey            }
450aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey        }
451aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey    }
4527aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey
4537aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    private class NotRespondingRunnable implements Runnable {
4547aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        @Override
4557aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        public void run() {
4567aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            Log.w(TAG, "Detected provider not responding: " + mContentProvider);
4577aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            mContentResolver.appNotRespondingViaProvider(mContentProvider);
4587aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        }
4597aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey    }
460718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana}
461