Loading packages/DocumentsUI/testing/TestDocumentsProvider/Android.mk 0 → 100644 +14 −0 Original line number Diff line number Diff line LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := TestDocumentsProvider LOCAL_CERTIFICATE := platform LOCAL_MODULE_TAGS := tests #LOCAL_SDK_VERSION := current LOCAL_PROGUARD_ENABLED := disabled LOCAL_DEX_PREOPT := false include $(BUILD_PACKAGE) packages/DocumentsUI/testing/TestDocumentsProvider/AndroidManifest.xml 0 → 100644 +30 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.documentsui.testing"> <application> <provider android:name="TestDocumentsProvider" android:authorities="com.android.documentsui.testing" android:exported="true" android:grantUriPermissions="true" android:permission="android.permission.MANAGE_DOCUMENTS"> <intent-filter> <action android:name="android.content.action.DOCUMENTS_PROVIDER" /> </intent-filter> </provider> </application> </manifest> packages/DocumentsUI/testing/TestDocumentsProvider/src/com/android/documentsui/testing/TestDocumentsProvider.java 0 → 100644 +299 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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.database.Cursor; import android.database.MatrixCursor; import android.database.MatrixCursor.RowBuilder; import android.os.AsyncTask; import android.os.CancellationSignal; import android.os.ParcelFileDescriptor; import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; import android.provider.DocumentsProvider; import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class TestDocumentsProvider extends DocumentsProvider { private static final String TAG = "TestDocumentsProvider"; private static final String[] DEFAULT_ROOT_PROJECTION = new String[] { Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE, Root.COLUMN_DOCUMENT_ID, Root.COLUMN_AVAILABLE_BYTES, }; private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[] { Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE, Document.COLUMN_DISPLAY_NAME, Document.COLUMN_LAST_MODIFIED, Document.COLUMN_FLAGS, Document.COLUMN_SIZE, }; private static String[] resolveRootProjection(String[] projection) { return projection != null ? projection : DEFAULT_ROOT_PROJECTION; } private static String[] resolveDocumentProjection(String[] projection) { return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION; } @Override public boolean onCreate() { resetRoots(); return true; } @Override public Cursor queryRoots(String[] projection) throws FileNotFoundException { final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection)); RowBuilder row = result.newRow(); row.add(Root.COLUMN_ROOT_ID, "local"); row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY); row.add(Root.COLUMN_TITLE, "TEST-Local"); row.add(Root.COLUMN_SUMMARY, "TEST-LocalSummary"); row.add(Root.COLUMN_DOCUMENT_ID, "doc:local"); row = result.newRow(); row.add(Root.COLUMN_ROOT_ID, "create"); row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_IS_CHILD); row.add(Root.COLUMN_TITLE, "TEST-Create"); row.add(Root.COLUMN_DOCUMENT_ID, "doc:create"); return result; } private Map<String, Doc> mDocs = new HashMap<>(); private Doc mLocalRoot; private Doc mCreateRoot; private Doc buildDoc(String docId, String displayName, String mimeType) { final Doc doc = new Doc(); doc.docId = docId; doc.displayName = displayName; doc.mimeType = mimeType; mDocs.put(doc.docId, doc); return doc; } public void resetRoots() { Log.d(TAG, "resetRoots()"); mDocs.clear(); mLocalRoot = buildDoc("doc:local", null, Document.MIME_TYPE_DIR); mCreateRoot = buildDoc("doc:create", null, Document.MIME_TYPE_DIR); mCreateRoot.flags = Document.FLAG_DIR_SUPPORTS_CREATE; { Doc file1 = buildDoc("doc:file1", "FILE1", "mime1/file1"); file1.contents = "fileone".getBytes(); file1.flags = Document.FLAG_SUPPORTS_WRITE; mLocalRoot.children.add(file1); mCreateRoot.children.add(file1); } { Doc file2 = buildDoc("doc:file2", "FILE2", "mime2/file2"); file2.contents = "filetwo".getBytes(); file2.flags = Document.FLAG_SUPPORTS_WRITE; mLocalRoot.children.add(file2); mCreateRoot.children.add(file2); } Doc dir1 = buildDoc("doc:dir1", "DIR1", Document.MIME_TYPE_DIR); mLocalRoot.children.add(dir1); { Doc file3 = buildDoc("doc:file3", "FILE3", "mime3/file3"); file3.contents = "filethree".getBytes(); file3.flags = Document.FLAG_SUPPORTS_WRITE; dir1.children.add(file3); } Doc dir2 = buildDoc("doc:dir2", "DIR2", Document.MIME_TYPE_DIR); mCreateRoot.children.add(dir2); { Doc file4 = buildDoc("doc:file4", "FILE4", "mime4/file4"); file4.contents = "filefour".getBytes(); file4.flags = Document.FLAG_SUPPORTS_WRITE; dir2.children.add(file4); } } private static class Doc { public String docId; public int flags; public String displayName; public long size; public String mimeType; public long lastModified; public byte[] contents; public List<Doc> children = new ArrayList<>(); public void include(MatrixCursor result) { final RowBuilder row = result.newRow(); row.add(Document.COLUMN_DOCUMENT_ID, docId); row.add(Document.COLUMN_DISPLAY_NAME, displayName); row.add(Document.COLUMN_SIZE, size); row.add(Document.COLUMN_MIME_TYPE, mimeType); row.add(Document.COLUMN_FLAGS, flags); row.add(Document.COLUMN_LAST_MODIFIED, lastModified); } } @Override public boolean isChildDocument(String parentDocumentId, String documentId) { for (Doc doc : mDocs.get(parentDocumentId).children) { if (doc.docId.equals(documentId)) { return true; } if (Document.MIME_TYPE_DIR.equals(doc.mimeType)) { return isChildDocument(doc.docId, documentId); } } return false; } @Override public String createDocument(String parentDocumentId, String mimeType, String displayName) throws FileNotFoundException { final String docId = "doc:" + System.currentTimeMillis(); final Doc doc = buildDoc(docId, displayName, mimeType); doc.flags = Document.FLAG_SUPPORTS_WRITE | Document.FLAG_SUPPORTS_RENAME; mDocs.get(parentDocumentId).children.add(doc); return docId; } @Override public String renameDocument(String documentId, String displayName) throws FileNotFoundException { mDocs.get(documentId).displayName = displayName; return null; } @Override public void deleteDocument(String documentId) throws FileNotFoundException { mDocs.remove(documentId); for (Doc doc : mDocs.values()) { doc.children.remove(documentId); } } @Override public Cursor queryDocument(String documentId, String[] projection) throws FileNotFoundException { final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection)); mDocs.get(documentId).include(result); return result; } @Override public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException { final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection)); for (Doc doc : mDocs.get(parentDocumentId).children) { doc.include(result); } return result; } @Override public ParcelFileDescriptor openDocument(String documentId, String mode, CancellationSignal signal) throws FileNotFoundException { final Doc doc = mDocs.get(documentId); if (doc == null) { throw new FileNotFoundException(); } final ParcelFileDescriptor[] pipe; try { pipe = ParcelFileDescriptor.createPipe(); } catch (IOException e) { throw new IllegalStateException(e); } if (mode.contains("w")) { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { synchronized (doc) { try { final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream( pipe[0]); doc.contents = readFullyNoClose(is); is.close(); doc.notifyAll(); } catch (IOException e) { Log.w(TAG, "Failed to stream", e); } } return null; } }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); return pipe[1]; } else { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { synchronized (doc) { try { final OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream( pipe[1]); while (doc.contents == null) { doc.wait(); } os.write(doc.contents); os.close(); } catch (IOException e) { Log.w(TAG, "Failed to stream", e); } catch (InterruptedException e) { Log.w(TAG, "Interuppted", e); } } return null; } }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); return pipe[0]; } } private static byte[] readFullyNoClose(InputStream in) throws IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int count; while ((count = in.read(buffer)) != -1) { bytes.write(buffer, 0, count); } return bytes.toByteArray(); } } packages/DocumentsUI/tests/Android.mk +4 −1 Original line number Diff line number Diff line Loading @@ -3,11 +3,12 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests #LOCAL_SDK_VERSION := current LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_JAVA_LIBRARIES := android.test.runner LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 mockito-target guava LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 mockito-target guava ub-uiautomator LOCAL_PACKAGE_NAME := DocumentsUITests LOCAL_INSTRUMENTATION_FOR := DocumentsUI Loading @@ -15,3 +16,5 @@ LOCAL_INSTRUMENTATION_FOR := DocumentsUI LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) include $(LOCAL_PATH)/../testing/TestDocumentsProvider/Android.mk packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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.content.Context; import android.content.Intent; import android.support.test.uiautomator.By; import android.support.test.uiautomator.BySelector; import android.support.test.uiautomator.Configurator; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; import android.test.InstrumentationTestCase; import android.view.MotionEvent; import java.util.concurrent.TimeoutException; public class FilesActivityUiTest extends InstrumentationTestCase { private static final String TAG = "FilesActivityUiTest"; private static final String TARGET_PKG = "com.android.documentsui"; private static final String LAUNCHER_PKG = "com.android.launcher"; private static final int ONE_SECOND = 1000; private static final int FIVE_SECONDS = 5 * ONE_SECOND; private ActionBar mBar; private UiDevice mDevice; private Context mContext; public void setUp() throws TimeoutException { // Initialize UiDevice instance. mDevice = UiDevice.getInstance(getInstrumentation()); Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE); // Start from the home screen. mDevice.pressHome(); mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), FIVE_SECONDS); // Launch app. mContext = getInstrumentation().getContext(); Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(TARGET_PKG); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); mContext.startActivity(intent); // Wait for the app to appear. mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), FIVE_SECONDS); mDevice.waitForIdle(); mBar = new ActionBar(); } public void testSwitchMode() throws Exception { UiObject2 mode = mBar.gridMode(100); if (mode != null) { mode.click(); assertNotNull(mBar.listMode(ONE_SECOND)); } else { mBar.listMode(100).click(); assertNotNull(mBar.gridMode(ONE_SECOND)); } } private class ActionBar { public UiObject2 gridMode(int timeout) { // Note that we're using By.desc rather than By.res, because of b/25285770 BySelector selector = By.desc("Grid view"); if (timeout > 0) { mDevice.wait(Until.findObject(selector), timeout); } return mDevice.findObject(selector); } public UiObject2 listMode(int timeout) { // Note that we're using By.desc rather than By.res, because of b/25285770 BySelector selector = By.desc("List view"); if (timeout > 0) { mDevice.wait(Until.findObject(selector), timeout); } return mDevice.findObject(selector); } } } Loading
packages/DocumentsUI/testing/TestDocumentsProvider/Android.mk 0 → 100644 +14 −0 Original line number Diff line number Diff line LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := TestDocumentsProvider LOCAL_CERTIFICATE := platform LOCAL_MODULE_TAGS := tests #LOCAL_SDK_VERSION := current LOCAL_PROGUARD_ENABLED := disabled LOCAL_DEX_PREOPT := false include $(BUILD_PACKAGE)
packages/DocumentsUI/testing/TestDocumentsProvider/AndroidManifest.xml 0 → 100644 +30 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.documentsui.testing"> <application> <provider android:name="TestDocumentsProvider" android:authorities="com.android.documentsui.testing" android:exported="true" android:grantUriPermissions="true" android:permission="android.permission.MANAGE_DOCUMENTS"> <intent-filter> <action android:name="android.content.action.DOCUMENTS_PROVIDER" /> </intent-filter> </provider> </application> </manifest>
packages/DocumentsUI/testing/TestDocumentsProvider/src/com/android/documentsui/testing/TestDocumentsProvider.java 0 → 100644 +299 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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.database.Cursor; import android.database.MatrixCursor; import android.database.MatrixCursor.RowBuilder; import android.os.AsyncTask; import android.os.CancellationSignal; import android.os.ParcelFileDescriptor; import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; import android.provider.DocumentsProvider; import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class TestDocumentsProvider extends DocumentsProvider { private static final String TAG = "TestDocumentsProvider"; private static final String[] DEFAULT_ROOT_PROJECTION = new String[] { Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE, Root.COLUMN_DOCUMENT_ID, Root.COLUMN_AVAILABLE_BYTES, }; private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[] { Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE, Document.COLUMN_DISPLAY_NAME, Document.COLUMN_LAST_MODIFIED, Document.COLUMN_FLAGS, Document.COLUMN_SIZE, }; private static String[] resolveRootProjection(String[] projection) { return projection != null ? projection : DEFAULT_ROOT_PROJECTION; } private static String[] resolveDocumentProjection(String[] projection) { return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION; } @Override public boolean onCreate() { resetRoots(); return true; } @Override public Cursor queryRoots(String[] projection) throws FileNotFoundException { final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection)); RowBuilder row = result.newRow(); row.add(Root.COLUMN_ROOT_ID, "local"); row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY); row.add(Root.COLUMN_TITLE, "TEST-Local"); row.add(Root.COLUMN_SUMMARY, "TEST-LocalSummary"); row.add(Root.COLUMN_DOCUMENT_ID, "doc:local"); row = result.newRow(); row.add(Root.COLUMN_ROOT_ID, "create"); row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_IS_CHILD); row.add(Root.COLUMN_TITLE, "TEST-Create"); row.add(Root.COLUMN_DOCUMENT_ID, "doc:create"); return result; } private Map<String, Doc> mDocs = new HashMap<>(); private Doc mLocalRoot; private Doc mCreateRoot; private Doc buildDoc(String docId, String displayName, String mimeType) { final Doc doc = new Doc(); doc.docId = docId; doc.displayName = displayName; doc.mimeType = mimeType; mDocs.put(doc.docId, doc); return doc; } public void resetRoots() { Log.d(TAG, "resetRoots()"); mDocs.clear(); mLocalRoot = buildDoc("doc:local", null, Document.MIME_TYPE_DIR); mCreateRoot = buildDoc("doc:create", null, Document.MIME_TYPE_DIR); mCreateRoot.flags = Document.FLAG_DIR_SUPPORTS_CREATE; { Doc file1 = buildDoc("doc:file1", "FILE1", "mime1/file1"); file1.contents = "fileone".getBytes(); file1.flags = Document.FLAG_SUPPORTS_WRITE; mLocalRoot.children.add(file1); mCreateRoot.children.add(file1); } { Doc file2 = buildDoc("doc:file2", "FILE2", "mime2/file2"); file2.contents = "filetwo".getBytes(); file2.flags = Document.FLAG_SUPPORTS_WRITE; mLocalRoot.children.add(file2); mCreateRoot.children.add(file2); } Doc dir1 = buildDoc("doc:dir1", "DIR1", Document.MIME_TYPE_DIR); mLocalRoot.children.add(dir1); { Doc file3 = buildDoc("doc:file3", "FILE3", "mime3/file3"); file3.contents = "filethree".getBytes(); file3.flags = Document.FLAG_SUPPORTS_WRITE; dir1.children.add(file3); } Doc dir2 = buildDoc("doc:dir2", "DIR2", Document.MIME_TYPE_DIR); mCreateRoot.children.add(dir2); { Doc file4 = buildDoc("doc:file4", "FILE4", "mime4/file4"); file4.contents = "filefour".getBytes(); file4.flags = Document.FLAG_SUPPORTS_WRITE; dir2.children.add(file4); } } private static class Doc { public String docId; public int flags; public String displayName; public long size; public String mimeType; public long lastModified; public byte[] contents; public List<Doc> children = new ArrayList<>(); public void include(MatrixCursor result) { final RowBuilder row = result.newRow(); row.add(Document.COLUMN_DOCUMENT_ID, docId); row.add(Document.COLUMN_DISPLAY_NAME, displayName); row.add(Document.COLUMN_SIZE, size); row.add(Document.COLUMN_MIME_TYPE, mimeType); row.add(Document.COLUMN_FLAGS, flags); row.add(Document.COLUMN_LAST_MODIFIED, lastModified); } } @Override public boolean isChildDocument(String parentDocumentId, String documentId) { for (Doc doc : mDocs.get(parentDocumentId).children) { if (doc.docId.equals(documentId)) { return true; } if (Document.MIME_TYPE_DIR.equals(doc.mimeType)) { return isChildDocument(doc.docId, documentId); } } return false; } @Override public String createDocument(String parentDocumentId, String mimeType, String displayName) throws FileNotFoundException { final String docId = "doc:" + System.currentTimeMillis(); final Doc doc = buildDoc(docId, displayName, mimeType); doc.flags = Document.FLAG_SUPPORTS_WRITE | Document.FLAG_SUPPORTS_RENAME; mDocs.get(parentDocumentId).children.add(doc); return docId; } @Override public String renameDocument(String documentId, String displayName) throws FileNotFoundException { mDocs.get(documentId).displayName = displayName; return null; } @Override public void deleteDocument(String documentId) throws FileNotFoundException { mDocs.remove(documentId); for (Doc doc : mDocs.values()) { doc.children.remove(documentId); } } @Override public Cursor queryDocument(String documentId, String[] projection) throws FileNotFoundException { final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection)); mDocs.get(documentId).include(result); return result; } @Override public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException { final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection)); for (Doc doc : mDocs.get(parentDocumentId).children) { doc.include(result); } return result; } @Override public ParcelFileDescriptor openDocument(String documentId, String mode, CancellationSignal signal) throws FileNotFoundException { final Doc doc = mDocs.get(documentId); if (doc == null) { throw new FileNotFoundException(); } final ParcelFileDescriptor[] pipe; try { pipe = ParcelFileDescriptor.createPipe(); } catch (IOException e) { throw new IllegalStateException(e); } if (mode.contains("w")) { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { synchronized (doc) { try { final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream( pipe[0]); doc.contents = readFullyNoClose(is); is.close(); doc.notifyAll(); } catch (IOException e) { Log.w(TAG, "Failed to stream", e); } } return null; } }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); return pipe[1]; } else { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { synchronized (doc) { try { final OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream( pipe[1]); while (doc.contents == null) { doc.wait(); } os.write(doc.contents); os.close(); } catch (IOException e) { Log.w(TAG, "Failed to stream", e); } catch (InterruptedException e) { Log.w(TAG, "Interuppted", e); } } return null; } }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); return pipe[0]; } } private static byte[] readFullyNoClose(InputStream in) throws IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int count; while ((count = in.read(buffer)) != -1) { bytes.write(buffer, 0, count); } return bytes.toByteArray(); } }
packages/DocumentsUI/tests/Android.mk +4 −1 Original line number Diff line number Diff line Loading @@ -3,11 +3,12 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests #LOCAL_SDK_VERSION := current LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_JAVA_LIBRARIES := android.test.runner LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 mockito-target guava LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 mockito-target guava ub-uiautomator LOCAL_PACKAGE_NAME := DocumentsUITests LOCAL_INSTRUMENTATION_FOR := DocumentsUI Loading @@ -15,3 +16,5 @@ LOCAL_INSTRUMENTATION_FOR := DocumentsUI LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) include $(LOCAL_PATH)/../testing/TestDocumentsProvider/Android.mk
packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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.content.Context; import android.content.Intent; import android.support.test.uiautomator.By; import android.support.test.uiautomator.BySelector; import android.support.test.uiautomator.Configurator; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject2; import android.support.test.uiautomator.Until; import android.test.InstrumentationTestCase; import android.view.MotionEvent; import java.util.concurrent.TimeoutException; public class FilesActivityUiTest extends InstrumentationTestCase { private static final String TAG = "FilesActivityUiTest"; private static final String TARGET_PKG = "com.android.documentsui"; private static final String LAUNCHER_PKG = "com.android.launcher"; private static final int ONE_SECOND = 1000; private static final int FIVE_SECONDS = 5 * ONE_SECOND; private ActionBar mBar; private UiDevice mDevice; private Context mContext; public void setUp() throws TimeoutException { // Initialize UiDevice instance. mDevice = UiDevice.getInstance(getInstrumentation()); Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE); // Start from the home screen. mDevice.pressHome(); mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), FIVE_SECONDS); // Launch app. mContext = getInstrumentation().getContext(); Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(TARGET_PKG); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); mContext.startActivity(intent); // Wait for the app to appear. mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), FIVE_SECONDS); mDevice.waitForIdle(); mBar = new ActionBar(); } public void testSwitchMode() throws Exception { UiObject2 mode = mBar.gridMode(100); if (mode != null) { mode.click(); assertNotNull(mBar.listMode(ONE_SECOND)); } else { mBar.listMode(100).click(); assertNotNull(mBar.gridMode(ONE_SECOND)); } } private class ActionBar { public UiObject2 gridMode(int timeout) { // Note that we're using By.desc rather than By.res, because of b/25285770 BySelector selector = By.desc("Grid view"); if (timeout > 0) { mDevice.wait(Until.findObject(selector), timeout); } return mDevice.findObject(selector); } public UiObject2 listMode(int timeout) { // Note that we're using By.desc rather than By.res, because of b/25285770 BySelector selector = By.desc("List view"); if (timeout > 0) { mDevice.wait(Until.findObject(selector), timeout); } return mDevice.findObject(selector); } } }