1 package org.robolectric.shadows;
2 
3 import static org.robolectric.util.reflector.Reflector.reflector;
4 
5 import android.content.ContentProvider;
6 import android.content.ContentProviderClient;
7 import android.content.ContentProviderOperation;
8 import android.content.ContentProviderResult;
9 import android.content.ContentValues;
10 import android.content.OperationApplicationException;
11 import android.content.res.AssetFileDescriptor;
12 import android.database.Cursor;
13 import android.net.Uri;
14 import android.os.Build;
15 import android.os.Bundle;
16 import android.os.CancellationSignal;
17 import android.os.ParcelFileDescriptor;
18 import android.os.RemoteException;
19 import java.io.FileNotFoundException;
20 import java.util.ArrayList;
21 import java.util.concurrent.atomic.AtomicBoolean;
22 import org.robolectric.RuntimeEnvironment;
23 import org.robolectric.annotation.Implementation;
24 import org.robolectric.annotation.Implements;
25 import org.robolectric.annotation.RealObject;
26 import org.robolectric.util.reflector.Accessor;
27 import org.robolectric.util.reflector.Direct;
28 import org.robolectric.util.reflector.ForType;
29 
30 @Implements(ContentProviderClient.class)
31 public class ShadowContentProviderClient {
32   @RealObject private ContentProviderClient realContentProviderClient;
33 
34   private ContentProvider provider;
35 
36   @Implementation
call(String method, String arg, Bundle extras)37   protected Bundle call(String method, String arg, Bundle extras) throws RemoteException {
38     return provider.call(method, arg, extras);
39   }
40 
41   @Implementation
getType(Uri uri)42   protected String getType(Uri uri) throws RemoteException {
43     return provider.getType(uri);
44   }
45 
46   @Implementation
getStreamTypes(Uri uri, String mimeTypeFilter)47   protected String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
48     return provider.getStreamTypes(uri, mimeTypeFilter);
49   }
50 
51   @Implementation
query( Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder)52   protected Cursor query(
53       Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder)
54       throws RemoteException {
55     return provider.query(url, projection, selection, selectionArgs, sortOrder);
56   }
57 
58   @Implementation
query( Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)59   protected Cursor query(
60       Uri url,
61       String[] projection,
62       String selection,
63       String[] selectionArgs,
64       String sortOrder,
65       CancellationSignal cancellationSignal)
66       throws RemoteException {
67     return provider.query(url, projection, selection, selectionArgs, sortOrder, cancellationSignal);
68   }
69 
70   @Implementation
insert(Uri url, ContentValues initialValues)71   protected Uri insert(Uri url, ContentValues initialValues) throws RemoteException {
72     return provider.insert(url, initialValues);
73   }
74 
75   @Implementation
bulkInsert(Uri url, ContentValues[] initialValues)76   protected int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
77     return provider.bulkInsert(url, initialValues);
78   }
79 
80   @Implementation
delete(Uri url, String selection, String[] selectionArgs)81   protected int delete(Uri url, String selection, String[] selectionArgs) throws RemoteException {
82     return provider.delete(url, selection, selectionArgs);
83   }
84 
85   @Implementation
update(Uri url, ContentValues values, String selection, String[] selectionArgs)86   protected int update(Uri url, ContentValues values, String selection, String[] selectionArgs)
87       throws RemoteException {
88     return provider.update(url, values, selection, selectionArgs);
89   }
90 
91   @Implementation
openFile(Uri url, String mode)92   protected ParcelFileDescriptor openFile(Uri url, String mode)
93       throws RemoteException, FileNotFoundException {
94     return provider.openFile(url, mode);
95   }
96 
97   @Implementation
openAssetFile(Uri url, String mode)98   protected AssetFileDescriptor openAssetFile(Uri url, String mode)
99       throws RemoteException, FileNotFoundException {
100     return provider.openAssetFile(url, mode);
101   }
102 
103   @Implementation
openTypedAssetFileDescriptor(Uri uri, String mimeType, Bundle opts)104   protected AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri, String mimeType, Bundle opts)
105       throws RemoteException, FileNotFoundException {
106     return provider.openTypedAssetFile(uri, mimeType, opts);
107   }
108 
109   @Implementation
applyBatch(ArrayList<ContentProviderOperation> operations)110   protected ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
111       throws RemoteException, OperationApplicationException {
112     return provider.applyBatch(operations);
113   }
114 
115   @Implementation
getLocalContentProvider()116   protected ContentProvider getLocalContentProvider() {
117     return ContentProvider.coerceToLocalContentProvider(provider.getIContentProvider());
118   }
119 
isStable()120   public boolean isStable() {
121     return reflector(ContentProviderClientReflector.class, realContentProviderClient).getStable();
122   }
123 
isReleased()124   public boolean isReleased() {
125     ContentProviderClientReflector contentProviderClientReflector =
126         reflector(ContentProviderClientReflector.class, realContentProviderClient);
127     if (RuntimeEnvironment.getApiLevel() <= Build.VERSION_CODES.M) {
128       return contentProviderClientReflector.getReleased();
129     } else {
130       return contentProviderClientReflector.getClosed().get();
131     }
132   }
133 
setContentProvider(ContentProvider provider)134   void setContentProvider(ContentProvider provider) {
135     this.provider = provider;
136   }
137 
138   @ForType(ContentProviderClient.class)
139   interface ContentProviderClientReflector {
140     @Direct
release()141     boolean release();
142 
143     @Accessor("mStable")
getStable()144     boolean getStable();
145 
146     @Accessor("mReleased")
getReleased()147     boolean getReleased();
148 
149     @Accessor("mClosed")
getClosed()150     AtomicBoolean getClosed();
151   }
152 }
153