PageRenderTime 51ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/frameworks/base/core/java/android/content/ContentProvider.java

https://gitlab.com/brian0218/rk3188_r-box_android4.2.2_sdk
Java | 1137 lines | 391 code | 80 blank | 666 comment | 74 complexity | d09f9d30e60362c20534cf1b15abc9b8 MD5 | raw file
  1. /*
  2. * Copyright (C) 2006 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 static android.content.pm.PackageManager.PERMISSION_GRANTED;
  18. import android.content.pm.PackageManager;
  19. import android.content.pm.PathPermission;
  20. import android.content.pm.ProviderInfo;
  21. import android.content.res.AssetFileDescriptor;
  22. import android.content.res.Configuration;
  23. import android.database.Cursor;
  24. import android.database.SQLException;
  25. import android.net.Uri;
  26. import android.os.AsyncTask;
  27. import android.os.Binder;
  28. import android.os.Bundle;
  29. import android.os.CancellationSignal;
  30. import android.os.ICancellationSignal;
  31. import android.os.OperationCanceledException;
  32. import android.os.ParcelFileDescriptor;
  33. import android.os.Process;
  34. import android.os.RemoteException;
  35. import android.os.UserHandle;
  36. import android.util.Log;
  37. import java.io.File;
  38. import java.io.FileDescriptor;
  39. import java.io.FileNotFoundException;
  40. import java.io.IOException;
  41. import java.io.PrintWriter;
  42. import java.util.ArrayList;
  43. /**
  44. * Content providers are one of the primary building blocks of Android applications, providing
  45. * content to applications. They encapsulate data and provide it to applications through the single
  46. * {@link ContentResolver} interface. A content provider is only required if you need to share
  47. * data between multiple applications. For example, the contacts data is used by multiple
  48. * applications and must be stored in a content provider. If you don't need to share data amongst
  49. * multiple applications you can use a database directly via
  50. * {@link android.database.sqlite.SQLiteDatabase}.
  51. *
  52. * <p>When a request is made via
  53. * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
  54. * request to the content provider registered with the authority. The content provider can interpret
  55. * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
  56. * URIs.</p>
  57. *
  58. * <p>The primary methods that need to be implemented are:
  59. * <ul>
  60. * <li>{@link #onCreate} which is called to initialize the provider</li>
  61. * <li>{@link #query} which returns data to the caller</li>
  62. * <li>{@link #insert} which inserts new data into the content provider</li>
  63. * <li>{@link #update} which updates existing data in the content provider</li>
  64. * <li>{@link #delete} which deletes data from the content provider</li>
  65. * <li>{@link #getType} which returns the MIME type of data in the content provider</li>
  66. * </ul></p>
  67. *
  68. * <p class="caution">Data access methods (such as {@link #insert} and
  69. * {@link #update}) may be called from many threads at once, and must be thread-safe.
  70. * Other methods (such as {@link #onCreate}) are only called from the application
  71. * main thread, and must avoid performing lengthy operations. See the method
  72. * descriptions for their expected thread behavior.</p>
  73. *
  74. * <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
  75. * ContentProvider instance, so subclasses don't have to worry about the details of
  76. * cross-process calls.</p>
  77. *
  78. * <div class="special reference">
  79. * <h3>Developer Guides</h3>
  80. * <p>For more information about using content providers, read the
  81. * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
  82. * developer guide.</p>
  83. */
  84. public abstract class ContentProvider implements ComponentCallbacks2 {
  85. private static final String TAG = "ContentProvider";
  86. /*
  87. * Note: if you add methods to ContentProvider, you must add similar methods to
  88. * MockContentProvider.
  89. */
  90. private Context mContext = null;
  91. private int mMyUid;
  92. private String mReadPermission;
  93. private String mWritePermission;
  94. private PathPermission[] mPathPermissions;
  95. private boolean mExported;
  96. private Transport mTransport = new Transport();
  97. /**
  98. * Construct a ContentProvider instance. Content providers must be
  99. * <a href="{@docRoot}guide/topics/manifest/provider-element.html">declared
  100. * in the manifest</a>, accessed with {@link ContentResolver}, and created
  101. * automatically by the system, so applications usually do not create
  102. * ContentProvider instances directly.
  103. *
  104. * <p>At construction time, the object is uninitialized, and most fields and
  105. * methods are unavailable. Subclasses should initialize themselves in
  106. * {@link #onCreate}, not the constructor.
  107. *
  108. * <p>Content providers are created on the application main thread at
  109. * application launch time. The constructor must not perform lengthy
  110. * operations, or application startup will be delayed.
  111. */
  112. public ContentProvider() {
  113. }
  114. /**
  115. * Constructor just for mocking.
  116. *
  117. * @param context A Context object which should be some mock instance (like the
  118. * instance of {@link android.test.mock.MockContext}).
  119. * @param readPermission The read permision you want this instance should have in the
  120. * test, which is available via {@link #getReadPermission()}.
  121. * @param writePermission The write permission you want this instance should have
  122. * in the test, which is available via {@link #getWritePermission()}.
  123. * @param pathPermissions The PathPermissions you want this instance should have
  124. * in the test, which is available via {@link #getPathPermissions()}.
  125. * @hide
  126. */
  127. public ContentProvider(
  128. Context context,
  129. String readPermission,
  130. String writePermission,
  131. PathPermission[] pathPermissions) {
  132. mContext = context;
  133. mReadPermission = readPermission;
  134. mWritePermission = writePermission;
  135. mPathPermissions = pathPermissions;
  136. }
  137. /**
  138. * Given an IContentProvider, try to coerce it back to the real
  139. * ContentProvider object if it is running in the local process. This can
  140. * be used if you know you are running in the same process as a provider,
  141. * and want to get direct access to its implementation details. Most
  142. * clients should not nor have a reason to use it.
  143. *
  144. * @param abstractInterface The ContentProvider interface that is to be
  145. * coerced.
  146. * @return If the IContentProvider is non-null and local, returns its actual
  147. * ContentProvider instance. Otherwise returns null.
  148. * @hide
  149. */
  150. public static ContentProvider coerceToLocalContentProvider(
  151. IContentProvider abstractInterface) {
  152. if (abstractInterface instanceof Transport) {
  153. return ((Transport)abstractInterface).getContentProvider();
  154. }
  155. return null;
  156. }
  157. /**
  158. * Binder object that deals with remoting.
  159. *
  160. * @hide
  161. */
  162. class Transport extends ContentProviderNative {
  163. ContentProvider getContentProvider() {
  164. return ContentProvider.this;
  165. }
  166. @Override
  167. public String getProviderName() {
  168. return getContentProvider().getClass().getName();
  169. }
  170. @Override
  171. public Cursor query(Uri uri, String[] projection,
  172. String selection, String[] selectionArgs, String sortOrder,
  173. ICancellationSignal cancellationSignal) {
  174. enforceReadPermission(uri);
  175. return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
  176. CancellationSignal.fromTransport(cancellationSignal));
  177. }
  178. @Override
  179. public String getType(Uri uri) {
  180. return ContentProvider.this.getType(uri);
  181. }
  182. @Override
  183. public Uri insert(Uri uri, ContentValues initialValues) {
  184. enforceWritePermission(uri);
  185. return ContentProvider.this.insert(uri, initialValues);
  186. }
  187. @Override
  188. public int bulkInsert(Uri uri, ContentValues[] initialValues) {
  189. enforceWritePermission(uri);
  190. return ContentProvider.this.bulkInsert(uri, initialValues);
  191. }
  192. @Override
  193. public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
  194. throws OperationApplicationException {
  195. for (ContentProviderOperation operation : operations) {
  196. if (operation.isReadOperation()) {
  197. enforceReadPermission(operation.getUri());
  198. }
  199. if (operation.isWriteOperation()) {
  200. enforceWritePermission(operation.getUri());
  201. }
  202. }
  203. return ContentProvider.this.applyBatch(operations);
  204. }
  205. @Override
  206. public int delete(Uri uri, String selection, String[] selectionArgs) {
  207. enforceWritePermission(uri);
  208. return ContentProvider.this.delete(uri, selection, selectionArgs);
  209. }
  210. @Override
  211. public int update(Uri uri, ContentValues values, String selection,
  212. String[] selectionArgs) {
  213. enforceWritePermission(uri);
  214. return ContentProvider.this.update(uri, values, selection, selectionArgs);
  215. }
  216. @Override
  217. public ParcelFileDescriptor openFile(Uri uri, String mode)
  218. throws FileNotFoundException {
  219. if (mode != null && mode.indexOf('w') != -1) enforceWritePermission(uri);
  220. else enforceReadPermission(uri);
  221. //enforceWritePermission(uri);//add by lt
  222. //enforceReadPermission(uri);//add by lt
  223. return ContentProvider.this.openFile(uri, mode);
  224. }
  225. @Override
  226. public AssetFileDescriptor openAssetFile(Uri uri, String mode)
  227. throws FileNotFoundException {
  228. if (mode != null && mode.indexOf('w') != -1) enforceWritePermission(uri);
  229. else enforceReadPermission(uri);
  230. return ContentProvider.this.openAssetFile(uri, mode);
  231. }
  232. @Override
  233. public Bundle call(String method, String arg, Bundle extras) {
  234. return ContentProvider.this.call(method, arg, extras);
  235. }
  236. @Override
  237. public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
  238. return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
  239. }
  240. @Override
  241. public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeType, Bundle opts)
  242. throws FileNotFoundException {
  243. enforceReadPermission(uri);
  244. return ContentProvider.this.openTypedAssetFile(uri, mimeType, opts);
  245. }
  246. @Override
  247. public ICancellationSignal createCancellationSignal() throws RemoteException {
  248. return CancellationSignal.createTransport();
  249. }
  250. private void enforceReadPermission(Uri uri) throws SecurityException {
  251. final Context context = getContext();
  252. final int pid = Binder.getCallingPid();
  253. final int uid = Binder.getCallingUid();
  254. String missingPerm = null;
  255. if (UserHandle.isSameApp(uid, mMyUid)) {
  256. return;
  257. }
  258. if (mExported) {
  259. final String componentPerm = getReadPermission();
  260. if (componentPerm != null) {
  261. if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
  262. return;
  263. } else {
  264. missingPerm = componentPerm;
  265. }
  266. }
  267. // track if unprotected read is allowed; any denied
  268. // <path-permission> below removes this ability
  269. boolean allowDefaultRead = (componentPerm == null);
  270. final PathPermission[] pps = getPathPermissions();
  271. if (pps != null) {
  272. final String path = uri.getPath();
  273. for (PathPermission pp : pps) {
  274. final String pathPerm = pp.getReadPermission();
  275. if (pathPerm != null && pp.match(path)) {
  276. if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
  277. return;
  278. } else {
  279. // any denied <path-permission> means we lose
  280. // default <provider> access.
  281. allowDefaultRead = false;
  282. missingPerm = pathPerm;
  283. }
  284. }
  285. }
  286. }
  287. // if we passed <path-permission> checks above, and no default
  288. // <provider> permission, then allow access.
  289. if (allowDefaultRead) return;
  290. }
  291. // last chance, check against any uri grants
  292. if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
  293. == PERMISSION_GRANTED) {
  294. return;
  295. }
  296. final String failReason = mExported
  297. ? " requires " + missingPerm + ", or grantUriPermission()"
  298. : " requires the provider be exported, or grantUriPermission()";
  299. throw new SecurityException("Permission Denial: reading "
  300. + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
  301. + ", uid=" + uid + failReason);
  302. }
  303. private void enforceWritePermission(Uri uri) throws SecurityException {
  304. final Context context = getContext();
  305. final int pid = Binder.getCallingPid();
  306. final int uid = Binder.getCallingUid();
  307. String missingPerm = null;
  308. if (UserHandle.isSameApp(uid, mMyUid)) {
  309. return;
  310. }
  311. if (mExported) {
  312. final String componentPerm = getWritePermission();
  313. if (componentPerm != null) {
  314. if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
  315. return;
  316. } else {
  317. missingPerm = componentPerm;
  318. }
  319. }
  320. // track if unprotected write is allowed; any denied
  321. // <path-permission> below removes this ability
  322. boolean allowDefaultWrite = (componentPerm == null);
  323. final PathPermission[] pps = getPathPermissions();
  324. if (pps != null) {
  325. final String path = uri.getPath();
  326. for (PathPermission pp : pps) {
  327. final String pathPerm = pp.getWritePermission();
  328. if (pathPerm != null && pp.match(path)) {
  329. if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
  330. return;
  331. } else {
  332. // any denied <path-permission> means we lose
  333. // default <provider> access.
  334. allowDefaultWrite = false;
  335. missingPerm = pathPerm;
  336. }
  337. }
  338. }
  339. }
  340. // if we passed <path-permission> checks above, and no default
  341. // <provider> permission, then allow access.
  342. if (allowDefaultWrite) return;
  343. }
  344. // last chance, check against any uri grants
  345. if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
  346. == PERMISSION_GRANTED) {
  347. return;
  348. }
  349. final String failReason = mExported
  350. ? " requires " + missingPerm + ", or grantUriPermission()"
  351. : " requires the provider be exported, or grantUriPermission()";
  352. throw new SecurityException("Permission Denial: writing "
  353. + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
  354. + ", uid=" + uid + failReason);
  355. }
  356. }
  357. /**
  358. * Retrieves the Context this provider is running in. Only available once
  359. * {@link #onCreate} has been called -- this will return null in the
  360. * constructor.
  361. */
  362. public final Context getContext() {
  363. return mContext;
  364. }
  365. /**
  366. * Change the permission required to read data from the content
  367. * provider. This is normally set for you from its manifest information
  368. * when the provider is first created.
  369. *
  370. * @param permission Name of the permission required for read-only access.
  371. */
  372. protected final void setReadPermission(String permission) {
  373. mReadPermission = permission;
  374. }
  375. /**
  376. * Return the name of the permission required for read-only access to
  377. * this content provider. This method can be called from multiple
  378. * threads, as described in
  379. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  380. * and Threads</a>.
  381. */
  382. public final String getReadPermission() {
  383. return mReadPermission;
  384. }
  385. /**
  386. * Change the permission required to read and write data in the content
  387. * provider. This is normally set for you from its manifest information
  388. * when the provider is first created.
  389. *
  390. * @param permission Name of the permission required for read/write access.
  391. */
  392. protected final void setWritePermission(String permission) {
  393. mWritePermission = permission;
  394. }
  395. /**
  396. * Return the name of the permission required for read/write access to
  397. * this content provider. This method can be called from multiple
  398. * threads, as described in
  399. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  400. * and Threads</a>.
  401. */
  402. public final String getWritePermission() {
  403. return mWritePermission;
  404. }
  405. /**
  406. * Change the path-based permission required to read and/or write data in
  407. * the content provider. This is normally set for you from its manifest
  408. * information when the provider is first created.
  409. *
  410. * @param permissions Array of path permission descriptions.
  411. */
  412. protected final void setPathPermissions(PathPermission[] permissions) {
  413. mPathPermissions = permissions;
  414. }
  415. /**
  416. * Return the path-based permissions required for read and/or write access to
  417. * this content provider. This method can be called from multiple
  418. * threads, as described in
  419. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  420. * and Threads</a>.
  421. */
  422. public final PathPermission[] getPathPermissions() {
  423. return mPathPermissions;
  424. }
  425. /**
  426. * Implement this to initialize your content provider on startup.
  427. * This method is called for all registered content providers on the
  428. * application main thread at application launch time. It must not perform
  429. * lengthy operations, or application startup will be delayed.
  430. *
  431. * <p>You should defer nontrivial initialization (such as opening,
  432. * upgrading, and scanning databases) until the content provider is used
  433. * (via {@link #query}, {@link #insert}, etc). Deferred initialization
  434. * keeps application startup fast, avoids unnecessary work if the provider
  435. * turns out not to be needed, and stops database errors (such as a full
  436. * disk) from halting application launch.
  437. *
  438. * <p>If you use SQLite, {@link android.database.sqlite.SQLiteOpenHelper}
  439. * is a helpful utility class that makes it easy to manage databases,
  440. * and will automatically defer opening until first use. If you do use
  441. * SQLiteOpenHelper, make sure to avoid calling
  442. * {@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} or
  443. * {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase}
  444. * from this method. (Instead, override
  445. * {@link android.database.sqlite.SQLiteOpenHelper#onOpen} to initialize the
  446. * database when it is first opened.)
  447. *
  448. * @return true if the provider was successfully loaded, false otherwise
  449. */
  450. public abstract boolean onCreate();
  451. /**
  452. * {@inheritDoc}
  453. * This method is always called on the application main thread, and must
  454. * not perform lengthy operations.
  455. *
  456. * <p>The default content provider implementation does nothing.
  457. * Override this method to take appropriate action.
  458. * (Content providers do not usually care about things like screen
  459. * orientation, but may want to know about locale changes.)
  460. */
  461. public void onConfigurationChanged(Configuration newConfig) {
  462. }
  463. /**
  464. * {@inheritDoc}
  465. * This method is always called on the application main thread, and must
  466. * not perform lengthy operations.
  467. *
  468. * <p>The default content provider implementation does nothing.
  469. * Subclasses may override this method to take appropriate action.
  470. */
  471. public void onLowMemory() {
  472. }
  473. public void onTrimMemory(int level) {
  474. }
  475. /**
  476. * Implement this to handle query requests from clients.
  477. * This method can be called from multiple threads, as described in
  478. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  479. * and Threads</a>.
  480. * <p>
  481. * Example client call:<p>
  482. * <pre>// Request a specific record.
  483. * Cursor managedCursor = managedQuery(
  484. ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
  485. projection, // Which columns to return.
  486. null, // WHERE clause.
  487. null, // WHERE clause value substitution
  488. People.NAME + " ASC"); // Sort order.</pre>
  489. * Example implementation:<p>
  490. * <pre>// SQLiteQueryBuilder is a helper class that creates the
  491. // proper SQL syntax for us.
  492. SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
  493. // Set the table we're querying.
  494. qBuilder.setTables(DATABASE_TABLE_NAME);
  495. // If the query ends in a specific record number, we're
  496. // being asked for a specific record, so set the
  497. // WHERE clause in our query.
  498. if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
  499. qBuilder.appendWhere("_id=" + uri.getPathLeafId());
  500. }
  501. // Make the query.
  502. Cursor c = qBuilder.query(mDb,
  503. projection,
  504. selection,
  505. selectionArgs,
  506. groupBy,
  507. having,
  508. sortOrder);
  509. c.setNotificationUri(getContext().getContentResolver(), uri);
  510. return c;</pre>
  511. *
  512. * @param uri The URI to query. This will be the full URI sent by the client;
  513. * if the client is requesting a specific record, the URI will end in a record number
  514. * that the implementation should parse and add to a WHERE or HAVING clause, specifying
  515. * that _id value.
  516. * @param projection The list of columns to put into the cursor. If
  517. * null all columns are included.
  518. * @param selection A selection criteria to apply when filtering rows.
  519. * If null then all rows are included.
  520. * @param selectionArgs You may include ?s in selection, which will be replaced by
  521. * the values from selectionArgs, in order that they appear in the selection.
  522. * The values will be bound as Strings.
  523. * @param sortOrder How the rows in the cursor should be sorted.
  524. * If null then the provider is free to define the sort order.
  525. * @return a Cursor or null.
  526. */
  527. public abstract Cursor query(Uri uri, String[] projection,
  528. String selection, String[] selectionArgs, String sortOrder);
  529. /**
  530. * Implement this to handle query requests from clients with support for cancellation.
  531. * This method can be called from multiple threads, as described in
  532. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  533. * and Threads</a>.
  534. * <p>
  535. * Example client call:<p>
  536. * <pre>// Request a specific record.
  537. * Cursor managedCursor = managedQuery(
  538. ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
  539. projection, // Which columns to return.
  540. null, // WHERE clause.
  541. null, // WHERE clause value substitution
  542. People.NAME + " ASC"); // Sort order.</pre>
  543. * Example implementation:<p>
  544. * <pre>// SQLiteQueryBuilder is a helper class that creates the
  545. // proper SQL syntax for us.
  546. SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
  547. // Set the table we're querying.
  548. qBuilder.setTables(DATABASE_TABLE_NAME);
  549. // If the query ends in a specific record number, we're
  550. // being asked for a specific record, so set the
  551. // WHERE clause in our query.
  552. if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
  553. qBuilder.appendWhere("_id=" + uri.getPathLeafId());
  554. }
  555. // Make the query.
  556. Cursor c = qBuilder.query(mDb,
  557. projection,
  558. selection,
  559. selectionArgs,
  560. groupBy,
  561. having,
  562. sortOrder);
  563. c.setNotificationUri(getContext().getContentResolver(), uri);
  564. return c;</pre>
  565. * <p>
  566. * If you implement this method then you must also implement the version of
  567. * {@link #query(Uri, String[], String, String[], String)} that does not take a cancellation
  568. * signal to ensure correct operation on older versions of the Android Framework in
  569. * which the cancellation signal overload was not available.
  570. *
  571. * @param uri The URI to query. This will be the full URI sent by the client;
  572. * if the client is requesting a specific record, the URI will end in a record number
  573. * that the implementation should parse and add to a WHERE or HAVING clause, specifying
  574. * that _id value.
  575. * @param projection The list of columns to put into the cursor. If
  576. * null all columns are included.
  577. * @param selection A selection criteria to apply when filtering rows.
  578. * If null then all rows are included.
  579. * @param selectionArgs You may include ?s in selection, which will be replaced by
  580. * the values from selectionArgs, in order that they appear in the selection.
  581. * The values will be bound as Strings.
  582. * @param sortOrder How the rows in the cursor should be sorted.
  583. * If null then the provider is free to define the sort order.
  584. * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
  585. * If the operation is canceled, then {@link OperationCanceledException} will be thrown
  586. * when the query is executed.
  587. * @return a Cursor or null.
  588. */
  589. public Cursor query(Uri uri, String[] projection,
  590. String selection, String[] selectionArgs, String sortOrder,
  591. CancellationSignal cancellationSignal) {
  592. return query(uri, projection, selection, selectionArgs, sortOrder);
  593. }
  594. /**
  595. * Implement this to handle requests for the MIME type of the data at the
  596. * given URI. The returned MIME type should start with
  597. * <code>vnd.android.cursor.item</code> for a single record,
  598. * or <code>vnd.android.cursor.dir/</code> for multiple items.
  599. * This method can be called from multiple threads, as described in
  600. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  601. * and Threads</a>.
  602. *
  603. * <p>Note that there are no permissions needed for an application to
  604. * access this information; if your content provider requires read and/or
  605. * write permissions, or is not exported, all applications can still call
  606. * this method regardless of their access permissions. This allows them
  607. * to retrieve the MIME type for a URI when dispatching intents.
  608. *
  609. * @param uri the URI to query.
  610. * @return a MIME type string, or null if there is no type.
  611. */
  612. public abstract String getType(Uri uri);
  613. /**
  614. * Implement this to handle requests to insert a new row.
  615. * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
  616. * after inserting.
  617. * This method can be called from multiple threads, as described in
  618. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  619. * and Threads</a>.
  620. * @param uri The content:// URI of the insertion request.
  621. * @param values A set of column_name/value pairs to add to the database.
  622. * @return The URI for the newly inserted item.
  623. */
  624. public abstract Uri insert(Uri uri, ContentValues values);
  625. /**
  626. * Override this to handle requests to insert a set of new rows, or the
  627. * default implementation will iterate over the values and call
  628. * {@link #insert} on each of them.
  629. * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
  630. * after inserting.
  631. * This method can be called from multiple threads, as described in
  632. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  633. * and Threads</a>.
  634. *
  635. * @param uri The content:// URI of the insertion request.
  636. * @param values An array of sets of column_name/value pairs to add to the database.
  637. * @return The number of values that were inserted.
  638. */
  639. public int bulkInsert(Uri uri, ContentValues[] values) {
  640. int numValues = values.length;
  641. for (int i = 0; i < numValues; i++) {
  642. insert(uri, values[i]);
  643. }
  644. return numValues;
  645. }
  646. /**
  647. * Implement this to handle requests to delete one or more rows.
  648. * The implementation should apply the selection clause when performing
  649. * deletion, allowing the operation to affect multiple rows in a directory.
  650. * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
  651. * after deleting.
  652. * This method can be called from multiple threads, as described in
  653. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  654. * and Threads</a>.
  655. *
  656. * <p>The implementation is responsible for parsing out a row ID at the end
  657. * of the URI, if a specific row is being deleted. That is, the client would
  658. * pass in <code>content://contacts/people/22</code> and the implementation is
  659. * responsible for parsing the record number (22) when creating a SQL statement.
  660. *
  661. * @param uri The full URI to query, including a row ID (if a specific record is requested).
  662. * @param selection An optional restriction to apply to rows when deleting.
  663. * @return The number of rows affected.
  664. * @throws SQLException
  665. */
  666. public abstract int delete(Uri uri, String selection, String[] selectionArgs);
  667. /**
  668. * Implement this to handle requests to update one or more rows.
  669. * The implementation should update all rows matching the selection
  670. * to set the columns according to the provided values map.
  671. * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
  672. * after updating.
  673. * This method can be called from multiple threads, as described in
  674. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  675. * and Threads</a>.
  676. *
  677. * @param uri The URI to query. This can potentially have a record ID if this
  678. * is an update request for a specific record.
  679. * @param values A Bundle mapping from column names to new column values (NULL is a
  680. * valid value).
  681. * @param selection An optional filter to match rows to update.
  682. * @return the number of rows affected.
  683. */
  684. public abstract int update(Uri uri, ContentValues values, String selection,
  685. String[] selectionArgs);
  686. /**
  687. * Override this to handle requests to open a file blob.
  688. * The default implementation always throws {@link FileNotFoundException}.
  689. * This method can be called from multiple threads, as described in
  690. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  691. * and Threads</a>.
  692. *
  693. * <p>This method returns a ParcelFileDescriptor, which is returned directly
  694. * to the caller. This way large data (such as images and documents) can be
  695. * returned without copying the content.
  696. *
  697. * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
  698. * their responsibility to close it when done. That is, the implementation
  699. * of this method should create a new ParcelFileDescriptor for each call.
  700. *
  701. * @param uri The URI whose file is to be opened.
  702. * @param mode Access mode for the file. May be "r" for read-only access,
  703. * "rw" for read and write access, or "rwt" for read and write access
  704. * that truncates any existing file.
  705. *
  706. * @return Returns a new ParcelFileDescriptor which you can use to access
  707. * the file.
  708. *
  709. * @throws FileNotFoundException Throws FileNotFoundException if there is
  710. * no file associated with the given URI or the mode is invalid.
  711. * @throws SecurityException Throws SecurityException if the caller does
  712. * not have permission to access the file.
  713. *
  714. * @see #openAssetFile(Uri, String)
  715. * @see #openFileHelper(Uri, String)
  716. */
  717. public ParcelFileDescriptor openFile(Uri uri, String mode)
  718. throws FileNotFoundException {
  719. throw new FileNotFoundException("No files supported by provider at "
  720. + uri);
  721. }
  722. /**
  723. * This is like {@link #openFile}, but can be implemented by providers
  724. * that need to be able to return sub-sections of files, often assets
  725. * inside of their .apk.
  726. * This method can be called from multiple threads, as described in
  727. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  728. * and Threads</a>.
  729. *
  730. * <p>If you implement this, your clients must be able to deal with such
  731. * file slices, either directly with
  732. * {@link ContentResolver#openAssetFileDescriptor}, or by using the higher-level
  733. * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
  734. * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
  735. * methods.
  736. *
  737. * <p class="note">If you are implementing this to return a full file, you
  738. * should create the AssetFileDescriptor with
  739. * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
  740. * applications that can not handle sub-sections of files.</p>
  741. *
  742. * @param uri The URI whose file is to be opened.
  743. * @param mode Access mode for the file. May be "r" for read-only access,
  744. * "w" for write-only access (erasing whatever data is currently in
  745. * the file), "wa" for write-only access to append to any existing data,
  746. * "rw" for read and write access on any existing data, and "rwt" for read
  747. * and write access that truncates any existing file.
  748. *
  749. * @return Returns a new AssetFileDescriptor which you can use to access
  750. * the file.
  751. *
  752. * @throws FileNotFoundException Throws FileNotFoundException if there is
  753. * no file associated with the given URI or the mode is invalid.
  754. * @throws SecurityException Throws SecurityException if the caller does
  755. * not have permission to access the file.
  756. *
  757. * @see #openFile(Uri, String)
  758. * @see #openFileHelper(Uri, String)
  759. */
  760. public AssetFileDescriptor openAssetFile(Uri uri, String mode)
  761. throws FileNotFoundException {
  762. ParcelFileDescriptor fd = openFile(uri, mode);
  763. return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
  764. }
  765. /**
  766. * Convenience for subclasses that wish to implement {@link #openFile}
  767. * by looking up a column named "_data" at the given URI.
  768. *
  769. * @param uri The URI to be opened.
  770. * @param mode The file mode. May be "r" for read-only access,
  771. * "w" for write-only access (erasing whatever data is currently in
  772. * the file), "wa" for write-only access to append to any existing data,
  773. * "rw" for read and write access on any existing data, and "rwt" for read
  774. * and write access that truncates any existing file.
  775. *
  776. * @return Returns a new ParcelFileDescriptor that can be used by the
  777. * client to access the file.
  778. */
  779. protected final ParcelFileDescriptor openFileHelper(Uri uri,
  780. String mode) throws FileNotFoundException {
  781. Cursor c = query(uri, new String[]{"_data"}, null, null, null);
  782. int count = (c != null) ? c.getCount() : 0;
  783. if (count != 1) {
  784. // If there is not exactly one result, throw an appropriate
  785. // exception.
  786. if (c != null) {
  787. c.close();
  788. }
  789. if (count == 0) {
  790. throw new FileNotFoundException("No entry for " + uri);
  791. }
  792. throw new FileNotFoundException("Multiple items at " + uri);
  793. }
  794. c.moveToFirst();
  795. int i = c.getColumnIndex("_data");
  796. String path = (i >= 0 ? c.getString(i) : null);
  797. c.close();
  798. if (path == null) {
  799. throw new FileNotFoundException("Column _data not found.");
  800. }
  801. int modeBits = ContentResolver.modeToMode(uri, mode);
  802. return ParcelFileDescriptor.open(new File(path), modeBits);
  803. }
  804. /**
  805. * Called by a client to determine the types of data streams that this
  806. * content provider supports for the given URI. The default implementation
  807. * returns null, meaning no types. If your content provider stores data
  808. * of a particular type, return that MIME type if it matches the given
  809. * mimeTypeFilter. If it can perform type conversions, return an array
  810. * of all supported MIME types that match mimeTypeFilter.
  811. *
  812. * @param uri The data in the content provider being queried.
  813. * @param mimeTypeFilter The type of data the client desires. May be
  814. * a pattern, such as *\/* to retrieve all possible data types.
  815. * @return Returns null if there are no possible data streams for the
  816. * given mimeTypeFilter. Otherwise returns an array of all available
  817. * concrete MIME types.
  818. *
  819. * @see #getType(Uri)
  820. * @see #openTypedAssetFile(Uri, String, Bundle)
  821. * @see ClipDescription#compareMimeTypes(String, String)
  822. */
  823. public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
  824. return null;
  825. }
  826. /**
  827. * Called by a client to open a read-only stream containing data of a
  828. * particular MIME type. This is like {@link #openAssetFile(Uri, String)},
  829. * except the file can only be read-only and the content provider may
  830. * perform data conversions to generate data of the desired type.
  831. *
  832. * <p>The default implementation compares the given mimeType against the
  833. * result of {@link #getType(Uri)} and, if the match, simple calls
  834. * {@link #openAssetFile(Uri, String)}.
  835. *
  836. * <p>See {@link ClipData} for examples of the use and implementation
  837. * of this method.
  838. *
  839. * @param uri The data in the content provider being queried.
  840. * @param mimeTypeFilter The type of data the client desires. May be
  841. * a pattern, such as *\/*, if the caller does not have specific type
  842. * requirements; in this case the content provider will pick its best
  843. * type matching the pattern.
  844. * @param opts Additional options from the client. The definitions of
  845. * these are specific to the content provider being called.
  846. *
  847. * @return Returns a new AssetFileDescriptor from which the client can
  848. * read data of the desired type.
  849. *
  850. * @throws FileNotFoundException Throws FileNotFoundException if there is
  851. * no file associated with the given URI or the mode is invalid.
  852. * @throws SecurityException Throws SecurityException if the caller does
  853. * not have permission to access the data.
  854. * @throws IllegalArgumentException Throws IllegalArgumentException if the
  855. * content provider does not support the requested MIME type.
  856. *
  857. * @see #getStreamTypes(Uri, String)
  858. * @see #openAssetFile(Uri, String)
  859. * @see ClipDescription#compareMimeTypes(String, String)
  860. */
  861. public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
  862. throws FileNotFoundException {
  863. if ("*/*".equals(mimeTypeFilter)) {
  864. // If they can take anything, the untyped open call is good enough.
  865. return openAssetFile(uri, "r");
  866. }
  867. String baseType = getType(uri);
  868. if (baseType != null && ClipDescription.compareMimeTypes(baseType, mimeTypeFilter)) {
  869. // Use old untyped open call if this provider has a type for this
  870. // URI and it matches the request.
  871. return openAssetFile(uri, "r");
  872. }
  873. throw new FileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter);
  874. }
  875. /**
  876. * Interface to write a stream of data to a pipe. Use with
  877. * {@link ContentProvider#openPipeHelper}.
  878. */
  879. public interface PipeDataWriter<T> {
  880. /**
  881. * Called from a background thread to stream data out to a pipe.
  882. * Note that the pipe is blocking, so this thread can block on
  883. * writes for an arbitrary amount of time if the client is slow
  884. * at reading.
  885. *
  886. * @param output The pipe where data should be written. This will be
  887. * closed for you upon returning from this function.
  888. * @param uri The URI whose data is to be written.
  889. * @param mimeType The desired type of data to be written.
  890. * @param opts Options supplied by caller.
  891. * @param args Your own custom arguments.
  892. */
  893. public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
  894. Bundle opts, T args);
  895. }
  896. /**
  897. * A helper function for implementing {@link #openTypedAssetFile}, for
  898. * creating a data pipe and background thread allowing you to stream
  899. * generated data back to the client. This function returns a new
  900. * ParcelFileDescriptor that should be returned to the caller (the caller
  901. * is responsible for closing it).
  902. *
  903. * @param uri The URI whose data is to be written.
  904. * @param mimeType The desired type of data to be written.
  905. * @param opts Options supplied by caller.
  906. * @param args Your own custom arguments.
  907. * @param func Interface implementing the function that will actually
  908. * stream the data.
  909. * @return Returns a new ParcelFileDescriptor holding the read side of
  910. * the pipe. This should be returned to the caller for reading; the caller
  911. * is responsible for closing it when done.
  912. */
  913. public <T> ParcelFileDescriptor openPipeHelper(final Uri uri, final String mimeType,
  914. final Bundle opts, final T args, final PipeDataWriter<T> func)
  915. throws FileNotFoundException {
  916. try {
  917. final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
  918. AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
  919. @Override
  920. protected Object doInBackground(Object... params) {
  921. func.writeDataToPipe(fds[1], uri, mimeType, opts, args);
  922. try {
  923. fds[1].close();
  924. } catch (IOException e) {
  925. Log.w(TAG, "Failure closing pipe", e);
  926. }
  927. return null;
  928. }
  929. };
  930. task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null);
  931. return fds[0];
  932. } catch (IOException e) {
  933. throw new FileNotFoundException("failure making pipe");
  934. }
  935. }
  936. /**
  937. * Returns true if this instance is a temporary content provider.
  938. * @return true if this instance is a temporary content provider
  939. */
  940. protected boolean isTemporary() {
  941. return false;
  942. }
  943. /**
  944. * Returns the Binder object for this provider.
  945. *
  946. * @return the Binder object for this provider
  947. * @hide
  948. */
  949. public IContentProvider getIContentProvider() {
  950. return mTransport;
  951. }
  952. /**
  953. * After being instantiated, this is called to tell the content provider
  954. * about itself.
  955. *
  956. * @param context The context this provider is running in
  957. * @param info Registered information about this content provider
  958. */
  959. public void attachInfo(Context context, ProviderInfo info) {
  960. /*
  961. * We may be using AsyncTask from binder threads. Make it init here
  962. * so its static handler is on the main thread.
  963. */
  964. AsyncTask.init();
  965. /*
  966. * Only allow it to be set once, so after the content service gives
  967. * this to us clients can't change it.
  968. */
  969. if (mContext == null) {
  970. mContext = context;
  971. mMyUid = Process.myUid();
  972. if (info != null) {
  973. setReadPermission(info.readPermission);
  974. setWritePermission(info.writePermission);
  975. setPathPermissions(info.pathPermissions);
  976. mExported = info.exported;
  977. }
  978. ContentProvider.this.onCreate();
  979. }
  980. }
  981. /**
  982. * Override this to handle requests to perform a batch of operations, or the
  983. * default implementation will iterate over the operations and call
  984. * {@link ContentProviderOperation#apply} on each of them.
  985. * If all calls to {@link ContentProviderOperation#apply} succeed
  986. * then a {@link ContentProviderResult} array with as many
  987. * elements as there were operations will be returned. If any of the calls
  988. * fail, it is up to the implementation how many of the others take effect.
  989. * This method can be called from multiple threads, as described in
  990. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  991. * and Threads</a>.
  992. *
  993. * @param operations the operations to apply
  994. * @return the results of the applications
  995. * @throws OperationApplicationException thrown if any operation fails.
  996. * @see ContentProviderOperation#apply
  997. */
  998. public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
  999. throws OperationApplicationException {
  1000. final int numOperations = operations.size();
  1001. final ContentProviderResult[] results = new ContentProviderResult[numOperations];
  1002. for (int i = 0; i < numOperations; i++) {
  1003. results[i] = operations.get(i).apply(this, results, i);
  1004. }
  1005. return results;
  1006. }
  1007. /**
  1008. * Call a provider-defined method. This can be used to implement
  1009. * interfaces that are cheaper and/or unnatural for a table-like
  1010. * model.
  1011. *
  1012. * @param method method name to call. Opaque to framework, but should not be null.
  1013. * @param arg provider-defined String argument. May be null.
  1014. * @param extras provider-defined Bundle argument. May be null.
  1015. * @return provider-defined return value. May be null. Null is also
  1016. * the default for providers which don't implement any call methods.
  1017. */
  1018. public Bundle call(String method, String arg, Bundle extras) {
  1019. return null;
  1020. }
  1021. /**
  1022. * Implement this to shut down the ContentProvider instance. You can then
  1023. * invoke this method in unit tests.
  1024. *
  1025. * <p>
  1026. * Android normally handles ContentProvider startup and shutdown
  1027. * automatically. You do not need to start up or shut down a
  1028. * ContentProvider. When you invoke a test method on a ContentProvider,
  1029. * however, a ContentProvider instance is started and keeps running after
  1030. * the test finishes, even if a succeeding test instantiates another
  1031. * ContentProvider. A conflict develops because the two instances are
  1032. * usually running against the same underlying data source (for example, an
  1033. * sqlite database).
  1034. * </p>
  1035. * <p>
  1036. * Implementing shutDown() avoids this conflict by providing a way to
  1037. * terminate the ContentProvider. This method can also prevent memory leaks
  1038. * from multiple instantiations of the ContentProvider, and it can ensure
  1039. * unit test isolation by allowing you to completely clean up the test
  1040. * fixture before moving on to the next test.
  1041. * </p>
  1042. */
  1043. public void shutdown() {
  1044. Log.w(TAG, "implement ContentProvider shutdown() to make sure all database " +
  1045. "connections are gracefully shutdown");
  1046. }
  1047. /**
  1048. * Print the Provider's state into the given stream. This gets invoked if
  1049. * you run "adb shell dumpsys activity provider &lt;provider_component_name&gt;".
  1050. *
  1051. * @param prefix Desired prefix to prepend at e