package androidx.documentfile.provider; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.DocumentsContract; import android.text.TextUtils; import android.util.Log; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; @RequiresApi(19) public class DocumentsContractApi19 { private static final int FLAG_VIRTUAL_DOCUMENT = 512; private static final String TAG = "DocumentFile"; private DocumentsContractApi19() { } public static boolean canRead(Context context, Uri uri) { return context.checkCallingOrSelfUriPermission(uri, 1) == 0 && !TextUtils.isEmpty(getRawType(context, uri)); } public static boolean canWrite(Context context, Uri uri) { if (context.checkCallingOrSelfUriPermission(uri, 2) != 0) { return false; } String rawType = getRawType(context, uri); int queryForInt = queryForInt(context, uri, "flags", 0); if (TextUtils.isEmpty(rawType)) { return false; } if ((queryForInt & 4) != 0) { return true; } if (!"vnd.android.document/directory".equals(rawType) || (queryForInt & 8) == 0) { return !TextUtils.isEmpty(rawType) && (queryForInt & 2) != 0; } return true; } private static void closeQuietly(@Nullable AutoCloseable autoCloseable) { if (autoCloseable != null) { try { autoCloseable.close(); } catch (RuntimeException e) { throw e; } catch (Exception unused) { } } } public static boolean exists(Context context, Uri uri) { ContentResolver contentResolver = context.getContentResolver(); boolean z2 = false; Cursor cursor = null; try { cursor = contentResolver.query(uri, new String[]{"document_id"}, null, null, null); if (cursor.getCount() > 0) { z2 = true; } return z2; } catch (Exception e) { Log.w("DocumentFile", "Failed query: " + e); return false; } finally { closeQuietly(cursor); } } public static long getFlags(Context context, Uri uri) { return queryForLong(context, uri, "flags", 0); } @Nullable public static String getName(Context context, Uri uri) { return queryForString(context, uri, "_display_name", null); } @Nullable private static String getRawType(Context context, Uri uri) { return queryForString(context, uri, "mime_type", null); } @Nullable public static String getType(Context context, Uri uri) { String rawType = getRawType(context, uri); if ("vnd.android.document/directory".equals(rawType)) { return null; } return rawType; } public static boolean isDirectory(Context context, Uri uri) { return "vnd.android.document/directory".equals(getRawType(context, uri)); } public static boolean isFile(Context context, Uri uri) { String rawType = getRawType(context, uri); return !"vnd.android.document/directory".equals(rawType) && !TextUtils.isEmpty(rawType); } public static boolean isVirtual(Context context, Uri uri) { return DocumentsContract.isDocumentUri(context, uri) && (getFlags(context, uri) & 512) != 0; } public static long lastModified(Context context, Uri uri) { return queryForLong(context, uri, "last_modified", 0); } public static long length(Context context, Uri uri) { return queryForLong(context, uri, "_size", 0); } private static int queryForInt(Context context, Uri uri, String str, int i) { return (int) queryForLong(context, uri, str, (long) i); } private static long queryForLong(Context context, Uri uri, String str, long j) { AutoCloseable autoCloseable = null; try { autoCloseable = context.getContentResolver().query(uri, new String[]{str}, null, null, null); if (autoCloseable.moveToFirst() && !autoCloseable.isNull(0)) { return autoCloseable.getLong(0); } closeQuietly(autoCloseable); return j; } catch (Exception e) { Log.w("DocumentFile", "Failed query: " + e); return j; } finally { closeQuietly(autoCloseable); } } @Nullable private static String queryForString(Context context, Uri uri, String str, @Nullable String str2) { AutoCloseable autoCloseable = null; try { autoCloseable = context.getContentResolver().query(uri, new String[]{str}, null, null, null); if (autoCloseable.moveToFirst() && !autoCloseable.isNull(0)) { return autoCloseable.getString(0); } closeQuietly(autoCloseable); return str2; } catch (Exception e) { Log.w("DocumentFile", "Failed query: " + e); return str2; } finally { closeQuietly(autoCloseable); } } }