Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c085688e authored by Kelvin Kwan's avatar Kelvin Kwan Committed by Android (Google) Code Review
Browse files

Merge "Enable Directory search across profiles"

parents 590d75d7 c4b803a1
Loading
Loading
Loading
Loading
+52 −7
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -31,6 +32,7 @@ import android.os.RemoteException;
import android.provider.DocumentsContract.Document;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.loader.content.AsyncTaskLoader;

import com.android.documentsui.archives.ArchivesProvider;
@@ -42,9 +44,12 @@ import com.android.documentsui.base.Lookup;
import com.android.documentsui.base.MimeTypes;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.base.UserId;
import com.android.documentsui.roots.RootCursorWrapper;
import com.android.documentsui.sorting.SortModel;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
@@ -57,6 +62,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {

    private final LockingContentObserver mObserver;
    private final RootInfo mRoot;
    private final State mState;
    private final Uri mUri;
    private final SortModel mModel;
    private final Lookup<String, String> mFileTypeLookup;
@@ -81,6 +87,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {

        super(context);
        mFeatures = features;
        mState = state;
        mRoot = state.stack.getRoot();
        mUri = uri;
        mModel = state.sortModel;
@@ -124,8 +131,16 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
            final Bundle queryArgs = new Bundle();
            mModel.addQuerySortArgs(queryArgs);

            final List<UserId> userIds = new ArrayList<>();
            if (mSearchMode) {
                queryArgs.putAll(mQueryArgs);
                if (mState.canShareAcrossProfile && mRoot.supportsCrossProfile()) {
                    userIds.addAll(
                            DocumentsApplication.getUserIdManager(getContext()).getUserIds());
                }
            }
            if (userIds.isEmpty()) {
                userIds.add(mDoc.userId);
            }

            if (mFeatures.isContentPagingEnabled()) {
@@ -134,17 +149,13 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
                DebugFlags.addForcedPagingArgs(queryArgs);
            }

            cursor = client.query(mUri, null, queryArgs, mSignal);
            cursor = queryOnUsers(userIds, authority, queryArgs);

            if (cursor == null) {
                throw new RemoteException("Provider returned null");
            }

            cursor.registerContentObserver(mObserver);

            cursor = new RootCursorWrapper(mDoc.userId, mUri.getAuthority(), mRoot.rootId, cursor,
                    -1);

            if (mSearchMode && !mFeatures.isFoldersInSearchResultsEnabled()) {
                // There is no findDocumentPath API. Enable filtering on folders in search mode.
                cursor = new FilteringCursorWrapper(cursor, null, SEARCH_REJECT_MIMES);
@@ -176,6 +187,38 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
        return result;
    }

    @Nullable
    private Cursor queryOnUsers(List<UserId> userIds, String authority, Bundle queryArgs)
            throws RemoteException {
        final List<Cursor> cursors = new ArrayList<>(userIds.size());
        for (UserId userId : userIds) {
            try (ContentProviderClient userClient =
                         DocumentsApplication.acquireUnstableProviderOrThrow(
                                 userId.getContentResolver(getContext()), authority)) {
                Cursor c = userClient.query(mUri, /* projection= */null, queryArgs, mSignal);
                if (c != null) {
                    cursors.add(new RootCursorWrapper(userId, mUri.getAuthority(), mRoot.rootId,
                            c, /* maxCount= */-1));
                }
            } catch (RemoteException e) {
                Log.d(TAG, "Failed to query for user " + userId, e);
                // Searching on other profile may not succeed because profile may be in quiet mode.
                if (UserId.CURRENT_USER.equals(userId)) {
                    throw e;
                }
            }
        }
        int size = cursors.size();
        switch (size) {
            case 0:
                return null;
            case 1:
                return cursors.get(0);
            default:
                return new MergeCursor(cursors.toArray(new Cursor[size]));
        }
    }

    @Override
    public void cancelLoadInBackground() {
        super.cancelLoadInBackground();
@@ -232,9 +275,11 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
        // Ensure the loader is stopped
        onStopLoading();

        if (mResult.cursor != null && mObserver != null) {
            mResult.cursor.unregisterContentObserver(mObserver);
        }

        FileUtils.closeQuietly(mResult);
        mResult = null;

        mDoc.userId.getContentResolver(getContext()).unregisterContentObserver(mObserver);
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.SharedMinimal.TAG;

import android.database.AbstractCursor;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.DocumentsContract.Document;
@@ -136,4 +137,14 @@ public class FilteringCursorWrapper extends AbstractCursor {
    public boolean isNull(int column) {
        return mCursor.isNull(column);
    }

    @Override
    public void registerContentObserver(ContentObserver observer) {
        mCursor.registerContentObserver(observer);
    }

    @Override
    public void unregisterContentObserver(ContentObserver observer) {
        mCursor.unregisterContentObserver(observer);
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -84,6 +84,11 @@ public class State implements android.os.Parcelable {

    public boolean openableOnly;

    /**
     * Represents whether the intent is a cross-profile intent
     */
    public boolean canShareAcrossProfile = false;

    /**
     * This is basically a sub-type for the copy operation. It can be either COPY,
     * COMPRESS, EXTRACT or MOVE.
+10 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import static com.android.documentsui.base.State.ACTION_OPEN_TREE;
import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Color;
import android.net.Uri;
@@ -206,6 +208,14 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons {
            final Intent moreApps = new Intent(intent);
            moreApps.setComponent(null);
            moreApps.setPackage(null);
            for (ResolveInfo info : getPackageManager().queryIntentActivities(moreApps,
                    PackageManager.MATCH_DEFAULT_ONLY)) {
                if (RootsFragment.PROFILE_TARGET_ACTIVITY.equals(
                        info.activityInfo.targetActivity)) {
                    mState.canShareAcrossProfile = true;
                    break;
                }
            }
            RootsFragment.show(getSupportFragmentManager(), moreApps);
        } else if (mState.action == ACTION_OPEN ||
                   mState.action == ACTION_CREATE ||
+3 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ public class RootsFragment extends Fragment {

    private static final String TAG = "RootsFragment";
    private static final String EXTRA_INCLUDE_APPS = "includeApps";
    private static final String PROFILE_TARGET_ACTIVITY =
    public static final String PROFILE_TARGET_ACTIVITY =
            "com.android.internal.app.IntentForwarderActivity";
    private static final int CONTEXT_MENU_ITEM_TIMEOUT = 500;

@@ -384,6 +384,8 @@ public class RootsFragment extends Fragment {

                // for change personal profile root.
                if (PROFILE_TARGET_ACTIVITY.equals(info.activityInfo.targetActivity)) {
                    // TODO: only set in current user
                    getBaseActivity().getDisplayState().canShareAcrossProfile = true;
                    profileItem = new ProfileItem(info, info.loadLabel(pm).toString(),
                            mActionHandler);
                } else {
Loading