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;