/core/java/android/content/ContentProviderNative.java
Java | 763 lines | 621 code | 112 blank | 30 comment | 44 complexity | 8bc58c128967867a39a78eec2c26d004 MD5 | raw file
- /*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package android.content;
- import android.content.res.AssetFileDescriptor;
- import android.database.BulkCursorDescriptor;
- import android.database.BulkCursorToCursorAdaptor;
- import android.database.Cursor;
- import android.database.CursorToBulkCursorAdaptor;
- import android.database.DatabaseUtils;
- import android.database.IContentObserver;
- import android.net.Uri;
- import android.os.Binder;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.ICancellationSignal;
- import android.os.Parcel;
- import android.os.ParcelFileDescriptor;
- import android.os.Parcelable;
- import android.os.RemoteException;
- import java.io.FileNotFoundException;
- import java.util.ArrayList;
- /**
- * {@hide}
- */
- abstract public class ContentProviderNative extends Binder implements IContentProvider {
- public ContentProviderNative()
- {
- attachInterface(this, descriptor);
- }
- /**
- * Cast a Binder object into a content resolver interface, generating
- * a proxy if needed.
- */
- static public IContentProvider asInterface(IBinder obj)
- {
- if (obj == null) {
- return null;
- }
- IContentProvider in =
- (IContentProvider)obj.queryLocalInterface(descriptor);
- if (in != null) {
- return in;
- }
- return new ContentProviderProxy(obj);
- }
- /**
- * Gets the name of the content provider.
- * Should probably be part of the {@link IContentProvider} interface.
- * @return The content provider name.
- */
- public abstract String getProviderName();
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- try {
- switch (code) {
- case QUERY_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- // String[] projection
- int num = data.readInt();
- String[] projection = null;
- if (num > 0) {
- projection = new String[num];
- for (int i = 0; i < num; i++) {
- projection[i] = data.readString();
- }
- }
- // String selection, String[] selectionArgs...
- String selection = data.readString();
- num = data.readInt();
- String[] selectionArgs = null;
- if (num > 0) {
- selectionArgs = new String[num];
- for (int i = 0; i < num; i++) {
- selectionArgs[i] = data.readString();
- }
- }
- String sortOrder = data.readString();
- IContentObserver observer = IContentObserver.Stub.asInterface(
- data.readStrongBinder());
- ICancellationSignal cancellationSignal = ICancellationSignal.Stub.asInterface(
- data.readStrongBinder());
- Cursor cursor = query(callingPkg, url, projection, selection, selectionArgs,
- sortOrder, cancellationSignal);
- if (cursor != null) {
- CursorToBulkCursorAdaptor adaptor = null;
- try {
- adaptor = new CursorToBulkCursorAdaptor(cursor, observer,
- getProviderName());
- cursor = null;
- BulkCursorDescriptor d = adaptor.getBulkCursorDescriptor();
- adaptor = null;
- reply.writeNoException();
- reply.writeInt(1);
- d.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- } finally {
- // Close cursor if an exception was thrown while constructing the adaptor.
- if (adaptor != null) {
- adaptor.close();
- }
- if (cursor != null) {
- cursor.close();
- }
- }
- } else {
- reply.writeNoException();
- reply.writeInt(0);
- }
- return true;
- }
- case GET_TYPE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- String type = getType(url);
- reply.writeNoException();
- reply.writeString(type);
- return true;
- }
- case INSERT_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- ContentValues values = ContentValues.CREATOR.createFromParcel(data);
- Uri out = insert(callingPkg, url, values);
- reply.writeNoException();
- Uri.writeToParcel(reply, out);
- return true;
- }
- case BULK_INSERT_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- ContentValues[] values = data.createTypedArray(ContentValues.CREATOR);
- int count = bulkInsert(callingPkg, url, values);
- reply.writeNoException();
- reply.writeInt(count);
- return true;
- }
- case APPLY_BATCH_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- final int numOperations = data.readInt();
- final ArrayList<ContentProviderOperation> operations =
- new ArrayList<ContentProviderOperation>(numOperations);
- for (int i = 0; i < numOperations; i++) {
- operations.add(i, ContentProviderOperation.CREATOR.createFromParcel(data));
- }
- final ContentProviderResult[] results = applyBatch(callingPkg, operations);
- reply.writeNoException();
- reply.writeTypedArray(results, 0);
- return true;
- }
- case DELETE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- String selection = data.readString();
- String[] selectionArgs = data.readStringArray();
- int count = delete(callingPkg, url, selection, selectionArgs);
- reply.writeNoException();
- reply.writeInt(count);
- return true;
- }
- case UPDATE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- ContentValues values = ContentValues.CREATOR.createFromParcel(data);
- String selection = data.readString();
- String[] selectionArgs = data.readStringArray();
- int count = update(callingPkg, url, values, selection, selectionArgs);
- reply.writeNoException();
- reply.writeInt(count);
- return true;
- }
- case OPEN_FILE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- String mode = data.readString();
- ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
- data.readStrongBinder());
- IBinder callerToken = data.readStrongBinder();
- ParcelFileDescriptor fd;
- fd = openFile(callingPkg, url, mode, signal, callerToken);
- reply.writeNoException();
- if (fd != null) {
- reply.writeInt(1);
- fd.writeToParcel(reply,
- Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- } else {
- reply.writeInt(0);
- }
- return true;
- }
- case OPEN_ASSET_FILE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- String mode = data.readString();
- ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
- data.readStrongBinder());
- AssetFileDescriptor fd;
- fd = openAssetFile(callingPkg, url, mode, signal);
- reply.writeNoException();
- if (fd != null) {
- reply.writeInt(1);
- fd.writeToParcel(reply,
- Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- } else {
- reply.writeInt(0);
- }
- return true;
- }
- case CALL_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- String method = data.readString();
- String stringArg = data.readString();
- Bundle args = data.readBundle();
- Bundle responseBundle = call(callingPkg, method, stringArg, args);
- reply.writeNoException();
- reply.writeBundle(responseBundle);
- return true;
- }
- case GET_STREAM_TYPES_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- String mimeTypeFilter = data.readString();
- String[] types = getStreamTypes(url, mimeTypeFilter);
- reply.writeNoException();
- reply.writeStringArray(types);
- return true;
- }
- case OPEN_TYPED_ASSET_FILE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- String mimeType = data.readString();
- Bundle opts = data.readBundle();
- ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
- data.readStrongBinder());
- AssetFileDescriptor fd;
- fd = openTypedAssetFile(callingPkg, url, mimeType, opts, signal);
- reply.writeNoException();
- if (fd != null) {
- reply.writeInt(1);
- fd.writeToParcel(reply,
- Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- } else {
- reply.writeInt(0);
- }
- return true;
- }
- case CREATE_CANCELATION_SIGNAL_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- ICancellationSignal cancellationSignal = createCancellationSignal();
- reply.writeNoException();
- reply.writeStrongBinder(cancellationSignal.asBinder());
- return true;
- }
- case CANONICALIZE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- Uri out = canonicalize(callingPkg, url);
- reply.writeNoException();
- Uri.writeToParcel(reply, out);
- return true;
- }
- case UNCANONICALIZE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- String callingPkg = data.readString();
- Uri url = Uri.CREATOR.createFromParcel(data);
- Uri out = uncanonicalize(callingPkg, url);
- reply.writeNoException();
- Uri.writeToParcel(reply, out);
- return true;
- }
- }
- } catch (Exception e) {
- DatabaseUtils.writeExceptionToParcel(reply, e);
- return true;
- }
- return super.onTransact(code, data, reply, flags);
- }
- public IBinder asBinder()
- {
- return this;
- }
- }
- final class ContentProviderProxy implements IContentProvider
- {
- public ContentProviderProxy(IBinder remote)
- {
- mRemote = remote;
- }
- public IBinder asBinder()
- {
- return mRemote;
- }
- public Cursor query(String callingPkg, Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder, ICancellationSignal cancellationSignal)
- throws RemoteException {
- BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- int length = 0;
- if (projection != null) {
- length = projection.length;
- }
- data.writeInt(length);
- for (int i = 0; i < length; i++) {
- data.writeString(projection[i]);
- }
- data.writeString(selection);
- if (selectionArgs != null) {
- length = selectionArgs.length;
- } else {
- length = 0;
- }
- data.writeInt(length);
- for (int i = 0; i < length; i++) {
- data.writeString(selectionArgs[i]);
- }
- data.writeString(sortOrder);
- data.writeStrongBinder(adaptor.getObserver().asBinder());
- data.writeStrongBinder(cancellationSignal != null ? cancellationSignal.asBinder() : null);
- mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- if (reply.readInt() != 0) {
- BulkCursorDescriptor d = BulkCursorDescriptor.CREATOR.createFromParcel(reply);
- adaptor.initialize(d);
- } else {
- adaptor.close();
- adaptor = null;
- }
- return adaptor;
- } catch (RemoteException ex) {
- adaptor.close();
- throw ex;
- } catch (RuntimeException ex) {
- adaptor.close();
- throw ex;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public String getType(Uri url) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- url.writeToParcel(data, 0);
- mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- String out = reply.readString();
- return out;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public Uri insert(String callingPkg, Uri url, ContentValues values) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- values.writeToParcel(data, 0);
- mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- Uri out = Uri.CREATOR.createFromParcel(reply);
- return out;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public int bulkInsert(String callingPkg, Uri url, ContentValues[] values) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- data.writeTypedArray(values, 0);
- mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
- return count;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public ContentProviderResult[] applyBatch(String callingPkg,
- ArrayList<ContentProviderOperation> operations)
- throws RemoteException, OperationApplicationException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- data.writeInt(operations.size());
- for (ContentProviderOperation operation : operations) {
- operation.writeToParcel(data, 0);
- }
- mRemote.transact(IContentProvider.APPLY_BATCH_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionWithOperationApplicationExceptionFromParcel(reply);
- final ContentProviderResult[] results =
- reply.createTypedArray(ContentProviderResult.CREATOR);
- return results;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public int delete(String callingPkg, Uri url, String selection, String[] selectionArgs)
- throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- data.writeString(selection);
- data.writeStringArray(selectionArgs);
- mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
- return count;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public int update(String callingPkg, Uri url, ContentValues values, String selection,
- String[] selectionArgs) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- values.writeToParcel(data, 0);
- data.writeString(selection);
- data.writeStringArray(selectionArgs);
- mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
- return count;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- @Override
- public ParcelFileDescriptor openFile(
- String callingPkg, Uri url, String mode, ICancellationSignal signal, IBinder token)
- throws RemoteException, FileNotFoundException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- data.writeString(mode);
- data.writeStrongBinder(signal != null ? signal.asBinder() : null);
- data.writeStrongBinder(token);
- mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null;
- return fd;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- @Override
- public AssetFileDescriptor openAssetFile(
- String callingPkg, Uri url, String mode, ICancellationSignal signal)
- throws RemoteException, FileNotFoundException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- data.writeString(mode);
- data.writeStrongBinder(signal != null ? signal.asBinder() : null);
- mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- AssetFileDescriptor fd = has != 0
- ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
- return fd;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public Bundle call(String callingPkg, String method, String request, Bundle args)
- throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- data.writeString(method);
- data.writeString(request);
- data.writeBundle(args);
- mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- Bundle bundle = reply.readBundle();
- return bundle;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- url.writeToParcel(data, 0);
- data.writeString(mimeTypeFilter);
- mRemote.transact(IContentProvider.GET_STREAM_TYPES_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- String[] out = reply.createStringArray();
- return out;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- @Override
- public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri url, String mimeType,
- Bundle opts, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- data.writeString(mimeType);
- data.writeBundle(opts);
- data.writeStrongBinder(signal != null ? signal.asBinder() : null);
- mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- AssetFileDescriptor fd = has != 0
- ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
- return fd;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public ICancellationSignal createCancellationSignal() throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- mRemote.transact(IContentProvider.CREATE_CANCELATION_SIGNAL_TRANSACTION,
- data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- ICancellationSignal cancellationSignal = ICancellationSignal.Stub.asInterface(
- reply.readStrongBinder());
- return cancellationSignal;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public Uri canonicalize(String callingPkg, Uri url) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- mRemote.transact(IContentProvider.CANONICALIZE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- Uri out = Uri.CREATOR.createFromParcel(reply);
- return out;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- public Uri uncanonicalize(String callingPkg, Uri url) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- try {
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeString(callingPkg);
- url.writeToParcel(data, 0);
- mRemote.transact(IContentProvider.UNCANONICALIZE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
- Uri out = Uri.CREATOR.createFromParcel(reply);
- return out;
- } finally {
- data.recycle();
- reply.recycle();
- }
- }
- private IBinder mRemote;
- }