/* * Copyright (C) 2014 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 android.support.v4.provider; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.provider.DocumentsContract; import android.text.TextUtils; import android.util.Log; class DocumentsContractApi19 { private static final String TAG = "DocumentFile"; public static boolean isDocumentUri(Context context, Uri self) { return DocumentsContract.isDocumentUri(context, self); } public static String getName(Context context, Uri self) { return queryForString(context, self, DocumentsContract.Document.COLUMN_DISPLAY_NAME, null); } private static String getRawType(Context context, Uri self) { return queryForString(context, self, DocumentsContract.Document.COLUMN_MIME_TYPE, null); } public static String getType(Context context, Uri self) { final String rawType = getRawType(context, self); if (DocumentsContract.Document.MIME_TYPE_DIR.equals(rawType)) { return null; } else { return rawType; } } public static boolean isDirectory(Context context, Uri self) { return DocumentsContract.Document.MIME_TYPE_DIR.equals(getRawType(context, self)); } public static boolean isFile(Context context, Uri self) { final String type = getRawType(context, self); if (DocumentsContract.Document.MIME_TYPE_DIR.equals(type) || TextUtils.isEmpty(type)) { return false; } else { return true; } } public static long lastModified(Context context, Uri self) { return queryForLong(context, self, DocumentsContract.Document.COLUMN_LAST_MODIFIED, 0); } public static long length(Context context, Uri self) { return queryForLong(context, self, DocumentsContract.Document.COLUMN_SIZE, 0); } public static boolean canRead(Context context, Uri self) { // Ignore if grant doesn't allow read if (context.checkCallingOrSelfUriPermission(self, Intent.FLAG_GRANT_READ_URI_PERMISSION) != PackageManager.PERMISSION_GRANTED) { return false; } // Ignore documents without MIME if (TextUtils.isEmpty(getRawType(context, self))) { return false; } return true; } public static boolean canWrite(Context context, Uri self) { // Ignore if grant doesn't allow write if (context.checkCallingOrSelfUriPermission(self, Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != PackageManager.PERMISSION_GRANTED) { return false; } final String type = getRawType(context, self); final int flags = queryForInt(context, self, DocumentsContract.Document.COLUMN_FLAGS, 0); // Ignore documents without MIME if (TextUtils.isEmpty(type)) { return false; } // Deletable documents considered writable if ((flags & DocumentsContract.Document.FLAG_SUPPORTS_DELETE) != 0) { return true; } if (DocumentsContract.Document.MIME_TYPE_DIR.equals(type) && (flags & DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE) != 0) { // Directories that allow create considered writable return true; } else if (!TextUtils.isEmpty(type) && (flags & DocumentsContract.Document.FLAG_SUPPORTS_WRITE) != 0) { // Writable normal files considered writable return true; } return false; } public static boolean delete(Context context, Uri self) { return DocumentsContract.deleteDocument(context.getContentResolver(), self); } public static boolean exists(Context context, Uri self) { final ContentResolver resolver = context.getContentResolver(); Cursor c = null; try { c = resolver.query(self, new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID }, null, null, null); return c.getCount() > 0; } catch (Exception e) { Log.w(TAG, "Failed query: " + e); return false; } finally { closeQuietly(c); } } private static String queryForString(Context context, Uri self, String column, String defaultValue) { final ContentResolver resolver = context.getContentResolver(); Cursor c = null; try { c = resolver.query(self, new String[] { column }, null, null, null); if (c.moveToFirst() && !c.isNull(0)) { return c.getString(0); } else { return defaultValue; } } catch (Exception e) { Log.w(TAG, "Failed query: " + e); return defaultValue; } finally { closeQuietly(c); } } private static int queryForInt(Context context, Uri self, String column, int defaultValue) { return (int) queryForLong(context, self, column, defaultValue); } private static long queryForLong(Context context, Uri self, String column, long defaultValue) { final ContentResolver resolver = context.getContentResolver(); Cursor c = null; try { c = resolver.query(self, new String[] { column }, null, null, null); if (c.moveToFirst() && !c.isNull(0)) { return c.getLong(0); } else { return defaultValue; } } catch (Exception e) { Log.w(TAG, "Failed query: " + e); return defaultValue; } finally { closeQuietly(c); } } private static void closeQuietly(AutoCloseable closeable) { if (closeable != null) { try { closeable.close(); } catch (RuntimeException rethrown) { throw rethrown; } catch (Exception ignored) { } } } }