summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kelvin Kwan <kelvinkwan@google.com> 2020-02-14 17:08:25 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-02-14 17:08:25 +0000
commit28fb87ee2f4b71e3bab308d37d9975630f60263b (patch)
tree14ea255c32058bb11ac1d6b1fff83fa86382379a
parentf14d37518e612e1d3952c9fbfe652f0c497196b4 (diff)
parenta94d06528eec4a6e36dbc308d26274353823e7e9 (diff)
Merge "Add recents root from different user to ProvidersCache's mTaskRoots"
-rw-r--r--src/com/android/documentsui/AbstractActionHandler.java7
-rw-r--r--src/com/android/documentsui/BaseActivity.java3
-rw-r--r--src/com/android/documentsui/RecentsLoader.java10
-rw-r--r--src/com/android/documentsui/roots/ProvidersAccess.java2
-rw-r--r--src/com/android/documentsui/roots/ProvidersCache.java68
-rw-r--r--tests/common/com/android/documentsui/testing/TestProvidersAccess.java23
-rw-r--r--tests/unit/com/android/documentsui/RecentsLoaderTests.java9
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();