/core/java/android/content/ContentProviderClient.java

https://github.com/tezet/android_frameworks_base · Java · 265 lines · 177 code · 19 blank · 69 comment · 17 complexity · adaa4a32758a143aaf9a57d4721dcab9 MD5 · raw file

  1. /*
  2. * Copyright (C) 2009 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package android.content;
  17. import android.database.Cursor;
  18. import android.net.Uri;
  19. import android.os.Bundle;
  20. import android.os.CancellationSignal;
  21. import android.os.DeadObjectException;
  22. import android.os.ICancellationSignal;
  23. import android.os.RemoteException;
  24. import android.os.ParcelFileDescriptor;
  25. import android.content.res.AssetFileDescriptor;
  26. import java.io.FileNotFoundException;
  27. import java.util.ArrayList;
  28. /**
  29. * The public interface object used to interact with a {@link ContentProvider}. This is obtained by
  30. * calling {@link ContentResolver#acquireContentProviderClient}. This object must be released
  31. * using {@link #release} in order to indicate to the system that the {@link ContentProvider} is
  32. * no longer needed and can be killed to free up resources.
  33. *
  34. * <p>Note that you should generally create a new ContentProviderClient instance
  35. * for each thread that will be performing operations. Unlike
  36. * {@link ContentResolver}, the methods here such as {@link #query} and
  37. * {@link #openFile} are not thread safe -- you must not call
  38. * {@link #release()} on the ContentProviderClient those calls are made from
  39. * until you are finished with the data they have returned.
  40. */
  41. public class ContentProviderClient {
  42. private final IContentProvider mContentProvider;
  43. private final ContentResolver mContentResolver;
  44. private final boolean mStable;
  45. private boolean mReleased;
  46. /**
  47. * @hide
  48. */
  49. ContentProviderClient(ContentResolver contentResolver,
  50. IContentProvider contentProvider, boolean stable) {
  51. mContentProvider = contentProvider;
  52. mContentResolver = contentResolver;
  53. mStable = stable;
  54. }
  55. /** See {@link ContentProvider#query ContentProvider.query} */
  56. public Cursor query(Uri url, String[] projection, String selection,
  57. String[] selectionArgs, String sortOrder) throws RemoteException {
  58. try {
  59. return query(url, projection, selection, selectionArgs, sortOrder, null);
  60. } catch (DeadObjectException e) {
  61. if (!mStable) {
  62. mContentResolver.unstableProviderDied(mContentProvider);
  63. }
  64. throw e;
  65. }
  66. }
  67. /** See {@link ContentProvider#query ContentProvider.query} */
  68. public Cursor query(Uri url, String[] projection, String selection,
  69. String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
  70. throws RemoteException {
  71. ICancellationSignal remoteCancellationSignal = null;
  72. if (cancellationSignal != null) {
  73. remoteCancellationSignal = mContentProvider.createCancellationSignal();
  74. cancellationSignal.setRemote(remoteCancellationSignal);
  75. }
  76. try {
  77. return mContentProvider.query(url, projection, selection, selectionArgs, sortOrder,
  78. remoteCancellationSignal);
  79. } catch (DeadObjectException e) {
  80. if (!mStable) {
  81. mContentResolver.unstableProviderDied(mContentProvider);
  82. }
  83. throw e;
  84. }
  85. }
  86. /** See {@link ContentProvider#getType ContentProvider.getType} */
  87. public String getType(Uri url) throws RemoteException {
  88. try {
  89. return mContentProvider.getType(url);
  90. } catch (DeadObjectException e) {
  91. if (!mStable) {
  92. mContentResolver.unstableProviderDied(mContentProvider);
  93. }
  94. throw e;
  95. }
  96. }
  97. /** See {@link ContentProvider#getStreamTypes ContentProvider.getStreamTypes} */
  98. public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
  99. try {
  100. return mContentProvider.getStreamTypes(url, mimeTypeFilter);
  101. } catch (DeadObjectException e) {
  102. if (!mStable) {
  103. mContentResolver.unstableProviderDied(mContentProvider);
  104. }
  105. throw e;
  106. }
  107. }
  108. /** See {@link ContentProvider#insert ContentProvider.insert} */
  109. public Uri insert(Uri url, ContentValues initialValues)
  110. throws RemoteException {
  111. try {
  112. return mContentProvider.insert(url, initialValues);
  113. } catch (DeadObjectException e) {
  114. if (!mStable) {
  115. mContentResolver.unstableProviderDied(mContentProvider);
  116. }
  117. throw e;
  118. }
  119. }
  120. /** See {@link ContentProvider#bulkInsert ContentProvider.bulkInsert} */
  121. public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
  122. try {
  123. return mContentProvider.bulkInsert(url, initialValues);
  124. } catch (DeadObjectException e) {
  125. if (!mStable) {
  126. mContentResolver.unstableProviderDied(mContentProvider);
  127. }
  128. throw e;
  129. }
  130. }
  131. /** See {@link ContentProvider#delete ContentProvider.delete} */
  132. public int delete(Uri url, String selection, String[] selectionArgs)
  133. throws RemoteException {
  134. try {
  135. return mContentProvider.delete(url, selection, selectionArgs);
  136. } catch (DeadObjectException e) {
  137. if (!mStable) {
  138. mContentResolver.unstableProviderDied(mContentProvider);
  139. }
  140. throw e;
  141. }
  142. }
  143. /** See {@link ContentProvider#update ContentProvider.update} */
  144. public int update(Uri url, ContentValues values, String selection,
  145. String[] selectionArgs) throws RemoteException {
  146. try {
  147. return mContentProvider.update(url, values, selection, selectionArgs);
  148. } catch (DeadObjectException e) {
  149. if (!mStable) {
  150. mContentResolver.unstableProviderDied(mContentProvider);
  151. }
  152. throw e;
  153. }
  154. }
  155. /**
  156. * See {@link ContentProvider#openFile ContentProvider.openFile}. Note that
  157. * this <em>does not</em>
  158. * take care of non-content: URIs such as file:. It is strongly recommended
  159. * you use the {@link ContentResolver#openFileDescriptor
  160. * ContentResolver.openFileDescriptor} API instead.
  161. */
  162. public ParcelFileDescriptor openFile(Uri url, String mode)
  163. throws RemoteException, FileNotFoundException {
  164. try {
  165. return mContentProvider.openFile(url, mode);
  166. } catch (DeadObjectException e) {
  167. if (!mStable) {
  168. mContentResolver.unstableProviderDied(mContentProvider);
  169. }
  170. throw e;
  171. }
  172. }
  173. /**
  174. * See {@link ContentProvider#openAssetFile ContentProvider.openAssetFile}.
  175. * Note that this <em>does not</em>
  176. * take care of non-content: URIs such as file:. It is strongly recommended
  177. * you use the {@link ContentResolver#openAssetFileDescriptor
  178. * ContentResolver.openAssetFileDescriptor} API instead.
  179. */
  180. public AssetFileDescriptor openAssetFile(Uri url, String mode)
  181. throws RemoteException, FileNotFoundException {
  182. try {
  183. return mContentProvider.openAssetFile(url, mode);
  184. } catch (DeadObjectException e) {
  185. if (!mStable) {
  186. mContentResolver.unstableProviderDied(mContentProvider);
  187. }
  188. throw e;
  189. }
  190. }
  191. /** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
  192. public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
  193. String mimeType, Bundle opts)
  194. throws RemoteException, FileNotFoundException {
  195. try {
  196. return mContentProvider.openTypedAssetFile(uri, mimeType, opts);
  197. } catch (DeadObjectException e) {
  198. if (!mStable) {
  199. mContentResolver.unstableProviderDied(mContentProvider);
  200. }
  201. throw e;
  202. }
  203. }
  204. /** See {@link ContentProvider#applyBatch ContentProvider.applyBatch} */
  205. public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
  206. throws RemoteException, OperationApplicationException {
  207. try {
  208. return mContentProvider.applyBatch(operations);
  209. } catch (DeadObjectException e) {
  210. if (!mStable) {
  211. mContentResolver.unstableProviderDied(mContentProvider);
  212. }
  213. throw e;
  214. }
  215. }
  216. /**
  217. * Call this to indicate to the system that the associated {@link ContentProvider} is no
  218. * longer needed by this {@link ContentProviderClient}.
  219. * @return true if this was release, false if it was already released
  220. */
  221. public boolean release() {
  222. synchronized (this) {
  223. if (mReleased) {
  224. throw new IllegalStateException("Already released");
  225. }
  226. mReleased = true;
  227. if (mStable) {
  228. return mContentResolver.releaseProvider(mContentProvider);
  229. } else {
  230. return mContentResolver.releaseUnstableProvider(mContentProvider);
  231. }
  232. }
  233. }
  234. /**
  235. * Get a reference to the {@link ContentProvider} that is associated with this
  236. * client. If the {@link ContentProvider} is running in a different process then
  237. * null will be returned. This can be used if you know you are running in the same
  238. * process as a provider, and want to get direct access to its implementation details.
  239. *
  240. * @return If the associated {@link ContentProvider} is local, returns it.
  241. * Otherwise returns null.
  242. */
  243. public ContentProvider getLocalContentProvider() {
  244. return ContentProvider.coerceToLocalContentProvider(mContentProvider);
  245. }
  246. }