PageRenderTime 214ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/core/java/android/content/ContentProvider.java

https://gitlab.com/drgroovestarr/frameworks_base
Java | 1167 lines | 597 code | 88 blank | 482 comment | 129 complexity | 58556c46f5d2650e9c93ee5a79355abf 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.Manifest.permission.INTERACT_ACROSS_USERS;
  18. import static android.app.AppOpsManager.MODE_ALLOWED;
  19. import static android.app.AppOpsManager.MODE_ERRORED;
  20. import static android.app.AppOpsManager.MODE_IGNORED;
  21. import static android.content.pm.PackageManager.PERMISSION_GRANTED;
  22. import android.annotation.NonNull;
  23. import android.annotation.Nullable;
  24. import android.app.AppOpsManager;
  25. import android.content.pm.PathPermission;
  26. import android.content.pm.ProviderInfo;
  27. import android.content.res.AssetFileDescriptor;
  28. import android.content.res.Configuration;
  29. import android.database.Cursor;
  30. import android.database.MatrixCursor;
  31. import android.database.SQLException;
  32. import android.net.Uri;
  33. import android.os.AsyncTask;
  34. import android.os.Binder;
  35. import android.os.Bundle;
  36. import android.os.CancellationSignal;
  37. import android.os.IBinder;
  38. import android.os.ICancellationSignal;
  39. import android.os.ParcelFileDescriptor;
  40. import android.os.Process;
  41. import android.os.RemoteException;
  42. import android.os.UserHandle;
  43. import android.os.storage.StorageManager;
  44. import android.text.TextUtils;
  45. import android.util.Log;
  46. import java.io.File;
  47. import java.io.FileDescriptor;
  48. import java.io.FileNotFoundException;
  49. import java.io.IOException;
  50. import java.io.PrintWriter;
  51. import java.util.ArrayList;
  52. import java.util.Arrays;
  53. /**
  54. * Content providers are one of the primary building blocks of Android applications, providing
  55. * content to applications. They encapsulate data and provide it to applications through the single
  56. * {@link ContentResolver} interface. A content provider is only required if you need to share
  57. * data between multiple applications. For example, the contacts data is used by multiple
  58. * applications and must be stored in a content provider. If you don't need to share data amongst
  59. * multiple applications you can use a database directly via
  60. * {@link android.database.sqlite.SQLiteDatabase}.
  61. *
  62. * <p>When a request is made via
  63. * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
  64. * request to the content provider registered with the authority. The content provider can interpret
  65. * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
  66. * URIs.</p>
  67. *
  68. * <p>The primary methods that need to be implemented are:
  69. * <ul>
  70. * <li>{@link #onCreate} which is called to initialize the provider</li>
  71. * <li>{@link #query} which returns data to the caller</li>
  72. * <li>{@link #insert} which inserts new data into the content provider</li>
  73. * <li>{@link #update} which updates existing data in the content provider</li>
  74. * <li>{@link #delete} which deletes data from the content provider</li>
  75. * <li>{@link #getType} which returns the MIME type of data in the content provider</li>
  76. * </ul></p>
  77. *
  78. * <p class="caution">Data access methods (such as {@link #insert} and
  79. * {@link #update}) may be called from many threads at once, and must be thread-safe.
  80. * Other methods (such as {@link #onCreate}) are only called from the application
  81. * main thread, and must avoid performing lengthy operations. See the method
  82. * descriptions for their expected thread behavior.</p>
  83. *
  84. * <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
  85. * ContentProvider instance, so subclasses don't have to worry about the details of
  86. * cross-process calls.</p>
  87. *
  88. * <div class="special reference">
  89. * <h3>Developer Guides</h3>
  90. * <p>For more information about using content providers, read the
  91. * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
  92. * developer guide.</p>
  93. */
  94. public abstract class ContentProvider implements ComponentCallbacks2 {
  95. private static final String TAG = "ContentProvider";
  96. /*
  97. * Note: if you add methods to ContentProvider, you must add similar methods to
  98. * MockContentProvider.
  99. */
  100. private Context mContext = null;
  101. private int mMyUid;
  102. // Since most Providers have only one authority, we keep both a String and a String[] to improve
  103. // performance.
  104. private String mAuthority;
  105. private String[] mAuthorities;
  106. private String mReadPermission;
  107. private String mWritePermission;
  108. private PathPermission[] mPathPermissions;
  109. private boolean mExported;
  110. private boolean mNoPerms;
  111. private boolean mSingleUser;
  112. private final ThreadLocal<String> mCallingPackage = new ThreadLocal<>();
  113. private Transport mTransport = new Transport();
  114. /**
  115. * Construct a ContentProvider instance. Content providers must be
  116. * <a href="{@docRoot}guide/topics/manifest/provider-element.html">declared
  117. * in the manifest</a>, accessed with {@link ContentResolver}, and created
  118. * automatically by the system, so applications usually do not create
  119. * ContentProvider instances directly.
  120. *
  121. * <p>At construction time, the object is uninitialized, and most fields and
  122. * methods are unavailable. Subclasses should initialize themselves in
  123. * {@link #onCreate}, not the constructor.
  124. *
  125. * <p>Content providers are created on the application main thread at
  126. * application launch time. The constructor must not perform lengthy
  127. * operations, or application startup will be delayed.
  128. */
  129. public ContentProvider() {
  130. }
  131. /**
  132. * Constructor just for mocking.
  133. *
  134. * @param context A Context object which should be some mock instance (like the
  135. * instance of {@link android.test.mock.MockContext}).
  136. * @param readPermission The read permision you want this instance should have in the
  137. * test, which is available via {@link #getReadPermission()}.
  138. * @param writePermission The write permission you want this instance should have
  139. * in the test, which is available via {@link #getWritePermission()}.
  140. * @param pathPermissions The PathPermissions you want this instance should have
  141. * in the test, which is available via {@link #getPathPermissions()}.
  142. * @hide
  143. */
  144. public ContentProvider(
  145. Context context,
  146. String readPermission,
  147. String writePermission,
  148. PathPermission[] pathPermissions) {
  149. mContext = context;
  150. mReadPermission = readPermission;
  151. mWritePermission = writePermission;
  152. mPathPermissions = pathPermissions;
  153. }
  154. /**
  155. * Given an IContentProvider, try to coerce it back to the real
  156. * ContentProvider object if it is running in the local process. This can
  157. * be used if you know you are running in the same process as a provider,
  158. * and want to get direct access to its implementation details. Most
  159. * clients should not nor have a reason to use it.
  160. *
  161. * @param abstractInterface The ContentProvider interface that is to be
  162. * coerced.
  163. * @return If the IContentProvider is non-{@code null} and local, returns its actual
  164. * ContentProvider instance. Otherwise returns {@code null}.
  165. * @hide
  166. */
  167. public static ContentProvider coerceToLocalContentProvider(
  168. IContentProvider abstractInterface) {
  169. if (abstractInterface instanceof Transport) {
  170. return ((Transport)abstractInterface).getContentProvider();
  171. }
  172. return null;
  173. }
  174. /**
  175. * Binder object that deals with remoting.
  176. *
  177. * @hide
  178. */
  179. class Transport extends ContentProviderNative {
  180. AppOpsManager mAppOpsManager = null;
  181. int mReadOp = AppOpsManager.OP_NONE;
  182. int mWriteOp = AppOpsManager.OP_NONE;
  183. ContentProvider getContentProvider() {
  184. return ContentProvider.this;
  185. }
  186. @Override
  187. public String getProviderName() {
  188. return getContentProvider().getClass().getName();
  189. }
  190. @Override
  191. public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection,
  192. @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
  193. validateIncomingUri(uri);
  194. uri = maybeGetUriWithoutUserId(uri);
  195. if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
  196. // The caller has no access to the data, so return an empty cursor with
  197. // the columns in the requested order. The caller may ask for an invalid
  198. // column and we would not catch that but this is not a problem in practice.
  199. // We do not call ContentProvider#query with a modified where clause since
  200. // the implementation is not guaranteed to be backed by a SQL database, hence
  201. // it may not handle properly the tautology where clause we would have created.
  202. if (projection != null) {
  203. return new MatrixCursor(projection, 0);
  204. }
  205. // Null projection means all columns but we have no idea which they are.
  206. // However, the caller may be expecting to access them my index. Hence,
  207. // we have to execute the query as if allowed to get a cursor with the
  208. // columns. We then use the column names to return an empty cursor.
  209. Cursor cursor = ContentProvider.this.query(
  210. uri, projection, queryArgs,
  211. CancellationSignal.fromTransport(cancellationSignal));
  212. if (cursor == null) {
  213. return null;
  214. }
  215. // Return an empty cursor for all columns.
  216. return new MatrixCursor(cursor.getColumnNames(), 0);
  217. }
  218. final String original = setCallingPackage(callingPkg);
  219. try {
  220. return ContentProvider.this.query(
  221. uri, projection, queryArgs,
  222. CancellationSignal.fromTransport(cancellationSignal));
  223. } finally {
  224. setCallingPackage(original);
  225. }
  226. }
  227. @Override
  228. public String getType(Uri uri) {
  229. validateIncomingUri(uri);
  230. uri = maybeGetUriWithoutUserId(uri);
  231. return ContentProvider.this.getType(uri);
  232. }
  233. @Override
  234. public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) {
  235. validateIncomingUri(uri);
  236. int userId = getUserIdFromUri(uri);
  237. uri = maybeGetUriWithoutUserId(uri);
  238. if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
  239. return rejectInsert(uri, initialValues);
  240. }
  241. final String original = setCallingPackage(callingPkg);
  242. try {
  243. return maybeAddUserId(ContentProvider.this.insert(uri, initialValues), userId);
  244. } finally {
  245. setCallingPackage(original);
  246. }
  247. }
  248. @Override
  249. public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) {
  250. validateIncomingUri(uri);
  251. uri = maybeGetUriWithoutUserId(uri);
  252. if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
  253. return 0;
  254. }
  255. final String original = setCallingPackage(callingPkg);
  256. try {
  257. return ContentProvider.this.bulkInsert(uri, initialValues);
  258. } finally {
  259. setCallingPackage(original);
  260. }
  261. }
  262. @Override
  263. public ContentProviderResult[] applyBatch(String callingPkg,
  264. ArrayList<ContentProviderOperation> operations)
  265. throws OperationApplicationException {
  266. int numOperations = operations.size();
  267. final int[] userIds = new int[numOperations];
  268. for (int i = 0; i < numOperations; i++) {
  269. ContentProviderOperation operation = operations.get(i);
  270. Uri uri = operation.getUri();
  271. validateIncomingUri(uri);
  272. userIds[i] = getUserIdFromUri(uri);
  273. if (userIds[i] != UserHandle.USER_CURRENT) {
  274. // Removing the user id from the uri.
  275. operation = new ContentProviderOperation(operation, true);
  276. operations.set(i, operation);
  277. }
  278. if (operation.isReadOperation()) {
  279. if (enforceReadPermission(callingPkg, uri, null)
  280. != AppOpsManager.MODE_ALLOWED) {
  281. throw new OperationApplicationException("App op not allowed", 0);
  282. }
  283. }
  284. if (operation.isWriteOperation()) {
  285. if (enforceWritePermission(callingPkg, uri, null)
  286. != AppOpsManager.MODE_ALLOWED) {
  287. throw new OperationApplicationException("App op not allowed", 0);
  288. }
  289. }
  290. }
  291. final String original = setCallingPackage(callingPkg);
  292. try {
  293. ContentProviderResult[] results = ContentProvider.this.applyBatch(operations);
  294. if (results != null) {
  295. for (int i = 0; i < results.length ; i++) {
  296. if (userIds[i] != UserHandle.USER_CURRENT) {
  297. // Adding the userId to the uri.
  298. results[i] = new ContentProviderResult(results[i], userIds[i]);
  299. }
  300. }
  301. }
  302. return results;
  303. } finally {
  304. setCallingPackage(original);
  305. }
  306. }
  307. @Override
  308. public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) {
  309. validateIncomingUri(uri);
  310. uri = maybeGetUriWithoutUserId(uri);
  311. if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
  312. return 0;
  313. }
  314. final String original = setCallingPackage(callingPkg);
  315. try {
  316. return ContentProvider.this.delete(uri, selection, selectionArgs);
  317. } finally {
  318. setCallingPackage(original);
  319. }
  320. }
  321. @Override
  322. public int update(String callingPkg, Uri uri, ContentValues values, String selection,
  323. String[] selectionArgs) {
  324. validateIncomingUri(uri);
  325. uri = maybeGetUriWithoutUserId(uri);
  326. if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
  327. return 0;
  328. }
  329. final String original = setCallingPackage(callingPkg);
  330. try {
  331. return ContentProvider.this.update(uri, values, selection, selectionArgs);
  332. } finally {
  333. setCallingPackage(original);
  334. }
  335. }
  336. @Override
  337. public ParcelFileDescriptor openFile(
  338. String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal,
  339. IBinder callerToken) throws FileNotFoundException {
  340. validateIncomingUri(uri);
  341. uri = maybeGetUriWithoutUserId(uri);
  342. enforceFilePermission(callingPkg, uri, mode, callerToken);
  343. final String original = setCallingPackage(callingPkg);
  344. try {
  345. return ContentProvider.this.openFile(
  346. uri, mode, CancellationSignal.fromTransport(cancellationSignal));
  347. } finally {
  348. setCallingPackage(original);
  349. }
  350. }
  351. @Override
  352. public AssetFileDescriptor openAssetFile(
  353. String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
  354. throws FileNotFoundException {
  355. validateIncomingUri(uri);
  356. uri = maybeGetUriWithoutUserId(uri);
  357. enforceFilePermission(callingPkg, uri, mode, null);
  358. final String original = setCallingPackage(callingPkg);
  359. try {
  360. return ContentProvider.this.openAssetFile(
  361. uri, mode, CancellationSignal.fromTransport(cancellationSignal));
  362. } finally {
  363. setCallingPackage(original);
  364. }
  365. }
  366. @Override
  367. public Bundle call(
  368. String callingPkg, String method, @Nullable String arg, @Nullable Bundle extras) {
  369. Bundle.setDefusable(extras, true);
  370. final String original = setCallingPackage(callingPkg);
  371. try {
  372. return ContentProvider.this.call(method, arg, extras);
  373. } finally {
  374. setCallingPackage(original);
  375. }
  376. }
  377. @Override
  378. public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
  379. validateIncomingUri(uri);
  380. uri = maybeGetUriWithoutUserId(uri);
  381. return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
  382. }
  383. @Override
  384. public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
  385. Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
  386. Bundle.setDefusable(opts, true);
  387. validateIncomingUri(uri);
  388. uri = maybeGetUriWithoutUserId(uri);
  389. enforceFilePermission(callingPkg, uri, "r", null);
  390. final String original = setCallingPackage(callingPkg);
  391. try {
  392. return ContentProvider.this.openTypedAssetFile(
  393. uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
  394. } finally {
  395. setCallingPackage(original);
  396. }
  397. }
  398. @Override
  399. public ICancellationSignal createCancellationSignal() {
  400. return CancellationSignal.createTransport();
  401. }
  402. @Override
  403. public Uri canonicalize(String callingPkg, Uri uri) {
  404. validateIncomingUri(uri);
  405. int userId = getUserIdFromUri(uri);
  406. uri = getUriWithoutUserId(uri);
  407. if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
  408. return null;
  409. }
  410. final String original = setCallingPackage(callingPkg);
  411. try {
  412. return maybeAddUserId(ContentProvider.this.canonicalize(uri), userId);
  413. } finally {
  414. setCallingPackage(original);
  415. }
  416. }
  417. @Override
  418. public Uri uncanonicalize(String callingPkg, Uri uri) {
  419. validateIncomingUri(uri);
  420. int userId = getUserIdFromUri(uri);
  421. uri = getUriWithoutUserId(uri);
  422. if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
  423. return null;
  424. }
  425. final String original = setCallingPackage(callingPkg);
  426. try {
  427. return maybeAddUserId(ContentProvider.this.uncanonicalize(uri), userId);
  428. } finally {
  429. setCallingPackage(original);
  430. }
  431. }
  432. @Override
  433. public boolean refresh(String callingPkg, Uri uri, Bundle args,
  434. ICancellationSignal cancellationSignal) throws RemoteException {
  435. validateIncomingUri(uri);
  436. uri = getUriWithoutUserId(uri);
  437. if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
  438. return false;
  439. }
  440. final String original = setCallingPackage(callingPkg);
  441. try {
  442. return ContentProvider.this.refresh(uri, args,
  443. CancellationSignal.fromTransport(cancellationSignal));
  444. } finally {
  445. setCallingPackage(original);
  446. }
  447. }
  448. private void enforceFilePermission(String callingPkg, Uri uri, String mode,
  449. IBinder callerToken) throws FileNotFoundException, SecurityException {
  450. if (mode != null && mode.indexOf('w') != -1) {
  451. if (enforceWritePermission(callingPkg, uri, callerToken)
  452. != AppOpsManager.MODE_ALLOWED) {
  453. throw new FileNotFoundException("App op not allowed");
  454. }
  455. } else {
  456. if (enforceReadPermission(callingPkg, uri, callerToken)
  457. != AppOpsManager.MODE_ALLOWED) {
  458. throw new FileNotFoundException("App op not allowed");
  459. }
  460. }
  461. }
  462. private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken)
  463. throws SecurityException {
  464. final int mode = enforceReadPermissionInner(uri, callingPkg, callerToken);
  465. if (mode != MODE_ALLOWED) {
  466. return mode;
  467. }
  468. if (mReadOp != AppOpsManager.OP_NONE) {
  469. return mAppOpsManager.noteProxyOp(mReadOp, callingPkg);
  470. }
  471. return AppOpsManager.MODE_ALLOWED;
  472. }
  473. private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
  474. throws SecurityException {
  475. final int mode = enforceWritePermissionInner(uri, callingPkg, callerToken);
  476. if (mode != MODE_ALLOWED) {
  477. return mode;
  478. }
  479. if (mWriteOp != AppOpsManager.OP_NONE) {
  480. return mAppOpsManager.noteProxyOp(mWriteOp, callingPkg);
  481. }
  482. return AppOpsManager.MODE_ALLOWED;
  483. }
  484. }
  485. boolean checkUser(int pid, int uid, Context context) {
  486. return UserHandle.getUserId(uid) == context.getUserId()
  487. || mSingleUser
  488. || context.checkPermission(INTERACT_ACROSS_USERS, pid, uid)
  489. == PERMISSION_GRANTED;
  490. }
  491. /**
  492. * Verify that calling app holds both the given permission and any app-op
  493. * associated with that permission.
  494. */
  495. private int checkPermissionAndAppOp(String permission, String callingPkg,
  496. IBinder callerToken) {
  497. if (getContext().checkPermission(permission, Binder.getCallingPid(), Binder.getCallingUid(),
  498. callerToken) != PERMISSION_GRANTED) {
  499. return MODE_ERRORED;
  500. }
  501. final int permOp = AppOpsManager.permissionToOpCode(permission);
  502. if (permOp != AppOpsManager.OP_NONE) {
  503. return mTransport.mAppOpsManager.noteProxyOp(permOp, callingPkg);
  504. }
  505. return MODE_ALLOWED;
  506. }
  507. /** {@hide} */
  508. protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken)
  509. throws SecurityException {
  510. final Context context = getContext();
  511. final int pid = Binder.getCallingPid();
  512. final int uid = Binder.getCallingUid();
  513. String missingPerm = null;
  514. int strongestMode = MODE_ALLOWED;
  515. if (UserHandle.isSameApp(uid, mMyUid)) {
  516. return MODE_ALLOWED;
  517. }
  518. if (mExported && checkUser(pid, uid, context)) {
  519. final String componentPerm = getReadPermission();
  520. if (componentPerm != null) {
  521. final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
  522. if (mode == MODE_ALLOWED) {
  523. return MODE_ALLOWED;
  524. } else {
  525. missingPerm = componentPerm;
  526. strongestMode = Math.max(strongestMode, mode);
  527. }
  528. }
  529. // track if unprotected read is allowed; any denied
  530. // <path-permission> below removes this ability
  531. boolean allowDefaultRead = (componentPerm == null);
  532. final PathPermission[] pps = getPathPermissions();
  533. if (pps != null) {
  534. final String path = uri.getPath();
  535. for (PathPermission pp : pps) {
  536. final String pathPerm = pp.getReadPermission();
  537. if (pathPerm != null && pp.match(path)) {
  538. final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
  539. if (mode == MODE_ALLOWED) {
  540. return MODE_ALLOWED;
  541. } else {
  542. // any denied <path-permission> means we lose
  543. // default <provider> access.
  544. allowDefaultRead = false;
  545. missingPerm = pathPerm;
  546. strongestMode = Math.max(strongestMode, mode);
  547. }
  548. }
  549. }
  550. }
  551. // if we passed <path-permission> checks above, and no default
  552. // <provider> permission, then allow access.
  553. if (allowDefaultRead) return MODE_ALLOWED;
  554. }
  555. // last chance, check against any uri grants
  556. final int callingUserId = UserHandle.getUserId(uid);
  557. final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, uid))
  558. ? maybeAddUserId(uri, callingUserId) : uri;
  559. if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION,
  560. callerToken) == PERMISSION_GRANTED) {
  561. return MODE_ALLOWED;
  562. }
  563. // If the worst denial we found above was ignored, then pass that
  564. // ignored through; otherwise we assume it should be a real error below.
  565. if (strongestMode == MODE_IGNORED) {
  566. return MODE_IGNORED;
  567. }
  568. final String suffix;
  569. if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(mReadPermission)) {
  570. suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
  571. } else if (mExported) {
  572. suffix = " requires " + missingPerm + ", or grantUriPermission()";
  573. } else {
  574. suffix = " requires the provider be exported, or grantUriPermission()";
  575. }
  576. throw new SecurityException("Permission Denial: reading "
  577. + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
  578. + ", uid=" + uid + suffix);
  579. }
  580. /** {@hide} */
  581. protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken)
  582. throws SecurityException {
  583. final Context context = getContext();
  584. final int pid = Binder.getCallingPid();
  585. final int uid = Binder.getCallingUid();
  586. String missingPerm = null;
  587. int strongestMode = MODE_ALLOWED;
  588. if (UserHandle.isSameApp(uid, mMyUid)) {
  589. return MODE_ALLOWED;
  590. }
  591. if (mExported && checkUser(pid, uid, context)) {
  592. final String componentPerm = getWritePermission();
  593. if (componentPerm != null) {
  594. final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
  595. if (mode == MODE_ALLOWED) {
  596. return MODE_ALLOWED;
  597. } else {
  598. missingPerm = componentPerm;
  599. strongestMode = Math.max(strongestMode, mode);
  600. }
  601. }
  602. // track if unprotected write is allowed; any denied
  603. // <path-permission> below removes this ability
  604. boolean allowDefaultWrite = (componentPerm == null);
  605. final PathPermission[] pps = getPathPermissions();
  606. if (pps != null) {
  607. final String path = uri.getPath();
  608. for (PathPermission pp : pps) {
  609. final String pathPerm = pp.getWritePermission();
  610. if (pathPerm != null && pp.match(path)) {
  611. final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
  612. if (mode == MODE_ALLOWED) {
  613. return MODE_ALLOWED;
  614. } else {
  615. // any denied <path-permission> means we lose
  616. // default <provider> access.
  617. allowDefaultWrite = false;
  618. missingPerm = pathPerm;
  619. strongestMode = Math.max(strongestMode, mode);
  620. }
  621. }
  622. }
  623. }
  624. // if we passed <path-permission> checks above, and no default
  625. // <provider> permission, then allow access.
  626. if (allowDefaultWrite) return MODE_ALLOWED;
  627. }
  628. // last chance, check against any uri grants
  629. if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
  630. callerToken) == PERMISSION_GRANTED) {
  631. return MODE_ALLOWED;
  632. }
  633. // If the worst denial we found above was ignored, then pass that
  634. // ignored through; otherwise we assume it should be a real error below.
  635. if (strongestMode == MODE_IGNORED) {
  636. return MODE_IGNORED;
  637. }
  638. final String failReason = mExported
  639. ? " requires " + missingPerm + ", or grantUriPermission()"
  640. : " requires the provider be exported, or grantUriPermission()";
  641. throw new SecurityException("Permission Denial: writing "
  642. + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
  643. + ", uid=" + uid + failReason);
  644. }
  645. /**
  646. * Retrieves the Context this provider is running in. Only available once
  647. * {@link #onCreate} has been called -- this will return {@code null} in the
  648. * constructor.
  649. */
  650. public final @Nullable Context getContext() {
  651. return mContext;
  652. }
  653. /**
  654. * Set the calling package, returning the current value (or {@code null})
  655. * which can be used later to restore the previous state.
  656. */
  657. private String setCallingPackage(String callingPackage) {
  658. final String original = mCallingPackage.get();
  659. mCallingPackage.set(callingPackage);
  660. return original;
  661. }
  662. /**
  663. * Return the package name of the caller that initiated the request being
  664. * processed on the current thread. The returned package will have been
  665. * verified to belong to the calling UID. Returns {@code null} if not
  666. * currently processing a request.
  667. * <p>
  668. * This will always return {@code null} when processing
  669. * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests.
  670. *
  671. * @see Binder#getCallingUid()
  672. * @see Context#grantUriPermission(String, Uri, int)
  673. * @throws SecurityException if the calling package doesn't belong to the
  674. * calling UID.
  675. */
  676. public final @Nullable String getCallingPackage() {
  677. final String pkg = mCallingPackage.get();
  678. if (pkg != null) {
  679. mTransport.mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg);
  680. }
  681. return pkg;
  682. }
  683. /**
  684. * Change the authorities of the ContentProvider.
  685. * This is normally set for you from its manifest information when the provider is first
  686. * created.
  687. * @hide
  688. * @param authorities the semi-colon separated authorities of the ContentProvider.
  689. */
  690. protected final void setAuthorities(String authorities) {
  691. if (authorities != null) {
  692. if (authorities.indexOf(';') == -1) {
  693. mAuthority = authorities;
  694. mAuthorities = null;
  695. } else {
  696. mAuthority = null;
  697. mAuthorities = authorities.split(";");
  698. }
  699. }
  700. }
  701. /** @hide */
  702. protected final boolean matchesOurAuthorities(String authority) {
  703. if (mAuthority != null) {
  704. return mAuthority.equals(authority);
  705. }
  706. if (mAuthorities != null) {
  707. int length = mAuthorities.length;
  708. for (int i = 0; i < length; i++) {
  709. if (mAuthorities[i].equals(authority)) return true;
  710. }
  711. }
  712. return false;
  713. }
  714. /**
  715. * Change the permission required to read data from the content
  716. * provider. This is normally set for you from its manifest information
  717. * when the provider is first created.
  718. *
  719. * @param permission Name of the permission required for read-only access.
  720. */
  721. protected final void setReadPermission(@Nullable String permission) {
  722. mReadPermission = permission;
  723. }
  724. /**
  725. * Return the name of the permission required for read-only access to
  726. * this content provider. This method can be called from multiple
  727. * threads, as described in
  728. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  729. * and Threads</a>.
  730. */
  731. public final @Nullable String getReadPermission() {
  732. return mReadPermission;
  733. }
  734. /**
  735. * Change the permission required to read and write data in the content
  736. * provider. This is normally set for you from its manifest information
  737. * when the provider is first created.
  738. *
  739. * @param permission Name of the permission required for read/write access.
  740. */
  741. protected final void setWritePermission(@Nullable String permission) {
  742. mWritePermission = permission;
  743. }
  744. /**
  745. * Return the name of the permission required for read/write access to
  746. * this content provider. This method can be called from multiple
  747. * threads, as described in
  748. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  749. * and Threads</a>.
  750. */
  751. public final @Nullable String getWritePermission() {
  752. return mWritePermission;
  753. }
  754. /**
  755. * Change the path-based permission required to read and/or write data in
  756. * the content provider. This is normally set for you from its manifest
  757. * information when the provider is first created.
  758. *
  759. * @param permissions Array of path permission descriptions.
  760. */
  761. protected final void setPathPermissions(@Nullable PathPermission[] permissions) {
  762. mPathPermissions = permissions;
  763. }
  764. /**
  765. * Return the path-based permissions required for read and/or write access to
  766. * this content provider. This method can be called from multiple
  767. * threads, as described in
  768. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  769. * and Threads</a>.
  770. */
  771. public final @Nullable PathPermission[] getPathPermissions() {
  772. return mPathPermissions;
  773. }
  774. /** @hide */
  775. public final void setAppOps(int readOp, int writeOp) {
  776. if (!mNoPerms) {
  777. mTransport.mReadOp = readOp;
  778. mTransport.mWriteOp = writeOp;
  779. }
  780. }
  781. /** @hide */
  782. public AppOpsManager getAppOpsManager() {
  783. return mTransport.mAppOpsManager;
  784. }
  785. /**
  786. * Implement this to initialize your content provider on startup.
  787. * This method is called for all registered content providers on the
  788. * application main thread at application launch time. It must not perform
  789. * lengthy operations, or application startup will be delayed.
  790. *
  791. * <p>You should defer nontrivial initialization (such as opening,
  792. * upgrading, and scanning databases) until the content provider is used
  793. * (via {@link #query}, {@link #insert}, etc). Deferred initialization
  794. * keeps application startup fast, avoids unnecessary work if the provider
  795. * turns out not to be needed, and stops database errors (such as a full
  796. * disk) from halting application launch.
  797. *
  798. * <p>If you use SQLite, {@link android.database.sqlite.SQLiteOpenHelper}
  799. * is a helpful utility class that makes it easy to manage databases,
  800. * and will automatically defer opening until first use. If you do use
  801. * SQLiteOpenHelper, make sure to avoid calling
  802. * {@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} or
  803. * {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase}
  804. * from this method. (Instead, override
  805. * {@link android.database.sqlite.SQLiteOpenHelper#onOpen} to initialize the
  806. * database when it is first opened.)
  807. *
  808. * @return true if the provider was successfully loaded, false otherwise
  809. */
  810. public abstract boolean onCreate();
  811. /**
  812. * {@inheritDoc}
  813. * This method is always called on the application main thread, and must
  814. * not perform lengthy operations.
  815. *
  816. * <p>The default content provider implementation does nothing.
  817. * Override this method to take appropriate action.
  818. * (Content providers do not usually care about things like screen
  819. * orientation, but may want to know about locale changes.)
  820. */
  821. @Override
  822. public void onConfigurationChanged(Configuration newConfig) {
  823. }
  824. /**
  825. * {@inheritDoc}
  826. * This method is always called on the application main thread, and must
  827. * not perform lengthy operations.
  828. *
  829. * <p>The default content provider implementation does nothing.
  830. * Subclasses may override this method to take appropriate action.
  831. */
  832. @Override
  833. public void onLowMemory() {
  834. }
  835. @Override
  836. public void onTrimMemory(int level) {
  837. }
  838. /**
  839. * Implement this to handle query requests from clients.
  840. *
  841. * <p>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher should override
  842. * {@link #query(Uri, String[], Bundle, CancellationSignal)} and provide a stub
  843. * implementation of this method.
  844. *
  845. * <p>This method can be called from multiple threads, as described in
  846. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  847. * and Threads</a>.
  848. * <p>
  849. * Example client call:<p>
  850. * <pre>// Request a specific record.
  851. * Cursor managedCursor = managedQuery(
  852. ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
  853. projection, // Which columns to return.
  854. null, // WHERE clause.
  855. null, // WHERE clause value substitution
  856. People.NAME + " ASC"); // Sort order.</pre>
  857. * Example implementation:<p>
  858. * <pre>// SQLiteQueryBuilder is a helper class that creates the
  859. // proper SQL syntax for us.
  860. SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
  861. // Set the table we're querying.
  862. qBuilder.setTables(DATABASE_TABLE_NAME);
  863. // If the query ends in a specific record number, we're
  864. // being asked for a specific record, so set the
  865. // WHERE clause in our query.
  866. if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
  867. qBuilder.appendWhere("_id=" + uri.getPathLeafId());
  868. }
  869. // Make the query.
  870. Cursor c = qBuilder.query(mDb,
  871. projection,
  872. selection,
  873. selectionArgs,
  874. groupBy,
  875. having,
  876. sortOrder);
  877. c.setNotificationUri(getContext().getContentResolver(), uri);
  878. return c;</pre>
  879. *
  880. * @param uri The URI to query. This will be the full URI sent by the client;
  881. * if the client is requesting a specific record, the URI will end in a record number
  882. * that the implementation should parse and add to a WHERE or HAVING clause, specifying
  883. * that _id value.
  884. * @param projection The list of columns to put into the cursor. If
  885. * {@code null} all columns are included.
  886. * @param selection A selection criteria to apply when filtering rows.
  887. * If {@code null} then all rows are included.
  888. * @param selectionArgs You may include ?s in selection, which will be replaced by
  889. * the values from selectionArgs, in order that they appear in the selection.
  890. * The values will be bound as Strings.
  891. * @param sortOrder How the rows in the cursor should be sorted.
  892. * If {@code null} then the provider is free to define the sort order.
  893. * @return a Cursor or {@code null}.
  894. */
  895. public abstract @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
  896. @Nullable String selection, @Nullable String[] selectionArgs,
  897. @Nullable String sortOrder);
  898. /**
  899. * Implement this to handle query requests from clients with support for cancellation.
  900. *
  901. * <p>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher should override
  902. * {@link #query(Uri, String[], Bundle, CancellationSignal)} instead of this method.
  903. *
  904. * <p>This method can be called from multiple threads, as described in
  905. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  906. * and Threads</a>.
  907. * <p>
  908. * Example client call:<p>
  909. * <pre>// Request a specific record.
  910. * Cursor managedCursor = managedQuery(
  911. ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
  912. projection, // Which columns to return.
  913. null, // WHERE clause.
  914. null, // WHERE clause value substitution
  915. People.NAME + " ASC"); // Sort order.</pre>
  916. * Example implementation:<p>
  917. * <pre>// SQLiteQueryBuilder is a helper class that creates the
  918. // proper SQL syntax for us.
  919. SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
  920. // Set the table we're querying.
  921. qBuilder.setTables(DATABASE_TABLE_NAME);
  922. // If the query ends in a specific record number, we're
  923. // being asked for a specific record, so set the
  924. // WHERE clause in our query.
  925. if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
  926. qBuilder.appendWhere("_id=" + uri.getPathLeafId());
  927. }
  928. // Make the query.
  929. Cursor c = qBuilder.query(mDb,
  930. projection,
  931. selection,
  932. selectionArgs,
  933. groupBy,
  934. having,
  935. sortOrder);
  936. c.setNotificationUri(getContext().getContentResolver(), uri);
  937. return c;</pre>
  938. * <p>
  939. * If you implement this method then you must also implement the version of
  940. * {@link #query(Uri, String[], String, String[], String)} that does not take a cancellation
  941. * signal to ensure correct operation on older versions of the Android Framework in
  942. * which the cancellation signal overload was not available.
  943. *
  944. * @param uri The URI to query. This will be the full URI sent by the client;
  945. * if the client is requesting a specific record, the URI will end in a record number
  946. * that the implementation should parse and add to a WHERE or HAVING clause, specifying
  947. * that _id value.
  948. * @param projection The list of columns to put into the cursor. If
  949. * {@code null} all columns are included.
  950. * @param selection A selection criteria to apply when filtering rows.
  951. * If {@code null} then all rows are included.
  952. * @param selectionArgs You may include ?s in selection, which will be replaced by
  953. * the values from selectionArgs, in order that they appear in the selection.
  954. * The values will be bound as Strings.
  955. * @param sortOrder How the rows in the cursor should be sorted.
  956. * If {@code null} then the provider is free to define the sort order.
  957. * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if none.
  958. * If the operation is canceled, then {@link android.os.OperationCanceledException} will be thrown
  959. * when the query is executed.
  960. * @return a Cursor or {@code null}.
  961. */
  962. public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
  963. @Nullable String selection, @Nullable String[] selectionArgs,
  964. @Nullable String sortOrder, @Nullable CancellationSignal cancellationSignal) {
  965. return query(uri, projection, selection, selectionArgs, sortOrder);
  966. }
  967. /**
  968. * Implement this to handle query requests where the arguments are packed into a {@link Bundle}.
  969. * Arguments may include traditional SQL style query arguments. When present these
  970. * should be handled according to the contract established in
  971. * {@link #query(Uri, String[], String, String[], String, CancellationSignal).
  972. *
  973. * <p>Traditional SQL arguments can be found in the bundle using the following keys:
  974. * <li>{@link ContentResolver#QUERY_ARG_SQL_SELECTION}
  975. * <li>{@link ContentResolver#QUERY_ARG_SQL_SELECTION_ARGS}
  976. * <li>{@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER}
  977. *
  978. * <p>This method can be called from multiple threads, as described in
  979. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  980. * and Threads</a>.
  981. *
  982. * <p>
  983. * Example client call:<p>
  984. * <pre>// Request 20 records starting at row index 30.
  985. Bundle queryArgs = new Bundle();
  986. queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 30);
  987. queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 20);
  988. Cursor cursor = getContentResolver().query(
  989. contentUri, // Content Uri is specific to individual content providers.
  990. projection, // String[] describing which columns to return.
  991. queryArgs, // Query arguments.
  992. null); // Cancellation signal.</pre>
  993. *
  994. * Example implementation:<p>
  995. * <pre>
  996. int recordsetSize = 0x1000; // Actual value is implementation specific.
  997. queryArgs = queryArgs != null ? queryArgs : Bundle.EMPTY; // ensure queryArgs is non-null
  998. int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
  999. int limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MIN_VALUE);
  1000. MatrixCursor c = new MatrixCursor(PROJECTION, limit);
  1001. // Calculate the number of items to include in the cursor.
  1002. int numItems = MathUtils.constrain(recordsetSize - offset, 0, limit);
  1003. // Build the paged result set....
  1004. for (int i = offset; i < offset + numItems; i++) {
  1005. // populate row from your data.
  1006. }
  1007. Bundle extras = new Bundle();
  1008. c.setExtras(extras);
  1009. // Any QUERY_ARG_* key may be included if honored.
  1010. // In an actual implementation, include only keys that are both present in queryArgs
  1011. // and reflected in the Cursor output. For example, if QUERY_ARG_OFFSET were included
  1012. // in queryArgs, but was ignored because it contained an invalid value (like –273),
  1013. // then QUERY_ARG_OFFSET should be omitted.
  1014. extras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, new String[] {
  1015. ContentResolver.QUERY_ARG_OFFSET,
  1016. ContentResolver.QUERY_ARG_LIMIT
  1017. });
  1018. extras.putInt(ContentResolver.EXTRA_TOTAL_COUNT, recordsetSize);
  1019. cursor.setNotificationUri(getContext().getContentResolver(), uri);
  1020. return cursor;</pre>
  1021. * <p>
  1022. * @see #query(Uri, String[], String, String[], String, CancellationSignal) for
  1023. * implementation details.
  1024. *
  1025. * @param uri The URI to query. This will be the full URI sent by the client.
  1026. * @param projection The list of columns to put into the cursor.
  1027. * If {@code null} provide a default set of columns.
  1028. * @param queryArgs A Bundle containing all additional information necessary for the query.
  1029. * Values in the Bundle may include SQL style arguments.
  1030. * @param cancellationSignal A signal to cancel the operation in progress,
  1031. * or {@code null}.
  1032. * @return a Cursor or {@code null}.
  1033. */
  1034. public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
  1035. @Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal) {
  1036. queryArgs = queryArgs != null ? queryArgs : Bundle.EMPTY;
  1037. // if client doesn't supply an SQL sort order argument, attempt to build one from
  1038. // QUERY_ARG_SORT* arguments.
  1039. String sortClause = queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER);
  1040. if (sortClause == null && queryArgs.containsKey(ContentResolver.QUERY_ARG_SORT_COLUMNS)) {
  1041. sortClause = ContentResolver.createSqlSortClause(queryArgs);
  1042. }
  1043. return query(
  1044. uri,
  1045. projection,
  1046. queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SELECTION),
  1047. queryArgs.getStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS),
  1048. sortClause,
  1049. cancellationSignal);
  1050. }
  1051. /**
  1052. * Implement this to handle requests for the MIME type of the data at the
  1053. * given URI. The returned MIME type should start with
  1054. * <code>vnd.android.cursor.item</code> for a single record,
  1055. * or <code>vnd.android.cursor.dir/</code> for multiple items.
  1056. * This method can be called from multiple threads, as described in
  1057. * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
  1058. * and Threads</a>.
  1059. *
  1060. * <p>Note that there are no permissions needed for an application to
  1061. * access this information; if your content provider requires read and/or
  1062. * write permissions, or