From a7765dc1e6172a4b9a296c9788ebfa3be02ee230 Mon Sep 17 00:00:00 2001 From: Andrey Epin Date: Tue, 12 Sep 2023 19:48:47 -0700 Subject: PreviewDataProvider to close content resolver's cursors Fix: 300182416 Test: atest IntentResolverUnitTests:PreviewDataProviderTest Change-Id: If4ee654683ed3e58001c6c07840d86dc2e24a5fc --- .../contentpreview/PreviewDataProvider.kt | 68 +++++++++++----------- .../contentpreview/PreviewDataProviderTest.kt | 22 ++++++- 2 files changed, 55 insertions(+), 35 deletions(-) (limited to 'java') diff --git a/java/src/com/android/intentresolver/contentpreview/PreviewDataProvider.kt b/java/src/com/android/intentresolver/contentpreview/PreviewDataProvider.kt index 9f1cc6c1..bb303c7b 100644 --- a/java/src/com/android/intentresolver/contentpreview/PreviewDataProvider.kt +++ b/java/src/com/android/intentresolver/contentpreview/PreviewDataProvider.kt @@ -264,44 +264,46 @@ constructor( private val query by lazy { readQueryResult() } - private fun readQueryResult(): QueryResult { - val cursor = - contentResolver.querySafe(uri)?.takeIf { it.moveToFirst() } ?: return QueryResult() - - var flagColIdx = -1 - var displayIconUriColIdx = -1 - var nameColIndex = -1 - var titleColIndex = -1 - // TODO: double-check why Cursor#getColumnInded didn't work - cursor.columnNames.forEachIndexed { i, columnName -> - when (columnName) { - DocumentsContract.Document.COLUMN_FLAGS -> flagColIdx = i - MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI -> displayIconUriColIdx = i - OpenableColumns.DISPLAY_NAME -> nameColIndex = i - Downloads.Impl.COLUMN_TITLE -> titleColIndex = i + private fun readQueryResult(): QueryResult = + contentResolver.querySafe(uri)?.use { cursor -> + if (!cursor.moveToFirst()) return@use null + + var flagColIdx = -1 + var displayIconUriColIdx = -1 + var nameColIndex = -1 + var titleColIndex = -1 + // TODO: double-check why Cursor#getColumnInded didn't work + cursor.columnNames.forEachIndexed { i, columnName -> + when (columnName) { + DocumentsContract.Document.COLUMN_FLAGS -> flagColIdx = i + MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI -> displayIconUriColIdx = i + OpenableColumns.DISPLAY_NAME -> nameColIndex = i + Downloads.Impl.COLUMN_TITLE -> titleColIndex = i + } } - } - - val supportsThumbnail = - flagColIdx >= 0 && ((cursor.getInt(flagColIdx) and FLAG_SUPPORTS_THUMBNAIL) != 0) - var title = "" - if (nameColIndex >= 0) { - title = cursor.getString(nameColIndex) ?: "" - } - if (TextUtils.isEmpty(title) && titleColIndex >= 0) { - title = cursor.getString(titleColIndex) ?: "" - } + val supportsThumbnail = + flagColIdx >= 0 && + ((cursor.getInt(flagColIdx) and FLAG_SUPPORTS_THUMBNAIL) != 0) - val iconUri = - if (displayIconUriColIdx >= 0) { - cursor.getString(displayIconUriColIdx)?.let(Uri::parse) - } else { - null + var title = "" + if (nameColIndex >= 0) { + title = cursor.getString(nameColIndex) ?: "" + } + if (TextUtils.isEmpty(title) && titleColIndex >= 0) { + title = cursor.getString(titleColIndex) ?: "" } - return QueryResult(supportsThumbnail, title, iconUri) - } + val iconUri = + if (displayIconUriColIdx >= 0) { + cursor.getString(displayIconUriColIdx)?.let(Uri::parse) + } else { + null + } + + QueryResult(supportsThumbnail, title, iconUri) + } + ?: QueryResult() } private class QueryResult( diff --git a/java/tests/src/com/android/intentresolver/contentpreview/PreviewDataProviderTest.kt b/java/tests/src/com/android/intentresolver/contentpreview/PreviewDataProviderTest.kt index 6599baa9..4a8c1392 100644 --- a/java/tests/src/com/android/intentresolver/contentpreview/PreviewDataProviderTest.kt +++ b/java/tests/src/com/android/intentresolver/contentpreview/PreviewDataProviderTest.kt @@ -192,8 +192,9 @@ class PreviewDataProviderTest { val uri = Uri.parse("content://org.pkg.app/test.pdf") val targetIntent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_STREAM, uri) } whenever(contentResolver.getType(uri)).thenReturn("application/pdf") - whenever(contentResolver.query(uri, METADATA_COLUMNS, null, null)) - .thenReturn(MatrixCursor(columns).apply { addRow(values) }) + val cursor = MatrixCursor(columns).apply { addRow(values) } + whenever(contentResolver.query(uri, METADATA_COLUMNS, null, null)).thenReturn(cursor) + val testSubject = PreviewDataProvider(testScope, targetIntent, contentResolver, mimeTypeClassifier) @@ -202,6 +203,23 @@ class PreviewDataProviderTest { assertThat(testSubject.firstFileInfo?.uri).isEqualTo(uri) assertThat(testSubject.firstFileInfo?.previewUri).isNotNull() verify(contentResolver, times(1)).getType(any()) + assertThat(cursor.isClosed).isTrue() + } + + @Test + fun test_emptyQueryResult_cursorGetsClosed() { + val uri = Uri.parse("content://org.pkg.app/test.pdf") + val targetIntent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_STREAM, uri) } + whenever(contentResolver.getType(uri)).thenReturn("application/pdf") + val cursor = MatrixCursor(emptyArray()) + whenever(contentResolver.query(uri, METADATA_COLUMNS, null, null)).thenReturn(cursor) + + val testSubject = + PreviewDataProvider(testScope, targetIntent, contentResolver, mimeTypeClassifier) + + assertThat(testSubject.previewType).isEqualTo(ContentPreviewType.CONTENT_PREVIEW_FILE) + verify(contentResolver, times(1)).query(uri, METADATA_COLUMNS, null, null) + assertThat(cursor.isClosed).isTrue() } @Test -- cgit v1.2.3-59-g8ed1b