• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package android.testing;
16 
17 import android.content.ContentProvider;
18 import android.content.ContentResolver;
19 import android.content.Context;
20 import android.content.IContentProvider;
21 import android.database.ContentObserver;
22 import android.net.Uri;
23 import android.util.ArraySet;
24 
25 import com.google.android.collect.Maps;
26 
27 import java.util.Map;
28 
29 /**
30  * A version of ContentResolver that allows easy mocking of providers.
31  * By default it acts as a normal ContentResolver and returns all the
32  * same providers.
33  * @see #addProvider(String, ContentProvider)
34  * @see #setFallbackToExisting(boolean)
35  */
36 public class TestableContentResolver extends ContentResolver {
37 
38     private final Map<String, ContentProvider> mProviders = Maps.newHashMap();
39     private final ContentResolver mParent;
40     private final ArraySet<ContentProvider> mInUse = new ArraySet<>();
41     private boolean mFallbackToExisting;
42 
TestableContentResolver(Context context)43     public TestableContentResolver(Context context) {
44         super(context);
45         mParent = context.getContentResolver();
46         mFallbackToExisting = true;
47     }
48 
49     /**
50      * Sets whether existing providers should be returned when a mock does not exist.
51      * The default is true.
52      */
setFallbackToExisting(boolean fallbackToExisting)53     public void setFallbackToExisting(boolean fallbackToExisting) {
54         mFallbackToExisting = fallbackToExisting;
55     }
56 
57     /**
58      * Adds access to a provider based on its authority
59      *
60      * @param name The authority name associated with the provider.
61      * @param provider An instance of {@link android.content.ContentProvider} or one of its
62      * subclasses, or null.
63      */
addProvider(String name, ContentProvider provider)64     public void addProvider(String name, ContentProvider provider) {
65         mProviders.put(name, provider);
66     }
67 
68     @Override
acquireProvider(Context context, String name)69     protected IContentProvider acquireProvider(Context context, String name) {
70         final ContentProvider provider = mProviders.get(name);
71         if (provider != null) {
72             return provider.getIContentProvider();
73         } else {
74             return mFallbackToExisting ? mParent.acquireProvider(name) : null;
75         }
76     }
77 
78     @Override
acquireExistingProvider(Context context, String name)79     protected IContentProvider acquireExistingProvider(Context context, String name) {
80         final ContentProvider provider = mProviders.get(name);
81         if (provider != null) {
82             return provider.getIContentProvider();
83         } else {
84             return mFallbackToExisting ? mParent.acquireExistingProvider(
85                     new Uri.Builder().authority(name).build()) : null;
86         }
87     }
88 
89     @Override
releaseProvider(IContentProvider provider)90     public boolean releaseProvider(IContentProvider provider) {
91         if (!mFallbackToExisting) return true;
92         if (mInUse.contains(provider)) {
93             mInUse.remove(provider);
94             return true;
95         }
96         return mParent.releaseProvider(provider);
97     }
98 
99     @Override
acquireUnstableProvider(Context c, String name)100     protected IContentProvider acquireUnstableProvider(Context c, String name) {
101         final ContentProvider provider = mProviders.get(name);
102         if (provider != null) {
103             return provider.getIContentProvider();
104         } else {
105             return mFallbackToExisting ? mParent.acquireUnstableProvider(name) : null;
106         }
107     }
108 
109     @Override
releaseUnstableProvider(IContentProvider icp)110     public boolean releaseUnstableProvider(IContentProvider icp) {
111         if (!mFallbackToExisting) return true;
112         if (mInUse.contains(icp)) {
113             mInUse.remove(icp);
114             return true;
115         }
116         return mParent.releaseUnstableProvider(icp);
117     }
118 
119     @Override
unstableProviderDied(IContentProvider icp)120     public void unstableProviderDied(IContentProvider icp) {
121         if (!mFallbackToExisting) return;
122         if (mInUse.contains(icp)) {
123             return;
124         }
125         mParent.unstableProviderDied(icp);
126     }
127 
128     @Override
notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork)129     public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
130         if (!mFallbackToExisting) return;
131         if (!mProviders.containsKey(uri.getAuthority())) {
132             super.notifyChange(uri, observer, syncToNetwork);
133         }
134     }
135 }
136