Loading packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchContract.kt +37 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,13 @@ const val SEARCH_IMMUTABLE_STATUS = "search_immutable_status" /** ContentProvider path for search mutable status */ const val SEARCH_MUTABLE_STATUS = "search_mutable_status" /** ContentProvider path for search static row */ const val SEARCH_STATIC_ROW = "search_static_row" /** ContentProvider path for search dynamic row */ const val SEARCH_DYNAMIC_ROW = "search_dynamic_row" /** Enum to define all column names in provider. */ enum class ColumnEnum(val id: String) { ENTRY_ID("entryId"), Loading Loading @@ -95,4 +102,34 @@ enum class QueryEnum( ColumnEnum.ENTRY_DISABLED, ) ), SEARCH_STATIC_ROW_QUERY( SEARCH_STATIC_ROW, listOf( ColumnEnum.ENTRY_ID, ColumnEnum.SEARCH_TITLE, ColumnEnum.SEARCH_KEYWORD, ColumnEnum.SEARCH_PATH, ColumnEnum.INTENT_TARGET_PACKAGE, ColumnEnum.INTENT_TARGET_CLASS, ColumnEnum.INTENT_EXTRAS, ColumnEnum.SLICE_URI, ColumnEnum.LEGACY_KEY, ColumnEnum.ENTRY_DISABLED, ) ), SEARCH_DYNAMIC_ROW_QUERY( SEARCH_DYNAMIC_ROW, listOf( ColumnEnum.ENTRY_ID, ColumnEnum.SEARCH_TITLE, ColumnEnum.SEARCH_KEYWORD, ColumnEnum.SEARCH_PATH, ColumnEnum.INTENT_TARGET_PACKAGE, ColumnEnum.INTENT_TARGET_CLASS, ColumnEnum.INTENT_EXTRAS, ColumnEnum.SLICE_URI, ColumnEnum.LEGACY_KEY, ColumnEnum.ENTRY_DISABLED, ) ), } packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchProvider.kt +63 −3 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import android.os.Parcel import android.os.Parcelable import android.util.Log import androidx.annotation.VisibleForTesting import com.android.settingslib.spa.framework.common.EntryStatusData import com.android.settingslib.spa.framework.common.SettingsEntry import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.util.SESSION_SEARCH Loading @@ -49,6 +48,8 @@ private const val TAG = "SpaSearchProvider" * $ adb shell content query --uri content://<AuthorityPath>/search_dynamic_data * $ adb shell content query --uri content://<AuthorityPath>/search_immutable_status * $ adb shell content query --uri content://<AuthorityPath>/search_mutable_status * $ adb shell content query --uri content://<AuthorityPath>/search_static_row * $ adb shell content query --uri content://<AuthorityPath>/search_dynamic_row */ class SpaSearchProvider : ContentProvider() { private val spaEnvironment get() = SpaEnvironmentFactory.instance Loading @@ -58,7 +59,9 @@ class SpaSearchProvider : ContentProvider() { SEARCH_STATIC_DATA to 301, SEARCH_DYNAMIC_DATA to 302, SEARCH_MUTABLE_STATUS to 303, SEARCH_IMMUTABLE_STATUS to 304 SEARCH_IMMUTABLE_STATUS to 304, SEARCH_STATIC_ROW to 305, SEARCH_DYNAMIC_ROW to 306 ) override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int { Loading Loading @@ -114,6 +117,8 @@ class SpaSearchProvider : ContentProvider() { querySearchMutableStatusData() queryMatchCode[SEARCH_IMMUTABLE_STATUS] -> querySearchImmutableStatusData() queryMatchCode[SEARCH_STATIC_ROW] -> querySearchStaticRow() queryMatchCode[SEARCH_DYNAMIC_ROW] -> querySearchDynamicRow() else -> throw UnsupportedOperationException("Unknown Uri $uri") } } catch (e: UnsupportedOperationException) { Loading Loading @@ -168,6 +173,31 @@ class SpaSearchProvider : ContentProvider() { return cursor } @VisibleForTesting fun querySearchStaticRow(): Cursor { val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.SEARCH_STATIC_ROW_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { if (!entry.isAllowSearch || entry.isSearchDataDynamic || entry.hasMutableStatus) continue fetchSearchRow(entry, cursor) } return cursor } @VisibleForTesting fun querySearchDynamicRow(): Cursor { val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.SEARCH_DYNAMIC_ROW_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { if (!entry.isAllowSearch || (!entry.isSearchDataDynamic && !entry.hasMutableStatus)) continue fetchSearchRow(entry, cursor) } return cursor } private fun fetchSearchData(entry: SettingsEntry, cursor: MatrixCursor) { val entryRepository by spaEnvironment.entryRepository Loading Loading @@ -196,12 +226,42 @@ class SpaSearchProvider : ContentProvider() { private fun fetchStatusData(entry: SettingsEntry, cursor: MatrixCursor) { // Fetch status data. We can add runtime arguments later if necessary val statusData = entry.getStatusData() ?: EntryStatusData() val statusData = entry.getStatusData() ?: return cursor.newRow() .add(ColumnEnum.ENTRY_ID.id, entry.id) .add(ColumnEnum.ENTRY_DISABLED.id, statusData.isDisabled) } private fun fetchSearchRow(entry: SettingsEntry, cursor: MatrixCursor) { val entryRepository by spaEnvironment.entryRepository // Fetch search data. We can add runtime arguments later if necessary val searchData = entry.getSearchData() ?: return val intent = entry.createIntent(SESSION_SEARCH) val row = cursor.newRow().add(ColumnEnum.ENTRY_ID.id, entry.id) .add(ColumnEnum.SEARCH_TITLE.id, searchData.title) .add(ColumnEnum.SEARCH_KEYWORD.id, searchData.keyword) .add( ColumnEnum.SEARCH_PATH.id, entryRepository.getEntryPathWithTitle(entry.id, searchData.title) ) intent?.let { row.add(ColumnEnum.INTENT_TARGET_PACKAGE.id, spaEnvironment.appContext.packageName) .add(ColumnEnum.INTENT_TARGET_CLASS.id, spaEnvironment.browseActivityClass?.name) .add(ColumnEnum.INTENT_EXTRAS.id, marshall(intent.extras)) } if (entry.hasSliceSupport) row.add( ColumnEnum.SLICE_URI.id, Uri.Builder() .fromEntry(entry, spaEnvironment.sliceProviderAuthorities) ) // TODO: support legacy key // Fetch status data. We can add runtime arguments later if necessary val statusData = entry.getStatusData() ?: return row.add(ColumnEnum.ENTRY_DISABLED.id, statusData.isDisabled) } private fun QueryEnum.getColumns(): Array<String> { return columnNames.map { it.id }.toTypedArray() } Loading packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/search/SpaSearchProviderTest.kt +94 −13 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ class SpaSearchProviderTest { .containsExactlyElementsIn(QueryEnum.SEARCH_DYNAMIC_DATA_QUERY.columnNames) Truth.assertThat(QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY.columnNames) .containsExactlyElementsIn(QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY.columnNames) Truth.assertThat(QueryEnum.SEARCH_STATIC_ROW_QUERY.columnNames) .containsExactlyElementsIn(QueryEnum.SEARCH_DYNAMIC_ROW_QUERY.columnNames) } @Test Loading @@ -53,20 +55,8 @@ class SpaSearchProviderTest { SpaEnvironmentFactory.reset(spaEnvironment) val immutableStatus = searchProvider.querySearchImmutableStatusData() Truth.assertThat(immutableStatus.count).isEqualTo(2) Truth.assertThat(immutableStatus.count).isEqualTo(1) immutableStatus.moveToFirst() immutableStatus.checkValue( QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchStaticWithNoStatus") ) immutableStatus.checkValue( QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_DISABLED, false.toString() ) immutableStatus.moveToNext() immutableStatus.checkValue( QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_ID, Loading Loading @@ -171,6 +161,97 @@ class SpaSearchProviderTest { listOf("kw1", "kw2").toString() ) } @Test fun testQuerySearchIndexRow() { SpaEnvironmentFactory.reset(spaEnvironment) val staticRow = searchProvider.querySearchStaticRow() Truth.assertThat(staticRow.count).isEqualTo(1) staticRow.moveToFirst() staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchStaticWithNoStatus") ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.SEARCH_TITLE, "SearchStaticWithNoStatus" ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.SEARCH_KEYWORD, listOf("").toString() ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.SEARCH_PATH, listOf("SearchStaticWithNoStatus", "SppForSearch").toString() ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.INTENT_TARGET_PACKAGE, spaEnvironment.appContext.packageName ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.INTENT_TARGET_CLASS, "com.android.settingslib.spa.tests.testutils.BlankActivity" ) // Check extras in intent val bundle = staticRow.getExtras(QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.INTENT_EXTRAS) Truth.assertThat(bundle).isNotNull() Truth.assertThat(bundle!!.size()).isEqualTo(3) Truth.assertThat(bundle.getString("spaActivityDestination")).isEqualTo("SppForSearch") Truth.assertThat(bundle.getString("highlightEntry")) .isEqualTo(pageOwner.getEntryId("SearchStaticWithNoStatus")) Truth.assertThat(bundle.getString("sessionSource")).isEqualTo("search") Truth.assertThat( staticRow.getString( QueryEnum.SEARCH_STATIC_ROW_QUERY.columnNames.indexOf( ColumnEnum.ENTRY_DISABLED ) ) ).isNull() val dynamicRow = searchProvider.querySearchDynamicRow() Truth.assertThat(dynamicRow.count).isEqualTo(3) dynamicRow.moveToFirst() dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchStaticWithMutableStatus") ) dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, false.toString() ) dynamicRow.moveToNext() dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchDynamicWithMutableStatus") ) dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, true.toString() ) dynamicRow.moveToNext() dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchDynamicWithImmutableStatus") ) dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.SEARCH_KEYWORD, listOf("kw1", "kw2").toString() ) dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, true.toString() ) } } private fun Cursor.checkValue(query: QueryEnum, column: ColumnEnum, value: String) { Loading Loading
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchContract.kt +37 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,13 @@ const val SEARCH_IMMUTABLE_STATUS = "search_immutable_status" /** ContentProvider path for search mutable status */ const val SEARCH_MUTABLE_STATUS = "search_mutable_status" /** ContentProvider path for search static row */ const val SEARCH_STATIC_ROW = "search_static_row" /** ContentProvider path for search dynamic row */ const val SEARCH_DYNAMIC_ROW = "search_dynamic_row" /** Enum to define all column names in provider. */ enum class ColumnEnum(val id: String) { ENTRY_ID("entryId"), Loading Loading @@ -95,4 +102,34 @@ enum class QueryEnum( ColumnEnum.ENTRY_DISABLED, ) ), SEARCH_STATIC_ROW_QUERY( SEARCH_STATIC_ROW, listOf( ColumnEnum.ENTRY_ID, ColumnEnum.SEARCH_TITLE, ColumnEnum.SEARCH_KEYWORD, ColumnEnum.SEARCH_PATH, ColumnEnum.INTENT_TARGET_PACKAGE, ColumnEnum.INTENT_TARGET_CLASS, ColumnEnum.INTENT_EXTRAS, ColumnEnum.SLICE_URI, ColumnEnum.LEGACY_KEY, ColumnEnum.ENTRY_DISABLED, ) ), SEARCH_DYNAMIC_ROW_QUERY( SEARCH_DYNAMIC_ROW, listOf( ColumnEnum.ENTRY_ID, ColumnEnum.SEARCH_TITLE, ColumnEnum.SEARCH_KEYWORD, ColumnEnum.SEARCH_PATH, ColumnEnum.INTENT_TARGET_PACKAGE, ColumnEnum.INTENT_TARGET_CLASS, ColumnEnum.INTENT_EXTRAS, ColumnEnum.SLICE_URI, ColumnEnum.LEGACY_KEY, ColumnEnum.ENTRY_DISABLED, ) ), }
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/search/SpaSearchProvider.kt +63 −3 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import android.os.Parcel import android.os.Parcelable import android.util.Log import androidx.annotation.VisibleForTesting import com.android.settingslib.spa.framework.common.EntryStatusData import com.android.settingslib.spa.framework.common.SettingsEntry import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.util.SESSION_SEARCH Loading @@ -49,6 +48,8 @@ private const val TAG = "SpaSearchProvider" * $ adb shell content query --uri content://<AuthorityPath>/search_dynamic_data * $ adb shell content query --uri content://<AuthorityPath>/search_immutable_status * $ adb shell content query --uri content://<AuthorityPath>/search_mutable_status * $ adb shell content query --uri content://<AuthorityPath>/search_static_row * $ adb shell content query --uri content://<AuthorityPath>/search_dynamic_row */ class SpaSearchProvider : ContentProvider() { private val spaEnvironment get() = SpaEnvironmentFactory.instance Loading @@ -58,7 +59,9 @@ class SpaSearchProvider : ContentProvider() { SEARCH_STATIC_DATA to 301, SEARCH_DYNAMIC_DATA to 302, SEARCH_MUTABLE_STATUS to 303, SEARCH_IMMUTABLE_STATUS to 304 SEARCH_IMMUTABLE_STATUS to 304, SEARCH_STATIC_ROW to 305, SEARCH_DYNAMIC_ROW to 306 ) override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int { Loading Loading @@ -114,6 +117,8 @@ class SpaSearchProvider : ContentProvider() { querySearchMutableStatusData() queryMatchCode[SEARCH_IMMUTABLE_STATUS] -> querySearchImmutableStatusData() queryMatchCode[SEARCH_STATIC_ROW] -> querySearchStaticRow() queryMatchCode[SEARCH_DYNAMIC_ROW] -> querySearchDynamicRow() else -> throw UnsupportedOperationException("Unknown Uri $uri") } } catch (e: UnsupportedOperationException) { Loading Loading @@ -168,6 +173,31 @@ class SpaSearchProvider : ContentProvider() { return cursor } @VisibleForTesting fun querySearchStaticRow(): Cursor { val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.SEARCH_STATIC_ROW_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { if (!entry.isAllowSearch || entry.isSearchDataDynamic || entry.hasMutableStatus) continue fetchSearchRow(entry, cursor) } return cursor } @VisibleForTesting fun querySearchDynamicRow(): Cursor { val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.SEARCH_DYNAMIC_ROW_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { if (!entry.isAllowSearch || (!entry.isSearchDataDynamic && !entry.hasMutableStatus)) continue fetchSearchRow(entry, cursor) } return cursor } private fun fetchSearchData(entry: SettingsEntry, cursor: MatrixCursor) { val entryRepository by spaEnvironment.entryRepository Loading Loading @@ -196,12 +226,42 @@ class SpaSearchProvider : ContentProvider() { private fun fetchStatusData(entry: SettingsEntry, cursor: MatrixCursor) { // Fetch status data. We can add runtime arguments later if necessary val statusData = entry.getStatusData() ?: EntryStatusData() val statusData = entry.getStatusData() ?: return cursor.newRow() .add(ColumnEnum.ENTRY_ID.id, entry.id) .add(ColumnEnum.ENTRY_DISABLED.id, statusData.isDisabled) } private fun fetchSearchRow(entry: SettingsEntry, cursor: MatrixCursor) { val entryRepository by spaEnvironment.entryRepository // Fetch search data. We can add runtime arguments later if necessary val searchData = entry.getSearchData() ?: return val intent = entry.createIntent(SESSION_SEARCH) val row = cursor.newRow().add(ColumnEnum.ENTRY_ID.id, entry.id) .add(ColumnEnum.SEARCH_TITLE.id, searchData.title) .add(ColumnEnum.SEARCH_KEYWORD.id, searchData.keyword) .add( ColumnEnum.SEARCH_PATH.id, entryRepository.getEntryPathWithTitle(entry.id, searchData.title) ) intent?.let { row.add(ColumnEnum.INTENT_TARGET_PACKAGE.id, spaEnvironment.appContext.packageName) .add(ColumnEnum.INTENT_TARGET_CLASS.id, spaEnvironment.browseActivityClass?.name) .add(ColumnEnum.INTENT_EXTRAS.id, marshall(intent.extras)) } if (entry.hasSliceSupport) row.add( ColumnEnum.SLICE_URI.id, Uri.Builder() .fromEntry(entry, spaEnvironment.sliceProviderAuthorities) ) // TODO: support legacy key // Fetch status data. We can add runtime arguments later if necessary val statusData = entry.getStatusData() ?: return row.add(ColumnEnum.ENTRY_DISABLED.id, statusData.isDisabled) } private fun QueryEnum.getColumns(): Array<String> { return columnNames.map { it.id }.toTypedArray() } Loading
packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/search/SpaSearchProviderTest.kt +94 −13 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ class SpaSearchProviderTest { .containsExactlyElementsIn(QueryEnum.SEARCH_DYNAMIC_DATA_QUERY.columnNames) Truth.assertThat(QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY.columnNames) .containsExactlyElementsIn(QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY.columnNames) Truth.assertThat(QueryEnum.SEARCH_STATIC_ROW_QUERY.columnNames) .containsExactlyElementsIn(QueryEnum.SEARCH_DYNAMIC_ROW_QUERY.columnNames) } @Test Loading @@ -53,20 +55,8 @@ class SpaSearchProviderTest { SpaEnvironmentFactory.reset(spaEnvironment) val immutableStatus = searchProvider.querySearchImmutableStatusData() Truth.assertThat(immutableStatus.count).isEqualTo(2) Truth.assertThat(immutableStatus.count).isEqualTo(1) immutableStatus.moveToFirst() immutableStatus.checkValue( QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchStaticWithNoStatus") ) immutableStatus.checkValue( QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_DISABLED, false.toString() ) immutableStatus.moveToNext() immutableStatus.checkValue( QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY, ColumnEnum.ENTRY_ID, Loading Loading @@ -171,6 +161,97 @@ class SpaSearchProviderTest { listOf("kw1", "kw2").toString() ) } @Test fun testQuerySearchIndexRow() { SpaEnvironmentFactory.reset(spaEnvironment) val staticRow = searchProvider.querySearchStaticRow() Truth.assertThat(staticRow.count).isEqualTo(1) staticRow.moveToFirst() staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchStaticWithNoStatus") ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.SEARCH_TITLE, "SearchStaticWithNoStatus" ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.SEARCH_KEYWORD, listOf("").toString() ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.SEARCH_PATH, listOf("SearchStaticWithNoStatus", "SppForSearch").toString() ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.INTENT_TARGET_PACKAGE, spaEnvironment.appContext.packageName ) staticRow.checkValue( QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.INTENT_TARGET_CLASS, "com.android.settingslib.spa.tests.testutils.BlankActivity" ) // Check extras in intent val bundle = staticRow.getExtras(QueryEnum.SEARCH_STATIC_ROW_QUERY, ColumnEnum.INTENT_EXTRAS) Truth.assertThat(bundle).isNotNull() Truth.assertThat(bundle!!.size()).isEqualTo(3) Truth.assertThat(bundle.getString("spaActivityDestination")).isEqualTo("SppForSearch") Truth.assertThat(bundle.getString("highlightEntry")) .isEqualTo(pageOwner.getEntryId("SearchStaticWithNoStatus")) Truth.assertThat(bundle.getString("sessionSource")).isEqualTo("search") Truth.assertThat( staticRow.getString( QueryEnum.SEARCH_STATIC_ROW_QUERY.columnNames.indexOf( ColumnEnum.ENTRY_DISABLED ) ) ).isNull() val dynamicRow = searchProvider.querySearchDynamicRow() Truth.assertThat(dynamicRow.count).isEqualTo(3) dynamicRow.moveToFirst() dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchStaticWithMutableStatus") ) dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, false.toString() ) dynamicRow.moveToNext() dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchDynamicWithMutableStatus") ) dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, true.toString() ) dynamicRow.moveToNext() dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_ID, pageOwner.getEntryId("SearchDynamicWithImmutableStatus") ) dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.SEARCH_KEYWORD, listOf("kw1", "kw2").toString() ) dynamicRow.checkValue( QueryEnum.SEARCH_DYNAMIC_ROW_QUERY, ColumnEnum.ENTRY_DISABLED, true.toString() ) } } private fun Cursor.checkValue(query: QueryEnum, column: ColumnEnum, value: String) { Loading