PageRenderTime 135ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/android/upstream/android/content/ContentProviderNative.java

https://bitbucket.org/festevezga/xobotos
Java | 624 lines | 501 code | 94 blank | 29 comment | 37 complexity | 769bb48ad8946e47309c77d642252fe1 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 android.content.res.AssetFileDescriptor;
  18. import android.database.BulkCursorNative;
  19. import android.database.BulkCursorToCursorAdaptor;
  20. import android.database.Cursor;
  21. import android.database.CursorToBulkCursorAdaptor;
  22. import android.database.CursorWindow;
  23. import android.database.DatabaseUtils;
  24. import android.database.IBulkCursor;
  25. import android.database.IContentObserver;
  26. import android.net.Uri;
  27. import android.os.Binder;
  28. import android.os.Bundle;
  29. import android.os.RemoteException;
  30. import android.os.IBinder;
  31. import android.os.Parcel;
  32. import android.os.ParcelFileDescriptor;
  33. import android.os.Parcelable;
  34. import java.io.FileNotFoundException;
  35. import java.util.ArrayList;
  36. /**
  37. * {@hide}
  38. */
  39. abstract public class ContentProviderNative extends Binder implements IContentProvider {
  40. private static final String TAG = "ContentProvider";
  41. public ContentProviderNative()
  42. {
  43. attachInterface(this, descriptor);
  44. }
  45. /**
  46. * Cast a Binder object into a content resolver interface, generating
  47. * a proxy if needed.
  48. */
  49. static public IContentProvider asInterface(IBinder obj)
  50. {
  51. if (obj == null) {
  52. return null;
  53. }
  54. IContentProvider in =
  55. (IContentProvider)obj.queryLocalInterface(descriptor);
  56. if (in != null) {
  57. return in;
  58. }
  59. return new ContentProviderProxy(obj);
  60. }
  61. /**
  62. * Gets the name of the content provider.
  63. * Should probably be part of the {@link IContentProvider} interface.
  64. * @return The content provider name.
  65. */
  66. public abstract String getProviderName();
  67. @Override
  68. public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
  69. throws RemoteException {
  70. try {
  71. switch (code) {
  72. case QUERY_TRANSACTION:
  73. {
  74. data.enforceInterface(IContentProvider.descriptor);
  75. Uri url = Uri.CREATOR.createFromParcel(data);
  76. // String[] projection
  77. int num = data.readInt();
  78. String[] projection = null;
  79. if (num > 0) {
  80. projection = new String[num];
  81. for (int i = 0; i < num; i++) {
  82. projection[i] = data.readString();
  83. }
  84. }
  85. // String selection, String[] selectionArgs...
  86. String selection = data.readString();
  87. num = data.readInt();
  88. String[] selectionArgs = null;
  89. if (num > 0) {
  90. selectionArgs = new String[num];
  91. for (int i = 0; i < num; i++) {
  92. selectionArgs[i] = data.readString();
  93. }
  94. }
  95. String sortOrder = data.readString();
  96. IContentObserver observer = IContentObserver.Stub.asInterface(
  97. data.readStrongBinder());
  98. Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder);
  99. if (cursor != null) {
  100. CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor(
  101. cursor, observer, getProviderName());
  102. final IBinder binder = adaptor.asBinder();
  103. final int count = adaptor.count();
  104. final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex(
  105. adaptor.getColumnNames());
  106. final boolean wantsAllOnMoveCalls = adaptor.getWantsAllOnMoveCalls();
  107. reply.writeNoException();
  108. reply.writeStrongBinder(binder);
  109. reply.writeInt(count);
  110. reply.writeInt(index);
  111. reply.writeInt(wantsAllOnMoveCalls ? 1 : 0);
  112. } else {
  113. reply.writeNoException();
  114. reply.writeStrongBinder(null);
  115. }
  116. return true;
  117. }
  118. case GET_TYPE_TRANSACTION:
  119. {
  120. data.enforceInterface(IContentProvider.descriptor);
  121. Uri url = Uri.CREATOR.createFromParcel(data);
  122. String type = getType(url);
  123. reply.writeNoException();
  124. reply.writeString(type);
  125. return true;
  126. }
  127. case INSERT_TRANSACTION:
  128. {
  129. data.enforceInterface(IContentProvider.descriptor);
  130. Uri url = Uri.CREATOR.createFromParcel(data);
  131. ContentValues values = ContentValues.CREATOR.createFromParcel(data);
  132. Uri out = insert(url, values);
  133. reply.writeNoException();
  134. Uri.writeToParcel(reply, out);
  135. return true;
  136. }
  137. case BULK_INSERT_TRANSACTION:
  138. {
  139. data.enforceInterface(IContentProvider.descriptor);
  140. Uri url = Uri.CREATOR.createFromParcel(data);
  141. ContentValues[] values = data.createTypedArray(ContentValues.CREATOR);
  142. int count = bulkInsert(url, values);
  143. reply.writeNoException();
  144. reply.writeInt(count);
  145. return true;
  146. }
  147. case APPLY_BATCH_TRANSACTION:
  148. {
  149. data.enforceInterface(IContentProvider.descriptor);
  150. final int numOperations = data.readInt();
  151. final ArrayList<ContentProviderOperation> operations =
  152. new ArrayList<ContentProviderOperation>(numOperations);
  153. for (int i = 0; i < numOperations; i++) {
  154. operations.add(i, ContentProviderOperation.CREATOR.createFromParcel(data));
  155. }
  156. final ContentProviderResult[] results = applyBatch(operations);
  157. reply.writeNoException();
  158. reply.writeTypedArray(results, 0);
  159. return true;
  160. }
  161. case DELETE_TRANSACTION:
  162. {
  163. data.enforceInterface(IContentProvider.descriptor);
  164. Uri url = Uri.CREATOR.createFromParcel(data);
  165. String selection = data.readString();
  166. String[] selectionArgs = data.readStringArray();
  167. int count = delete(url, selection, selectionArgs);
  168. reply.writeNoException();
  169. reply.writeInt(count);
  170. return true;
  171. }
  172. case UPDATE_TRANSACTION:
  173. {
  174. data.enforceInterface(IContentProvider.descriptor);
  175. Uri url = Uri.CREATOR.createFromParcel(data);
  176. ContentValues values = ContentValues.CREATOR.createFromParcel(data);
  177. String selection = data.readString();
  178. String[] selectionArgs = data.readStringArray();
  179. int count = update(url, values, selection, selectionArgs);
  180. reply.writeNoException();
  181. reply.writeInt(count);
  182. return true;
  183. }
  184. case OPEN_FILE_TRANSACTION:
  185. {
  186. data.enforceInterface(IContentProvider.descriptor);
  187. Uri url = Uri.CREATOR.createFromParcel(data);
  188. String mode = data.readString();
  189. ParcelFileDescriptor fd;
  190. fd = openFile(url, mode);
  191. reply.writeNoException();
  192. if (fd != null) {
  193. reply.writeInt(1);
  194. fd.writeToParcel(reply,
  195. Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
  196. } else {
  197. reply.writeInt(0);
  198. }
  199. return true;
  200. }
  201. case OPEN_ASSET_FILE_TRANSACTION:
  202. {
  203. data.enforceInterface(IContentProvider.descriptor);
  204. Uri url = Uri.CREATOR.createFromParcel(data);
  205. String mode = data.readString();
  206. AssetFileDescriptor fd;
  207. fd = openAssetFile(url, mode);
  208. reply.writeNoException();
  209. if (fd != null) {
  210. reply.writeInt(1);
  211. fd.writeToParcel(reply,
  212. Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
  213. } else {
  214. reply.writeInt(0);
  215. }
  216. return true;
  217. }
  218. case CALL_TRANSACTION:
  219. {
  220. data.enforceInterface(IContentProvider.descriptor);
  221. String method = data.readString();
  222. String stringArg = data.readString();
  223. Bundle args = data.readBundle();
  224. Bundle responseBundle = call(method, stringArg, args);
  225. reply.writeNoException();
  226. reply.writeBundle(responseBundle);
  227. return true;
  228. }
  229. case GET_STREAM_TYPES_TRANSACTION:
  230. {
  231. data.enforceInterface(IContentProvider.descriptor);
  232. Uri url = Uri.CREATOR.createFromParcel(data);
  233. String mimeTypeFilter = data.readString();
  234. String[] types = getStreamTypes(url, mimeTypeFilter);
  235. reply.writeNoException();
  236. reply.writeStringArray(types);
  237. return true;
  238. }
  239. case OPEN_TYPED_ASSET_FILE_TRANSACTION:
  240. {
  241. data.enforceInterface(IContentProvider.descriptor);
  242. Uri url = Uri.CREATOR.createFromParcel(data);
  243. String mimeType = data.readString();
  244. Bundle opts = data.readBundle();
  245. AssetFileDescriptor fd;
  246. fd = openTypedAssetFile(url, mimeType, opts);
  247. reply.writeNoException();
  248. if (fd != null) {
  249. reply.writeInt(1);
  250. fd.writeToParcel(reply,
  251. Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
  252. } else {
  253. reply.writeInt(0);
  254. }
  255. return true;
  256. }
  257. }
  258. } catch (Exception e) {
  259. DatabaseUtils.writeExceptionToParcel(reply, e);
  260. return true;
  261. }
  262. return super.onTransact(code, data, reply, flags);
  263. }
  264. public IBinder asBinder()
  265. {
  266. return this;
  267. }
  268. }
  269. final class ContentProviderProxy implements IContentProvider
  270. {
  271. public ContentProviderProxy(IBinder remote)
  272. {
  273. mRemote = remote;
  274. }
  275. public IBinder asBinder()
  276. {
  277. return mRemote;
  278. }
  279. public Cursor query(Uri url, String[] projection, String selection,
  280. String[] selectionArgs, String sortOrder) throws RemoteException {
  281. BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
  282. Parcel data = Parcel.obtain();
  283. Parcel reply = Parcel.obtain();
  284. try {
  285. data.writeInterfaceToken(IContentProvider.descriptor);
  286. url.writeToParcel(data, 0);
  287. int length = 0;
  288. if (projection != null) {
  289. length = projection.length;
  290. }
  291. data.writeInt(length);
  292. for (int i = 0; i < length; i++) {
  293. data.writeString(projection[i]);
  294. }
  295. data.writeString(selection);
  296. if (selectionArgs != null) {
  297. length = selectionArgs.length;
  298. } else {
  299. length = 0;
  300. }
  301. data.writeInt(length);
  302. for (int i = 0; i < length; i++) {
  303. data.writeString(selectionArgs[i]);
  304. }
  305. data.writeString(sortOrder);
  306. data.writeStrongBinder(adaptor.getObserver().asBinder());
  307. mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
  308. DatabaseUtils.readExceptionFromParcel(reply);
  309. IBulkCursor bulkCursor = BulkCursorNative.asInterface(reply.readStrongBinder());
  310. if (bulkCursor != null) {
  311. int rowCount = reply.readInt();
  312. int idColumnPosition = reply.readInt();
  313. boolean wantsAllOnMoveCalls = reply.readInt() != 0;
  314. adaptor.initialize(bulkCursor, rowCount, idColumnPosition, wantsAllOnMoveCalls);
  315. } else {
  316. adaptor.close();
  317. adaptor = null;
  318. }
  319. return adaptor;
  320. } catch (RemoteException ex) {
  321. adaptor.close();
  322. throw ex;
  323. } catch (RuntimeException ex) {
  324. adaptor.close();
  325. throw ex;
  326. } finally {
  327. data.recycle();
  328. reply.recycle();
  329. }
  330. }
  331. public String getType(Uri url) throws RemoteException
  332. {
  333. Parcel data = Parcel.obtain();
  334. Parcel reply = Parcel.obtain();
  335. try {
  336. data.writeInterfaceToken(IContentProvider.descriptor);
  337. url.writeToParcel(data, 0);
  338. mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0);
  339. DatabaseUtils.readExceptionFromParcel(reply);
  340. String out = reply.readString();
  341. return out;
  342. } finally {
  343. data.recycle();
  344. reply.recycle();
  345. }
  346. }
  347. public Uri insert(Uri url, ContentValues values) throws RemoteException
  348. {
  349. Parcel data = Parcel.obtain();
  350. Parcel reply = Parcel.obtain();
  351. try {
  352. data.writeInterfaceToken(IContentProvider.descriptor);
  353. url.writeToParcel(data, 0);
  354. values.writeToParcel(data, 0);
  355. mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0);
  356. DatabaseUtils.readExceptionFromParcel(reply);
  357. Uri out = Uri.CREATOR.createFromParcel(reply);
  358. return out;
  359. } finally {
  360. data.recycle();
  361. reply.recycle();
  362. }
  363. }
  364. public int bulkInsert(Uri url, ContentValues[] values) throws RemoteException {
  365. Parcel data = Parcel.obtain();
  366. Parcel reply = Parcel.obtain();
  367. try {
  368. data.writeInterfaceToken(IContentProvider.descriptor);
  369. url.writeToParcel(data, 0);
  370. data.writeTypedArray(values, 0);
  371. mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0);
  372. DatabaseUtils.readExceptionFromParcel(reply);
  373. int count = reply.readInt();
  374. return count;
  375. } finally {
  376. data.recycle();
  377. reply.recycle();
  378. }
  379. }
  380. public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
  381. throws RemoteException, OperationApplicationException {
  382. Parcel data = Parcel.obtain();
  383. Parcel reply = Parcel.obtain();
  384. try {
  385. data.writeInterfaceToken(IContentProvider.descriptor);
  386. data.writeInt(operations.size());
  387. for (ContentProviderOperation operation : operations) {
  388. operation.writeToParcel(data, 0);
  389. }
  390. mRemote.transact(IContentProvider.APPLY_BATCH_TRANSACTION, data, reply, 0);
  391. DatabaseUtils.readExceptionWithOperationApplicationExceptionFromParcel(reply);
  392. final ContentProviderResult[] results =
  393. reply.createTypedArray(ContentProviderResult.CREATOR);
  394. return results;
  395. } finally {
  396. data.recycle();
  397. reply.recycle();
  398. }
  399. }
  400. public int delete(Uri url, String selection, String[] selectionArgs)
  401. throws RemoteException {
  402. Parcel data = Parcel.obtain();
  403. Parcel reply = Parcel.obtain();
  404. try {
  405. data.writeInterfaceToken(IContentProvider.descriptor);
  406. url.writeToParcel(data, 0);
  407. data.writeString(selection);
  408. data.writeStringArray(selectionArgs);
  409. mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0);
  410. DatabaseUtils.readExceptionFromParcel(reply);
  411. int count = reply.readInt();
  412. return count;
  413. } finally {
  414. data.recycle();
  415. reply.recycle();
  416. }
  417. }
  418. public int update(Uri url, ContentValues values, String selection,
  419. String[] selectionArgs) throws RemoteException {
  420. Parcel data = Parcel.obtain();
  421. Parcel reply = Parcel.obtain();
  422. try {
  423. data.writeInterfaceToken(IContentProvider.descriptor);
  424. url.writeToParcel(data, 0);
  425. values.writeToParcel(data, 0);
  426. data.writeString(selection);
  427. data.writeStringArray(selectionArgs);
  428. mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0);
  429. DatabaseUtils.readExceptionFromParcel(reply);
  430. int count = reply.readInt();
  431. return count;
  432. } finally {
  433. data.recycle();
  434. reply.recycle();
  435. }
  436. }
  437. public ParcelFileDescriptor openFile(Uri url, String mode)
  438. throws RemoteException, FileNotFoundException {
  439. Parcel data = Parcel.obtain();
  440. Parcel reply = Parcel.obtain();
  441. try {
  442. data.writeInterfaceToken(IContentProvider.descriptor);
  443. url.writeToParcel(data, 0);
  444. data.writeString(mode);
  445. mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
  446. DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
  447. int has = reply.readInt();
  448. ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null;
  449. return fd;
  450. } finally {
  451. data.recycle();
  452. reply.recycle();
  453. }
  454. }
  455. public AssetFileDescriptor openAssetFile(Uri url, String mode)
  456. throws RemoteException, FileNotFoundException {
  457. Parcel data = Parcel.obtain();
  458. Parcel reply = Parcel.obtain();
  459. try {
  460. data.writeInterfaceToken(IContentProvider.descriptor);
  461. url.writeToParcel(data, 0);
  462. data.writeString(mode);
  463. mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
  464. DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
  465. int has = reply.readInt();
  466. AssetFileDescriptor fd = has != 0
  467. ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
  468. return fd;
  469. } finally {
  470. data.recycle();
  471. reply.recycle();
  472. }
  473. }
  474. public Bundle call(String method, String request, Bundle args)
  475. throws RemoteException {
  476. Parcel data = Parcel.obtain();
  477. Parcel reply = Parcel.obtain();
  478. try {
  479. data.writeInterfaceToken(IContentProvider.descriptor);
  480. data.writeString(method);
  481. data.writeString(request);
  482. data.writeBundle(args);
  483. mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0);
  484. DatabaseUtils.readExceptionFromParcel(reply);
  485. Bundle bundle = reply.readBundle();
  486. return bundle;
  487. } finally {
  488. data.recycle();
  489. reply.recycle();
  490. }
  491. }
  492. public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException
  493. {
  494. Parcel data = Parcel.obtain();
  495. Parcel reply = Parcel.obtain();
  496. try {
  497. data.writeInterfaceToken(IContentProvider.descriptor);
  498. url.writeToParcel(data, 0);
  499. data.writeString(mimeTypeFilter);
  500. mRemote.transact(IContentProvider.GET_STREAM_TYPES_TRANSACTION, data, reply, 0);
  501. DatabaseUtils.readExceptionFromParcel(reply);
  502. String[] out = reply.createStringArray();
  503. return out;
  504. } finally {
  505. data.recycle();
  506. reply.recycle();
  507. }
  508. }
  509. public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts)
  510. throws RemoteException, FileNotFoundException {
  511. Parcel data = Parcel.obtain();
  512. Parcel reply = Parcel.obtain();
  513. try {
  514. data.writeInterfaceToken(IContentProvider.descriptor);
  515. url.writeToParcel(data, 0);
  516. data.writeString(mimeType);
  517. data.writeBundle(opts);
  518. mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0);
  519. DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
  520. int has = reply.readInt();
  521. AssetFileDescriptor fd = has != 0
  522. ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
  523. return fd;
  524. } finally {
  525. data.recycle();
  526. reply.recycle();
  527. }
  528. }
  529. private IBinder mRemote;
  530. }