Test location init with doc URI.
Make a more complete test environment.
Move GetRootDocumentTask to roots package.
Change-Id: Icb8f4c42c38c17aa97ec428ef9d46d76d2286fa7
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index 81463d8..59d4bb9 100644
--- a/src/com/android/documentsui/AbstractActionHandler.java
+++ b/src/com/android/documentsui/AbstractActionHandler.java
@@ -37,6 +37,7 @@
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
import com.android.documentsui.files.LauncherActivity;
+import com.android.documentsui.files.OpenUriForViewTask;
import com.android.documentsui.roots.LoadRootTask;
import com.android.documentsui.roots.RootsAccess;
import com.android.documentsui.sidebar.EjectRootTask;
@@ -53,21 +54,25 @@
protected final T mActivity;
protected final State mState;
protected final RootsAccess mRoots;
+ protected final DocumentsAccess mDocs;
protected final Lookup<String, Executor> mExecutors;
public AbstractActionHandler(
T activity,
State state,
RootsAccess roots,
+ DocumentsAccess docs,
Lookup<String, Executor> executors) {
assert(activity != null);
assert(state != null);
assert(roots != null);
+ assert(docs != null);
mActivity = activity;
mState = state;
mRoots = roots;
+ mDocs = docs;
mExecutors = executors;
}
@@ -138,9 +143,15 @@
}
@Override
+ public final void loadDocument(Uri uri) {
+ new OpenUriForViewTask<>(mActivity, mState, mRoots, mDocs, uri)
+ .executeOnExecutor(mExecutors.lookup(uri.getAuthority()));
+ }
+
+ @Override
public final void loadRoot(Uri uri) {
- new LoadRootTask<>(mActivity, mRoots, mState, uri).executeOnExecutor(
- mExecutors.lookup(uri.getAuthority()));
+ new LoadRootTask<>(mActivity, mRoots, mState, uri)
+ .executeOnExecutor(mExecutors.lookup(uri.getAuthority()));
}
protected final void loadHomeDir() {
@@ -152,10 +163,10 @@
* from our concrete activity implementations.
*/
public interface CommonAddons {
+ void refreshCurrentRootAndDirectory(@AnimationType int anim);
void onRootPicked(RootInfo root);
- // TODO: Move this to PickAddons.
+ // TODO: Move this to PickAddons as multi-document picking is exclusive to that activity.
void onDocumentsPicked(List<DocumentInfo> docs);
void onDocumentPicked(DocumentInfo doc, Model model);
- void refreshCurrentRootAndDirectory(@AnimationType int anim);
}
}
diff --git a/src/com/android/documentsui/ActionHandler.java b/src/com/android/documentsui/ActionHandler.java
index f4aa0ca..0c33f6c 100644
--- a/src/com/android/documentsui/ActionHandler.java
+++ b/src/com/android/documentsui/ActionHandler.java
@@ -52,6 +52,8 @@
void loadRoot(Uri uri);
+ void loadDocument(Uri uri);
+
void openInNewWindow(DocumentStack path);
void pasteIntoFolder(RootInfo root);
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index d9d6cf4..340cd6b 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -68,6 +68,7 @@
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.dirlist.MultiSelectManager;
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+import com.android.documentsui.roots.GetRootDocumentTask;
import com.android.documentsui.roots.RootsCache;
import com.android.documentsui.sidebar.RootsFragment;
import com.android.documentsui.sorting.SortController;
diff --git a/src/com/android/documentsui/DocumentsAccess.java b/src/com/android/documentsui/DocumentsAccess.java
new file mode 100644
index 0000000..cd9c4c9
--- /dev/null
+++ b/src/com/android/documentsui/DocumentsAccess.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.util.Log;
+
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.RootInfo;
+
+import java.io.FileNotFoundException;
+
+/**
+ * Provides synchronous access to {@link DocumentInfo} instances given some identifying information.
+ */
+public interface DocumentsAccess {
+
+ @Nullable DocumentInfo getRootDocument(RootInfo root);
+ @Nullable DocumentInfo getRootDocument(Uri uri);
+ @Nullable DocumentInfo getDocument(Uri uri);
+
+ public static DocumentsAccess create(Context context) {
+ return new RuntimeDocumentAccess(context);
+ }
+
+ public final class RuntimeDocumentAccess implements DocumentsAccess {
+
+ private static final String TAG = "DocumentAccess";
+
+ private final Context mContext;
+
+ private RuntimeDocumentAccess(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public @Nullable DocumentInfo getRootDocument(RootInfo root) {
+ return getRootDocument(
+ DocumentsContract.buildDocumentUri(root.authority, root.documentId));
+ }
+
+ @Override
+ public @Nullable DocumentInfo getRootDocument(Uri uri) {
+ try {
+ return DocumentInfo.fromUri(mContext.getContentResolver(), uri);
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "Failed to find root", e);
+ return null;
+ }
+ }
+
+ @Override
+ public DocumentInfo getDocument(Uri uri) {
+ try {
+ return DocumentInfo.fromUri(mContext.getContentResolver(), uri);
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "Couldn't create DocumentInfo for uri: " + uri);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/documentsui/base/RootInfo.java b/src/com/android/documentsui/base/RootInfo.java
index 1b4656a..2c32b9e 100644
--- a/src/com/android/documentsui/base/RootInfo.java
+++ b/src/com/android/documentsui/base/RootInfo.java
@@ -37,6 +37,7 @@
import com.android.documentsui.IconUtils;
import com.android.documentsui.R;
+import com.android.documentsui.roots.RootsAccess;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -349,8 +350,9 @@
}
/**
- * Gets the {@link DocumentInfo} of the root folder of this root.
+ * @deprecate use {@link RootsAccess#getRootDocumentBlocking}.
*/
+ @Deprecated
public @Nullable DocumentInfo getRootDocumentBlocking(Context context) {
try {
final Uri uri = DocumentsContract.buildDocumentUri(authority, documentId);
diff --git a/src/com/android/documentsui/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index d6c4f42..67b5a53 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -26,10 +26,9 @@
import android.util.Log;
import com.android.documentsui.AbstractActionHandler;
+import com.android.documentsui.DocumentsAccess;
import com.android.documentsui.DocumentsApplication;
-import com.android.documentsui.GetRootDocumentTask;
import com.android.documentsui.Metrics;
-import com.android.documentsui.ProviderExecutor;
import com.android.documentsui.base.ConfirmationCallback;
import com.android.documentsui.base.ConfirmationCallback.Result;
import com.android.documentsui.base.DocumentInfo;
@@ -47,6 +46,7 @@
import com.android.documentsui.dirlist.MultiSelectManager;
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
import com.android.documentsui.files.ActionHandler.Addons;
+import com.android.documentsui.roots.GetRootDocumentTask;
import com.android.documentsui.roots.RootsAccess;
import com.android.documentsui.services.FileOperation;
import com.android.documentsui.services.FileOperationService;
@@ -77,13 +77,14 @@
T activity,
State state,
RootsAccess roots,
+ DocumentsAccess docs,
Lookup<String, Executor> executors,
DialogController dialogs,
FragmentTuner tuner,
DocumentClipper clipper,
ClipStore clipStore) {
- super(activity, state, roots, executors);
+ super(activity, state, roots, docs, executors);
mDialogs = dialogs;
mTuner = tuner;
@@ -101,7 +102,7 @@
mActivity::isDestroyed,
(DocumentInfo doc) -> mClipper.copyFromClipData(
root, doc, data, mDialogs::showFileOperationFailures)
- ).executeOnExecutor(ProviderExecutor.forAuthority(root.authority));
+ ).executeOnExecutor(mExecutors.lookup(root.authority));
return true;
}
@@ -120,7 +121,7 @@
mActivity,
mActivity::isDestroyed,
(DocumentInfo doc) -> pasteIntoFolder(root, doc)
- ).executeOnExecutor(ProviderExecutor.forAuthority(root.authority));
+ ).executeOnExecutor(mExecutors.lookup(root.authority));
}
private void pasteIntoFolder(RootInfo root, DocumentInfo doc) {
@@ -174,6 +175,7 @@
assert(!selected.isEmpty());
final DocumentInfo srcParent = mState.stack.peek();
+ assert(srcParent != null);
// Model must be accessed in UI thread, since underlying cursor is not threadsafe.
List<DocumentInfo> docs = model.getDocuments(selected);
@@ -268,8 +270,7 @@
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri uri = intent.getData();
assert(uri != null);
- new OpenUriForViewTask<>(mActivity, mState).executeOnExecutor(
- ProviderExecutor.forAuthority(uri.getAuthority()), uri);
+ loadDocument(uri);
return true;
}
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 2d1ed94..0f497eb 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -36,6 +36,7 @@
import android.view.MenuItem;
import com.android.documentsui.BaseActivity;
+import com.android.documentsui.DocumentsAccess;
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.FocusManager;
import com.android.documentsui.MenuManager.DirectoryDetails;
@@ -104,6 +105,7 @@
this,
mState,
mRoots,
+ DocumentsAccess.create(this),
ProviderExecutor::forAuthority,
mDialogs,
mTuner,
diff --git a/src/com/android/documentsui/files/OpenUriForViewTask.java b/src/com/android/documentsui/files/OpenUriForViewTask.java
index f8424c1..2a830c5 100644
--- a/src/com/android/documentsui/files/OpenUriForViewTask.java
+++ b/src/com/android/documentsui/files/OpenUriForViewTask.java
@@ -20,7 +20,7 @@
import android.util.Log;
import com.android.documentsui.AbstractActionHandler.CommonAddons;
-import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.DocumentsAccess;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.PairedTask;
import com.android.documentsui.base.RootInfo;
@@ -28,44 +28,58 @@
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.roots.RootsAccess;
-import java.io.FileNotFoundException;
import java.util.Collection;
+import javax.annotation.Nullable;
+
/**
* Builds a stack for the specific Uris. Multi roots are not supported, as it's impossible
* to know which root to select. Also, the stack doesn't contain intermediate directories.
* It's primarly used for opening ZIP archives from Downloads app.
*/
-final class OpenUriForViewTask<T extends Activity & CommonAddons>
- extends PairedTask<T, Uri, Void> {
+public final class OpenUriForViewTask<T extends Activity & CommonAddons>
+ extends PairedTask<T, Void, Void> {
+ private static final String TAG = "OpenUriForViewTask";
+
+ private final T mActivity;
private final State mState;
- public OpenUriForViewTask(T activity, State state) {
+ private final RootsAccess mRoots;
+ private final DocumentsAccess mDocs;
+ private final Uri mUri;
+
+ public OpenUriForViewTask(
+ T activity, State state, RootsAccess roots, DocumentsAccess docs, Uri uri) {
super(activity);
+ mActivity = activity;
mState = state;
+ mRoots = roots;
+ mDocs = docs;
+ mUri = uri;
}
@Override
- public Void run(Uri... params) {
- final Uri uri = params[0];
+ public Void run(Void... params) {
- final RootsAccess rootsCache = DocumentsApplication.getRootsCache(mOwner);
- final String authority = uri.getAuthority();
+ final String authority = mUri.getAuthority();
+ final Collection<RootInfo> roots = mRoots.getRootsForAuthorityBlocking(authority);
- final Collection<RootInfo> roots =
- rootsCache.getRootsForAuthorityBlocking(authority);
if (roots.isEmpty()) {
- Log.e(FilesActivity.TAG, "Failed to find root for the requested Uri: " + uri);
+ Log.e(TAG, "Failed to find root for the requested Uri: " + mUri);
return null;
}
+ assert(mState.stack.isEmpty());
+
+ // NOTE: There's no guarantee that this root will be the correct root for the doc.
final RootInfo root = roots.iterator().next();
mState.stack.root = root;
- mState.stack.add(root.getRootDocumentBlocking(mOwner));
- try {
- mState.stack.add(DocumentInfo.fromUri(mOwner.getContentResolver(), uri));
- } catch (FileNotFoundException e) {
- Log.e(FilesActivity.TAG, "Failed to resolve DocumentInfo from Uri: " + uri);
+ mState.stack.add(mDocs.getRootDocument(root));
+ @Nullable DocumentInfo doc = mDocs.getDocument(mUri);
+ if (doc == null) {
+ Log.e(TAG, "Failed to resolve DocumentInfo from Uri: " + mUri);
+ } else {
+ mState.stack.add(doc);
}
return null;
@@ -73,6 +87,6 @@
@Override
public void finish(Void result) {
- mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
+ mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index 59d0b48..cec1397 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -27,6 +27,7 @@
import android.util.Log;
import com.android.documentsui.AbstractActionHandler;
+import com.android.documentsui.DocumentsAccess;
import com.android.documentsui.Metrics;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
@@ -58,10 +59,11 @@
T activity,
State state,
RootsAccess roots,
+ DocumentsAccess docs,
Lookup<String, Executor> executors,
FragmentTuner tuner) {
- super(activity, state, roots, executors);
+ super(activity, state, roots, docs, executors);
mTuner = tuner;
mConfig = new Config();
diff --git a/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java b/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
index 3dadca4..bb22e08 100644
--- a/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
+++ b/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
@@ -106,4 +106,4 @@
mState.external = mExternal;
mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java
index 1f2f69f..d1b1ec1 100644
--- a/src/com/android/documentsui/picker/PickActivity.java
+++ b/src/com/android/documentsui/picker/PickActivity.java
@@ -43,6 +43,7 @@
import android.view.Menu;
import com.android.documentsui.BaseActivity;
+import com.android.documentsui.DocumentsAccess;
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.FocusManager;
import com.android.documentsui.MenuManager.DirectoryDetails;
@@ -91,6 +92,7 @@
this,
mState,
DocumentsApplication.getRootsCache(this),
+ DocumentsAccess.create(this),
ProviderExecutor::forAuthority,
mTuner);
diff --git a/src/com/android/documentsui/GetRootDocumentTask.java b/src/com/android/documentsui/roots/GetRootDocumentTask.java
similarity index 96%
rename from src/com/android/documentsui/GetRootDocumentTask.java
rename to src/com/android/documentsui/roots/GetRootDocumentTask.java
index e56b110..1503ae1 100644
--- a/src/com/android/documentsui/GetRootDocumentTask.java
+++ b/src/com/android/documentsui/roots/GetRootDocumentTask.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.documentsui;
+package com.android.documentsui.roots;
import android.annotation.Nullable;
import android.app.Activity;
@@ -22,6 +22,7 @@
import android.content.Context;
import android.util.Log;
+import com.android.documentsui.TimeoutTask;
import com.android.documentsui.base.CheckedTask;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.RootInfo;
diff --git a/src/com/android/documentsui/sidebar/RootsFragment.java b/src/com/android/documentsui/sidebar/RootsFragment.java
index 1174503..a250a8d 100644
--- a/src/com/android/documentsui/sidebar/RootsFragment.java
+++ b/src/com/android/documentsui/sidebar/RootsFragment.java
@@ -49,7 +49,6 @@
import com.android.documentsui.ActionHandler;
import com.android.documentsui.BaseActivity;
import com.android.documentsui.DocumentsApplication;
-import com.android.documentsui.GetRootDocumentTask;
import com.android.documentsui.ItemDragListener;
import com.android.documentsui.R;
import com.android.documentsui.base.BooleanConsumer;
@@ -59,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.roots.GetRootDocumentTask;
import com.android.documentsui.roots.RootsCache;
import com.android.documentsui.roots.RootsLoader;
diff --git a/tests/common/com/android/documentsui/TestActivity.java b/tests/common/com/android/documentsui/TestActivity.java
index 4cca190..9f32a76 100644
--- a/tests/common/com/android/documentsui/TestActivity.java
+++ b/tests/common/com/android/documentsui/TestActivity.java
@@ -43,6 +43,7 @@
public TestEventListener<Intent> startActivity;
public TestEventListener<Intent> startService;
public TestEventListener<RootInfo> rootPicked;
+ public TestEventListener<Integer> refreshCurrentRootAndDirectory;
public static TestActivity create() {
TestActivity activity = Mockito.mock(TestActivity.class, Mockito.CALLS_REAL_METHODS);
@@ -58,6 +59,7 @@
startActivity = new TestEventListener<>();
startService = new TestEventListener<>();
rootPicked = new TestEventListener<>();
+ refreshCurrentRootAndDirectory = new TestEventListener<>();
}
@Override
@@ -95,6 +97,11 @@
public final void onRootPicked(RootInfo root) {
rootPicked.accept(root);
}
+
+ @Override
+ public final void refreshCurrentRootAndDirectory(int anim) {
+ refreshCurrentRootAndDirectory.accept(anim);
+ }
}
// Trick Mockito into finding our Addons methods correctly. W/o this
diff --git a/tests/common/com/android/documentsui/dirlist/TestModel.java b/tests/common/com/android/documentsui/dirlist/TestModel.java
index 1204400..7f62ac7 100644
--- a/tests/common/com/android/documentsui/dirlist/TestModel.java
+++ b/tests/common/com/android/documentsui/dirlist/TestModel.java
@@ -17,11 +17,14 @@
package com.android.documentsui.dirlist;
import android.database.MatrixCursor;
+import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import com.android.documentsui.DirectoryResult;
import com.android.documentsui.roots.RootCursorWrapper;
+import libcore.net.MimeUtils;
+
import java.util.Random;
public class TestModel extends Model {
@@ -36,33 +39,75 @@
};
private final String mAuthority;
+ private int mLastId = 0;
+ private Random mRand = new Random();
+ private MatrixCursor mCursor;
public TestModel(String authority) {
super();
mAuthority = authority;
+ reset();
}
- public void update(String... names) {
- Random rand = new Random();
+ public void reset() {
+ mLastId = 0;
+ mCursor = new MatrixCursor(COLUMNS);
+ }
- MatrixCursor c = new MatrixCursor(COLUMNS);
+ public void update() {
+ DirectoryResult r = new DirectoryResult();
+ r.cursor = mCursor;
+ super.update(r);
+ }
+
+ public void createFolders(String... names) {
for (int i = 0; i < names.length; i++) {
- MatrixCursor.RowBuilder row = c.newRow();
- row.add(RootCursorWrapper.COLUMN_AUTHORITY, mAuthority);
- row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
- row.add(Document.COLUMN_FLAGS, Document.FLAG_SUPPORTS_DELETE);
- // Generate random document names and sizes. This forces the model's internal sort code
- // to actually do something.
- row.add(Document.COLUMN_DISPLAY_NAME, names[i]);
- row.add(Document.COLUMN_SIZE, rand.nextInt());
+ createFolder(i, names[i]);
+ }
+ }
+
+ public void createFiles(String... names) {
+ for (int i = 0; i < names.length; i++) {
+ create(++mLastId, names[i], guessMimeType(names[i]));
+ }
+ }
+
+ private void createFolder(int i, String name) {
+ create(
+ ++mLastId,
+ name,
+ DocumentsContract.Document.MIME_TYPE_DIR,
+ Document.FLAG_SUPPORTS_DELETE
+ | Document.FLAG_SUPPORTS_WRITE
+ | Document.FLAG_DIR_SUPPORTS_CREATE);
+ }
+
+ private void create(int id, String name, String mimeType) {
+ create(id, name, mimeType, Document.FLAG_SUPPORTS_DELETE);
+ }
+
+ public void create(int id, String name, String mimeType, int flags) {
+ MatrixCursor.RowBuilder row = mCursor.newRow();
+ row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(id));
+ row.add(RootCursorWrapper.COLUMN_AUTHORITY, mAuthority);
+ row.add(Document.COLUMN_DISPLAY_NAME, name);
+ row.add(Document.COLUMN_MIME_TYPE, mimeType);
+ row.add(Document.COLUMN_FLAGS, flags);
+ row.add(Document.COLUMN_SIZE, mRand.nextInt());
+ }
+
+ private static String guessMimeType(String name) {
+ int i = name.indexOf('.');
+
+ while(i != -1) {
+ name = name.substring(i + 1);
+ String type = MimeUtils.guessMimeTypeFromExtension(name);
+ if (type != null) {
+ return type;
+ }
+ i = name.indexOf('.');
}
- DirectoryResult r = new DirectoryResult();
- r.cursor = c;
- update(r);
- }
-
- String idForPosition(int p) {
- return Integer.toString(p);
+ return "text/plain";
}
}
diff --git a/tests/common/com/android/documentsui/testing/TestActionHandler.java b/tests/common/com/android/documentsui/testing/TestActionHandler.java
index 4581a5c..08bee36 100644
--- a/tests/common/com/android/documentsui/testing/TestActionHandler.java
+++ b/tests/common/com/android/documentsui/testing/TestActionHandler.java
@@ -34,7 +34,7 @@
}
public TestActionHandler(TestEnv env) {
- super(TestActivity.create(), env.state, env.roots, (String authority) -> null);
+ super(TestActivity.create(), env.state, env.roots, env.docs, (String authority) -> null);
}
@Override
diff --git a/tests/common/com/android/documentsui/testing/TestDocumentsAccess.java b/tests/common/com/android/documentsui/testing/TestDocumentsAccess.java
new file mode 100644
index 0000000..40f799e
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/TestDocumentsAccess.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.documentsui.testing;
+
+import android.net.Uri;
+
+import com.android.documentsui.DocumentsAccess;
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.RootInfo;
+
+import javax.annotation.Nullable;
+
+public class TestDocumentsAccess implements DocumentsAccess {
+
+ public @Nullable DocumentInfo nextRootDocument;
+ public @Nullable DocumentInfo nextDocument;
+
+ @Override
+ public DocumentInfo getRootDocument(Uri uri) {
+ return nextRootDocument;
+ }
+
+ @Override
+ public DocumentInfo getRootDocument(RootInfo root) {
+ return nextRootDocument;
+ }
+
+ @Override
+ public DocumentInfo getDocument(Uri uri) {
+ return nextDocument;
+ }
+}
diff --git a/tests/common/com/android/documentsui/testing/TestEnv.java b/tests/common/com/android/documentsui/testing/TestEnv.java
index f898e6b..b9e5fdf 100644
--- a/tests/common/com/android/documentsui/testing/TestEnv.java
+++ b/tests/common/com/android/documentsui/testing/TestEnv.java
@@ -18,34 +18,72 @@
import android.os.Handler;
import android.os.Looper;
+import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.TestModel;
+import junit.framework.Assert;
+
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
public class TestEnv {
- public static final String AUTHORITY = "hullabaloo";
+ public static final String[] FOLDERS = {
+ "My Root Doc",
+ "Things",
+ "Others"
+ };
+
+ public static final String[] FILES = {
+ "abc.txt",
+ "def.png",
+ "ghi.jpg",
+ "jkl.gif",
+ "mno.psd",
+ "pqr.tiff",
+ "stu.nef",
+ "vwx.tar.gz",
+ "yx.012"
+ };
public final TestScheduledExecutorService mExecutor;
public final State state = new State();
public final TestRootsAccess roots = new TestRootsAccess();
- public final TestModel model = new TestModel(AUTHORITY);
+ public final TestDocumentsAccess docs = new TestDocumentsAccess();
+ public final TestModel model;
- private TestEnv() {
+ private TestEnv(String authority) {
mExecutor = new TestScheduledExecutorService();
+ model = new TestModel(authority);
}
public static TestEnv create() {
- TestEnv env = new TestEnv();
+ return create(TestRootsAccess.HOME.authority);
+ }
+
+ public static TestEnv create(String authority) {
+ TestEnv env = new TestEnv(authority);
env.reset();
return env;
}
+ public void clear() {
+ model.reset();
+ model.update();
+ }
+
public void reset() {
- model.update("a", "b", "c", "x", "y", "z");
- state.stack.push(model.getDocument("1"));
+ model.reset();
+ model.createFolders(FOLDERS);
+ model.createFiles(FILES);
+
+ model.update();
+
+ DocumentInfo rootDoc = model.getDocument("1");
+ Assert.assertNotNull(rootDoc);
+ Assert.assertEquals(rootDoc.displayName, FOLDERS[0]);
+ state.stack.push(rootDoc);
}
public void beforeAsserts() throws Exception {
diff --git a/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java b/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
index ee9ee4d..d924a44 100644
--- a/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
@@ -54,6 +54,7 @@
mActivity,
mEnv.state,
mEnv.roots,
+ mEnv.docs,
mEnv::lookupExecutor) {
@Override
diff --git a/tests/unit/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java b/tests/unit/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
index 1208f03..8424249 100644
--- a/tests/unit/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
@@ -18,36 +18,24 @@
import android.content.Context;
import android.database.Cursor;
+import android.support.test.filters.SmallTest;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
import com.android.documentsui.base.State;
+import com.android.documentsui.testing.TestEnv;
@SmallTest
public class ModelBackedDocumentsAdapterTest extends AndroidTestCase {
private static final String AUTHORITY = "test_authority";
- private static final String[] NAMES = new String[] {
- "4",
- "foo",
- "1",
- "bar",
- "*(Ljifl;a",
- "0",
- "baz",
- "2",
- "3",
- "%$%VD"
- };
- private TestModel mModel;
+ private TestEnv mEnv;
private ModelBackedDocumentsAdapter mAdapter;
public void setUp() {
final Context testContext = TestContext.createStorageTestContext(getContext(), AUTHORITY);
- mModel = new TestModel(AUTHORITY);
- mModel.update(NAMES);
+ mEnv = TestEnv.create(AUTHORITY);
DocumentsAdapter.Environment env = new TestEnvironment(testContext);
@@ -58,7 +46,7 @@
// Tests that the item count is correct.
public void testItemCount() {
- assertEquals(mModel.getItemCount(), mAdapter.getItemCount());
+ assertEquals(mEnv.model.getItemCount(), mAdapter.getItemCount());
}
private final class TestEnvironment implements DocumentsAdapter.Environment {
@@ -83,7 +71,7 @@
@Override
public Model getModel() {
- return mModel;
+ return mEnv.model;
}
@Override
diff --git a/tests/unit/com/android/documentsui/dirlist/ModelTest.java b/tests/unit/com/android/documentsui/dirlist/ModelTest.java
index faad880..75f46e4 100644
--- a/tests/unit/com/android/documentsui/dirlist/ModelTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/ModelTest.java
@@ -22,9 +22,9 @@
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.provider.DocumentsContract.Document;
+import android.support.test.filters.SmallTest;
import android.test.AndroidTestCase;
import android.test.mock.MockContentResolver;
-import android.test.suitebuilder.annotation.SmallTest;
import com.android.documentsui.DirectoryResult;
import com.android.documentsui.base.DocumentInfo;
diff --git a/tests/unit/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java b/tests/unit/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
index d44a467..f79aa35 100644
--- a/tests/unit/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
@@ -18,93 +18,57 @@
import android.content.Context;
import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.provider.DocumentsContract.Document;
+import android.support.test.filters.SmallTest;
import android.support.v7.widget.RecyclerView;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
import android.view.ViewGroup;
-import com.android.documentsui.DirectoryResult;
import com.android.documentsui.base.State;
-import com.android.documentsui.roots.RootCursorWrapper;
-import com.android.documentsui.testing.SortModels;
+import com.android.documentsui.testing.TestEnv;
@SmallTest
public class SectionBreakDocumentsAdapterWrapperTest extends AndroidTestCase {
private static final String AUTHORITY = "test_authority";
- private static final String[] NAMES = new String[] {
- "4",
- "foo",
- "1",
- "bar",
- "*(Ljifl;a",
- "0",
- "baz",
- "2",
- "3",
- "%$%VD"
- };
- private TestModel mModel;
+ private TestEnv mEnv;
private SectionBreakDocumentsAdapterWrapper mAdapter;
public void setUp() {
+ mEnv = TestEnv.create(AUTHORITY);
+ mEnv.clear();
+
final Context testContext = TestContext.createStorageTestContext(getContext(), AUTHORITY);
DocumentsAdapter.Environment env = new TestEnvironment(testContext);
- mModel = new TestModel(AUTHORITY);
mAdapter = new SectionBreakDocumentsAdapterWrapper(
env,
new ModelBackedDocumentsAdapter(
- env, new IconHelper(testContext, State.MODE_GRID)));
+ env, new IconHelper(testContext, State.MODE_GRID)));
- mModel.addUpdateListener(mAdapter.getModelUpdateListener());
- }
-
- // Tests that the item count is correct for a directory containing only subdirs.
- public void testItemCount_allDirs() {
- MatrixCursor c = new MatrixCursor(TestModel.COLUMNS);
-
- for (int i = 0; i < 5; ++i) {
- MatrixCursor.RowBuilder row = c.newRow();
- row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
- row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
- row.add(Document.COLUMN_SIZE, i);
- row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
- }
- DirectoryResult r = new DirectoryResult();
- r.cursor = c;
- mModel.update(r);
-
- assertEquals(mModel.getItemCount(), mAdapter.getItemCount());
- }
-
- // Tests that the item count is correct for a directory containing only files.
- public void testItemCount_allFiles() {
- mModel.update(NAMES);
- assertEquals(mModel.getItemCount(), mAdapter.getItemCount());
+ mEnv.model.addUpdateListener(mAdapter.getModelUpdateListener());
}
// Tests that the item count is correct for a directory containing files and subdirs.
public void testItemCount_mixed() {
- MatrixCursor c = new MatrixCursor(TestModel.COLUMNS);
+ mEnv.reset(); // creates a mix of folders and files for us.
- for (int i = 0; i < 5; ++i) {
- MatrixCursor.RowBuilder row = c.newRow();
- row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
- row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
- row.add(Document.COLUMN_SIZE, i);
- String mimeType =(i < 2) ? Document.MIME_TYPE_DIR : "text/*";
- row.add(Document.COLUMN_MIME_TYPE, mimeType);
- }
- DirectoryResult r = new DirectoryResult();
- r.cursor = c;
- mModel.update(r);
+ assertEquals(mEnv.model.getItemCount() + 1, mAdapter.getItemCount());
+ }
- assertEquals(mModel.getItemCount() + 1, mAdapter.getItemCount());
+ // Tests that the item count is correct for a directory containing only subdirs.
+ public void testItemCount_allDirs() {
+ mEnv.model.createFolders("Trader Joe's", "Alphabeta", "Lucky", "Vons", "Gelson's");
+ mEnv.model.update();
+ assertEquals(mEnv.model.getItemCount(), mAdapter.getItemCount());
+ }
+
+ // Tests that the item count is correct for a directory containing only files.
+ public void testItemCount_allFiles() {
+ mEnv.model.createFiles("123.txt", "234.jpg", "abc.pdf");
+ mEnv.model.update();
+ assertEquals(mEnv.model.getItemCount(), mAdapter.getItemCount());
}
private final class TestEnvironment implements DocumentsAdapter.Environment {
@@ -129,7 +93,7 @@
@Override
public Model getModel() {
- return mModel;
+ return mEnv.model;
}
@Override
diff --git a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
index ada1b5f..ee8aafc 100644
--- a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
@@ -26,6 +26,7 @@
import android.support.test.runner.AndroidJUnit4;
import com.android.documentsui.R;
+import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
import com.android.documentsui.testing.TestConfirmationCallback;
@@ -60,6 +61,7 @@
mActivity,
mEnv.state,
mEnv.roots,
+ mEnv.docs,
mEnv::lookupExecutor,
mDialogs,
null, // tuner, not currently used.
@@ -107,19 +109,41 @@
}
@Test
- public void testInitLocation_LoadsFromRootUri() throws Exception {
- mActivity.resources.bools.put(R.bool.productivity_device, true);
+ public void testInitLocation_ViewDocument() throws Exception {
+ Intent intent = mActivity.getIntent();
+ intent.setAction(Intent.ACTION_VIEW);
+ DocumentInfo destDoc = mEnv.model.getDocument("2");
+
+ // configure DocumentsAccess to return something.
+ mEnv.docs.nextRootDocument = mEnv.model.getDocument("1");
+ mEnv.docs.nextDocument = destDoc;
+
+ Uri destUri = mEnv.model.getItemUri(destDoc.documentId);
+ intent.setData(destUri);
+
+ mEnv.state.stack.clear(); // Stack must be clear, we've even got an assert!
+ mHandler.initLocation(intent);
+ assertDocumentPicked(destUri);
+ }
+
+ private void assertDocumentPicked(Uri expectedUri) throws Exception {
+ mEnv.beforeAsserts();
+
+ mActivity.refreshCurrentRootAndDirectory.assertCalled();
+ DocumentInfo doc = mEnv.state.stack.peekLast();
+ Uri actualUri = mEnv.model.getItemUri(doc.documentId);
+ assertEquals(expectedUri, actualUri);
+ }
+
+ @Test
+ public void testInitLocation_BrowseRoot() throws Exception {
Intent intent = mActivity.getIntent();
intent.setAction(DocumentsContract.ACTION_BROWSE);
intent.setData(TestRootsAccess.PICKLES.getUri());
mHandler.initLocation(intent);
- assertRootPicked(TestRootsAccess.PICKLES);
- }
-
- private void assertRootPicked(RootInfo root) throws Exception {
- assertRootPicked(root.getUri());
+ assertRootPicked(TestRootsAccess.PICKLES.getUri());
}
private void assertRootPicked(Uri expectedUri) throws Exception {