Merge "Fix leak where system held onto slice providers" into pi-dev
am: a2b1e5f013
Change-Id: I09ba87cf5c1f1a0099119a015fdd113a3da2375c
This commit is contained in:
@@ -154,8 +154,8 @@ public class PinnedSliceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentProviderClient getClient() {
|
ContentProviderClient getClient() {
|
||||||
ContentProviderClient client =
|
ContentProviderClient client = mService.getContext().getContentResolver()
|
||||||
mService.getContext().getContentResolver().acquireContentProviderClient(mUri);
|
.acquireUnstableContentProviderClient(mUri);
|
||||||
if (client == null) return null;
|
if (client == null) return null;
|
||||||
client.setDetectNotResponding(SLICE_TIMEOUT);
|
client.setDetectNotResponding(SLICE_TIMEOUT);
|
||||||
return client;
|
return client;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package com.android.server.slice;
|
package com.android.server.slice;
|
||||||
|
|
||||||
|
import static android.testing.TestableContentResolver.UNSTABLE;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doReturn;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -71,11 +71,12 @@ public class PinnedSliceStateTest extends UiServiceTestCase {
|
|||||||
mSliceService = mock(SliceManagerService.class);
|
mSliceService = mock(SliceManagerService.class);
|
||||||
when(mSliceService.getContext()).thenReturn(mContext);
|
when(mSliceService.getContext()).thenReturn(mContext);
|
||||||
when(mSliceService.getLock()).thenReturn(new Object());
|
when(mSliceService.getLock()).thenReturn(new Object());
|
||||||
when(mSliceService.getHandler()).thenReturn(new Handler(TestableLooper.get(this).getLooper()));
|
when(mSliceService.getHandler()).thenReturn(
|
||||||
|
new Handler(TestableLooper.get(this).getLooper()));
|
||||||
mContentProvider = mock(ContentProvider.class);
|
mContentProvider = mock(ContentProvider.class);
|
||||||
mIContentProvider = mock(IContentProvider.class);
|
mIContentProvider = mock(IContentProvider.class);
|
||||||
when(mContentProvider.getIContentProvider()).thenReturn(mIContentProvider);
|
when(mContentProvider.getIContentProvider()).thenReturn(mIContentProvider);
|
||||||
mContext.getContentResolver().addProvider(AUTH, mContentProvider);
|
mContext.getContentResolver().addProvider(AUTH, mContentProvider, UNSTABLE);
|
||||||
mPinnedSliceManager = new PinnedSliceState(mSliceService, TEST_URI, "pkg");
|
mPinnedSliceManager = new PinnedSliceState(mSliceService, TEST_URI, "pkg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.content.Context;
|
|||||||
import android.content.IContentProvider;
|
import android.content.IContentProvider;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.util.ArrayMap;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
|
||||||
import com.google.android.collect.Maps;
|
import com.google.android.collect.Maps;
|
||||||
@@ -35,7 +36,11 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class TestableContentResolver extends ContentResolver {
|
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 ContentResolver mParent;
|
||||||
private final ArraySet<ContentProvider> mInUse = new ArraySet<>();
|
private final ArraySet<ContentProvider> mInUse = new ArraySet<>();
|
||||||
private boolean mFallbackToExisting;
|
private boolean mFallbackToExisting;
|
||||||
@@ -62,7 +67,23 @@ public class TestableContentResolver extends ContentResolver {
|
|||||||
* subclasses, or null.
|
* subclasses, or null.
|
||||||
*/
|
*/
|
||||||
public void addProvider(String name, ContentProvider provider) {
|
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
|
@Override
|
||||||
@@ -98,7 +119,7 @@ public class TestableContentResolver extends ContentResolver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IContentProvider acquireUnstableProvider(Context c, String name) {
|
protected IContentProvider acquireUnstableProvider(Context c, String name) {
|
||||||
final ContentProvider provider = mProviders.get(name);
|
final ContentProvider provider = mUnstableProviders.get(name);
|
||||||
if (provider != null) {
|
if (provider != null) {
|
||||||
return provider.getIContentProvider();
|
return provider.getIContentProvider();
|
||||||
} else {
|
} else {
|
||||||
@@ -128,7 +149,8 @@ public class TestableContentResolver extends ContentResolver {
|
|||||||
@Override
|
@Override
|
||||||
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
|
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
|
||||||
if (!mFallbackToExisting) return;
|
if (!mFallbackToExisting) return;
|
||||||
if (!mProviders.containsKey(uri.getAuthority())) {
|
if (!mProviders.containsKey(uri.getAuthority())
|
||||||
|
&& !mUnstableProviders.containsKey(uri.getAuthority())) {
|
||||||
super.notifyChange(uri, observer, syncToNetwork);
|
super.notifyChange(uri, observer, syncToNetwork);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user