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;
28ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
297aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport com.android.documentsui.DocumentsApplication;
30251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkeyimport com.android.documentsui.RootCursorWrapper;
31ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
320c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkeyimport libcore.io.IoUtils;
330c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey
34b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.DataInputStream;
35b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.DataOutputStream;
360c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkeyimport java.io.FileNotFoundException;
37b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.IOException;
38b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.net.ProtocolException;
39ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
40ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey/**
41ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey * Representation of a {@link Document}.
42ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey */
43d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeypublic class DocumentInfo implements Durable, Parcelable {
44b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    private static final int VERSION_INIT = 1;
45d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    private static final int VERSION_SPLIT_URI = 2;
46b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
47d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    public String authority;
48d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    public String documentId;
495dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey    public String mimeType;
505dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey    public String displayName;
515dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey    public long lastModified;
525dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey    public int flags;
535dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey    public String summary;
545dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey    public long size;
555dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey    public int icon;
56ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
57d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    /** Derived fields that aren't persisted */
58d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    public Uri derivedUri;
59d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
60b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    public DocumentInfo() {
61b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        reset();
62b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    }
63b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
64b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    @Override
65b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    public void reset() {
66d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        authority = null;
67d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        documentId = null;
68b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        mimeType = null;
69b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        displayName = null;
70b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        lastModified = -1;
71b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        flags = 0;
72b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        summary = null;
73b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        size = -1;
74b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        icon = 0;
75d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
76d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        derivedUri = null;
77b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    }
78b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
79b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    @Override
80b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    public void read(DataInputStream in) throws IOException {
81b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        final int version = in.readInt();
82b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        switch (version) {
83b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            case VERSION_INIT:
84d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey                throw new ProtocolException("Ignored upgrade");
85d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            case VERSION_SPLIT_URI:
86d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey                authority = DurableUtils.readNullableString(in);
87d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey                documentId = DurableUtils.readNullableString(in);
88b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                mimeType = DurableUtils.readNullableString(in);
89b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                displayName = DurableUtils.readNullableString(in);
90b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                lastModified = in.readLong();
91b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                flags = in.readInt();
92b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                summary = DurableUtils.readNullableString(in);
93b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                size = in.readLong();
94b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                icon = in.readInt();
95d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey                deriveFields();
96b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                break;
97b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey            default:
98b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey                throw new ProtocolException("Unknown version " + version);
99b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        }
100b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    }
101b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
102b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    @Override
103b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    public void write(DataOutputStream out) throws IOException {
104d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        out.writeInt(VERSION_SPLIT_URI);
105d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        DurableUtils.writeNullableString(out, authority);
106d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        DurableUtils.writeNullableString(out, documentId);
107b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        DurableUtils.writeNullableString(out, mimeType);
108b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        DurableUtils.writeNullableString(out, displayName);
109b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        out.writeLong(lastModified);
110b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        out.writeInt(flags);
111b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        DurableUtils.writeNullableString(out, summary);
112b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        out.writeLong(size);
113b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey        out.writeInt(icon);
114b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey    }
115b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey
116d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    @Override
117d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    public int describeContents() {
118d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        return 0;
119d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    }
120d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
121d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    @Override
122d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    public void writeToParcel(Parcel dest, int flags) {
123d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        DurableUtils.writeToParcel(dest, this);
124d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    }
125d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
126d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    public static final Creator<DocumentInfo> CREATOR = new Creator<DocumentInfo>() {
127d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        @Override
128d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public DocumentInfo createFromParcel(Parcel in) {
129d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            final DocumentInfo doc = new DocumentInfo();
130d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            DurableUtils.readFromParcel(in, doc);
131d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            return doc;
132d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        }
133d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
134d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        @Override
135d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        public DocumentInfo[] newArray(int size) {
136d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey            return new DocumentInfo[size];
137d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        }
138d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    };
139d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
140251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey    public static DocumentInfo fromDirectoryCursor(Cursor cursor) {
141251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey        final String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
142d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        return fromCursor(cursor, authority);
143d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    }
144d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
145d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    public static DocumentInfo fromCursor(Cursor cursor, String authority) {
146deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        final DocumentInfo info = new DocumentInfo();
147deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        info.updateFromCursor(cursor, authority);
148deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        return info;
149ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
150ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
151deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey    public void updateFromCursor(Cursor cursor, String authority) {
152deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.authority = authority;
153deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
154deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
155deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
156deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
157deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.displayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
158deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
159deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.flags = getCursorInt(cursor, Document.COLUMN_FLAGS);
160deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.summary = getCursorString(cursor, Document.COLUMN_SUMMARY);
161deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.size = getCursorLong(cursor, Document.COLUMN_SIZE);
162deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.icon = getCursorInt(cursor, Document.COLUMN_ICON);
163deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        this.deriveFields();
164deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey    }
165deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
166deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey    public static DocumentInfo fromUri(ContentResolver resolver, Uri uri)
167deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            throws FileNotFoundException {
168deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        final DocumentInfo info = new DocumentInfo();
169deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        info.updateFromUri(resolver, uri);
170deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        return info;
171deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey    }
172deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
173deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey    /**
174deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey     * Update a possibly stale restored document against a live
175deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey     * {@link DocumentsProvider}.
176deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey     */
177deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey    public void updateSelf(ContentResolver resolver) throws FileNotFoundException {
178deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey        updateFromUri(resolver, derivedUri);
179deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey    }
180deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey
181deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey    public void updateFromUri(ContentResolver resolver, Uri uri) throws FileNotFoundException {
1827aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey        ContentProviderClient client = null;
1830c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey        Cursor cursor = null;
184ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        try {
1857aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            client = DocumentsApplication.acquireUnstableProviderOrThrow(
1867aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey                    resolver, uri.getAuthority());
187ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey            cursor = client.query(uri, null, null, null, null);
188ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            if (!cursor.moveToFirst()) {
1890c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey                throw new FileNotFoundException("Missing details for " + uri);
190ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey            }
191deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey            updateFromCursor(cursor, uri.getAuthority());
1920c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey        } catch (Throwable t) {
1930c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey            throw asFileNotFoundException(t);
194ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        } finally {
1950c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey            IoUtils.closeQuietly(cursor);
1967aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey            ContentProviderClient.releaseQuietly(client);
197ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey        }
198ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
199ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
200d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    private void deriveFields() {
201d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey        derivedUri = DocumentsContract.buildDocumentUri(authority, documentId);
202d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    }
203d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey
204ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    @Override
205ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    public String toString() {
2065545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey        return "Document{docId=" + documentId + ", name=" + displayName + "}";
207ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
208ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
209ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    public boolean isCreateSupported() {
210ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        return (flags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0;
211ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
212ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
213ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    public boolean isThumbnailSupported() {
214ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        return (flags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
215ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
216ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
217b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    public boolean isDirectory() {
218ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        return Document.MIME_TYPE_DIR.equals(mimeType);
219b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey    }
220b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey
2214eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey    public boolean isGridPreferred() {
222ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        return (flags & Document.FLAG_DIR_PREFERS_GRID) != 0;
2234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey    }
2244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey
2254eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey    public boolean isDeleteSupported() {
226ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        return (flags & Document.FLAG_SUPPORTS_DELETE) != 0;
2274eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey    }
2284eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey
229f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey    public boolean isGridTitlesHidden() {
230f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey        return (flags & Document.FLAG_DIR_HIDE_GRID_TITLES) != 0;
231f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey    }
232f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey
233ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public static String getCursorString(Cursor cursor, String columnName) {
234b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        final int index = cursor.getColumnIndex(columnName);
235b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        return (index != -1) ? cursor.getString(index) : null;
236ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
237ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
238a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey    /**
239a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey     * Missing or null values are returned as -1.
240a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey     */
241ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public static long getCursorLong(Cursor cursor, String columnName) {
242b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        final int index = cursor.getColumnIndex(columnName);
243a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        if (index == -1) return -1;
244a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        final String value = cursor.getString(index);
245a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        if (value == null) return -1;
246a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        try {
247a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            return Long.parseLong(value);
248a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        } catch (NumberFormatException e) {
249a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey            return -1;
250a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey        }
251ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
252ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
253d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey    /**
254d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey     * Missing or null values are returned as 0.
255d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey     */
256ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public static int getCursorInt(Cursor cursor, String columnName) {
257b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        final int index = cursor.getColumnIndex(columnName);
258b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey        return (index != -1) ? cursor.getInt(index) : 0;
259ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey    }
260ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey
2610c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey    public static FileNotFoundException asFileNotFoundException(Throwable t)
2620c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey            throws FileNotFoundException {
2630c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey        if (t instanceof FileNotFoundException) {
2640c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey            throw (FileNotFoundException) t;
2650c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey        }
2660c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey        final FileNotFoundException fnfe = new FileNotFoundException(t.getMessage());
2670c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey        fnfe.initCause(t);
2680c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey        throw fnfe;
2690c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey    }
270aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey
271aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey    public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
272aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey        if (lhs == null) return -1;
273aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey        if (rhs == null) return 1;
274aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey        return lhs.compareToIgnoreCase(rhs);
275aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey    }
276ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey}
277