Merge "Add pick ActionHandler test." into nyc-andromeda-dev
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index f867a02..6b341b8 100644
--- a/src/com/android/documentsui/AbstractActionHandler.java
+++ b/src/com/android/documentsui/AbstractActionHandler.java
@@ -163,13 +163,13 @@
* from our concrete activity implementations.
*/
public interface CommonAddons {
- void refreshCurrentRootAndDirectory(@AnimationType int anim);
- void onRootPicked(RootInfo root);
- // TODO: Move this to PickAddons as multi-document picking is exclusive to that activity.
- void onDocumentsPicked(List<DocumentInfo> docs);
- void onDocumentPicked(DocumentInfo doc);
- void openContainerDocument(DocumentInfo doc);
- RootInfo getCurrentRoot();
- DocumentInfo getCurrentDirectory();
+ void refreshCurrentRootAndDirectory(@AnimationType int anim);
+ void onRootPicked(RootInfo root);
+ // TODO: Move this to PickAddons as multi-document picking is exclusive to that activity.
+ void onDocumentsPicked(List<DocumentInfo> docs);
+ void onDocumentPicked(DocumentInfo doc);
+ void openContainerDocument(DocumentInfo doc);
+ RootInfo getCurrentRoot();
+ DocumentInfo getCurrentDirectory();
}
}
diff --git a/src/com/android/documentsui/OnRootsChangedTask.java b/src/com/android/documentsui/OnRootsChangedTask.java
new file mode 100644
index 0000000..0776e8f
--- /dev/null
+++ b/src/com/android/documentsui/OnRootsChangedTask.java
@@ -0,0 +1,81 @@
+/*
+ * 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;
+
+import android.net.Uri;
+
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.PairedTask;
+import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.dirlist.AnimationView;
+
+import java.util.Collection;
+
+final class OnRootsChangedTask
+ extends PairedTask<BaseActivity, RootInfo, RootInfo> {
+ RootInfo mCurrentRoot;
+ DocumentInfo mDefaultRootDocument;
+
+ public OnRootsChangedTask(BaseActivity activity) {
+ super(activity);
+ }
+
+ @Override
+ protected RootInfo run(RootInfo... roots) {
+ assert(roots.length == 1);
+ mCurrentRoot = roots[0];
+ final Collection<RootInfo> cachedRoots = mOwner.mRoots.getRootsBlocking();
+ for (final RootInfo root : cachedRoots) {
+ if (root.getUri().equals(mCurrentRoot.getUri())) {
+ // We don't need to change the current root as the current root was not removed.
+ return null;
+ }
+ }
+
+ // Choose the default root.
+ final RootInfo defaultRoot = mOwner.mRoots.getDefaultRootBlocking(mOwner.mState);
+ assert(defaultRoot != null);
+ if (!defaultRoot.isRecents()) {
+ mDefaultRootDocument = defaultRoot.getRootDocumentBlocking(mOwner);
+ }
+ return defaultRoot;
+ }
+
+ @Override
+ protected void finish(RootInfo defaultRoot) {
+ if (defaultRoot == null) {
+ return;
+ }
+
+ // If the activity has been launched for the specific root and it is removed, finish the
+ // activity.
+ final Uri uri = mOwner.getIntent().getData();
+ if (uri != null && uri.equals(mCurrentRoot.getUri())) {
+ mOwner.finish();
+ return;
+ }
+
+ // Clear entire backstack and start in new root.
+ mOwner.mState.onRootChanged(defaultRoot);
+ mOwner.mSearchManager.update(defaultRoot);
+
+ if (defaultRoot.isRecents()) {
+ mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
+ } else {
+ mOwner.openContainerDocument(mDefaultRootDocument);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/base/RootInfo.java b/src/com/android/documentsui/base/RootInfo.java
index 2c32b9e..f84f915 100644
--- a/src/com/android/documentsui/base/RootInfo.java
+++ b/src/com/android/documentsui/base/RootInfo.java
@@ -35,9 +35,9 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.documentsui.DocumentsAccess;
import com.android.documentsui.IconUtils;
import com.android.documentsui.R;
-import com.android.documentsui.roots.RootsAccess;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -350,7 +350,7 @@
}
/**
- * @deprecate use {@link RootsAccess#getRootDocumentBlocking}.
+ * @deprecate use {@link DocumentsAccess#getRootDocumentBlocking}.
*/
@Deprecated
public @Nullable DocumentInfo getRootDocumentBlocking(Context context) {
diff --git a/src/com/android/documentsui/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index feb70d0..1214097 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -461,8 +461,6 @@
public void reset(Model model, MultiSelectManager selectionMgr) {
assert(model != null);
- // Allowed to be null in testing, for now.
- // assert(selectionMgr != null);
this.model = model;
this.selectionMgr = selectionMgr;
diff --git a/src/com/android/documentsui/files/QuickViewIntentBuilder.java b/src/com/android/documentsui/files/QuickViewIntentBuilder.java
index 995d280..b8d9fcb 100644
--- a/src/com/android/documentsui/files/QuickViewIntentBuilder.java
+++ b/src/com/android/documentsui/files/QuickViewIntentBuilder.java
@@ -49,9 +49,10 @@
public final class QuickViewIntentBuilder {
// trusted quick view package can be set via system property on debug builds.
- // Unfortunately when the value is set, it interferes with testing.
+ // Unfortunately when the value is set, it interferes with testing (supercedes
+ // any value set in the resource system).
// For that reason when trusted quick view package is set to this magic value
- // we won't the system property. It's a gross hack, but stuff's gotta get done.
+ // we won't honor the system property.
public static final String IGNORE_DEBUG_PROP = "*disabled*";
private static final String TAG = "QuickViewIntentBuilder";
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index 369b489..d5f7bbe 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -17,7 +17,6 @@
package com.android.documentsui.picker;
import static com.android.documentsui.base.Shared.DEBUG;
-import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;
import android.app.Activity;
import android.content.Intent;
@@ -33,6 +32,7 @@
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.Lookup;
import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.DocumentDetails;
import com.android.documentsui.dirlist.FragmentTuner;
@@ -83,7 +83,7 @@
// Concensus was that the experice was too confusing.
// In all other cases, where the user is visiting us from another app
// we restore the stack as last used from that app.
- if (mState.action == ACTION_PICK_COPY_DESTINATION) {
+ if (Shared.ACTION_PICK_COPY_DESTINATION.equals(intent.getAction())) {
if (DEBUG) Log.d(TAG, "Launching directly into Home directory.");
loadHomeDir();
} else {
@@ -155,7 +155,6 @@
public void reset(Model model, MultiSelectManager selectionMgr) {
assert(model != null);
- assert(selectionMgr != null);
this.model = model;
this.selectionMgr = selectionMgr;
diff --git a/src/com/android/documentsui/roots/RootsAccess.java b/src/com/android/documentsui/roots/RootsAccess.java
index ee5e522..6323840 100644
--- a/src/com/android/documentsui/roots/RootsAccess.java
+++ b/src/com/android/documentsui/roots/RootsAccess.java
@@ -42,6 +42,10 @@
Collection<RootInfo> getMatchingRootsBlocking(State state);
+ Collection<RootInfo> getRootsBlocking();
+
+ RootInfo getDefaultRootBlocking(State state);
+
/**
* Returns a list of roots for the specified authority. If not found, then
* an empty list is returned.
diff --git a/src/com/android/documentsui/roots/RootsCache.java b/src/com/android/documentsui/roots/RootsCache.java
index 2fda191..ea08b40 100644
--- a/src/com/android/documentsui/roots/RootsCache.java
+++ b/src/com/android/documentsui/roots/RootsCache.java
@@ -307,6 +307,7 @@
return mRecentsRoot.equals(root);
}
+ @Override
public Collection<RootInfo> getRootsBlocking() {
waitForFirstLoad();
loadStoppedAuthorities();
diff --git a/tests/common/com/android/documentsui/TestActivity.java b/tests/common/com/android/documentsui/TestActivity.java
index 3987636..7d73589 100644
--- a/tests/common/com/android/documentsui/TestActivity.java
+++ b/tests/common/com/android/documentsui/TestActivity.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.net.Uri;
import com.android.documentsui.AbstractActionHandler.CommonAddons;
import com.android.documentsui.base.DocumentInfo;
diff --git a/tests/common/com/android/documentsui/testing/TestRootsAccess.java b/tests/common/com/android/documentsui/testing/TestRootsAccess.java
index 5678cf3..734d521 100644
--- a/tests/common/com/android/documentsui/testing/TestRootsAccess.java
+++ b/tests/common/com/android/documentsui/testing/TestRootsAccess.java
@@ -102,4 +102,18 @@
public Collection<RootInfo> getRootsForAuthorityBlocking(String authority) {
return roots.get(authority);
}
+
+ @Override
+ public Collection<RootInfo> getRootsBlocking() {
+ List<RootInfo> result = new ArrayList<>();
+ for (Collection<RootInfo> vals : roots.values()) {
+ result.addAll(vals);
+ }
+ return result;
+ }
+
+ @Override
+ public RootInfo getDefaultRootBlocking(State state) {
+ return DOWNLOADS;
+ }
}
diff --git a/tests/common/com/android/documentsui/testing/android/TestResources.java b/tests/common/com/android/documentsui/testing/android/TestResources.java
index 246b4e8..c962e77 100644
--- a/tests/common/com/android/documentsui/testing/android/TestResources.java
+++ b/tests/common/com/android/documentsui/testing/android/TestResources.java
@@ -78,7 +78,8 @@
}
@NonNull
- public final String getString(@StringRes int id, Object... formatArgs) throws NotFoundException {
+ public final String getString(
+ @StringRes int id, Object... formatArgs) throws NotFoundException {
return getString(id);
}
}
diff --git a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
new file mode 100644
index 0000000..c7afff1
--- /dev/null
+++ b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.picker;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.R;
+import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+import com.android.documentsui.testing.TestEnv;
+import com.android.documentsui.testing.TestRootsAccess;
+import com.android.documentsui.ui.TestDialogController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class ActionHandlerTest {
+
+ private TestEnv mEnv;
+ private TestActivity mActivity;
+ private TestDialogController mDialogs;
+ private ActionHandler<TestActivity> mHandler;
+ private Selection mSelection;
+
+ @Before
+ public void setUp() {
+ mEnv = TestEnv.create();
+ mActivity = TestActivity.create();
+ mDialogs = new TestDialogController();
+ mEnv.roots.configurePm(mActivity.packageMgr);
+
+ mHandler = new ActionHandler<>(
+ mActivity,
+ mEnv.state,
+ mEnv.roots,
+ mEnv.docs,
+ mEnv::lookupExecutor,
+ null // tuner, not currently used.
+ );
+
+ mDialogs.confirmNext();
+
+ mSelection = new Selection();
+ mSelection.add("1");
+
+ mHandler.reset(mEnv.model, null);
+ }
+
+ @Test
+ public void testInitLocation_CopyDestination_DefaultsToDownloads() throws Exception {
+ mActivity.resources.bools.put(R.bool.productivity_device, false);
+
+ Intent intent = mActivity.getIntent();
+ intent.setAction(Shared.ACTION_PICK_COPY_DESTINATION);
+ mHandler.initLocation(mActivity.getIntent());
+ assertRootPicked(TestRootsAccess.DOWNLOADS.getUri());
+ }
+
+ @Test
+ public void testInitLocation_CopyDestination_DefaultsToHome() throws Exception {
+ mActivity.resources.bools.put(R.bool.productivity_device, true);
+
+ Intent intent = mActivity.getIntent();
+ intent.setAction(Shared.ACTION_PICK_COPY_DESTINATION);
+ mHandler.initLocation(intent);
+ assertRootPicked(TestRootsAccess.HOME.getUri());
+ }
+
+ private void assertRootPicked(Uri expectedUri) throws Exception {
+ mEnv.beforeAsserts();
+
+ mActivity.rootPicked.assertCalled();
+ RootInfo root = mActivity.rootPicked.getLastValue();
+ assertNotNull(root);
+ assertEquals(expectedUri, root.getUri());
+ }
+}
diff --git a/tests/unit/com/android/documentsui/picker/TestActivity.java b/tests/unit/com/android/documentsui/picker/TestActivity.java
new file mode 100644
index 0000000..056eb18
--- /dev/null
+++ b/tests/unit/com/android/documentsui/picker/TestActivity.java
@@ -0,0 +1,33 @@
+/*
+ * 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.picker;
+
+import org.mockito.Mockito;
+
+public abstract class TestActivity extends AbstractBase {
+
+ public static TestActivity create() {
+ TestActivity activity = Mockito.mock(TestActivity.class, Mockito.CALLS_REAL_METHODS);
+ activity.init();
+ return activity;
+ }
+}
+
+// Trick Mockito into finding our Addons methods correctly. W/o this
+// hack, Mockito thinks Addons methods are not implemented.
+abstract class AbstractBase extends com.android.documentsui.TestActivity
+ implements ActionHandler.Addons {}