Loading tests/common/com/android/documentsui/DocumentsProviderHelper.java +15 −2 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ public class DocumentsProviderHelper { } public void assertChildCount(String parentId, int expected) throws Exception { List<DocumentInfo> children = listChildren(parentId); List<DocumentInfo> children = listChildren(parentId, -1); assertEquals("Incorrect file count after copy", expected, children.size()); } Loading Loading @@ -264,10 +264,19 @@ public class DocumentsProviderHelper { } public List<DocumentInfo> listChildren(String documentId) throws Exception { return listChildren(documentId, 100); } public List<DocumentInfo> listChildren(Uri parentUri, int maxCount) throws Exception { String id = DocumentsContract.getDocumentId(parentUri); return listChildren(id, maxCount); } public List<DocumentInfo> listChildren(String documentId, int maxCount) throws Exception { Uri uri = buildChildDocumentsUri(mAuthority, documentId); List<DocumentInfo> children = new ArrayList<>(); try (Cursor cursor = mClient.query(uri, null, null, null, null, null)) { Cursor wrapper = new RootCursorWrapper(mAuthority, "totally-fake", cursor, 100); Cursor wrapper = new RootCursorWrapper(mAuthority, "totally-fake", cursor, maxCount); while (wrapper.moveToNext()) { children.add(DocumentInfo.fromDirectoryCursor(wrapper)); } Loading Loading @@ -314,4 +323,8 @@ public class DocumentsProviderHelper { extra.putLong(DocumentsContract.EXTRA_LOADING, duration); mClient.call("setLoadingDuration", null, extra); } public void configure(String args, Bundle configuration) throws RemoteException { mClient.call("configure", args, configuration); } } tests/common/com/android/documentsui/StubProvider.java +10 −4 Original line number Diff line number Diff line Loading @@ -65,6 +65,8 @@ public class StubProvider extends DocumentsProvider { public static final String EXTRA_STREAM_TYPES = "com.android.documentsui.stubprovider.STREAM_TYPES"; public static final String EXTRA_CONTENT = "com.android.documentsui.stubprovider.CONTENT"; public static final String EXTRA_ENABLE_ROOT_NOTIFICATION = "com.android.documentsui.stubprovider.ROOT_NOTIFICATION"; public static final String EXTRA_FLAGS = "com.android.documentsui.stubprovider.FLAGS"; public static final String EXTRA_PARENT_ID = "com.android.documentsui.stubprovider.PARENT"; Loading @@ -91,6 +93,7 @@ public class StubProvider extends DocumentsProvider { private SharedPreferences mPrefs; private Set<String> mSimulateReadErrorIds = new HashSet<>(); private long mLoadingDuration = 0; private boolean mRootNotification = true; @Override public void attachInfo(Context context, ProviderInfo info) { Loading Loading @@ -630,16 +633,19 @@ public class StubProvider extends DocumentsProvider { private void configure(String arg, Bundle extras) { Log.d(TAG, "Configure " + arg); String rootName = extras.getString(EXTRA_ROOT, ROOT_0_ID); long rootSize = extras.getLong(EXTRA_SIZE, 1) * 1024 * 1024; long rootSize = extras.getLong(EXTRA_SIZE, 100) * 1024 * 1024; setSize(rootName, rootSize); mRootNotification = extras.getBoolean(EXTRA_ENABLE_ROOT_NOTIFICATION, true); } private void notifyParentChanged(String parentId) { getContext().getContentResolver().notifyChange( DocumentsContract.buildChildDocumentsUri(mAuthority, parentId), null, false); if (mRootNotification) { // Notify also about possible change in remaining space on the root. getContext().getContentResolver().notifyChange(DocumentsContract.buildRootsUri(mAuthority), null, false); getContext().getContentResolver().notifyChange( DocumentsContract.buildRootsUri(mAuthority), null, false); } } private void includeDocument(MatrixCursor result, StubDocument document) { Loading tests/common/com/android/documentsui/bots/UiBot.java +0 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import static org.hamcrest.Matchers.endsWith; import android.content.Context; import android.support.test.espresso.Espresso; import android.support.test.espresso.NoMatchingViewException; import android.support.test.espresso.action.ViewActions; import android.support.test.espresso.matcher.BoundedMatcher; import android.support.test.espresso.matcher.ViewMatchers; Loading tests/functional/com/android/documentsui/ActivityTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.RemoteException; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; Loading Loading @@ -127,6 +128,9 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen // so if a drawer is on top of a file we want to select, it will actually click the drawer. // Thus to start a clean state, we always try to close first. bots.roots.closeDrawer(); // Configure the provider back to default. mDocsHelper.configure(null, Bundle.EMPTY); } @Override Loading tests/functional/com/android/documentsui/FileManagementUiTest.java +75 −0 Original line number Diff line number Diff line Loading @@ -20,12 +20,19 @@ import static com.android.documentsui.StubProvider.ROOT_0_ID; import static com.android.documentsui.StubProvider.ROOT_1_ID; import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.support.test.filters.LargeTest; import android.support.test.filters.Suppress; import android.view.KeyEvent; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.Shared; import com.android.documentsui.files.FilesActivity; import com.android.documentsui.sorting.SortDimension; import com.android.documentsui.sorting.SortModel; import java.util.List; @LargeTest public class FileManagementUiTest extends ActivityTest<FilesActivity> { Loading Loading @@ -122,4 +129,72 @@ public class FileManagementUiTest extends ActivityTest<FilesActivity> { bots.directory.waitForDocument("file1.png"); } public void testCopyLargeAmountOfFiles() throws Exception { // Suppress root notification. We're gonna create tons of files and it will soon crash // DocsUI because too many root refreshes are queued in an executor. Bundle conf = new Bundle(); conf.putBoolean(StubProvider.EXTRA_ENABLE_ROOT_NOTIFICATION, false); mDocsHelper.configure(null, conf); final Uri test = mDocsHelper.createFolder(rootDir0, "test"); final Uri target = mDocsHelper.createFolder(rootDir0, "target"); String nameOfLastFile = ""; for (int i = 0; i <= Shared.MAX_DOCS_IN_INTENT; ++i) { final String name = i + ".txt"; final Uri doc = mDocsHelper.createDocument(test, "text/plain", name); mDocsHelper.writeDocument(doc, Integer.toString(i).getBytes()); nameOfLastFile = nameOfLastFile.compareTo(name) < 0 ? name : nameOfLastFile; } bots.roots.openRoot(ROOT_0_ID); bots.directory.openDocument("test"); bots.sortHeader.sortBy( SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.waitForDocument("0.txt"); bots.keyboard.pressKey( KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON); bots.keyboard.pressKey( KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON); bots.roots.openRoot(ROOT_0_ID); bots.directory.openDocument("target"); bots.directory.pasteFilesFromClipboard(); // Use these 2 events as a signal that many files have already been copied. Only considering // Android devices a more reliable way is to wait until notification goes away, but ARC++ // uses Chrome OS notifications so it isn't even an option. bots.directory.waitForDocument("0.txt"); bots.directory.waitForDocument(nameOfLastFile); final int expectedCount = Shared.MAX_DOCS_IN_INTENT + 1; List<DocumentInfo> children = mDocsHelper.listChildren(target, -1); if (children.size() == expectedCount) { return; } // Files weren't copied fast enough, so gonna do some polling until they all arrive or copy // seems stalled. while (true) { Thread.sleep(200); List<DocumentInfo> newChildren = mDocsHelper.listChildren(target, -1); if (newChildren.size() == expectedCount) { return; } if (newChildren.size() > expectedCount) { // Should never happen fail("Something wrong with this test case. Copied file count " + newChildren.size() + " exceeds expected number " + expectedCount); } if (newChildren.size() <= children.size()) { fail("Only copied " + children.size() + " files, expected to copy " + expectedCount + " files."); } children = newChildren; } } } Loading
tests/common/com/android/documentsui/DocumentsProviderHelper.java +15 −2 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ public class DocumentsProviderHelper { } public void assertChildCount(String parentId, int expected) throws Exception { List<DocumentInfo> children = listChildren(parentId); List<DocumentInfo> children = listChildren(parentId, -1); assertEquals("Incorrect file count after copy", expected, children.size()); } Loading Loading @@ -264,10 +264,19 @@ public class DocumentsProviderHelper { } public List<DocumentInfo> listChildren(String documentId) throws Exception { return listChildren(documentId, 100); } public List<DocumentInfo> listChildren(Uri parentUri, int maxCount) throws Exception { String id = DocumentsContract.getDocumentId(parentUri); return listChildren(id, maxCount); } public List<DocumentInfo> listChildren(String documentId, int maxCount) throws Exception { Uri uri = buildChildDocumentsUri(mAuthority, documentId); List<DocumentInfo> children = new ArrayList<>(); try (Cursor cursor = mClient.query(uri, null, null, null, null, null)) { Cursor wrapper = new RootCursorWrapper(mAuthority, "totally-fake", cursor, 100); Cursor wrapper = new RootCursorWrapper(mAuthority, "totally-fake", cursor, maxCount); while (wrapper.moveToNext()) { children.add(DocumentInfo.fromDirectoryCursor(wrapper)); } Loading Loading @@ -314,4 +323,8 @@ public class DocumentsProviderHelper { extra.putLong(DocumentsContract.EXTRA_LOADING, duration); mClient.call("setLoadingDuration", null, extra); } public void configure(String args, Bundle configuration) throws RemoteException { mClient.call("configure", args, configuration); } }
tests/common/com/android/documentsui/StubProvider.java +10 −4 Original line number Diff line number Diff line Loading @@ -65,6 +65,8 @@ public class StubProvider extends DocumentsProvider { public static final String EXTRA_STREAM_TYPES = "com.android.documentsui.stubprovider.STREAM_TYPES"; public static final String EXTRA_CONTENT = "com.android.documentsui.stubprovider.CONTENT"; public static final String EXTRA_ENABLE_ROOT_NOTIFICATION = "com.android.documentsui.stubprovider.ROOT_NOTIFICATION"; public static final String EXTRA_FLAGS = "com.android.documentsui.stubprovider.FLAGS"; public static final String EXTRA_PARENT_ID = "com.android.documentsui.stubprovider.PARENT"; Loading @@ -91,6 +93,7 @@ public class StubProvider extends DocumentsProvider { private SharedPreferences mPrefs; private Set<String> mSimulateReadErrorIds = new HashSet<>(); private long mLoadingDuration = 0; private boolean mRootNotification = true; @Override public void attachInfo(Context context, ProviderInfo info) { Loading Loading @@ -630,16 +633,19 @@ public class StubProvider extends DocumentsProvider { private void configure(String arg, Bundle extras) { Log.d(TAG, "Configure " + arg); String rootName = extras.getString(EXTRA_ROOT, ROOT_0_ID); long rootSize = extras.getLong(EXTRA_SIZE, 1) * 1024 * 1024; long rootSize = extras.getLong(EXTRA_SIZE, 100) * 1024 * 1024; setSize(rootName, rootSize); mRootNotification = extras.getBoolean(EXTRA_ENABLE_ROOT_NOTIFICATION, true); } private void notifyParentChanged(String parentId) { getContext().getContentResolver().notifyChange( DocumentsContract.buildChildDocumentsUri(mAuthority, parentId), null, false); if (mRootNotification) { // Notify also about possible change in remaining space on the root. getContext().getContentResolver().notifyChange(DocumentsContract.buildRootsUri(mAuthority), null, false); getContext().getContentResolver().notifyChange( DocumentsContract.buildRootsUri(mAuthority), null, false); } } private void includeDocument(MatrixCursor result, StubDocument document) { Loading
tests/common/com/android/documentsui/bots/UiBot.java +0 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import static org.hamcrest.Matchers.endsWith; import android.content.Context; import android.support.test.espresso.Espresso; import android.support.test.espresso.NoMatchingViewException; import android.support.test.espresso.action.ViewActions; import android.support.test.espresso.matcher.BoundedMatcher; import android.support.test.espresso.matcher.ViewMatchers; Loading
tests/functional/com/android/documentsui/ActivityTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.RemoteException; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; Loading Loading @@ -127,6 +128,9 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen // so if a drawer is on top of a file we want to select, it will actually click the drawer. // Thus to start a clean state, we always try to close first. bots.roots.closeDrawer(); // Configure the provider back to default. mDocsHelper.configure(null, Bundle.EMPTY); } @Override Loading
tests/functional/com/android/documentsui/FileManagementUiTest.java +75 −0 Original line number Diff line number Diff line Loading @@ -20,12 +20,19 @@ import static com.android.documentsui.StubProvider.ROOT_0_ID; import static com.android.documentsui.StubProvider.ROOT_1_ID; import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.support.test.filters.LargeTest; import android.support.test.filters.Suppress; import android.view.KeyEvent; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.Shared; import com.android.documentsui.files.FilesActivity; import com.android.documentsui.sorting.SortDimension; import com.android.documentsui.sorting.SortModel; import java.util.List; @LargeTest public class FileManagementUiTest extends ActivityTest<FilesActivity> { Loading Loading @@ -122,4 +129,72 @@ public class FileManagementUiTest extends ActivityTest<FilesActivity> { bots.directory.waitForDocument("file1.png"); } public void testCopyLargeAmountOfFiles() throws Exception { // Suppress root notification. We're gonna create tons of files and it will soon crash // DocsUI because too many root refreshes are queued in an executor. Bundle conf = new Bundle(); conf.putBoolean(StubProvider.EXTRA_ENABLE_ROOT_NOTIFICATION, false); mDocsHelper.configure(null, conf); final Uri test = mDocsHelper.createFolder(rootDir0, "test"); final Uri target = mDocsHelper.createFolder(rootDir0, "target"); String nameOfLastFile = ""; for (int i = 0; i <= Shared.MAX_DOCS_IN_INTENT; ++i) { final String name = i + ".txt"; final Uri doc = mDocsHelper.createDocument(test, "text/plain", name); mDocsHelper.writeDocument(doc, Integer.toString(i).getBytes()); nameOfLastFile = nameOfLastFile.compareTo(name) < 0 ? name : nameOfLastFile; } bots.roots.openRoot(ROOT_0_ID); bots.directory.openDocument("test"); bots.sortHeader.sortBy( SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.waitForDocument("0.txt"); bots.keyboard.pressKey( KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON); bots.keyboard.pressKey( KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON); bots.roots.openRoot(ROOT_0_ID); bots.directory.openDocument("target"); bots.directory.pasteFilesFromClipboard(); // Use these 2 events as a signal that many files have already been copied. Only considering // Android devices a more reliable way is to wait until notification goes away, but ARC++ // uses Chrome OS notifications so it isn't even an option. bots.directory.waitForDocument("0.txt"); bots.directory.waitForDocument(nameOfLastFile); final int expectedCount = Shared.MAX_DOCS_IN_INTENT + 1; List<DocumentInfo> children = mDocsHelper.listChildren(target, -1); if (children.size() == expectedCount) { return; } // Files weren't copied fast enough, so gonna do some polling until they all arrive or copy // seems stalled. while (true) { Thread.sleep(200); List<DocumentInfo> newChildren = mDocsHelper.listChildren(target, -1); if (newChildren.size() == expectedCount) { return; } if (newChildren.size() > expectedCount) { // Should never happen fail("Something wrong with this test case. Copied file count " + newChildren.size() + " exceeds expected number " + expectedCount); } if (newChildren.size() <= children.size()) { fail("Only copied " + children.size() + " files, expected to copy " + expectedCount + " files."); } children = newChildren; } } }