blob: 548dded9c47e5cd26ca3843dd8ddcdfbdb1b8dc9 [file] [log] [blame]
/*
* Copyright (C) 2009 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.test.mock;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.AttributionSource;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallback;
import android.os.RemoteException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
/**
* Mock implementation of ContentProvider. All methods are non-functional and throw
* {@link java.lang.UnsupportedOperationException}. Tests can extend this class to
* implement behavior needed for tests.
*/
public class MockContentProvider extends ContentProvider {
/*
* Note: if you add methods to ContentProvider, you must add similar methods to
* MockContentProvider.
*/
/**
* IContentProvider that directs all calls to this MockContentProvider.
*/
private class InversionIContentProvider implements IContentProvider {
@Override
public ContentProviderResult[] applyBatch(@NonNull AttributionSource attributionSource,
String authority, ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
return MockContentProvider.this.applyBatch(authority, operations);
}
@Override
public int bulkInsert(@NonNull AttributionSource attributionSource, Uri url,
ContentValues[] initialValues) throws RemoteException {
return MockContentProvider.this.bulkInsert(url, initialValues);
}
@Override
public int delete(@NonNull AttributionSource attributionSource, Uri url,
Bundle extras) throws RemoteException {
return MockContentProvider.this.delete(url, extras);
}
@Override
public String getType(@NonNull AttributionSource attributionSource,
Uri url) throws RemoteException {
return MockContentProvider.this.getType(url);
}
@Override
public void getTypeAsync(@NonNull AttributionSource attributionSource,
Uri uri, RemoteCallback callback) throws RemoteException {
MockContentProvider.this.getTypeAsync(uri, callback);
}
@Override
public void getTypeAnonymousAsync(Uri uri, RemoteCallback callback) throws RemoteException {
MockContentProvider.this.getTypeAnonymousAsync(uri, callback);
}
@Override
public Uri insert(@NonNull AttributionSource attributionSource, Uri url,
ContentValues initialValues, Bundle extras) throws RemoteException {
return MockContentProvider.this.insert(url, initialValues, extras);
}
@Override
public AssetFileDescriptor openAssetFile(@NonNull AttributionSource attributionSource,
Uri url, String mode, ICancellationSignal signal)
throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openAssetFile(url, mode);
}
@Override
public ParcelFileDescriptor openFile(@NonNull AttributionSource attributionSource,
Uri url, String mode, ICancellationSignal signal)
throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openFile(url, mode);
}
@Override
public Cursor query(@NonNull AttributionSource attributionSource, Uri url,
@Nullable String[] projection, @Nullable Bundle queryArgs,
@Nullable ICancellationSignal cancellationSignal) throws RemoteException {
return MockContentProvider.this.query(url, projection, queryArgs, null);
}
@Override
public int update(@NonNull AttributionSource attributionSource, Uri url,
ContentValues values, Bundle extras) throws RemoteException {
return MockContentProvider.this.update(url, values, extras);
}
@Override
public Bundle call(@NonNull AttributionSource attributionSource, String authority,
String method, String request, Bundle args) throws RemoteException {
return MockContentProvider.this.call(authority, method, request, args);
}
@Override
public IBinder asBinder() {
return MockContentProvider.this.getIContentProviderBinder();
}
@Override
public String[] getStreamTypes(AttributionSource attributionSource,
Uri url, String mimeTypeFilter) throws RemoteException {
return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter);
}
@Override
public AssetFileDescriptor openTypedAssetFile(
@NonNull AttributionSource attributionSource, Uri url, String mimeType,
Bundle opts, ICancellationSignal signal)
throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
}
@Override
public ICancellationSignal createCancellationSignal() throws RemoteException {
return null;
}
@Override
public Uri canonicalize(@NonNull AttributionSource attributionSource, Uri uri)
throws RemoteException {
return MockContentProvider.this.canonicalize(uri);
}
@Override
public void canonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
RemoteCallback callback) {
MockContentProvider.this.canonicalizeAsync(uri, callback);
}
@Override
public Uri uncanonicalize(@NonNull AttributionSource attributionSource, Uri uri)
throws RemoteException {
return MockContentProvider.this.uncanonicalize(uri);
}
@Override
public void uncanonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
RemoteCallback callback) {
MockContentProvider.this.uncanonicalizeAsync(uri, callback);
}
@Override
public boolean refresh(@NonNull AttributionSource attributionSource, Uri url,
Bundle args, ICancellationSignal cancellationSignal) throws RemoteException {
return MockContentProvider.this.refresh(url, args);
}
@Override
public int checkUriPermission(@NonNull AttributionSource attributionSource, Uri uri,
int uid, int modeFlags) {
return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
}
}
private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();
/**
* A constructor using {@link MockContext} instance as a Context in it.
*/
protected MockContentProvider() {
super(new MockContext(), "", "", null);
}
/**
* A constructor accepting a Context instance, which is supposed to be the subclasss of
* {@link MockContext}.
*/
public MockContentProvider(Context context) {
super(context, "", "", null);
}
/**
* A constructor which initialize four member variables which
* {@link android.content.ContentProvider} have internally.
*
* @param context A Context object which should be some mock instance (like the
* instance of {@link android.test.mock.MockContext}).
* @param readPermission The read permision you want this instance should have in the
* test, which is available via {@link #getReadPermission()}.
* @param writePermission The write permission you want this instance should have
* in the test, which is available via {@link #getWritePermission()}.
* @param pathPermissions The PathPermissions you want this instance should have
* in the test, which is available via {@link #getPathPermissions()}.
*/
public MockContentProvider(Context context,
String readPermission,
String writePermission,
PathPermission[] pathPermissions) {
super(context, readPermission, writePermission, pathPermissions);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public String getType(Uri uri) {
throw new UnsupportedOperationException("unimplemented mock method");
}
/**
* @hide
*/
@SuppressWarnings("deprecation")
public void getTypeAsync(Uri uri, RemoteCallback remoteCallback) {
AsyncTask.SERIAL_EXECUTOR.execute(() -> {
final Bundle bundle = new Bundle();
bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri));
remoteCallback.sendResult(bundle);
});
}
@Override
public String getTypeAnonymous(Uri uri) {
throw new UnsupportedOperationException("unimplemented mock method");
}
/**
* @hide
*/
@SuppressWarnings("deprecation")
public void getTypeAnonymousAsync(Uri uri, RemoteCallback remoteCallback) {
AsyncTask.SERIAL_EXECUTOR.execute(() -> {
final Bundle bundle = new Bundle();
bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getTypeAnonymous(uri));
remoteCallback.sendResult(bundle);
});
}
@Override
public Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public boolean onCreate() {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException("unimplemented mock method");
}
/**
* If you're reluctant to implement this manually, please just call super.bulkInsert().
*/
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public void attachInfo(Context context, ProviderInfo info) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
throw new UnsupportedOperationException("unimplemented mock method");
}
/**
* @hide
*/
@Override
public Bundle call(String method, String request, Bundle args) {
throw new UnsupportedOperationException("unimplemented mock method call");
}
@Override
public String[] getStreamTypes(Uri url, String mimeTypeFilter) {
throw new UnsupportedOperationException("unimplemented mock method call");
}
@Override
public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) {
throw new UnsupportedOperationException("unimplemented mock method call");
}
/**
* @hide
*/
@SuppressWarnings("deprecation")
public void canonicalizeAsync(Uri uri, RemoteCallback callback) {
AsyncTask.SERIAL_EXECUTOR.execute(() -> {
final Bundle bundle = new Bundle();
bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, canonicalize(uri));
callback.sendResult(bundle);
});
}
/**
* @hide
*/
@SuppressWarnings("deprecation")
public void uncanonicalizeAsync(Uri uri, RemoteCallback callback) {
AsyncTask.SERIAL_EXECUTOR.execute(() -> {
final Bundle bundle = new Bundle();
bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, uncanonicalize(uri));
callback.sendResult(bundle);
});
}
/**
* @hide
*/
public boolean refresh(Uri url, Bundle args) {
throw new UnsupportedOperationException("unimplemented mock method call");
}
/** {@hide} */
@Override
public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
throw new UnsupportedOperationException("unimplemented mock method call");
}
/**
* Returns IContentProvider which calls back same methods in this class.
* By overriding this class, we avoid the mechanism hidden behind ContentProvider
* (IPC, etc.)
*
* @hide
*/
@Override
public final IContentProvider getIContentProvider() {
return mIContentProvider;
}
/**
* @hide
*/
public IBinder getIContentProviderBinder() {
return new Binder();
}
/**
* Like {@link #attachInfo(Context, android.content.pm.ProviderInfo)}, but for use
* when directly instantiating the provider for testing.
*
* <p>Provided for use by {@code android.test.ProviderTestCase2} and
* {@code android.test.RenamingDelegatingContext}.
*
* @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
* New tests should be written using the
* <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
*/
@Deprecated
public static void attachInfoForTesting(
ContentProvider provider, Context context, ProviderInfo providerInfo) {
provider.attachInfoForTesting(context, providerInfo);
}
}