Fix leak where system held onto slice providers

Test: uiservicestests
Bug: 110985973
Change-Id: Ie8fab3c7b8c22d302825fb147d2c3468f9ae7172
(cherry picked from commit e1c0c2cb8d)
This commit is contained in:
Jason Monk
2018-07-03 11:08:32 -04:00
parent 9ccabdbc45
commit c2eca4758b
4 changed files with 94 additions and 10 deletions

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.IContentProvider;
import android.database.ContentObserver;
import android.net.Uri;
import android.util.ArrayMap;
import android.util.ArraySet;
import com.google.android.collect.Maps;
@@ -35,7 +36,11 @@ import java.util.Map;
*/
public class TestableContentResolver extends ContentResolver {
private final Map<String, ContentProvider> mProviders = Maps.newHashMap();
public static final int STABLE = 1;
public static final int UNSTABLE = 2;
private final Map<String, ContentProvider> mProviders = new ArrayMap<>();
private final Map<String, ContentProvider> mUnstableProviders = new ArrayMap<>();
private final ContentResolver mParent;
private final ArraySet<ContentProvider> mInUse = new ArraySet<>();
private boolean mFallbackToExisting;
@@ -62,7 +67,23 @@ public class TestableContentResolver extends ContentResolver {
* subclasses, or null.
*/
public void addProvider(String name, ContentProvider provider) {
mProviders.put(name, provider);
addProvider(name, provider, STABLE | UNSTABLE);
}
/**
* Adds access to a provider based on its authority
*
* @param name The authority name associated with the provider.
* @param provider An instance of {@link android.content.ContentProvider} or one of its
* subclasses, or null.
*/
public void addProvider(String name, ContentProvider provider, int flags) {
if ((flags & STABLE) != 0) {
mProviders.put(name, provider);
}
if ((flags & UNSTABLE) != 0) {
mUnstableProviders.put(name, provider);
}
}
@Override
@@ -98,7 +119,7 @@ public class TestableContentResolver extends ContentResolver {
@Override
protected IContentProvider acquireUnstableProvider(Context c, String name) {
final ContentProvider provider = mProviders.get(name);
final ContentProvider provider = mUnstableProviders.get(name);
if (provider != null) {
return provider.getIContentProvider();
} else {
@@ -128,7 +149,8 @@ public class TestableContentResolver extends ContentResolver {
@Override
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
if (!mFallbackToExisting) return;
if (!mProviders.containsKey(uri.getAuthority())) {
if (!mProviders.containsKey(uri.getAuthority())
&& !mUnstableProviders.containsKey(uri.getAuthority())) {
super.notifyChange(uri, observer, syncToNetwork);
}
}

View File

@@ -0,0 +1,61 @@
package android.testing;
import android.content.ContentProvider;
import android.content.IContentProvider;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class TestableContentResolverTest {
@Rule
public TestableContext mContext = new TestableContext(InstrumentationRegistry.getContext());
private TestableContentResolver mContentResolver;
@Before
public void setup() {
mContentResolver = new TestableContentResolver(mContext);
mContentResolver.setFallbackToExisting(false);
}
@Test
public void testDefaultContentProvider() {
ContentProvider provider = Mockito.mock(ContentProvider.class);
IContentProvider iprovider = Mockito.mock(IContentProvider.class);
Mockito.when(provider.getIContentProvider()).thenReturn(iprovider);
mContentResolver.addProvider("test", provider);
Assert.assertEquals(iprovider, mContentResolver.acquireProvider(mContext, "test"));
Assert.assertEquals(iprovider, mContentResolver.acquireUnstableProvider(mContext, "test"));
}
@Test
public void testStableContentProvider() {
ContentProvider provider = Mockito.mock(ContentProvider.class);
IContentProvider iprovider = Mockito.mock(IContentProvider.class);
Mockito.when(provider.getIContentProvider()).thenReturn(iprovider);
mContentResolver.addProvider("test", provider, TestableContentResolver.STABLE);
Assert.assertEquals(iprovider, mContentResolver.acquireProvider(mContext, "test"));
Assert.assertNull(mContentResolver.acquireUnstableProvider(mContext, "test"));
}
@Test
public void testUnstableContentProvider() {
ContentProvider provider = Mockito.mock(ContentProvider.class);
IContentProvider iprovider = Mockito.mock(IContentProvider.class);
Mockito.when(provider.getIContentProvider()).thenReturn(iprovider);
mContentResolver.addProvider("test", provider, TestableContentResolver.UNSTABLE);
Assert.assertEquals(iprovider, mContentResolver.acquireUnstableProvider(mContext, "test"));
Assert.assertNull(mContentResolver.acquireProvider(mContext, "test"));
}
}