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

Commit 723d39c9 authored by Fan Zhang's avatar Fan Zhang
Browse files

Refined the StrictMode for CardContentProvider

- Modify CardContentProvider and add Mainthread checking

Bug: 111820446
Test: robotest
Change-Id: I7af25e8938b79c4c0fe225d58d59da4dde15ba45
parent 059c9c8e
Loading
Loading
Loading
Loading
+16 −17
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import android.util.Log;

import androidx.annotation.VisibleForTesting;

import com.android.settingslib.utils.ThreadUtils;

/**
 * Provider stores and manages user interaction feedback for homepage contextual cards.
 */
@@ -61,9 +63,7 @@ public class CardContentProvider extends ContentProvider {
    public Uri insert(Uri uri, ContentValues values) {
        final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
        try {
            if (Build.IS_DEBUGGABLE) {
                enableStrictMode(true);
            }
            maybeEnableStrictMode();

            final SQLiteDatabase database = mDBHelper.getWritableDatabase();
            final String table = getTableFromMatch(uri);
@@ -84,10 +84,7 @@ public class CardContentProvider extends ContentProvider {
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
        try {
            if (Build.IS_DEBUGGABLE) {
                enableStrictMode(true);
            }

            maybeEnableStrictMode();
            final SQLiteDatabase database = mDBHelper.getWritableDatabase();
            final String table = getTableFromMatch(uri);
            final int rowsDeleted = database.delete(table, selection, selectionArgs);
@@ -108,9 +105,7 @@ public class CardContentProvider extends ContentProvider {
            String[] selectionArgs, String sortOrder) {
        final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
        try {
            if (Build.IS_DEBUGGABLE) {
                enableStrictMode(true);
            }
            maybeEnableStrictMode();

            final SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
            final String table = getTableFromMatch(uri);
@@ -130,9 +125,7 @@ public class CardContentProvider extends ContentProvider {
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
        try {
            if (Build.IS_DEBUGGABLE) {
                enableStrictMode(true);
            }
            maybeEnableStrictMode();

            final SQLiteDatabase database = mDBHelper.getWritableDatabase();
            final String table = getTableFromMatch(uri);
@@ -144,10 +137,16 @@ public class CardContentProvider extends ContentProvider {
        }
    }

    private void enableStrictMode(boolean enabled) {
        StrictMode.setThreadPolicy(enabled
                ? new StrictMode.ThreadPolicy.Builder().detectAll().build()
                : StrictMode.ThreadPolicy.LAX);
    @VisibleForTesting
    void maybeEnableStrictMode() {
        if (Build.IS_DEBUGGABLE && ThreadUtils.isMainThread()) {
            enableStrictMode();
        }
    }

    @VisibleForTesting
    void enableStrictMode() {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().build());
    }

    @VisibleForTesting
+107 −14
Original line number Diff line number Diff line
@@ -19,13 +19,19 @@ package com.android.settings.homepage;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;

import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowThreadUtils;

import org.junit.After;
import org.junit.Before;
@@ -33,18 +39,23 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = ShadowThreadUtils.class)
public class CardContentProviderTest {

    private Context mContext;
    private CardContentProvider mProvider;
    private ContentResolver mResolver;
    private Uri mUri;

    @Before
    public void setUp() {
        mContext = RuntimeEnvironment.application;
        mProvider = Robolectric.setupContentProvider(CardContentProvider.class);
        mProvider = spy(Robolectric.setupContentProvider(CardContentProvider.class));
        mResolver = mContext.getContentResolver();
        mUri = new Uri.Builder()
                .scheme(ContentResolver.SCHEME_CONTENT)
                .authority(CardContentProvider.CARD_AUTHORITY)
@@ -54,6 +65,7 @@ public class CardContentProviderTest {

    @After
    public void cleanUp() {
        ShadowThreadUtils.reset();
        CardDatabaseHelper.getInstance(mContext).close();
        CardDatabaseHelper.sCardDatabaseHelper = null;
    }
@@ -61,7 +73,7 @@ public class CardContentProviderTest {
    @Test
    public void cardData_insert() {
        final int cnt_before_instert = getRowCount();
        mContext.getContentResolver().insert(mUri, insertOneRow());
        mResolver.insert(mUri, insertOneRow());
        final int cnt_after_instert = getRowCount();

        assertThat(cnt_after_instert - cnt_before_instert).isEqualTo(1);
@@ -69,7 +81,7 @@ public class CardContentProviderTest {

    @Test
    public void cardData_query() {
        mContext.getContentResolver().insert(mUri, insertOneRow());
        mResolver.insert(mUri, insertOneRow());
        final int count = getRowCount();

        assertThat(count).isGreaterThan(0);
@@ -77,29 +89,27 @@ public class CardContentProviderTest {

    @Test
    public void cardData_delete() {
        final ContentResolver contentResolver = mContext.getContentResolver();
        contentResolver.insert(mUri, insertOneRow());
        final int del_count = contentResolver.delete(mUri, null, null);
        mResolver.insert(mUri, insertOneRow());
        final int del_count = mResolver.delete(mUri, null, null);

        assertThat(del_count).isGreaterThan(0);
    }

    @Test
    public void cardData_update() {
        final ContentResolver contentResolver = mContext.getContentResolver();
        contentResolver.insert(mUri, insertOneRow());
        mResolver.insert(mUri, insertOneRow());

        final double updatingScore = 0.87;
        final ContentValues values = new ContentValues();
        values.put(CardDatabaseHelper.CardColumns.SCORE, updatingScore);
        final String strWhere = CardDatabaseHelper.CardColumns.NAME + "=?";
        final String[] selectionArgs = {"auto_rotate"};
        final int update_count = contentResolver.update(mUri, values, strWhere, selectionArgs);
        final int update_count = mResolver.update(mUri, values, strWhere, selectionArgs);

        assertThat(update_count).isGreaterThan(0);

        final String[] columns = {CardDatabaseHelper.CardColumns.SCORE};
        final Cursor cr = contentResolver.query(mUri, columns, strWhere, selectionArgs, null);
        final Cursor cr = mResolver.query(mUri, columns, strWhere, selectionArgs, null);
        cr.moveToFirst();
        final double qryScore = cr.getDouble(0);

@@ -107,6 +117,90 @@ public class CardContentProviderTest {
        assertThat(qryScore).isEqualTo(updatingScore);
    }

    @Test
    public void insert_isMainThread_shouldEnableStrictMode() {
        ShadowThreadUtils.setIsMainThread(true);
        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);

        mProvider.insert(mUri, insertOneRow());

        verify(mProvider).enableStrictMode();
    }

    @Test
    public void query_isMainThread_shouldEnableStrictMode() {
        ShadowThreadUtils.setIsMainThread(true);
        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);

        mProvider.query(mUri, null, null, null);

        verify(mProvider).enableStrictMode();
    }

    @Test
    public void delete_isMainThread_shouldEnableStrictMode() {
        ShadowThreadUtils.setIsMainThread(true);
        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);

        mProvider.delete(mUri, null, null);

        verify(mProvider).enableStrictMode();
    }

    @Test
    public void update_isMainThread_shouldEnableStrictMode() {
        ShadowThreadUtils.setIsMainThread(true);
        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);
        final ContentValues values = new ContentValues();
        values.put(CardDatabaseHelper.CardColumns.SCORE, "0.01");

        mProvider.update(mUri, values, null, null);

        verify(mProvider).enableStrictMode();
    }

    @Test
    public void insert_notMainThread_shouldNotEnableStrictMode() {
        ShadowThreadUtils.setIsMainThread(false);
        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);

        mProvider.insert(mUri, insertOneRow());

        verify(mProvider, never()).enableStrictMode();
    }

    @Test
    public void query_notMainThread_shouldNotEnableStrictMode() {
        ShadowThreadUtils.setIsMainThread(false);
        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);

        mProvider.query(mUri, null, null, null);

        verify(mProvider, never()).enableStrictMode();
    }

    @Test
    public void delete_notMainThread_shouldNotEnableStrictMode() {
        ShadowThreadUtils.setIsMainThread(false);
        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);

        mProvider.delete(mUri, null, null);

        verify(mProvider, never()).enableStrictMode();
    }

    @Test
    public void update_notMainThread_shouldNotEnableStrictMode() {
        ShadowThreadUtils.setIsMainThread(false);
        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);
        final ContentValues values = new ContentValues();
        values.put(CardDatabaseHelper.CardColumns.SCORE, "0.01");

        mProvider.update(mUri, values, null, null);

        verify(mProvider, never()).enableStrictMode();
    }

    @Test(expected = UnsupportedOperationException.class)
    public void getType_shouldCrash() {
        mProvider.getType(null);
@@ -138,8 +232,7 @@ public class CardContentProviderTest {
    }

    private int getRowCount() {
        final ContentResolver contentResolver = mContext.getContentResolver();
        final Cursor cr = contentResolver.query(mUri, null, null, null);
        final Cursor cr = mResolver.query(mUri, null, null, null);
        final int count = cr.getCount();
        cr.close();
        return count;