1 /* 2 * Copyright (C) 2009 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 17 package android.test.mock; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.content.ContentProvider; 22 import android.content.ContentProviderOperation; 23 import android.content.ContentProviderResult; 24 import android.content.ContentResolver; 25 import android.content.ContentValues; 26 import android.content.Context; 27 import android.content.IContentProvider; 28 import android.content.Intent; 29 import android.content.OperationApplicationException; 30 import android.content.pm.PathPermission; 31 import android.content.pm.ProviderInfo; 32 import android.content.res.AssetFileDescriptor; 33 import android.database.Cursor; 34 import android.net.Uri; 35 import android.os.AsyncTask; 36 import android.os.Bundle; 37 import android.os.IBinder; 38 import android.os.ICancellationSignal; 39 import android.os.ParcelFileDescriptor; 40 import android.os.RemoteCallback; 41 import android.os.RemoteException; 42 43 import java.io.FileNotFoundException; 44 import java.util.ArrayList; 45 46 /** 47 * Mock implementation of ContentProvider. All methods are non-functional and throw 48 * {@link java.lang.UnsupportedOperationException}. Tests can extend this class to 49 * implement behavior needed for tests. 50 */ 51 public class MockContentProvider extends ContentProvider { 52 /* 53 * Note: if you add methods to ContentProvider, you must add similar methods to 54 * MockContentProvider. 55 */ 56 57 /** 58 * IContentProvider that directs all calls to this MockContentProvider. 59 */ 60 private class InversionIContentProvider implements IContentProvider { 61 @Override applyBatch(String callingPackage, @Nullable String featureId, String authority, ArrayList<ContentProviderOperation> operations)62 public ContentProviderResult[] applyBatch(String callingPackage, 63 @Nullable String featureId, String authority, 64 ArrayList<ContentProviderOperation> operations) 65 throws RemoteException, OperationApplicationException { 66 return MockContentProvider.this.applyBatch(authority, operations); 67 } 68 69 @Override bulkInsert(String callingPackage, @Nullable String featureId, Uri url, ContentValues[] initialValues)70 public int bulkInsert(String callingPackage, @Nullable String featureId, Uri url, 71 ContentValues[] initialValues) throws RemoteException { 72 return MockContentProvider.this.bulkInsert(url, initialValues); 73 } 74 75 @Override delete(String callingPackage, @Nullable String featureId, Uri url, Bundle extras)76 public int delete(String callingPackage, @Nullable String featureId, Uri url, 77 Bundle extras) throws RemoteException { 78 return MockContentProvider.this.delete(url, extras); 79 } 80 81 @Override getType(Uri url)82 public String getType(Uri url) throws RemoteException { 83 return MockContentProvider.this.getType(url); 84 } 85 86 @Override getTypeAsync(Uri uri, RemoteCallback callback)87 public void getTypeAsync(Uri uri, RemoteCallback callback) throws RemoteException { 88 MockContentProvider.this.getTypeAsync(uri, callback); 89 } 90 91 @Override insert(String callingPackage, @Nullable String featureId, Uri url, ContentValues initialValues, Bundle extras)92 public Uri insert(String callingPackage, @Nullable String featureId, Uri url, 93 ContentValues initialValues, Bundle extras) throws RemoteException { 94 return MockContentProvider.this.insert(url, initialValues, extras); 95 } 96 97 @Override openAssetFile(String callingPackage, @Nullable String featureId, Uri url, String mode, ICancellationSignal signal)98 public AssetFileDescriptor openAssetFile(String callingPackage, 99 @Nullable String featureId, Uri url, String mode, ICancellationSignal signal) 100 throws RemoteException, FileNotFoundException { 101 return MockContentProvider.this.openAssetFile(url, mode); 102 } 103 104 @Override openFile(String callingPackage, @Nullable String featureId, Uri url, String mode, ICancellationSignal signal, IBinder callerToken)105 public ParcelFileDescriptor openFile(String callingPackage, @Nullable String featureId, 106 Uri url, String mode, ICancellationSignal signal, IBinder callerToken) 107 throws RemoteException, FileNotFoundException { 108 return MockContentProvider.this.openFile(url, mode); 109 } 110 111 @Override query(String callingPackage, @Nullable String featureId, Uri url, @Nullable String[] projection, @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal)112 public Cursor query(String callingPackage, @Nullable String featureId, Uri url, 113 @Nullable String[] projection, @Nullable Bundle queryArgs, 114 @Nullable ICancellationSignal cancellationSignal) throws RemoteException { 115 return MockContentProvider.this.query(url, projection, queryArgs, null); 116 } 117 118 @Override update(String callingPackage, @Nullable String featureId, Uri url, ContentValues values, Bundle extras)119 public int update(String callingPackage, @Nullable String featureId, Uri url, 120 ContentValues values, Bundle extras) throws RemoteException { 121 return MockContentProvider.this.update(url, values, extras); 122 } 123 124 @Override call(String callingPackage, @Nullable String featureId, String authority, String method, String request, Bundle args)125 public Bundle call(String callingPackage, @Nullable String featureId, String authority, 126 String method, String request, Bundle args) throws RemoteException { 127 return MockContentProvider.this.call(authority, method, request, args); 128 } 129 130 @Override asBinder()131 public IBinder asBinder() { 132 return MockContentProvider.this.getIContentProviderBinder(); 133 } 134 135 @Override getStreamTypes(Uri url, String mimeTypeFilter)136 public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException { 137 return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter); 138 } 139 140 @Override openTypedAssetFile(String callingPackage, @Nullable String featureId, Uri url, String mimeType, Bundle opts, ICancellationSignal signal)141 public AssetFileDescriptor openTypedAssetFile(String callingPackage, 142 @Nullable String featureId, Uri url, String mimeType, Bundle opts, 143 ICancellationSignal signal) throws RemoteException, FileNotFoundException { 144 return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts); 145 } 146 147 @Override createCancellationSignal()148 public ICancellationSignal createCancellationSignal() throws RemoteException { 149 return null; 150 } 151 152 @Override canonicalize(String callingPkg, @Nullable String featureId, Uri uri)153 public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri) 154 throws RemoteException { 155 return MockContentProvider.this.canonicalize(uri); 156 } 157 158 @Override canonicalizeAsync(String callingPkg, String featureId, Uri uri, RemoteCallback callback)159 public void canonicalizeAsync(String callingPkg, String featureId, Uri uri, 160 RemoteCallback callback) { 161 MockContentProvider.this.canonicalizeAsync(uri, callback); 162 } 163 164 @Override uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri)165 public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri) 166 throws RemoteException { 167 return MockContentProvider.this.uncanonicalize(uri); 168 } 169 170 @Override refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args, ICancellationSignal cancellationSignal)171 public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, 172 Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { 173 return MockContentProvider.this.refresh(url, args); 174 } 175 176 @Override checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri, int uid, int modeFlags)177 public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri, 178 int uid, int modeFlags) { 179 return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags); 180 } 181 } 182 private final InversionIContentProvider mIContentProvider = new InversionIContentProvider(); 183 184 /** 185 * A constructor using {@link MockContext} instance as a Context in it. 186 */ MockContentProvider()187 protected MockContentProvider() { 188 super(new MockContext(), "", "", null); 189 } 190 191 /** 192 * A constructor accepting a Context instance, which is supposed to be the subclasss of 193 * {@link MockContext}. 194 */ MockContentProvider(Context context)195 public MockContentProvider(Context context) { 196 super(context, "", "", null); 197 } 198 199 /** 200 * A constructor which initialize four member variables which 201 * {@link android.content.ContentProvider} have internally. 202 * 203 * @param context A Context object which should be some mock instance (like the 204 * instance of {@link android.test.mock.MockContext}). 205 * @param readPermission The read permision you want this instance should have in the 206 * test, which is available via {@link #getReadPermission()}. 207 * @param writePermission The write permission you want this instance should have 208 * in the test, which is available via {@link #getWritePermission()}. 209 * @param pathPermissions The PathPermissions you want this instance should have 210 * in the test, which is available via {@link #getPathPermissions()}. 211 */ MockContentProvider(Context context, String readPermission, String writePermission, PathPermission[] pathPermissions)212 public MockContentProvider(Context context, 213 String readPermission, 214 String writePermission, 215 PathPermission[] pathPermissions) { 216 super(context, readPermission, writePermission, pathPermissions); 217 } 218 219 @Override delete(Uri uri, String selection, String[] selectionArgs)220 public int delete(Uri uri, String selection, String[] selectionArgs) { 221 throw new UnsupportedOperationException("unimplemented mock method"); 222 } 223 224 @Override getType(Uri uri)225 public String getType(Uri uri) { 226 throw new UnsupportedOperationException("unimplemented mock method"); 227 } 228 229 /** 230 * @hide 231 */ 232 @SuppressWarnings("deprecation") getTypeAsync(Uri uri, RemoteCallback remoteCallback)233 public void getTypeAsync(Uri uri, RemoteCallback remoteCallback) { 234 AsyncTask.SERIAL_EXECUTOR.execute(() -> { 235 final Bundle bundle = new Bundle(); 236 bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri)); 237 remoteCallback.sendResult(bundle); 238 }); 239 } 240 241 @Override insert(Uri uri, ContentValues values)242 public Uri insert(Uri uri, ContentValues values) { 243 throw new UnsupportedOperationException("unimplemented mock method"); 244 } 245 246 @Override onCreate()247 public boolean onCreate() { 248 throw new UnsupportedOperationException("unimplemented mock method"); 249 } 250 251 @Override query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)252 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 253 String sortOrder) { 254 throw new UnsupportedOperationException("unimplemented mock method"); 255 } 256 257 @Override update(Uri uri, ContentValues values, String selection, String[] selectionArgs)258 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 259 throw new UnsupportedOperationException("unimplemented mock method"); 260 } 261 262 /** 263 * If you're reluctant to implement this manually, please just call super.bulkInsert(). 264 */ 265 @Override bulkInsert(Uri uri, ContentValues[] values)266 public int bulkInsert(Uri uri, ContentValues[] values) { 267 throw new UnsupportedOperationException("unimplemented mock method"); 268 } 269 270 @Override attachInfo(Context context, ProviderInfo info)271 public void attachInfo(Context context, ProviderInfo info) { 272 throw new UnsupportedOperationException("unimplemented mock method"); 273 } 274 275 @Override applyBatch(ArrayList<ContentProviderOperation> operations)276 public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) { 277 throw new UnsupportedOperationException("unimplemented mock method"); 278 } 279 280 /** 281 * @hide 282 */ 283 @Override call(String method, String request, Bundle args)284 public Bundle call(String method, String request, Bundle args) { 285 throw new UnsupportedOperationException("unimplemented mock method call"); 286 } 287 288 @Override getStreamTypes(Uri url, String mimeTypeFilter)289 public String[] getStreamTypes(Uri url, String mimeTypeFilter) { 290 throw new UnsupportedOperationException("unimplemented mock method call"); 291 } 292 293 @Override openTypedAssetFile(Uri url, String mimeType, Bundle opts)294 public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) { 295 throw new UnsupportedOperationException("unimplemented mock method call"); 296 } 297 298 /** 299 * @hide 300 */ 301 @SuppressWarnings("deprecation") canonicalizeAsync(Uri uri, RemoteCallback callback)302 public void canonicalizeAsync(Uri uri, RemoteCallback callback) { 303 AsyncTask.SERIAL_EXECUTOR.execute(() -> { 304 final Bundle bundle = new Bundle(); 305 bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, canonicalize(uri)); 306 callback.sendResult(bundle); 307 }); 308 } 309 310 /** 311 * @hide 312 */ refresh(Uri url, Bundle args)313 public boolean refresh(Uri url, Bundle args) { 314 throw new UnsupportedOperationException("unimplemented mock method call"); 315 } 316 317 /** {@hide} */ 318 @Override checkUriPermission(@onNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)319 public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) { 320 throw new UnsupportedOperationException("unimplemented mock method call"); 321 } 322 323 /** 324 * Returns IContentProvider which calls back same methods in this class. 325 * By overriding this class, we avoid the mechanism hidden behind ContentProvider 326 * (IPC, etc.) 327 * 328 * @hide 329 */ 330 @Override getIContentProvider()331 public final IContentProvider getIContentProvider() { 332 return mIContentProvider; 333 } 334 335 /** 336 * @hide 337 */ getIContentProviderBinder()338 public IBinder getIContentProviderBinder() { 339 throw new UnsupportedOperationException("unimplemented mock method"); 340 } 341 342 /** 343 * Like {@link #attachInfo(Context, android.content.pm.ProviderInfo)}, but for use 344 * when directly instantiating the provider for testing. 345 * 346 * <p>Provided for use by {@code android.test.ProviderTestCase2} and 347 * {@code android.test.RenamingDelegatingContext}. 348 * 349 * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>. 350 * New tests should be written using the 351 * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>. 352 */ 353 @Deprecated attachInfoForTesting( ContentProvider provider, Context context, ProviderInfo providerInfo)354 public static void attachInfoForTesting( 355 ContentProvider provider, Context context, ProviderInfo providerInfo) { 356 provider.attachInfoForTesting(context, providerInfo); 357 } 358 } 359