Merge "Handle pipe thumbnails, acquire unstable refs." into klp-dev
This commit is contained in:
@@ -72,6 +72,7 @@ public class ContentProviderClient {
|
|||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
ICancellationSignal remoteCancellationSignal = null;
|
ICancellationSignal remoteCancellationSignal = null;
|
||||||
if (cancellationSignal != null) {
|
if (cancellationSignal != null) {
|
||||||
|
cancellationSignal.throwIfCanceled();
|
||||||
remoteCancellationSignal = mContentProvider.createCancellationSignal();
|
remoteCancellationSignal = mContentProvider.createCancellationSignal();
|
||||||
cancellationSignal.setRemote(remoteCancellationSignal);
|
cancellationSignal.setRemote(remoteCancellationSignal);
|
||||||
}
|
}
|
||||||
@@ -208,6 +209,7 @@ public class ContentProviderClient {
|
|||||||
throws RemoteException, FileNotFoundException {
|
throws RemoteException, FileNotFoundException {
|
||||||
ICancellationSignal remoteSignal = null;
|
ICancellationSignal remoteSignal = null;
|
||||||
if (signal != null) {
|
if (signal != null) {
|
||||||
|
signal.throwIfCanceled();
|
||||||
remoteSignal = mContentProvider.createCancellationSignal();
|
remoteSignal = mContentProvider.createCancellationSignal();
|
||||||
signal.setRemote(remoteSignal);
|
signal.setRemote(remoteSignal);
|
||||||
}
|
}
|
||||||
@@ -244,6 +246,7 @@ public class ContentProviderClient {
|
|||||||
throws RemoteException, FileNotFoundException {
|
throws RemoteException, FileNotFoundException {
|
||||||
ICancellationSignal remoteSignal = null;
|
ICancellationSignal remoteSignal = null;
|
||||||
if (signal != null) {
|
if (signal != null) {
|
||||||
|
signal.throwIfCanceled();
|
||||||
remoteSignal = mContentProvider.createCancellationSignal();
|
remoteSignal = mContentProvider.createCancellationSignal();
|
||||||
signal.setRemote(remoteSignal);
|
signal.setRemote(remoteSignal);
|
||||||
}
|
}
|
||||||
@@ -269,6 +272,7 @@ public class ContentProviderClient {
|
|||||||
throws RemoteException, FileNotFoundException {
|
throws RemoteException, FileNotFoundException {
|
||||||
ICancellationSignal remoteSignal = null;
|
ICancellationSignal remoteSignal = null;
|
||||||
if (signal != null) {
|
if (signal != null) {
|
||||||
|
signal.throwIfCanceled();
|
||||||
remoteSignal = mContentProvider.createCancellationSignal();
|
remoteSignal = mContentProvider.createCancellationSignal();
|
||||||
signal.setRemote(remoteSignal);
|
signal.setRemote(remoteSignal);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.provider;
|
|||||||
import static android.net.TrafficStats.KB_IN_BYTES;
|
import static android.net.TrafficStats.KB_IN_BYTES;
|
||||||
import static libcore.io.OsConstants.SEEK_SET;
|
import static libcore.io.OsConstants.SEEK_SET;
|
||||||
|
|
||||||
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -34,16 +35,18 @@ import android.os.Bundle;
|
|||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.ParcelFileDescriptor.OnCloseListener;
|
import android.os.ParcelFileDescriptor.OnCloseListener;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.android.collect.Lists;
|
import com.google.android.collect.Lists;
|
||||||
|
|
||||||
import libcore.io.ErrnoException;
|
import libcore.io.ErrnoException;
|
||||||
import libcore.io.IoBridge;
|
|
||||||
import libcore.io.IoUtils;
|
import libcore.io.IoUtils;
|
||||||
import libcore.io.Libcore;
|
import libcore.io.Libcore;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -76,6 +79,11 @@ public final class DocumentsContract {
|
|||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
|
public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer is large enough to rewind past any EXIF headers.
|
||||||
|
*/
|
||||||
|
private static final int THUMBNAIL_BUFFER_SIZE = (int) (128 * KB_IN_BYTES);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants related to a document, including {@link Cursor} columns names
|
* Constants related to a document, including {@link Cursor} columns names
|
||||||
* and flags.
|
* and flags.
|
||||||
@@ -642,35 +650,47 @@ public final class DocumentsContract {
|
|||||||
*/
|
*/
|
||||||
public static Bitmap getDocumentThumbnail(
|
public static Bitmap getDocumentThumbnail(
|
||||||
ContentResolver resolver, Uri documentUri, Point size, CancellationSignal signal) {
|
ContentResolver resolver, Uri documentUri, Point size, CancellationSignal signal) {
|
||||||
|
final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
|
||||||
|
documentUri.getAuthority());
|
||||||
|
try {
|
||||||
|
return getDocumentThumbnail(client, documentUri, size, signal);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
ContentProviderClient.closeQuietly(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public static Bitmap getDocumentThumbnail(
|
||||||
|
ContentProviderClient client, Uri documentUri, Point size, CancellationSignal signal)
|
||||||
|
throws RemoteException {
|
||||||
final Bundle openOpts = new Bundle();
|
final Bundle openOpts = new Bundle();
|
||||||
openOpts.putParcelable(DocumentsContract.EXTRA_THUMBNAIL_SIZE, size);
|
openOpts.putParcelable(DocumentsContract.EXTRA_THUMBNAIL_SIZE, size);
|
||||||
|
|
||||||
AssetFileDescriptor afd = null;
|
AssetFileDescriptor afd = null;
|
||||||
try {
|
try {
|
||||||
afd = resolver.openTypedAssetFileDescriptor(documentUri, "image/*", openOpts, signal);
|
afd = client.openTypedAssetFileDescriptor(documentUri, "image/*", openOpts, signal);
|
||||||
|
|
||||||
final FileDescriptor fd = afd.getFileDescriptor();
|
final FileDescriptor fd = afd.getFileDescriptor();
|
||||||
final long offset = afd.getStartOffset();
|
final long offset = afd.getStartOffset();
|
||||||
final long length = afd.getDeclaredLength();
|
|
||||||
|
|
||||||
// Some thumbnails might be a region inside a larger file, such as
|
// Try seeking on the returned FD, since it gives us the most
|
||||||
// an EXIF thumbnail. Since BitmapFactory aggressively seeks around
|
// optimal decode path; otherwise fall back to buffering.
|
||||||
// the entire file, we read the region manually.
|
BufferedInputStream is = null;
|
||||||
byte[] region = null;
|
try {
|
||||||
if (offset > 0 && length <= 64 * KB_IN_BYTES) {
|
|
||||||
region = new byte[(int) length];
|
|
||||||
Libcore.os.lseek(fd, offset, SEEK_SET);
|
Libcore.os.lseek(fd, offset, SEEK_SET);
|
||||||
if (IoBridge.read(fd, region, 0, region.length) != region.length) {
|
} catch (ErrnoException e) {
|
||||||
region = null;
|
is = new BufferedInputStream(new FileInputStream(fd), THUMBNAIL_BUFFER_SIZE);
|
||||||
}
|
is.mark(THUMBNAIL_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We requested a rough thumbnail size, but the remote size may have
|
// We requested a rough thumbnail size, but the remote size may have
|
||||||
// returned something giant, so defensively scale down as needed.
|
// returned something giant, so defensively scale down as needed.
|
||||||
final BitmapFactory.Options opts = new BitmapFactory.Options();
|
final BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||||
opts.inJustDecodeBounds = true;
|
opts.inJustDecodeBounds = true;
|
||||||
if (region != null) {
|
if (is != null) {
|
||||||
BitmapFactory.decodeByteArray(region, 0, region.length, opts);
|
BitmapFactory.decodeStream(is, null, opts);
|
||||||
} else {
|
} else {
|
||||||
BitmapFactory.decodeFileDescriptor(fd, null, opts);
|
BitmapFactory.decodeFileDescriptor(fd, null, opts);
|
||||||
}
|
}
|
||||||
@@ -681,14 +701,17 @@ public final class DocumentsContract {
|
|||||||
opts.inJustDecodeBounds = false;
|
opts.inJustDecodeBounds = false;
|
||||||
opts.inSampleSize = Math.min(widthSample, heightSample);
|
opts.inSampleSize = Math.min(widthSample, heightSample);
|
||||||
Log.d(TAG, "Decoding with sample size " + opts.inSampleSize);
|
Log.d(TAG, "Decoding with sample size " + opts.inSampleSize);
|
||||||
if (region != null) {
|
if (is != null) {
|
||||||
return BitmapFactory.decodeByteArray(region, 0, region.length, opts);
|
is.reset();
|
||||||
|
return BitmapFactory.decodeStream(is, null, opts);
|
||||||
} else {
|
} else {
|
||||||
|
try {
|
||||||
|
Libcore.os.lseek(fd, offset, SEEK_SET);
|
||||||
|
} catch (ErrnoException e) {
|
||||||
|
e.rethrowAsIOException();
|
||||||
|
}
|
||||||
return BitmapFactory.decodeFileDescriptor(fd, null, opts);
|
return BitmapFactory.decodeFileDescriptor(fd, null, opts);
|
||||||
}
|
}
|
||||||
} catch (ErrnoException e) {
|
|
||||||
Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e);
|
|
||||||
return null;
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e);
|
Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e);
|
||||||
return null;
|
return null;
|
||||||
@@ -709,13 +732,25 @@ public final class DocumentsContract {
|
|||||||
*/
|
*/
|
||||||
public static Uri createDocument(ContentResolver resolver, Uri parentDocumentUri,
|
public static Uri createDocument(ContentResolver resolver, Uri parentDocumentUri,
|
||||||
String mimeType, String displayName) {
|
String mimeType, String displayName) {
|
||||||
|
final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
|
||||||
|
parentDocumentUri.getAuthority());
|
||||||
|
try {
|
||||||
|
return createDocument(client, parentDocumentUri, mimeType, displayName);
|
||||||
|
} finally {
|
||||||
|
ContentProviderClient.closeQuietly(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public static Uri createDocument(ContentProviderClient client, Uri parentDocumentUri,
|
||||||
|
String mimeType, String displayName) {
|
||||||
final Bundle in = new Bundle();
|
final Bundle in = new Bundle();
|
||||||
in.putString(Document.COLUMN_DOCUMENT_ID, getDocumentId(parentDocumentUri));
|
in.putString(Document.COLUMN_DOCUMENT_ID, getDocumentId(parentDocumentUri));
|
||||||
in.putString(Document.COLUMN_MIME_TYPE, mimeType);
|
in.putString(Document.COLUMN_MIME_TYPE, mimeType);
|
||||||
in.putString(Document.COLUMN_DISPLAY_NAME, displayName);
|
in.putString(Document.COLUMN_DISPLAY_NAME, displayName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Bundle out = resolver.call(parentDocumentUri, METHOD_CREATE_DOCUMENT, null, in);
|
final Bundle out = client.call(METHOD_CREATE_DOCUMENT, null, in);
|
||||||
return buildDocumentUri(
|
return buildDocumentUri(
|
||||||
parentDocumentUri.getAuthority(), out.getString(Document.COLUMN_DOCUMENT_ID));
|
parentDocumentUri.getAuthority(), out.getString(Document.COLUMN_DOCUMENT_ID));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -730,11 +765,22 @@ public final class DocumentsContract {
|
|||||||
* @param documentUri document with {@link Document#FLAG_SUPPORTS_DELETE}
|
* @param documentUri document with {@link Document#FLAG_SUPPORTS_DELETE}
|
||||||
*/
|
*/
|
||||||
public static boolean deleteDocument(ContentResolver resolver, Uri documentUri) {
|
public static boolean deleteDocument(ContentResolver resolver, Uri documentUri) {
|
||||||
|
final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
|
||||||
|
documentUri.getAuthority());
|
||||||
|
try {
|
||||||
|
return deleteDocument(client, documentUri);
|
||||||
|
} finally {
|
||||||
|
ContentProviderClient.closeQuietly(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public static boolean deleteDocument(ContentProviderClient client, Uri documentUri) {
|
||||||
final Bundle in = new Bundle();
|
final Bundle in = new Bundle();
|
||||||
in.putString(Document.COLUMN_DOCUMENT_ID, getDocumentId(documentUri));
|
in.putString(Document.COLUMN_DOCUMENT_ID, getDocumentId(documentUri));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Bundle out = resolver.call(documentUri, METHOD_DELETE_DOCUMENT, null, in);
|
final Bundle out = client.call(METHOD_DELETE_DOCUMENT, null, in);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(TAG, "Failed to delete document", e);
|
Log.w(TAG, "Failed to delete document", e);
|
||||||
|
|||||||
@@ -17,10 +17,18 @@
|
|||||||
package com.android.externalstorage;
|
package com.android.externalstorage;
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
|
import android.content.res.AssetFileDescriptor;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.MatrixCursor;
|
import android.database.MatrixCursor;
|
||||||
import android.database.MatrixCursor.RowBuilder;
|
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.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
@@ -31,7 +39,14 @@ import android.provider.DocumentsContract.Root;
|
|||||||
import android.provider.DocumentsProvider;
|
import android.provider.DocumentsProvider;
|
||||||
import android.util.Log;
|
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.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
public class TestDocumentsProvider extends DocumentsProvider {
|
public class TestDocumentsProvider extends DocumentsProvider {
|
||||||
@@ -85,7 +100,7 @@ public class TestDocumentsProvider extends DocumentsProvider {
|
|||||||
if (CRASH_DOCUMENT) System.exit(12);
|
if (CRASH_DOCUMENT) System.exit(12);
|
||||||
|
|
||||||
final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
|
final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
|
||||||
includeFile(result, documentId);
|
includeFile(result, documentId, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,12 +137,12 @@ public class TestDocumentsProvider extends DocumentsProvider {
|
|||||||
public boolean includeIfFinished(MatrixCursor result) {
|
public boolean includeIfFinished(MatrixCursor result) {
|
||||||
Log.d(TAG, hashCode() + ": includeIfFinished() found " + mFinished);
|
Log.d(TAG, hashCode() + ": includeIfFinished() found " + mFinished);
|
||||||
if (mFinished) {
|
if (mFinished) {
|
||||||
includeFile(result, "_networkfile1");
|
includeFile(result, "_networkfile1", 0);
|
||||||
includeFile(result, "_networkfile2");
|
includeFile(result, "_networkfile2", 0);
|
||||||
includeFile(result, "_networkfile3");
|
includeFile(result, "_networkfile3", 0);
|
||||||
includeFile(result, "_networkfile4");
|
includeFile(result, "_networkfile4", 0);
|
||||||
includeFile(result, "_networkfile5");
|
includeFile(result, "_networkfile5", 0);
|
||||||
includeFile(result, "_networkfile6");
|
includeFile(result, "_networkfile6", 0);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -162,11 +177,11 @@ public class TestDocumentsProvider extends DocumentsProvider {
|
|||||||
result.setNotificationUri(resolver, notifyUri);
|
result.setNotificationUri(resolver, notifyUri);
|
||||||
|
|
||||||
// Always include local results
|
// Always include local results
|
||||||
includeFile(result, MY_DOC_NULL);
|
includeFile(result, MY_DOC_NULL, 0);
|
||||||
includeFile(result, "localfile1");
|
includeFile(result, "localfile1", 0);
|
||||||
includeFile(result, "localfile2");
|
includeFile(result, "localfile2", Document.FLAG_SUPPORTS_THUMBNAIL);
|
||||||
includeFile(result, "localfile3");
|
includeFile(result, "localfile3", 0);
|
||||||
includeFile(result, "localfile4");
|
includeFile(result, "localfile4", 0);
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
// Try picking up an existing network fetch
|
// Try picking up an existing network fetch
|
||||||
@@ -217,7 +232,8 @@ public class TestDocumentsProvider extends DocumentsProvider {
|
|||||||
SystemClock.sleep(3000);
|
SystemClock.sleep(3000);
|
||||||
|
|
||||||
final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,16 +243,52 @@ public class TestDocumentsProvider extends DocumentsProvider {
|
|||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Override
|
||||||
public boolean onCreate() {
|
public boolean onCreate() {
|
||||||
return true;
|
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();
|
final RowBuilder row = result.newRow();
|
||||||
row.add(Document.COLUMN_DOCUMENT_ID, docId);
|
row.add(Document.COLUMN_DOCUMENT_ID, docId);
|
||||||
row.add(Document.COLUMN_DISPLAY_NAME, docId);
|
row.add(Document.COLUMN_DISPLAY_NAME, docId);
|
||||||
row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
|
row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
|
||||||
|
row.add(Document.COLUMN_FLAGS, flags);
|
||||||
|
|
||||||
if (MY_DOC_ID.equals(docId)) {
|
if (MY_DOC_ID.equals(docId)) {
|
||||||
row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
|
row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
|
||||||
|
|||||||
Reference in New Issue
Block a user