1ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey/* 2ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project 3ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * 4ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * you may not use this file except in compliance with the License. 6ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * You may obtain a copy of the License at 7ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * 8ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * 10ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * See the License for the specific language governing permissions and 14ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey * limitations under the License. 15ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey */ 16ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 17ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeypackage com.android.documentsui.model; 18ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 19ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkeyimport android.content.ContentProviderClient; 20ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.content.ContentResolver; 21ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.database.Cursor; 22ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.net.Uri; 23d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport android.os.Parcel; 24d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport android.os.Parcelable; 25ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.provider.DocumentsContract; 26ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport android.provider.DocumentsContract.Document; 277aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.provider.DocumentsProvider; 28d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKayimport android.support.annotation.VisibleForTesting; 29ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 307aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport com.android.documentsui.DocumentsApplication; 31251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkeyimport com.android.documentsui.RootCursorWrapper; 32ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 330c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkeyimport libcore.io.IoUtils; 340c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey 35b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.DataInputStream; 36b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.DataOutputStream; 370c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkeyimport java.io.FileNotFoundException; 38b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.IOException; 39b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.net.ProtocolException; 4030551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKayimport java.util.Objects; 41ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 42ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey/** 43ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Representation of a {@link Document}. 44ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey */ 45d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeypublic class DocumentInfo implements Durable, Parcelable { 46b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private static final int VERSION_INIT = 1; 47d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey private static final int VERSION_SPLIT_URI = 2; 48b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 49d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public String authority; 50d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public String documentId; 515dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public String mimeType; 525dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public String displayName; 535dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public long lastModified; 545dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public int flags; 555dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public String summary; 565dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public long size; 575dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public int icon; 58ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 59d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey /** Derived fields that aren't persisted */ 60d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public Uri derivedUri; 61d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 62b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public DocumentInfo() { 63b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey reset(); 64b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 65b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 66b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 67b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public void reset() { 68d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey authority = null; 69d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey documentId = null; 70b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mimeType = null; 71b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey displayName = null; 72b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey lastModified = -1; 73b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey flags = 0; 74b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey summary = null; 75b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey size = -1; 76b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey icon = 0; 77d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey derivedUri = null; 78b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 79b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 80b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 81b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public void read(DataInputStream in) throws IOException { 82b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final int version = in.readInt(); 83b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey switch (version) { 84b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey case VERSION_INIT: 85d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey throw new ProtocolException("Ignored upgrade"); 86d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey case VERSION_SPLIT_URI: 87d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey authority = DurableUtils.readNullableString(in); 88d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey documentId = DurableUtils.readNullableString(in); 89b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mimeType = DurableUtils.readNullableString(in); 90b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey displayName = DurableUtils.readNullableString(in); 91b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey lastModified = in.readLong(); 92b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey flags = in.readInt(); 93b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey summary = DurableUtils.readNullableString(in); 94b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey size = in.readLong(); 95b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey icon = in.readInt(); 96d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey deriveFields(); 97b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey break; 98b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey default: 99b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey throw new ProtocolException("Unknown version " + version); 100b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 101b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 102b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 103b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey @Override 104b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey public void write(DataOutputStream out) throws IOException { 105d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey out.writeInt(VERSION_SPLIT_URI); 106d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey DurableUtils.writeNullableString(out, authority); 107d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey DurableUtils.writeNullableString(out, documentId); 108b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey DurableUtils.writeNullableString(out, mimeType); 109b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey DurableUtils.writeNullableString(out, displayName); 110b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeLong(lastModified); 111b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeInt(flags); 112b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey DurableUtils.writeNullableString(out, summary); 113b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeLong(size); 114b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey out.writeInt(icon); 115b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 116b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 117d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey @Override 118d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public int describeContents() { 119d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey return 0; 120d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 121d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 122d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey @Override 123d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public void writeToParcel(Parcel dest, int flags) { 124d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey DurableUtils.writeToParcel(dest, this); 125d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 126d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 127d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static final Creator<DocumentInfo> CREATOR = new Creator<DocumentInfo>() { 128d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey @Override 129d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public DocumentInfo createFromParcel(Parcel in) { 130d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final DocumentInfo doc = new DocumentInfo(); 131d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey DurableUtils.readFromParcel(in, doc); 132d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey return doc; 133d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 134d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 135d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey @Override 136d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public DocumentInfo[] newArray(int size) { 137d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey return new DocumentInfo[size]; 138d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 139d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey }; 140d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 141251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey public static DocumentInfo fromDirectoryCursor(Cursor cursor) { 142dcc68fdd0ca1f0d2d2dfb979dd837ac2dd2e16f3Steve McKay assert(cursor != null); 143251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); 144d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey return fromCursor(cursor, authority); 145d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 146d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 147d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey public static DocumentInfo fromCursor(Cursor cursor, String authority) { 148dcc68fdd0ca1f0d2d2dfb979dd837ac2dd2e16f3Steve McKay assert(cursor != null); 149deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final DocumentInfo info = new DocumentInfo(); 150deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey info.updateFromCursor(cursor, authority); 151deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey return info; 152ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 153ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 154deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey public void updateFromCursor(Cursor cursor, String authority) { 155deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.authority = authority; 156deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); 157deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 158deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.displayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME); 159deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED); 160deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.flags = getCursorInt(cursor, Document.COLUMN_FLAGS); 161deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.summary = getCursorString(cursor, Document.COLUMN_SUMMARY); 162deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.size = getCursorLong(cursor, Document.COLUMN_SIZE); 163deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.icon = getCursorInt(cursor, Document.COLUMN_ICON); 164deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey this.deriveFields(); 165deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } 166deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 167deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey public static DocumentInfo fromUri(ContentResolver resolver, Uri uri) 168deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey throws FileNotFoundException { 169deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final DocumentInfo info = new DocumentInfo(); 170deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey info.updateFromUri(resolver, uri); 171deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey return info; 172deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } 173deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 174deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey /** 175deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey * Update a possibly stale restored document against a live 176deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey * {@link DocumentsProvider}. 177deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey */ 178deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey public void updateSelf(ContentResolver resolver) throws FileNotFoundException { 179deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey updateFromUri(resolver, derivedUri); 180deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey } 181deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 182deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey public void updateFromUri(ContentResolver resolver, Uri uri) throws FileNotFoundException { 1837aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient client = null; 1840c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey Cursor cursor = null; 185ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey try { 1867aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey client = DocumentsApplication.acquireUnstableProviderOrThrow( 1877aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey resolver, uri.getAuthority()); 188ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey cursor = client.query(uri, null, null, null, null); 189ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey if (!cursor.moveToFirst()) { 1900c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey throw new FileNotFoundException("Missing details for " + uri); 191ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 192deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey updateFromCursor(cursor, uri.getAuthority()); 1930c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey } catch (Throwable t) { 1940c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey throw asFileNotFoundException(t); 195ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } finally { 1960c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey IoUtils.closeQuietly(cursor); 1977aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentProviderClient.releaseQuietly(client); 198ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 199ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 200ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 201d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay @VisibleForTesting 202d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay void deriveFields() { 203d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey derivedUri = DocumentsContract.buildDocumentUri(authority, documentId); 204d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey } 205d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey 206ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 207ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public String toString() { 208d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay return "Document{" 209d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay + "docId=" + documentId 210d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay + ", name=" + displayName 21127d20a3024d477bc23055825e0f05203982539c3Steve McKay + ", isContainer=" + isContainer() 212d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay + ", isDirectory=" + isDirectory() 21327d20a3024d477bc23055825e0f05203982539c3Steve McKay + ", isArchive=" + isArchive() 214168e464812341fdc64c3b85659b60114bee3b86eSteve McKay + ", isPartial=" + isPartial() 21527d20a3024d477bc23055825e0f05203982539c3Steve McKay + ", isVirtualDocument=" + isVirtualDocument() 21627d20a3024d477bc23055825e0f05203982539c3Steve McKay + ", isDeleteSupported=" + isDeleteSupported() 21727d20a3024d477bc23055825e0f05203982539c3Steve McKay + ", isCreateSupported=" + isCreateSupported() 21827d20a3024d477bc23055825e0f05203982539c3Steve McKay + ", isRenameSupported=" + isRenameSupported() 219d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay + "}"; 220ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 221ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 222ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public boolean isCreateSupported() { 223ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return (flags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0; 224ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 225ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 226ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public boolean isThumbnailSupported() { 227ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return (flags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0; 228ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 229ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 230b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public boolean isDirectory() { 231ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return Document.MIME_TYPE_DIR.equals(mimeType); 232b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 233b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 2344eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public boolean isGridPreferred() { 235ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return (flags & Document.FLAG_DIR_PREFERS_GRID) != 0; 2364eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 2374eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 2384eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public boolean isDeleteSupported() { 239ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return (flags & Document.FLAG_SUPPORTS_DELETE) != 0; 2404eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 2414eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 24227d20a3024d477bc23055825e0f05203982539c3Steve McKay public boolean isRemoveSupported() { 24327d20a3024d477bc23055825e0f05203982539c3Steve McKay return (flags & Document.FLAG_SUPPORTS_REMOVE) != 0; 24427d20a3024d477bc23055825e0f05203982539c3Steve McKay } 24527d20a3024d477bc23055825e0f05203982539c3Steve McKay 2463b327ef9f9dec19612202b4b0b450966870a077fAga Wronska public boolean isRenameSupported() { 2473b327ef9f9dec19612202b4b0b450966870a077fAga Wronska return (flags & Document.FLAG_SUPPORTS_RENAME) != 0; 2483b327ef9f9dec19612202b4b0b450966870a077fAga Wronska } 2493b327ef9f9dec19612202b4b0b450966870a077fAga Wronska 25039acff5a36ab0540981cdae3027ea1a45fe040e5Tomasz Mikolajewski public boolean isArchive() { 25139acff5a36ab0540981cdae3027ea1a45fe040e5Tomasz Mikolajewski return (flags & Document.FLAG_ARCHIVE) != 0; 25239acff5a36ab0540981cdae3027ea1a45fe040e5Tomasz Mikolajewski } 25339acff5a36ab0540981cdae3027ea1a45fe040e5Tomasz Mikolajewski 254168e464812341fdc64c3b85659b60114bee3b86eSteve McKay public boolean isPartial() { 255168e464812341fdc64c3b85659b60114bee3b86eSteve McKay return (flags & Document.FLAG_PARTIAL) != 0; 256168e464812341fdc64c3b85659b60114bee3b86eSteve McKay } 257168e464812341fdc64c3b85659b60114bee3b86eSteve McKay 25839acff5a36ab0540981cdae3027ea1a45fe040e5Tomasz Mikolajewski public boolean isContainer() { 25939acff5a36ab0540981cdae3027ea1a45fe040e5Tomasz Mikolajewski return isDirectory() || isArchive(); 26039acff5a36ab0540981cdae3027ea1a45fe040e5Tomasz Mikolajewski } 26139acff5a36ab0540981cdae3027ea1a45fe040e5Tomasz Mikolajewski 262470a3dbc5d9c299803ba407497458acefd34f546Tomasz Mikolajewski public boolean isVirtualDocument() { 263470a3dbc5d9c299803ba407497458acefd34f546Tomasz Mikolajewski return (flags & Document.FLAG_VIRTUAL_DOCUMENT) != 0; 264470a3dbc5d9c299803ba407497458acefd34f546Tomasz Mikolajewski } 265470a3dbc5d9c299803ba407497458acefd34f546Tomasz Mikolajewski 266d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay public int hashCode() { 267d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay return derivedUri.hashCode() + mimeType.hashCode(); 268d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay } 269d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay 27030551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay public boolean equals(Object o) { 27130551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay if (o == null) { 272d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay return false; 273d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay } 274d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay 27530551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay if (this == o) { 27630551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay return true; 27730551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay } 27830551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay 27930551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay if (o instanceof DocumentInfo) { 28030551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay DocumentInfo other = (DocumentInfo) o; 28130551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay // Uri + mime type should be totally unique. 28230551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay return Objects.equals(derivedUri, other.derivedUri) 28330551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay && Objects.equals(mimeType, other.mimeType); 28430551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay } 28530551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay 28630551a257ca39f716a1d83c5cfd64d9c20efa6adSteve McKay return false; 287d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay } 288d3afdeebeb9dcfbb5f24e4afac988e2e96de26deSteve McKay 289ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public static String getCursorString(Cursor cursor, String columnName) { 290b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final int index = cursor.getColumnIndex(columnName); 291b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return (index != -1) ? cursor.getString(index) : null; 292ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 293ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 294a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey /** 295a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey * Missing or null values are returned as -1. 296a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey */ 297ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public static long getCursorLong(Cursor cursor, String columnName) { 298b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final int index = cursor.getColumnIndex(columnName); 299a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey if (index == -1) return -1; 300a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey final String value = cursor.getString(index); 301a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey if (value == null) return -1; 302a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey try { 303a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey return Long.parseLong(value); 304a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } catch (NumberFormatException e) { 305a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey return -1; 306a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 307ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 308ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 309d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey /** 310d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey * Missing or null values are returned as 0. 311d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey */ 312ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public static int getCursorInt(Cursor cursor, String columnName) { 313b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final int index = cursor.getColumnIndex(columnName); 314b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return (index != -1) ? cursor.getInt(index) : 0; 315ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 316ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 3170c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey public static FileNotFoundException asFileNotFoundException(Throwable t) 3180c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey throws FileNotFoundException { 3190c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey if (t instanceof FileNotFoundException) { 3200c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey throw (FileNotFoundException) t; 3210c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey } 3220c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey final FileNotFoundException fnfe = new FileNotFoundException(t.getMessage()); 3230c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey fnfe.initCause(t); 3240c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey throw fnfe; 3250c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey } 326ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey} 327