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

Commit a2b1e5f0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 4db8f31c c2eca475
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"));
    }
}