Loading src/com/android/documentsui/loaders/FolderLoader.kt +21 −8 Original line number Diff line number Diff line Loading @@ -40,9 +40,14 @@ import com.android.documentsui.sorting.SortModel * - A content lock for which a locking content observer is built * - A list of user IDs on behalf of which the search is conducted * - The root info of the listed directory * - The document info of the listed directory * - The document info of the listed directory, may be null. * - a lookup from file extension to file type * - The model capable of sorting results * * Typically, here we expect mListedDir to be not null, as this is the directory we are listing. * However, when profile is switched while using the app as a file picker, it is possible that * the listing directory is null. If this is the case, we assume that we should be listing the * location specified by the mRoot. */ class FolderLoader( context: Context, Loading @@ -50,7 +55,7 @@ class FolderLoader( mimeTypeLookup: Lookup<String, String>, contentLock: ContentLock, private val mRoot: RootInfo, private val mListedDir: DocumentInfo, private val mListedDir: DocumentInfo?, private val mOptions: QueryOptions, private val mSortModel: SortModel, ) : BaseFileLoader(context, userIdList, mimeTypeLookup) { Loading @@ -61,14 +66,22 @@ class FolderLoader( // Creates a directory result object corresponding to the current parameters of the loader. override fun loadInBackground(): DirectoryResult? { val rejectBeforeTimestamp = mOptions.getRejectBeforeTimestamp() val folderChildrenUri = DocumentsContract.buildChildDocumentsUri( val folderChildrenUri = if (mListedDir == null) { DocumentsContract.buildChildDocumentsUri( mRoot.authority, mRoot.documentId ) } else { DocumentsContract.buildChildDocumentsUri( mListedDir.authority, mListedDir.documentId ) } val result = DirectoryResult() // If we are listing an archive, in the current approach, we cache the client as part of // DirectoryResult. This way, when the loader is closed, we can close the archive client. if (mListedDir.isInArchive) { if (mListedDir != null && mListedDir.isInArchive) { result.setClient(openArchive(folderChildrenUri)) } var cursor = Loading @@ -88,7 +101,7 @@ class FolderLoader( // TODO(b:380945065): Add filtering by category, such as images, audio, video. val sortedCursor = mSortModel.sortCursor(filteredCursor, mimeTypeLookup) result.doc = mListedDir result.doc = mListedDir ?: DocumentInfo() result.cursor = sortedCursor return result } Loading tests/unit/com/android/documentsui/loaders/FolderLoaderTest.kt +42 −11 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ import com.android.documentsui.rules.CheckAndForceMaterial3Flag import com.android.documentsui.testing.TestFileTypeLookup import com.android.documentsui.testing.TestProvidersAccess import java.time.Duration import junit.framework.Assert.assertEquals import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -57,23 +58,31 @@ class FolderLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTes @get:Rule val checkFlags = CheckAndForceMaterial3Flag() @Test @RequiresFlagsEnabled(FLAG_USE_SEARCH_V2_READ_ONLY) fun testLoadInBackground() { val mockProvider = mEnv.mockProviders[TestProvidersAccess.DOWNLOADS.authority] val docs = createDocuments(TOTAL_FILE_COUNT) mockProvider!!.setNextChildDocumentsReturns(*docs) val userIds = listOf(TestProvidersAccess.DOWNLOADS.userId) val queryOptions = val contentLock = ContentLock() lateinit var queryOptions: QueryOptions @Before override fun setUp() { super.setUp() queryOptions = QueryOptions( TOTAL_FILE_COUNT, testParams.lastModifiedDelta, null, true, arrayOf<String>("*/*"), arrayOf("*/*"), testParams.otherArgs, ) val contentLock = ContentLock() // Set up sample files using Downloads provider. val mockProvider = mEnv.mockProviders[TestProvidersAccess.DOWNLOADS.authority] val docs = createDocuments(TOTAL_FILE_COUNT) mockProvider!!.setNextChildDocumentsReturns(*docs) } @Test @RequiresFlagsEnabled(FLAG_USE_SEARCH_V2_READ_ONLY) fun testLoadInBackground() { val userIds = listOf(TestProvidersAccess.DOWNLOADS.userId) // TODO(majewski): Is there a better way to create Downloads root folder DocumentInfo? val rootFolderInfo = DocumentInfo() rootFolderInfo.authority = TestProvidersAccess.DOWNLOADS.authority Loading @@ -93,4 +102,26 @@ class FolderLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTes val directoryResult = loader.loadInBackground() assertEquals(testParams.expectedCount, getFileCount(directoryResult)) } @Test @RequiresFlagsEnabled(FLAG_USE_SEARCH_V2_READ_ONLY) fun testListRootIfNullFolder() { val mockProvider = mEnv.mockProviders[TestProvidersAccess.DOWNLOADS.authority] val docs = createDocuments(TOTAL_FILE_COUNT) mockProvider!!.setNextChildDocumentsReturns(*docs) val loader = FolderLoader( mActivity, listOf(TestProvidersAccess.DOWNLOADS.userId), TestFileTypeLookup(), contentLock, TestProvidersAccess.DOWNLOADS, null, queryOptions, mEnv.state.sortModel ) val directoryResult = loader.loadInBackground() assertEquals(testParams.expectedCount, getFileCount(directoryResult)) } } Loading
src/com/android/documentsui/loaders/FolderLoader.kt +21 −8 Original line number Diff line number Diff line Loading @@ -40,9 +40,14 @@ import com.android.documentsui.sorting.SortModel * - A content lock for which a locking content observer is built * - A list of user IDs on behalf of which the search is conducted * - The root info of the listed directory * - The document info of the listed directory * - The document info of the listed directory, may be null. * - a lookup from file extension to file type * - The model capable of sorting results * * Typically, here we expect mListedDir to be not null, as this is the directory we are listing. * However, when profile is switched while using the app as a file picker, it is possible that * the listing directory is null. If this is the case, we assume that we should be listing the * location specified by the mRoot. */ class FolderLoader( context: Context, Loading @@ -50,7 +55,7 @@ class FolderLoader( mimeTypeLookup: Lookup<String, String>, contentLock: ContentLock, private val mRoot: RootInfo, private val mListedDir: DocumentInfo, private val mListedDir: DocumentInfo?, private val mOptions: QueryOptions, private val mSortModel: SortModel, ) : BaseFileLoader(context, userIdList, mimeTypeLookup) { Loading @@ -61,14 +66,22 @@ class FolderLoader( // Creates a directory result object corresponding to the current parameters of the loader. override fun loadInBackground(): DirectoryResult? { val rejectBeforeTimestamp = mOptions.getRejectBeforeTimestamp() val folderChildrenUri = DocumentsContract.buildChildDocumentsUri( val folderChildrenUri = if (mListedDir == null) { DocumentsContract.buildChildDocumentsUri( mRoot.authority, mRoot.documentId ) } else { DocumentsContract.buildChildDocumentsUri( mListedDir.authority, mListedDir.documentId ) } val result = DirectoryResult() // If we are listing an archive, in the current approach, we cache the client as part of // DirectoryResult. This way, when the loader is closed, we can close the archive client. if (mListedDir.isInArchive) { if (mListedDir != null && mListedDir.isInArchive) { result.setClient(openArchive(folderChildrenUri)) } var cursor = Loading @@ -88,7 +101,7 @@ class FolderLoader( // TODO(b:380945065): Add filtering by category, such as images, audio, video. val sortedCursor = mSortModel.sortCursor(filteredCursor, mimeTypeLookup) result.doc = mListedDir result.doc = mListedDir ?: DocumentInfo() result.cursor = sortedCursor return result } Loading
tests/unit/com/android/documentsui/loaders/FolderLoaderTest.kt +42 −11 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ import com.android.documentsui.rules.CheckAndForceMaterial3Flag import com.android.documentsui.testing.TestFileTypeLookup import com.android.documentsui.testing.TestProvidersAccess import java.time.Duration import junit.framework.Assert.assertEquals import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -57,23 +58,31 @@ class FolderLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTes @get:Rule val checkFlags = CheckAndForceMaterial3Flag() @Test @RequiresFlagsEnabled(FLAG_USE_SEARCH_V2_READ_ONLY) fun testLoadInBackground() { val mockProvider = mEnv.mockProviders[TestProvidersAccess.DOWNLOADS.authority] val docs = createDocuments(TOTAL_FILE_COUNT) mockProvider!!.setNextChildDocumentsReturns(*docs) val userIds = listOf(TestProvidersAccess.DOWNLOADS.userId) val queryOptions = val contentLock = ContentLock() lateinit var queryOptions: QueryOptions @Before override fun setUp() { super.setUp() queryOptions = QueryOptions( TOTAL_FILE_COUNT, testParams.lastModifiedDelta, null, true, arrayOf<String>("*/*"), arrayOf("*/*"), testParams.otherArgs, ) val contentLock = ContentLock() // Set up sample files using Downloads provider. val mockProvider = mEnv.mockProviders[TestProvidersAccess.DOWNLOADS.authority] val docs = createDocuments(TOTAL_FILE_COUNT) mockProvider!!.setNextChildDocumentsReturns(*docs) } @Test @RequiresFlagsEnabled(FLAG_USE_SEARCH_V2_READ_ONLY) fun testLoadInBackground() { val userIds = listOf(TestProvidersAccess.DOWNLOADS.userId) // TODO(majewski): Is there a better way to create Downloads root folder DocumentInfo? val rootFolderInfo = DocumentInfo() rootFolderInfo.authority = TestProvidersAccess.DOWNLOADS.authority Loading @@ -93,4 +102,26 @@ class FolderLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTes val directoryResult = loader.loadInBackground() assertEquals(testParams.expectedCount, getFileCount(directoryResult)) } @Test @RequiresFlagsEnabled(FLAG_USE_SEARCH_V2_READ_ONLY) fun testListRootIfNullFolder() { val mockProvider = mEnv.mockProviders[TestProvidersAccess.DOWNLOADS.authority] val docs = createDocuments(TOTAL_FILE_COUNT) mockProvider!!.setNextChildDocumentsReturns(*docs) val loader = FolderLoader( mActivity, listOf(TestProvidersAccess.DOWNLOADS.userId), TestFileTypeLookup(), contentLock, TestProvidersAccess.DOWNLOADS, null, queryOptions, mEnv.state.sortModel ) val directoryResult = loader.loadInBackground() assertEquals(testParams.expectedCount, getFileCount(directoryResult)) } }