Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a66cf9ce authored by Jason Monk's avatar Jason Monk Committed by android-build-merger
Browse files

Merge "Fix leak where system held onto slice providers" into pi-dev

am: a2b1e5f0

Change-Id: I09ba87cf5c1f1a0099119a015fdd113a3da2375c
parents 1318f4fa a2b1e5f0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -154,8 +154,8 @@ public class PinnedSliceState {
    }

    ContentProviderClient getClient() {
        ContentProviderClient client =
                mService.getContext().getContentResolver().acquireContentProviderClient(mUri);
        ContentProviderClient client = mService.getContext().getContentResolver()
                .acquireUnstableContentProviderClient(mUri);
        if (client == null) return null;
        client.setDetectNotResponding(SLICE_TIMEOUT);
        return client;
+5 −4
Original line number Diff line number Diff line
package com.android.server.slice;

import static android.testing.TestableContentResolver.UNSTABLE;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -71,11 +71,12 @@ public class PinnedSliceStateTest extends UiServiceTestCase {
        mSliceService = mock(SliceManagerService.class);
        when(mSliceService.getContext()).thenReturn(mContext);
        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);
        mIContentProvider = mock(IContentProvider.class);
        when(mContentProvider.getIContentProvider()).thenReturn(mIContentProvider);
        mContext.getContentResolver().addProvider(AUTH, mContentProvider);
        mContext.getContentResolver().addProvider(AUTH, mContentProvider, UNSTABLE);
        mPinnedSliceManager = new PinnedSliceState(mSliceService, TEST_URI, "pkg");
    }

+26 −4
Original line number Diff line number Diff line
@@ -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,8 +67,24 @@ public class TestableContentResolver extends ContentResolver {
     * subclasses, or null.
     */
    public void addProvider(String name, ContentProvider 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
    protected IContentProvider acquireProvider(Context context, String name) {
@@ -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);
        }
    }
+61 −0
Original line number Diff line number Diff line
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"));
    }
}