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

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

Merge "Add recents root from different user to ProvidersCache's mTaskRoots"

parents f14d3751 a94d0652
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -803,7 +803,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
    }

    protected final void loadRecent() {
        mState.stack.changeRoot(mProviders.getRecentsRoot());
        mState.stack.changeRoot(mProviders.getRecentsRoot(UserId.DEFAULT_USER));
        mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
    }

@@ -851,7 +851,8 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
                            mProviders,
                            mState,
                            mExecutors,
                            mInjector.fileTypeLookup);
                            mInjector.fileTypeLookup,
                            mState.stack.getRoot().userId);
                }
                loader.setObserver(observer);
                return loader;
+2 −1
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
import com.android.documentsui.base.State.ViewMode;
import com.android.documentsui.base.UserId;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.AppsRowManager;
import com.android.documentsui.dirlist.DirectoryFragment;
@@ -751,7 +752,7 @@ public abstract class BaseActivity
        if (root != null) {
            return root;
        } else {
            return mProviders.getRecentsRoot();
            return mProviders.getRecentsRoot(UserId.DEFAULT_USER);
        }
    }

+7 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.text.format.DateUtils;
import com.android.documentsui.base.Lookup;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.base.UserId;
import com.android.documentsui.roots.ProvidersAccess;
import com.android.documentsui.roots.RootCursorWrapper;

@@ -43,9 +44,12 @@ public class RecentsLoader extends MultiRootDocumentsLoader {
    /** Maximum documents from a single root. */
    private static final int MAX_DOCS_FROM_ROOT = 64;

    private final UserId mUserId;

    public RecentsLoader(Context context, ProvidersAccess providers, State state,
            Lookup<String, Executor> executors, Lookup<String, String> fileTypeMap) {
            Lookup<String, Executor> executors, Lookup<String, String> fileTypeMap, UserId userId) {
        super(context, providers, state, executors, fileTypeMap);
        mUserId = userId;
    }

    @Override
@@ -60,8 +64,8 @@ public class RecentsLoader extends MultiRootDocumentsLoader {

    @Override
    protected boolean shouldIgnoreRoot(RootInfo root) {
        // only query the root is local only and support recents
        return !root.isLocalOnly() || !root.supportsRecents();
        // only query the root is local only, support recents, and is from the selected user.
        return !root.isLocalOnly() || !root.supportsRecents() || !mUserId.equals(root.userId);
    }

    @Override
+1 −1
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ public interface ProvidersAccess {

    RootInfo getDefaultRootBlocking(State state);

    RootInfo getRecentsRoot();
    RootInfo getRecentsRoot(UserId userId);

    String getApplicationName(UserId userId, String authority);

+42 −26
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * Cache of known storage backends and their roots.
@@ -95,7 +96,8 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName {
    @GuardedBy("mRootsChangedObservers")
    private final Map<UserId, RootsChangedObserver> mRootsChangedObservers = new HashMap<>();

    private final RootInfo mRecentsRoot;
    @GuardedBy("mRecentsRoots")
    private final Map<UserId, RootInfo> mRecentsRoots = new HashMap<>();

    private final Object mLock = new Object();
    private final CountDownLatch mFirstLoad = new CountDownLatch(1);
@@ -118,11 +120,12 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName {
    public ProvidersCache(Context context, UserIdManager userIdManager) {
        mContext = context;
        mUserIdManager = userIdManager;
    }

        // Create a new anonymous "Recents" RootInfo. It's a faker.
        mRecentsRoot = new RootInfo() {{
    private RootInfo generateRecentsRoot(UserId rootUserId) {
        return new RootInfo() {{
            // Special root for recents
            userId = UserId.DEFAULT_USER;
            userId = rootUserId;
            derivedIcon = R.drawable.ic_root_recent;
            derivedType = RootInfo.TYPE_RECENTS;
            flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_SEARCH;
@@ -132,13 +135,23 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName {
        }};
    }

    private RootsChangedObserver getRootsChangedObserver(UserId userId) {
        synchronized (mRootsChangedObservers) {
            if (!mRootsChangedObservers.containsKey(userId)) {
                mRootsChangedObservers.put(userId, new RootsChangedObserver(userId));
    private RootInfo createOrGetRecentsRoot(UserId userId) {
        return createOrGetByUserId(mRecentsRoots, userId, user -> generateRecentsRoot(user));
    }

    private RootsChangedObserver createOrGetRootsChangedObserver(UserId userId) {
        return createOrGetByUserId(mRootsChangedObservers, userId,
                user -> new RootsChangedObserver(user));
    }

    private static <T> T createOrGetByUserId(Map<UserId, T> map, UserId userId,
            Function<UserId, T> supplier) {
        synchronized (map) {
            if (!map.containsKey(userId)) {
                map.put(userId, supplier.apply(userId));
            }
        }
        return mRootsChangedObservers.get(userId);
        return map.get(userId);
    }

    private class RootsChangedObserver extends ContentObserver {
@@ -179,15 +192,18 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName {
        // NOTE: This method is called when the UI language changes.
        // For that reason we update our RecentsRoot to reflect
        // the current language.
        mRecentsRoot.title = mContext.getString(R.string.root_recent);

        final String title = mContext.getString(R.string.root_recent);
        for (UserId userId : mUserIdManager.getUserIds()) {
            RootInfo recentRoot = createOrGetRecentsRoot(userId);
            recentRoot.title = title;
            // Nothing else about the root should ever change.
        assert(mRecentsRoot.authority == null);
        assert(mRecentsRoot.rootId == null);
        assert(mRecentsRoot.derivedIcon == R.drawable.ic_root_recent);
        assert(mRecentsRoot.derivedType == RootInfo.TYPE_RECENTS);
        assert(mRecentsRoot.flags == (Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD));
        assert(mRecentsRoot.availableBytes == -1);
            assert (recentRoot.authority == null);
            assert (recentRoot.rootId == null);
            assert (recentRoot.derivedIcon == R.drawable.ic_root_recent);
            assert (recentRoot.derivedType == RootInfo.TYPE_RECENTS);
            assert (recentRoot.flags == (Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD));
            assert (recentRoot.availableBytes == -1);
        }

        new UpdateTask(forceRefreshAll, null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }
@@ -311,7 +327,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName {
                // Watch for any future updates
                final Uri rootsUri = DocumentsContract.buildRootsUri(authority);
                resolver.registerContentObserver(rootsUri, true,
                        getRootsChangedObserver(userId));
                        createOrGetRootsChangedObserver(userId));
            }
        }

@@ -403,12 +419,12 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName {
    }

    @Override
    public RootInfo getRecentsRoot() {
        return mRecentsRoot;
    public RootInfo getRecentsRoot(UserId userId) {
        return createOrGetRecentsRoot(userId);
    }

    public boolean isRecentsRoot(RootInfo root) {
        return mRecentsRoot.equals(root);
        return mRecentsRoots.containsValue(root);
    }

    @Override
@@ -443,7 +459,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName {
    @Override
    public RootInfo getDefaultRootBlocking(State state) {
        RootInfo root = ProvidersAccess.getDefaultRoot(getRootsBlocking(), state);
        return root != null ? root : mRecentsRoot;
        return root != null ? root : createOrGetRecentsRoot(UserId.CURRENT_USER);
    }

    public void logCache() {
@@ -493,11 +509,11 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName {
        protected Void doInBackground(Void... params) {
            final long start = SystemClock.elapsedRealtime();

            mTaskRoots.put(new UserAuthority(mRecentsRoot.userId, mRecentsRoot.authority),
                    mRecentsRoot);
            for (UserId userId : mUserIdManager.getUserIds()) {
                final PackageManager pm = userId.getPackageManager(mContext);
                final RootInfo recents = createOrGetRecentsRoot(userId);
                mTaskRoots.put(new UserAuthority(recents.userId, recents.authority), recents);

                final PackageManager pm = userId.getPackageManager(mContext);
                // Pick up provider with action string
                final Intent intent = new Intent(DocumentsContract.PROVIDER_INTERFACE);
                final List<ResolveInfo> providers = pm.queryIntentContentProviders(intent, 0);
Loading