diff options
author | Jeff Sharkey <jsharkey@android.com> | 2013-09-11 17:33:06 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2013-09-11 17:33:52 -0700 |
commit | de2b22fbc60b29dd8af60cf05862066c04559dc0 (patch) | |
tree | 054f58b61d61769ab231276e08ad5616eda690de /packages/ExternalStorageProvider | |
parent | aca405cd592679af4a4b31b01dfed6fd59c4a168 (diff) | |
download | frameworks_base-de2b22fbc60b29dd8af60cf05862066c04559dc0.zip frameworks_base-de2b22fbc60b29dd8af60cf05862066c04559dc0.tar.gz frameworks_base-de2b22fbc60b29dd8af60cf05862066c04559dc0.tar.bz2 |
Handle pipe thumbnails, acquire unstable refs.
Support decoding thumbnails delivered over pipes by wrapping in a
buffered stream. Also switch to using unstable provider references
to avoid crashing DocumentsUI.
Bug: 10516148, 10510851
Change-Id: I85f6eeaca70c97742bf79656d1d0c6da381fdd47
Diffstat (limited to 'packages/ExternalStorageProvider')
-rw-r--r-- | packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java | 80 |
1 files changed, 66 insertions, 14 deletions
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java index 014c664..a917e3f 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java @@ -17,10 +17,18 @@ package com.android.externalstorage; import android.content.ContentResolver; +import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.database.MatrixCursor; import android.database.MatrixCursor.RowBuilder; +import android.graphics.Bitmap; +import android.graphics.Bitmap.CompressFormat; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.os.CancellationSignal; import android.os.ParcelFileDescriptor; @@ -31,7 +39,14 @@ import android.provider.DocumentsContract.Root; import android.provider.DocumentsProvider; import android.util.Log; +import libcore.io.IoUtils; +import libcore.io.Streams; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; import java.lang.ref.WeakReference; public class TestDocumentsProvider extends DocumentsProvider { @@ -85,7 +100,7 @@ public class TestDocumentsProvider extends DocumentsProvider { if (CRASH_DOCUMENT) System.exit(12); final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection)); - includeFile(result, documentId); + includeFile(result, documentId, 0); return result; } @@ -122,12 +137,12 @@ public class TestDocumentsProvider extends DocumentsProvider { public boolean includeIfFinished(MatrixCursor result) { Log.d(TAG, hashCode() + ": includeIfFinished() found " + mFinished); if (mFinished) { - includeFile(result, "_networkfile1"); - includeFile(result, "_networkfile2"); - includeFile(result, "_networkfile3"); - includeFile(result, "_networkfile4"); - includeFile(result, "_networkfile5"); - includeFile(result, "_networkfile6"); + includeFile(result, "_networkfile1", 0); + includeFile(result, "_networkfile2", 0); + includeFile(result, "_networkfile3", 0); + includeFile(result, "_networkfile4", 0); + includeFile(result, "_networkfile5", 0); + includeFile(result, "_networkfile6", 0); return true; } else { return false; @@ -162,11 +177,11 @@ public class TestDocumentsProvider extends DocumentsProvider { result.setNotificationUri(resolver, notifyUri); // Always include local results - includeFile(result, MY_DOC_NULL); - includeFile(result, "localfile1"); - includeFile(result, "localfile2"); - includeFile(result, "localfile3"); - includeFile(result, "localfile4"); + includeFile(result, MY_DOC_NULL, 0); + includeFile(result, "localfile1", 0); + includeFile(result, "localfile2", Document.FLAG_SUPPORTS_THUMBNAIL); + includeFile(result, "localfile3", 0); + includeFile(result, "localfile4", 0); synchronized (this) { // Try picking up an existing network fetch @@ -217,7 +232,8 @@ public class TestDocumentsProvider extends DocumentsProvider { SystemClock.sleep(3000); final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection)); - includeFile(result, "It was /worth/ the_wait for?the file:with the&incredibly long name"); + includeFile( + result, "It was /worth/ the_wait for?the file:with the&incredibly long name", 0); return result; } @@ -228,15 +244,51 @@ public class TestDocumentsProvider extends DocumentsProvider { } @Override + public AssetFileDescriptor openDocumentThumbnail( + String docId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException { + final Bitmap bitmap = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(bitmap); + final Paint paint = new Paint(); + paint.setColor(Color.BLUE); + canvas.drawColor(Color.RED); + canvas.drawLine(0, 0, 32, 32, paint); + + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + bitmap.compress(CompressFormat.JPEG, 50, bos); + + final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + try { + final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createReliablePipe(); + new AsyncTask<Object, Object, Object>() { + @Override + protected Object doInBackground(Object... params) { + final FileOutputStream fos = new FileOutputStream(fds[1].getFileDescriptor()); + try { + Streams.copy(bis, fos); + } catch (IOException e) { + throw new RuntimeException(e); + } + IoUtils.closeQuietly(fds[1]); + return null; + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + return new AssetFileDescriptor(fds[0], 0, AssetFileDescriptor.UNKNOWN_LENGTH); + } catch (IOException e) { + throw new FileNotFoundException(e.getMessage()); + } + } + + @Override public boolean onCreate() { return true; } - private static void includeFile(MatrixCursor result, String docId) { + private static void includeFile(MatrixCursor result, String docId, int flags) { final RowBuilder row = result.newRow(); row.add(Document.COLUMN_DOCUMENT_ID, docId); row.add(Document.COLUMN_DISPLAY_NAME, docId); row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis()); + row.add(Document.COLUMN_FLAGS, flags); if (MY_DOC_ID.equals(docId)) { row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR); |