diff --git a/src/com/android/settings/homepage/CardContentProvider.java b/src/com/android/settings/homepage/CardContentProvider.java index 3081ae1fa81..640a00b3683 100644 --- a/src/com/android/settings/homepage/CardContentProvider.java +++ b/src/com/android/settings/homepage/CardContentProvider.java @@ -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 diff --git a/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java b/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java index bf1527a4a42..eec87b0286e 100644 --- a/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java +++ b/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java @@ -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 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,10 +232,9 @@ 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; } -} +} \ No newline at end of file