Loading src/com/android/documentsui/inspector/MetadataLoader.java +1 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ final class MetadataLoader extends AsyncTaskLoader<Bundle> { public Bundle loadInBackground() { try { return DocumentsContract.getDocumentMetadata(mContext.getContentResolver(), mUri); } catch (FileNotFoundException e) { } catch (FileNotFoundException | RuntimeException e) { Log.e(TAG, "Failed to load metadata for doc: " + mUri, e); } Loading tests/common/com/android/documentsui/InspectorProvider.java +32 −1 Original line number Diff line number Diff line Loading @@ -15,12 +15,16 @@ */ package com.android.documentsui; import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_METADATA; import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_SETTINGS; import android.database.Cursor; import android.database.MatrixCursor; import android.database.MatrixCursor.RowBuilder; import android.media.ExifInterface; import android.os.Bundle; import android.provider.DocumentsContract.Document; import java.io.FileNotFoundException; /** Loading @@ -32,6 +36,8 @@ import java.io.FileNotFoundException; * openInProvider Dummy1 50B Dummy11 50B Dummy22 150B * test.txt Dummy2 150B Dummy12 150B Dummy23 100B * update.txt Dummy3 100B Dummy13 100B * test.jpg * invalid.jpg */ public class InspectorProvider extends TestRootProvider { Loading @@ -39,6 +45,15 @@ public class InspectorProvider extends TestRootProvider { public static final String OPEN_IN_PROVIDER_TEST = "OpenInProviderTest"; public static final String ROOT_ID = "inspector-root"; // Virtual jpeg files for test metadata loading from provider. // TEST_JPEG is a normal jpeg file with legal exif data. // INVALID_JPEG is a invalid jpeg file with broken exif data. // TEST_JPEG_WIDTH, TEST_JPEG_HEIGHT are exif information for TEST_JPEG. public static final String TEST_JPEG = "test.jpg"; public static final String INVALID_JPEG = "invalid.jpg"; public static final int TEST_JPEG_WIDTH = 3840; public static final int TEST_JPEG_HEIGHT = 2160; private static final String ROOT_DOC_ID = "root0"; private static final int ROOT_FLAGS = 0; Loading Loading @@ -94,6 +109,8 @@ public class InspectorProvider extends TestRootProvider { addFile(c, OPEN_IN_PROVIDER_TEST, FLAG_SUPPORTS_SETTINGS); addFile(c, "test.txt"); addFile(c, "update.txt"); addFile(c, TEST_JPEG, FLAG_SUPPORTS_METADATA); addFile(c, INVALID_JPEG, FLAG_SUPPORTS_METADATA); return c; } } Loading @@ -108,6 +125,20 @@ public class InspectorProvider extends TestRootProvider { row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis()); } @Override public Bundle getDocumentMetadata(String documentId) throws FileNotFoundException { if (TEST_JPEG.contentEquals(documentId)) { Bundle metaData = new Bundle(); metaData.putInt(ExifInterface.TAG_IMAGE_WIDTH, TEST_JPEG_WIDTH); metaData.putInt(ExifInterface.TAG_IMAGE_LENGTH, TEST_JPEG_HEIGHT); return metaData; } else if (INVALID_JPEG.contentEquals(documentId)) { // Suppose there are some errors occurs. // Return null makes DocumentsContract throw a RemoteExcpetion, // and rethrow a RemoteException when using ContentResolver. return null; } return super.getDocumentMetadata(documentId); } } tests/common/com/android/documentsui/testing/LatchedConsumer.java 0 → 100644 +41 −0 Original line number Diff line number Diff line package com.android.documentsui.testing; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; /** * Helper class for testing async processes. */ public class LatchedConsumer<T> implements Consumer<T> { private T value; private CountDownLatch latch; public LatchedConsumer(int expectedCount) { latch = new CountDownLatch(expectedCount); } public CountDownLatch getLatch() { return latch; } public T getValue() { return value; } @Override public void accept(T value) { this.value = value; latch.countDown(); } public void assertNotCalled(long timeout, TimeUnit unit) throws InterruptedException { assertFalse(latch.await(timeout, unit)); } public void assertCalled(long timeout, TimeUnit unit) throws InterruptedException { assertTrue(latch.await(timeout, unit)); } } tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java +45 −47 Original line number Diff line number Diff line Loading @@ -17,23 +17,27 @@ package com.android.documentsui.inspector; import android.content.ContentResolver; import android.content.Context; import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; import android.os.Looper; import android.provider.DocumentsContract; import androidx.annotation.Nullable; import android.support.test.InstrumentationRegistry; import com.android.documentsui.InspectorProvider; import android.test.suitebuilder.annotation.MediumTest; import com.android.documentsui.InspectorProvider; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.inspector.InspectorController.DataSupplier; import com.android.documentsui.testing.LatchedConsumer; import com.android.documentsui.testing.TestLoaderManager; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import junit.framework.TestCase; import org.junit.Before; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * This test relies the inspector providers test.txt file in inspector root. */ Loading Loading @@ -72,17 +76,17 @@ public class DocumentLoaderTest extends TestCase { public void testLoadsDocument() throws Exception { Uri validUri = DocumentsContract.buildDocumentUri( InspectorProvider.AUTHORITY, TEST_DOC_NAME); TestDocConsumer consumer = new TestDocConsumer(1); LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1); mLoader.loadDocInfo(validUri, consumer); // this is a test double that requires explicitly loading. @see TestLoaderManager mLoaderManager.getLoader(0).startLoading(); consumer.latch.await(1000, TimeUnit.MILLISECONDS); consumer.assertCalled(1000, TimeUnit.MILLISECONDS); assertNotNull(consumer.info); assertEquals(consumer.info.displayName, TEST_DOC_NAME); assertEquals(consumer.info.size, 0); assertNotNull(consumer.getValue()); assertEquals(consumer.getValue().displayName, TEST_DOC_NAME); assertEquals(consumer.getValue().size, 0); } /** Loading @@ -93,21 +97,21 @@ public class DocumentLoaderTest extends TestCase { @Test public void testInvalidInput() throws Exception { Uri invalidUri = Uri.parse("content://poodles/chuckleberry/ham"); TestDocConsumer consumer = new TestDocConsumer(1); LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1); mLoader.loadDocInfo(invalidUri, consumer); // this is a test double that requires explicitly loading. @see TestLoaderManager mLoaderManager.getLoader(0).startLoading(); consumer.latch.await(1000, TimeUnit.MILLISECONDS); assertNull(consumer.info); consumer.assertCalled(1000, TimeUnit.MILLISECONDS); assertNull(consumer.getValue()); } @Test public void testNonContentUri() { Uri invalidUri = Uri.parse("http://poodles/chuckleberry/ham"); TestDocConsumer consumer = new TestDocConsumer(1); LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1); try { mLoader.loadDocInfo(invalidUri, consumer); Loading @@ -125,12 +129,12 @@ public class DocumentLoaderTest extends TestCase { DocumentInfo info = DocumentInfo.fromUri(mResolver, dirUri); TestDirConsumer consumer = new TestDirConsumer(1); LatchedConsumer<Integer> consumer = new LatchedConsumer<>(1); mLoader.loadDirCount(info, consumer); mLoaderManager.getLoader(0).startLoading(); consumer.latch.await(1000, TimeUnit.MILLISECONDS); assertEquals(consumer.childCount, 4); consumer.assertCalled(1000, TimeUnit.MILLISECONDS); assertEquals(consumer.getValue().intValue(), 4); } @Test Loading @@ -139,7 +143,7 @@ public class DocumentLoaderTest extends TestCase { InspectorProvider.AUTHORITY, NOT_DIRECTORY); DocumentInfo info = DocumentInfo.fromUri(mResolver, uri); TestDirConsumer consumer = new TestDirConsumer(1); LatchedConsumer<Integer> consumer = new LatchedConsumer<>(1); try { mLoader.loadDirCount(info, consumer); Loading @@ -148,39 +152,33 @@ public class DocumentLoaderTest extends TestCase { } catch (Exception expected) {} } /** * Helper function for testing async processes. */ private static class TestDocConsumer implements Consumer<DocumentInfo> { private DocumentInfo info; private CountDownLatch latch; @Test public void testLoadMetadata() throws Exception { Uri uri = DocumentsContract.buildDocumentUri( InspectorProvider.AUTHORITY, InspectorProvider.TEST_JPEG); LatchedConsumer<Bundle> consumer = new LatchedConsumer<>(1); public TestDocConsumer(int expectedCount) { latch = new CountDownLatch(expectedCount); } mLoader.getDocumentMetadata(uri, consumer); mLoaderManager.getLoader(0).startLoading(); @Nullable @Override public void accept(DocumentInfo documentInfo) { info = documentInfo; latch.countDown(); } consumer.assertCalled(100, TimeUnit.MILLISECONDS); assertNotNull(consumer.getValue()); assertEquals(consumer.getValue().getInt(ExifInterface.TAG_IMAGE_WIDTH), InspectorProvider.TEST_JPEG_WIDTH); assertEquals(consumer.getValue().getInt(ExifInterface.TAG_IMAGE_LENGTH), InspectorProvider.TEST_JPEG_HEIGHT); } private static class TestDirConsumer implements Consumer<Integer> { private int childCount; private CountDownLatch latch; @Test public void testLoadMetadata_Unsupported() throws Exception { Uri uri = DocumentsContract.buildDocumentUri( InspectorProvider.AUTHORITY, InspectorProvider.INVALID_JPEG); LatchedConsumer<Bundle> consumer = new LatchedConsumer<>(1); public TestDirConsumer(int expectedCount) { latch = new CountDownLatch(expectedCount); } mLoader.getDocumentMetadata(uri, consumer); mLoaderManager.getLoader(0).startLoading(); @Override public void accept(Integer integer) { childCount = integer; latch.countDown(); } consumer.assertCalled(100, TimeUnit.MILLISECONDS); assertNull(consumer.getValue()); } } Loading
src/com/android/documentsui/inspector/MetadataLoader.java +1 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ final class MetadataLoader extends AsyncTaskLoader<Bundle> { public Bundle loadInBackground() { try { return DocumentsContract.getDocumentMetadata(mContext.getContentResolver(), mUri); } catch (FileNotFoundException e) { } catch (FileNotFoundException | RuntimeException e) { Log.e(TAG, "Failed to load metadata for doc: " + mUri, e); } Loading
tests/common/com/android/documentsui/InspectorProvider.java +32 −1 Original line number Diff line number Diff line Loading @@ -15,12 +15,16 @@ */ package com.android.documentsui; import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_METADATA; import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_SETTINGS; import android.database.Cursor; import android.database.MatrixCursor; import android.database.MatrixCursor.RowBuilder; import android.media.ExifInterface; import android.os.Bundle; import android.provider.DocumentsContract.Document; import java.io.FileNotFoundException; /** Loading @@ -32,6 +36,8 @@ import java.io.FileNotFoundException; * openInProvider Dummy1 50B Dummy11 50B Dummy22 150B * test.txt Dummy2 150B Dummy12 150B Dummy23 100B * update.txt Dummy3 100B Dummy13 100B * test.jpg * invalid.jpg */ public class InspectorProvider extends TestRootProvider { Loading @@ -39,6 +45,15 @@ public class InspectorProvider extends TestRootProvider { public static final String OPEN_IN_PROVIDER_TEST = "OpenInProviderTest"; public static final String ROOT_ID = "inspector-root"; // Virtual jpeg files for test metadata loading from provider. // TEST_JPEG is a normal jpeg file with legal exif data. // INVALID_JPEG is a invalid jpeg file with broken exif data. // TEST_JPEG_WIDTH, TEST_JPEG_HEIGHT are exif information for TEST_JPEG. public static final String TEST_JPEG = "test.jpg"; public static final String INVALID_JPEG = "invalid.jpg"; public static final int TEST_JPEG_WIDTH = 3840; public static final int TEST_JPEG_HEIGHT = 2160; private static final String ROOT_DOC_ID = "root0"; private static final int ROOT_FLAGS = 0; Loading Loading @@ -94,6 +109,8 @@ public class InspectorProvider extends TestRootProvider { addFile(c, OPEN_IN_PROVIDER_TEST, FLAG_SUPPORTS_SETTINGS); addFile(c, "test.txt"); addFile(c, "update.txt"); addFile(c, TEST_JPEG, FLAG_SUPPORTS_METADATA); addFile(c, INVALID_JPEG, FLAG_SUPPORTS_METADATA); return c; } } Loading @@ -108,6 +125,20 @@ public class InspectorProvider extends TestRootProvider { row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis()); } @Override public Bundle getDocumentMetadata(String documentId) throws FileNotFoundException { if (TEST_JPEG.contentEquals(documentId)) { Bundle metaData = new Bundle(); metaData.putInt(ExifInterface.TAG_IMAGE_WIDTH, TEST_JPEG_WIDTH); metaData.putInt(ExifInterface.TAG_IMAGE_LENGTH, TEST_JPEG_HEIGHT); return metaData; } else if (INVALID_JPEG.contentEquals(documentId)) { // Suppose there are some errors occurs. // Return null makes DocumentsContract throw a RemoteExcpetion, // and rethrow a RemoteException when using ContentResolver. return null; } return super.getDocumentMetadata(documentId); } }
tests/common/com/android/documentsui/testing/LatchedConsumer.java 0 → 100644 +41 −0 Original line number Diff line number Diff line package com.android.documentsui.testing; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; /** * Helper class for testing async processes. */ public class LatchedConsumer<T> implements Consumer<T> { private T value; private CountDownLatch latch; public LatchedConsumer(int expectedCount) { latch = new CountDownLatch(expectedCount); } public CountDownLatch getLatch() { return latch; } public T getValue() { return value; } @Override public void accept(T value) { this.value = value; latch.countDown(); } public void assertNotCalled(long timeout, TimeUnit unit) throws InterruptedException { assertFalse(latch.await(timeout, unit)); } public void assertCalled(long timeout, TimeUnit unit) throws InterruptedException { assertTrue(latch.await(timeout, unit)); } }
tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java +45 −47 Original line number Diff line number Diff line Loading @@ -17,23 +17,27 @@ package com.android.documentsui.inspector; import android.content.ContentResolver; import android.content.Context; import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; import android.os.Looper; import android.provider.DocumentsContract; import androidx.annotation.Nullable; import android.support.test.InstrumentationRegistry; import com.android.documentsui.InspectorProvider; import android.test.suitebuilder.annotation.MediumTest; import com.android.documentsui.InspectorProvider; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.inspector.InspectorController.DataSupplier; import com.android.documentsui.testing.LatchedConsumer; import com.android.documentsui.testing.TestLoaderManager; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import junit.framework.TestCase; import org.junit.Before; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * This test relies the inspector providers test.txt file in inspector root. */ Loading Loading @@ -72,17 +76,17 @@ public class DocumentLoaderTest extends TestCase { public void testLoadsDocument() throws Exception { Uri validUri = DocumentsContract.buildDocumentUri( InspectorProvider.AUTHORITY, TEST_DOC_NAME); TestDocConsumer consumer = new TestDocConsumer(1); LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1); mLoader.loadDocInfo(validUri, consumer); // this is a test double that requires explicitly loading. @see TestLoaderManager mLoaderManager.getLoader(0).startLoading(); consumer.latch.await(1000, TimeUnit.MILLISECONDS); consumer.assertCalled(1000, TimeUnit.MILLISECONDS); assertNotNull(consumer.info); assertEquals(consumer.info.displayName, TEST_DOC_NAME); assertEquals(consumer.info.size, 0); assertNotNull(consumer.getValue()); assertEquals(consumer.getValue().displayName, TEST_DOC_NAME); assertEquals(consumer.getValue().size, 0); } /** Loading @@ -93,21 +97,21 @@ public class DocumentLoaderTest extends TestCase { @Test public void testInvalidInput() throws Exception { Uri invalidUri = Uri.parse("content://poodles/chuckleberry/ham"); TestDocConsumer consumer = new TestDocConsumer(1); LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1); mLoader.loadDocInfo(invalidUri, consumer); // this is a test double that requires explicitly loading. @see TestLoaderManager mLoaderManager.getLoader(0).startLoading(); consumer.latch.await(1000, TimeUnit.MILLISECONDS); assertNull(consumer.info); consumer.assertCalled(1000, TimeUnit.MILLISECONDS); assertNull(consumer.getValue()); } @Test public void testNonContentUri() { Uri invalidUri = Uri.parse("http://poodles/chuckleberry/ham"); TestDocConsumer consumer = new TestDocConsumer(1); LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1); try { mLoader.loadDocInfo(invalidUri, consumer); Loading @@ -125,12 +129,12 @@ public class DocumentLoaderTest extends TestCase { DocumentInfo info = DocumentInfo.fromUri(mResolver, dirUri); TestDirConsumer consumer = new TestDirConsumer(1); LatchedConsumer<Integer> consumer = new LatchedConsumer<>(1); mLoader.loadDirCount(info, consumer); mLoaderManager.getLoader(0).startLoading(); consumer.latch.await(1000, TimeUnit.MILLISECONDS); assertEquals(consumer.childCount, 4); consumer.assertCalled(1000, TimeUnit.MILLISECONDS); assertEquals(consumer.getValue().intValue(), 4); } @Test Loading @@ -139,7 +143,7 @@ public class DocumentLoaderTest extends TestCase { InspectorProvider.AUTHORITY, NOT_DIRECTORY); DocumentInfo info = DocumentInfo.fromUri(mResolver, uri); TestDirConsumer consumer = new TestDirConsumer(1); LatchedConsumer<Integer> consumer = new LatchedConsumer<>(1); try { mLoader.loadDirCount(info, consumer); Loading @@ -148,39 +152,33 @@ public class DocumentLoaderTest extends TestCase { } catch (Exception expected) {} } /** * Helper function for testing async processes. */ private static class TestDocConsumer implements Consumer<DocumentInfo> { private DocumentInfo info; private CountDownLatch latch; @Test public void testLoadMetadata() throws Exception { Uri uri = DocumentsContract.buildDocumentUri( InspectorProvider.AUTHORITY, InspectorProvider.TEST_JPEG); LatchedConsumer<Bundle> consumer = new LatchedConsumer<>(1); public TestDocConsumer(int expectedCount) { latch = new CountDownLatch(expectedCount); } mLoader.getDocumentMetadata(uri, consumer); mLoaderManager.getLoader(0).startLoading(); @Nullable @Override public void accept(DocumentInfo documentInfo) { info = documentInfo; latch.countDown(); } consumer.assertCalled(100, TimeUnit.MILLISECONDS); assertNotNull(consumer.getValue()); assertEquals(consumer.getValue().getInt(ExifInterface.TAG_IMAGE_WIDTH), InspectorProvider.TEST_JPEG_WIDTH); assertEquals(consumer.getValue().getInt(ExifInterface.TAG_IMAGE_LENGTH), InspectorProvider.TEST_JPEG_HEIGHT); } private static class TestDirConsumer implements Consumer<Integer> { private int childCount; private CountDownLatch latch; @Test public void testLoadMetadata_Unsupported() throws Exception { Uri uri = DocumentsContract.buildDocumentUri( InspectorProvider.AUTHORITY, InspectorProvider.INVALID_JPEG); LatchedConsumer<Bundle> consumer = new LatchedConsumer<>(1); public TestDirConsumer(int expectedCount) { latch = new CountDownLatch(expectedCount); } mLoader.getDocumentMetadata(uri, consumer); mLoaderManager.getLoader(0).startLoading(); @Override public void accept(Integer integer) { childCount = integer; latch.countDown(); } consumer.assertCalled(100, TimeUnit.MILLISECONDS); assertNull(consumer.getValue()); } }