• 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  * Alternative to a MockContentResolver that falls back to real providers.
31  */
32 public class TestableContentResolver extends ContentResolver {
33 
34     private final Map<String, ContentProvider> mProviders = Maps.newHashMap();
35     private final ContentResolver mParent;
36     private final ArraySet<ContentProvider> mInUse = new ArraySet<>();
37     private boolean mFallbackToExisting;
38 
TestableContentResolver(Context context)39     public TestableContentResolver(Context context) {
40         super(context);
41         mParent = context.getContentResolver();
42         mFallbackToExisting = true;
43     }
44 
45     /**
46      * Sets whether existing providers should be returned when a mock does not exist.
47      * The default is true.
48      */
setFallbackToExisting(boolean fallbackToExisting)49     public void setFallbackToExisting(boolean fallbackToExisting) {
50         mFallbackToExisting = fallbackToExisting;
51     }
52 
53     /**
54      * Adds access to a provider based on its authority
55      *
56      * @param name The authority name associated with the provider.
57      * @param provider An instance of {@link android.content.ContentProvider} or one of its
58      * subclasses, or null.
59      */
addProvider(String name, ContentProvider provider)60     public void addProvider(String name, ContentProvider provider) {
61         mProviders.put(name, provider);
62     }
63 
64     @Override
acquireProvider(Context context, String name)65     protected IContentProvider acquireProvider(Context context, String name) {
66         final ContentProvider provider = mProviders.get(name);
67         if (provider != null) {
68             return provider.getIContentProvider();
69         } else {
70             return mFallbackToExisting ? mParent.acquireProvider(name) : null;
71         }
72     }
73 
74     @Override
acquireExistingProvider(Context context, String name)75     protected IContentProvider acquireExistingProvider(Context context, String name) {
76         final ContentProvider provider = mProviders.get(name);
77         if (provider != null) {
78             return provider.getIContentProvider();
79         } else {
80             return mFallbackToExisting ? mParent.acquireExistingProvider(
81                     new Uri.Builder().authority(name).build()) : null;
82         }
83     }
84 
85     @Override
releaseProvider(IContentProvider provider)86     public boolean releaseProvider(IContentProvider provider) {
87         if (!mFallbackToExisting) return true;
88         if (mInUse.contains(provider)) {
89             mInUse.remove(provider);
90             return true;
91         }
92         return mParent.releaseProvider(provider);
93     }
94 
95     @Override
acquireUnstableProvider(Context c, String name)96     protected IContentProvider acquireUnstableProvider(Context c, String name) {
97         final ContentProvider provider = mProviders.get(name);
98         if (provider != null) {
99             return provider.getIContentProvider();
100         } else {
101             return mFallbackToExisting ? mParent.acquireUnstableProvider(name) : null;
102         }
103     }
104 
105     @Override
releaseUnstableProvider(IContentProvider icp)106     public boolean releaseUnstableProvider(IContentProvider icp) {
107         if (!mFallbackToExisting) return true;
108         if (mInUse.contains(icp)) {
109             mInUse.remove(icp);
110             return true;
111         }
112         return mParent.releaseUnstableProvider(icp);
113     }
114 
115     @Override
unstableProviderDied(IContentProvider icp)116     public void unstableProviderDied(IContentProvider icp) {
117         if (!mFallbackToExisting) return;
118         if (mInUse.contains(icp)) {
119             return;
120         }
121         mParent.unstableProviderDied(icp);
122     }
123 
124     @Override
notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork)125     public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
126         if (!mFallbackToExisting) return;
127         if (!mProviders.containsKey(uri.getAuthority())) {
128             super.notifyChange(uri, observer, syncToNetwork);
129         }
130     }
131 }
132