diff options
author | 2020-02-14 17:08:25 +0000 | |
---|---|---|
committer | 2020-02-14 17:08:25 +0000 | |
commit | 28fb87ee2f4b71e3bab308d37d9975630f60263b (patch) | |
tree | 14ea255c32058bb11ac1d6b1fff83fa86382379a | |
parent | f14d37518e612e1d3952c9fbfe652f0c497196b4 (diff) | |
parent | a94d06528eec4a6e36dbc308d26274353823e7e9 (diff) |
Merge "Add recents root from different user to ProvidersCache's mTaskRoots"
7 files changed, 85 insertions, 37 deletions
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java index cced342e0..bee4aac5a 100644 --- a/src/com/android/documentsui/AbstractActionHandler.java +++ b/src/com/android/documentsui/AbstractActionHandler.java @@ -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); } @@ -846,12 +846,13 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA if (DEBUG) { Log.d(TAG, "Creating new loader recents."); } - loader = new RecentsLoader( + loader = new RecentsLoader( context, mProviders, mState, mExecutors, - mInjector.fileTypeLookup); + mInjector.fileTypeLookup, + mState.stack.getRoot().userId); } loader.setObserver(observer); return loader; diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java index afa141317..c5726d9eb 100644 --- a/src/com/android/documentsui/BaseActivity.java +++ b/src/com/android/documentsui/BaseActivity.java @@ -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); } } diff --git a/src/com/android/documentsui/RecentsLoader.java b/src/com/android/documentsui/RecentsLoader.java index 45864ce98..c8472cf3a 100644 --- a/src/com/android/documentsui/RecentsLoader.java +++ b/src/com/android/documentsui/RecentsLoader.java @@ -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 diff --git a/src/com/android/documentsui/roots/ProvidersAccess.java b/src/com/android/documentsui/roots/ProvidersAccess.java index d4d31a68c..dfb7b5da6 100644 --- a/src/com/android/documentsui/roots/ProvidersAccess.java +++ b/src/com/android/documentsui/roots/ProvidersAccess.java @@ -53,7 +53,7 @@ public interface ProvidersAccess { RootInfo getDefaultRootBlocking(State state); - RootInfo getRecentsRoot(); + RootInfo getRecentsRoot(UserId userId); String getApplicationName(UserId userId, String authority); diff --git a/src/com/android/documentsui/roots/ProvidersCache.java b/src/com/android/documentsui/roots/ProvidersCache.java index b474d3473..e9ebe91f9 100644 --- a/src/com/android/documentsui/roots/ProvidersCache.java +++ b/src/com/android/documentsui/roots/ProvidersCache.java @@ -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); - - // 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); + 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 (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); diff --git a/tests/common/com/android/documentsui/testing/TestProvidersAccess.java b/tests/common/com/android/documentsui/testing/TestProvidersAccess.java index 859e1615e..2ebbae0e5 100644 --- a/tests/common/com/android/documentsui/testing/TestProvidersAccess.java +++ b/tests/common/com/android/documentsui/testing/TestProvidersAccess.java @@ -47,7 +47,6 @@ public class TestProvidersAccess implements ProvidersAccess { public static final RootInfo EXTERNALSTORAGE; public static final RootInfo NO_TREE_ROOT; - static { UserId userId = UserId.DEFAULT_USER; @@ -154,6 +153,26 @@ public class TestProvidersAccess implements ProvidersAccess { NO_TREE_ROOT.flags = Root.FLAG_LOCAL_ONLY; } + public static class OtherUser { + public static final UserId USER_ID = UserId.of(UserId.DEFAULT_USER.getIdentifier() + 1); + + public static final RootInfo DOWNLOADS; + + static { + UserId userId = OtherUser.USER_ID; + + DOWNLOADS = new RootInfo(); + DOWNLOADS.userId = userId; + DOWNLOADS.authority = Providers.AUTHORITY_DOWNLOADS; + DOWNLOADS.rootId = Providers.ROOT_ID_DOWNLOADS; + DOWNLOADS.title = "Downloads"; + DOWNLOADS.derivedType = RootInfo.TYPE_DOWNLOADS; + DOWNLOADS.flags = Root.FLAG_LOCAL_ONLY + | Root.FLAG_SUPPORTS_CREATE + | Root.FLAG_SUPPORTS_RECENTS; + } + } + public final Map<String, Collection<RootInfo>> roots = new HashMap<>(); private @Nullable RootInfo nextRoot; @@ -222,7 +241,7 @@ public class TestProvidersAccess implements ProvidersAccess { } @Override - public RootInfo getRecentsRoot() { + public RootInfo getRecentsRoot(UserId userId) { return RECENTS; } diff --git a/tests/unit/com/android/documentsui/RecentsLoaderTests.java b/tests/unit/com/android/documentsui/RecentsLoaderTests.java index 73ba36f3c..85ab7429f 100644 --- a/tests/unit/com/android/documentsui/RecentsLoaderTests.java +++ b/tests/unit/com/android/documentsui/RecentsLoaderTests.java @@ -28,6 +28,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.State; +import com.android.documentsui.base.UserId; import com.android.documentsui.testing.ActivityManagers; import com.android.documentsui.testing.TestCursor; import com.android.documentsui.testing.TestEnv; @@ -61,7 +62,8 @@ public class RecentsLoaderTests { mEnv.state.acceptMimes = new String[] { "*/*" }; mLoader = new RecentsLoader(mActivity, mEnv.providers, mEnv.state, - TestImmediateExecutor.createLookup(), new TestFileTypeLookup()); + TestImmediateExecutor.createLookup(), new TestFileTypeLookup(), + UserId.DEFAULT_USER); } @Test @@ -75,6 +77,11 @@ public class RecentsLoaderTests { } @Test + public void testLocalOnlyRoot_supportRecent_differentUser_beIgnored() { + assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.OtherUser.DOWNLOADS)); + } + + @Test public void testDocumentsNotIncludeDirectory() { final DocumentInfo doc = mEnv.model.createFolder("test"); doc.lastModified = System.currentTimeMillis(); |