method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle) throws java.io.FileNotFoundException;
method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
+ method public static void ejectRoot(android.content.ContentResolver, android.net.Uri);
method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
method public static java.lang.String getDocumentId(android.net.Uri);
method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
field public static final java.lang.String COLUMN_TITLE = "title";
field public static final int FLAG_LOCAL_ONLY = 2; // 0x2
field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
+ field public static final int FLAG_SUPPORTS_EJECT = 32; // 0x20
field public static final int FLAG_SUPPORTS_IS_CHILD = 16; // 0x10
field public static final int FLAG_SUPPORTS_RECENTS = 4; // 0x4
field public static final int FLAG_SUPPORTS_SEARCH = 8; // 0x8
method public android.content.IntentSender createWebLinkIntent(java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+ method public void ejectRoot(java.lang.String);
method public android.provider.DocumentsContract.Path findDocumentPath(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle) throws java.io.FileNotFoundException;
method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
+ method public static void ejectRoot(android.content.ContentResolver, android.net.Uri);
method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
method public static java.lang.String getDocumentId(android.net.Uri);
method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
field public static final java.lang.String COLUMN_TITLE = "title";
field public static final int FLAG_LOCAL_ONLY = 2; // 0x2
field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
+ field public static final int FLAG_SUPPORTS_EJECT = 32; // 0x20
field public static final int FLAG_SUPPORTS_IS_CHILD = 16; // 0x10
field public static final int FLAG_SUPPORTS_RECENTS = 4; // 0x4
field public static final int FLAG_SUPPORTS_SEARCH = 8; // 0x8
method public android.content.IntentSender createWebLinkIntent(java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+ method public void ejectRoot(java.lang.String);
method public android.provider.DocumentsContract.Path findDocumentPath(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle) throws java.io.FileNotFoundException;
method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
+ method public static void ejectRoot(android.content.ContentResolver, android.net.Uri);
method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
method public static java.lang.String getDocumentId(android.net.Uri);
method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
field public static final java.lang.String COLUMN_TITLE = "title";
field public static final int FLAG_LOCAL_ONLY = 2; // 0x2
field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
+ field public static final int FLAG_SUPPORTS_EJECT = 32; // 0x20
field public static final int FLAG_SUPPORTS_IS_CHILD = 16; // 0x10
field public static final int FLAG_SUPPORTS_RECENTS = 4; // 0x4
field public static final int FLAG_SUPPORTS_SEARCH = 8; // 0x8
method public android.content.IntentSender createWebLinkIntent(java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+ method public void ejectRoot(java.lang.String);
method public android.provider.DocumentsContract.Path findDocumentPath(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
public static final int FLAG_SUPPORTS_IS_CHILD = 1 << 4;
/**
+ * Flag indicating that this root can be ejected.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsContract#ejectRoot(ContentResolver, Uri)
+ * @see DocumentsProvider#ejectRoot(String)
+ */
+ public static final int FLAG_SUPPORTS_EJECT = 1 << 5;
+
+ /**
* Flag indicating that this root is currently empty. This may be used
* to hide the root when opening documents, but the root will still be
* shown when creating documents and {@link #FLAG_SUPPORTS_CREATE} is
* @hide
*/
public static final int FLAG_REMOVABLE_USB = 1 << 20;
-
- /** {@hide} */
- public static final int FLAG_SUPPORTS_EJECT = 1 << 21;
}
/**
client.call(METHOD_REMOVE_DOCUMENT, null, in);
}
- /** {@hide} */
- public static boolean ejectRoot(ContentResolver resolver, Uri rootUri) {
+ /**
+ * Ejects the given root. It throws {@link IllegalStateException} when ejection failed.
+ *
+ * @param rootUri root with {@link Root#FLAG_SUPPORTS_EJECT} to be ejected
+ */
+ public static void ejectRoot(ContentResolver resolver, Uri rootUri) {
final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
rootUri.getAuthority());
try {
- return ejectRoot(client, rootUri);
- } catch (Exception e) {
- Log.w(TAG, "Failed to eject root", e);
- return false;
+ ejectRoot(client, rootUri);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
} finally {
ContentProviderClient.releaseQuietly(client);
}
}
/** {@hide} */
- public static boolean ejectRoot(ContentProviderClient client, Uri rootUri)
+ public static void ejectRoot(ContentProviderClient client, Uri rootUri)
throws RemoteException {
final Bundle in = new Bundle();
in.putParcelable(DocumentsContract.EXTRA_URI, rootUri);
- final Bundle out = client.call(METHOD_EJECT_ROOT, null, in);
-
- if (out == null) {
- throw new RemoteException("Failed to get a reponse from ejectRoot.");
- }
- if (!out.containsKey(DocumentsContract.EXTRA_RESULT)) {
- throw new RemoteException("Response did not include result field..");
- }
- return out.getBoolean(DocumentsContract.EXTRA_RESULT);
+ client.call(METHOD_EJECT_ROOT, null, in);
}
/**
throw new UnsupportedOperationException("Search not supported");
}
- /** {@hide} */
+ /**
+ * Ejects the root. Throws {@link IllegalStateException} if ejection failed.
+ *
+ * @param rootId the root to be ejected.
+ * @see Root#FLAG_SUPPORTS_EJECT
+ */
@SuppressWarnings("unused")
- public boolean ejectRoot(String rootId) {
+ public void ejectRoot(String rootId) {
throw new UnsupportedOperationException("Eject not supported");
}
if (METHOD_EJECT_ROOT.equals(method)) {
// Given that certain system apps can hold MOUNT_UNMOUNT permission, but only apps
// signed with platform signature can hold MANAGE_DOCUMENTS, we are going to check for
- // MANAGE_DOCUMENTS here instead
- getContext().enforceCallingPermission(
- android.Manifest.permission.MANAGE_DOCUMENTS, null);
+ // MANAGE_DOCUMENTS or associated URI permission here instead
final Uri rootUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
- final String rootId = DocumentsContract.getRootId(rootUri);
- final boolean ejected = ejectRoot(rootId);
+ enforceWritePermissionInner(rootUri, getCallingPackage(), null);
- out.putBoolean(DocumentsContract.EXTRA_RESULT, ejected);
+ final String rootId = DocumentsContract.getRootId(rootUri);
+ ejectRoot(rootId);
return out;
}
}
@Override
- public boolean ejectRoot(String rootId) {
+ public void ejectRoot(String rootId) {
final long token = Binder.clearCallingIdentity();
- boolean ejected = false;
RootInfo root = mRoots.get(rootId);
if (root != null) {
try {
mStorageManager.unmount(root.volumeId);
- ejected = true;
} catch (RuntimeException e) {
- Log.w(TAG, "Root '" + root.title + "' could not be ejected");
+ throw new IllegalStateException(e);
} finally {
Binder.restoreCallingIdentity(token);
}
}
- return ejected;
}
@Override