Loading src/com/android/documentsui/AbstractActionHandler.java +3 −2 Original line number Diff line number Diff line Loading @@ -1026,8 +1026,9 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA int maxResults = (root == null || root.isRecents()) ? RecentsLoader.MAX_DOCS_FROM_ROOT : MAX_RESULTS; QueryOptions options = new QueryOptions( maxResults, lastModifiedDelta, Duration.ofMillis(MAX_SEARCH_TIME_MS), mState.showHiddenFiles, mState.acceptMimes, mSearchMgr.buildQueryArgs()); maxResults, maxResults, lastModifiedDelta, Duration.ofMillis(MAX_SEARCH_TIME_MS), mState.showHiddenFiles, mState.acceptMimes, mSearchMgr.buildQueryArgs()); if (stack.isRecents() || mSearchMgr.isSearching()) { Log.d(TAG, "Creating search loader V2"); Loading src/com/android/documentsui/base/FolderInfo.kt +22 −3 Original line number Diff line number Diff line Loading @@ -22,7 +22,26 @@ package com.android.documentsui.base * interchangeably. Additionally the "folderId" is rootId for the RootInfo, but documentId for * DocumentInfo. */ data class FolderInfo(val folderId: String, val authority: String) { constructor(folder: DocumentInfo) : this(folder.documentId, folder.authority) constructor(rootInfo: RootInfo) : this(rootInfo.rootId, rootInfo.authority) data class FolderInfo( val folderId: String, val authority: String, // Specifies whether the Root this folder exists on supports search result limiting: this can // help to find more search results (increasing the limit) or improve performance (decreasing // the limit). We could just send the limit regardless of whether the root says it supports this // but this allows SearchLoader to be judicious and not starting sending new parameters that // it hasn't done in the past. // // TODO(b:419704219) remove this property when RootInfo/DocumentInfo have a shared interface. val supportsSearchResultLimiting: Boolean ) { constructor(rootInfo: RootInfo) : this( rootInfo.rootId, rootInfo.authority, rootInfo.supportsSearchResultLimit() ) constructor(folder: DocumentInfo, folderRoot: RootInfo) : this( folder.documentId, folder.authority, folderRoot.supportsSearchResultLimit() ) } src/com/android/documentsui/base/RootInfo.java +9 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.documentsui.base.Shared.compareToIgnoreCaseNullable; import static com.android.documentsui.base.SharedMinimal.VERBOSE; import static com.android.documentsui.util.Material3Config.getRes; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.graphics.drawable.Drawable; Loading Loading @@ -390,6 +391,14 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> { return queryArgs != null && queryArgs.contains(QUERY_ARG_MIME_TYPES); } /** * Returns true if the DocumentsProvider hosting this root supports us specifying a limit for * the maximum number of search results it should return. */ public boolean supportsSearchResultLimit() { return queryArgs != null && queryArgs.contains(ContentResolver.QUERY_ARG_LIMIT); } public boolean supportsEject() { return (flags & Root.FLAG_SUPPORTS_EJECT) != 0; } Loading src/com/android/documentsui/loaders/QueryOptions.kt +16 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.documentsui.loaders import android.os.Bundle import java.time.Duration import java.util.Objects /** * The constant to be used for the maxResults parameter, if we wish to get all (unlimited) results. Loading @@ -25,7 +26,11 @@ const val ALL_RESULTS: Int = -1 /** * Common query options. These are: * - maximum number to return; pass ALL_RESULTS to impose no limits. * - maximum number of results to return across all queried providers; pass ALL_RESULTS to impose * no limits. * - maximum number of results to return *per root*; pass ALL_RESULTS to impose no limits, * and note that this only works for DocumentsProviders that support QUERY_ARG_LIMIT for queries * on their Roots. * - maximum lastModified delta in milliseconds: the delta from now used to reject files that were * not modified in the specified milliseconds; pass null for no limits. * - maximum time the query should return, including empty, results; pass null for no limits. Loading @@ -40,6 +45,7 @@ const val ALL_RESULTS: Int = -1 */ data class QueryOptions( val maxResults: Int, val maxResultsPerRoot: Int, val maxLastModifiedDelta: Duration?, val maxQueryTime: Duration?, val showHidden: Boolean, Loading @@ -54,6 +60,7 @@ data class QueryOptions( other as QueryOptions return maxResults == other.maxResults && maxResultsPerRoot == other.maxResultsPerRoot && maxLastModifiedDelta == other.maxLastModifiedDelta && maxQueryTime == other.maxQueryTime && showHidden == other.showHidden && Loading @@ -80,11 +87,13 @@ data class QueryOptions( fun isQueryTimeUnlimited() = maxQueryTime == null override fun hashCode(): Int { var result = maxResults result = 31 * result + maxLastModifiedDelta.hashCode() result = 31 * result + maxQueryTime.hashCode() result = 31 * result + showHidden.hashCode() result = 31 * result + acceptableMimeTypes.contentHashCode() return result return Objects.hash( maxResults, maxResultsPerRoot, maxLastModifiedDelta, maxQueryTime, showHidden, acceptableMimeTypes.contentHashCode() ) } } src/com/android/documentsui/loaders/SearchLoader.kt +10 −2 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.documentsui.loaders import android.content.ContentResolver import android.content.Context import android.database.Cursor import android.net.Uri Loading Loading @@ -220,7 +221,10 @@ class SearchLoader( ) } private fun createQueryArgs(rejectBeforeTimestamp: Long): Bundle { private fun createQueryArgs( rootSupportsSearchResultLimiting: Boolean, rejectBeforeTimestamp: Long ): Bundle { val queryArgs = Bundle() sortModel.addQuerySortArgs(queryArgs) if (rejectBeforeTimestamp > 0L) { Loading @@ -232,6 +236,9 @@ class SearchLoader( if (!TextUtils.isEmpty(query)) { queryArgs.putString(DocumentsContract.QUERY_ARG_DISPLAY_NAME, query) } if (rootSupportsSearchResultLimiting && options.maxResultsPerRoot > ALL_RESULTS) { queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, options.maxResultsPerRoot) } queryArgs.putAll(options.otherQueryArgs) return queryArgs } Loading @@ -251,7 +258,8 @@ class SearchLoader( } val rootSearchUri = createContentProviderQuery(folder) // TODO(b:385789236): Correctly pass sort order information. val queryArgs = createQueryArgs(rejectBeforeTimestamp) val queryArgs = createQueryArgs(folder.supportsSearchResultLimiting, rejectBeforeTimestamp) sortModel.addQuerySortArgs(queryArgs) if (DEBUG) { Log.d(TAG, "Query $rootSearchUri and queryArgs $queryArgs") Loading Loading
src/com/android/documentsui/AbstractActionHandler.java +3 −2 Original line number Diff line number Diff line Loading @@ -1026,8 +1026,9 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA int maxResults = (root == null || root.isRecents()) ? RecentsLoader.MAX_DOCS_FROM_ROOT : MAX_RESULTS; QueryOptions options = new QueryOptions( maxResults, lastModifiedDelta, Duration.ofMillis(MAX_SEARCH_TIME_MS), mState.showHiddenFiles, mState.acceptMimes, mSearchMgr.buildQueryArgs()); maxResults, maxResults, lastModifiedDelta, Duration.ofMillis(MAX_SEARCH_TIME_MS), mState.showHiddenFiles, mState.acceptMimes, mSearchMgr.buildQueryArgs()); if (stack.isRecents() || mSearchMgr.isSearching()) { Log.d(TAG, "Creating search loader V2"); Loading
src/com/android/documentsui/base/FolderInfo.kt +22 −3 Original line number Diff line number Diff line Loading @@ -22,7 +22,26 @@ package com.android.documentsui.base * interchangeably. Additionally the "folderId" is rootId for the RootInfo, but documentId for * DocumentInfo. */ data class FolderInfo(val folderId: String, val authority: String) { constructor(folder: DocumentInfo) : this(folder.documentId, folder.authority) constructor(rootInfo: RootInfo) : this(rootInfo.rootId, rootInfo.authority) data class FolderInfo( val folderId: String, val authority: String, // Specifies whether the Root this folder exists on supports search result limiting: this can // help to find more search results (increasing the limit) or improve performance (decreasing // the limit). We could just send the limit regardless of whether the root says it supports this // but this allows SearchLoader to be judicious and not starting sending new parameters that // it hasn't done in the past. // // TODO(b:419704219) remove this property when RootInfo/DocumentInfo have a shared interface. val supportsSearchResultLimiting: Boolean ) { constructor(rootInfo: RootInfo) : this( rootInfo.rootId, rootInfo.authority, rootInfo.supportsSearchResultLimit() ) constructor(folder: DocumentInfo, folderRoot: RootInfo) : this( folder.documentId, folder.authority, folderRoot.supportsSearchResultLimit() ) }
src/com/android/documentsui/base/RootInfo.java +9 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.documentsui.base.Shared.compareToIgnoreCaseNullable; import static com.android.documentsui.base.SharedMinimal.VERBOSE; import static com.android.documentsui.util.Material3Config.getRes; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.graphics.drawable.Drawable; Loading Loading @@ -390,6 +391,14 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> { return queryArgs != null && queryArgs.contains(QUERY_ARG_MIME_TYPES); } /** * Returns true if the DocumentsProvider hosting this root supports us specifying a limit for * the maximum number of search results it should return. */ public boolean supportsSearchResultLimit() { return queryArgs != null && queryArgs.contains(ContentResolver.QUERY_ARG_LIMIT); } public boolean supportsEject() { return (flags & Root.FLAG_SUPPORTS_EJECT) != 0; } Loading
src/com/android/documentsui/loaders/QueryOptions.kt +16 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.documentsui.loaders import android.os.Bundle import java.time.Duration import java.util.Objects /** * The constant to be used for the maxResults parameter, if we wish to get all (unlimited) results. Loading @@ -25,7 +26,11 @@ const val ALL_RESULTS: Int = -1 /** * Common query options. These are: * - maximum number to return; pass ALL_RESULTS to impose no limits. * - maximum number of results to return across all queried providers; pass ALL_RESULTS to impose * no limits. * - maximum number of results to return *per root*; pass ALL_RESULTS to impose no limits, * and note that this only works for DocumentsProviders that support QUERY_ARG_LIMIT for queries * on their Roots. * - maximum lastModified delta in milliseconds: the delta from now used to reject files that were * not modified in the specified milliseconds; pass null for no limits. * - maximum time the query should return, including empty, results; pass null for no limits. Loading @@ -40,6 +45,7 @@ const val ALL_RESULTS: Int = -1 */ data class QueryOptions( val maxResults: Int, val maxResultsPerRoot: Int, val maxLastModifiedDelta: Duration?, val maxQueryTime: Duration?, val showHidden: Boolean, Loading @@ -54,6 +60,7 @@ data class QueryOptions( other as QueryOptions return maxResults == other.maxResults && maxResultsPerRoot == other.maxResultsPerRoot && maxLastModifiedDelta == other.maxLastModifiedDelta && maxQueryTime == other.maxQueryTime && showHidden == other.showHidden && Loading @@ -80,11 +87,13 @@ data class QueryOptions( fun isQueryTimeUnlimited() = maxQueryTime == null override fun hashCode(): Int { var result = maxResults result = 31 * result + maxLastModifiedDelta.hashCode() result = 31 * result + maxQueryTime.hashCode() result = 31 * result + showHidden.hashCode() result = 31 * result + acceptableMimeTypes.contentHashCode() return result return Objects.hash( maxResults, maxResultsPerRoot, maxLastModifiedDelta, maxQueryTime, showHidden, acceptableMimeTypes.contentHashCode() ) } }
src/com/android/documentsui/loaders/SearchLoader.kt +10 −2 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.documentsui.loaders import android.content.ContentResolver import android.content.Context import android.database.Cursor import android.net.Uri Loading Loading @@ -220,7 +221,10 @@ class SearchLoader( ) } private fun createQueryArgs(rejectBeforeTimestamp: Long): Bundle { private fun createQueryArgs( rootSupportsSearchResultLimiting: Boolean, rejectBeforeTimestamp: Long ): Bundle { val queryArgs = Bundle() sortModel.addQuerySortArgs(queryArgs) if (rejectBeforeTimestamp > 0L) { Loading @@ -232,6 +236,9 @@ class SearchLoader( if (!TextUtils.isEmpty(query)) { queryArgs.putString(DocumentsContract.QUERY_ARG_DISPLAY_NAME, query) } if (rootSupportsSearchResultLimiting && options.maxResultsPerRoot > ALL_RESULTS) { queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, options.maxResultsPerRoot) } queryArgs.putAll(options.otherQueryArgs) return queryArgs } Loading @@ -251,7 +258,8 @@ class SearchLoader( } val rootSearchUri = createContentProviderQuery(folder) // TODO(b:385789236): Correctly pass sort order information. val queryArgs = createQueryArgs(rejectBeforeTimestamp) val queryArgs = createQueryArgs(folder.supportsSearchResultLimiting, rejectBeforeTimestamp) sortModel.addQuerySortArgs(queryArgs) if (DEBUG) { Log.d(TAG, "Query $rootSearchUri and queryArgs $queryArgs") Loading