RootInfo.java revision c29dd61cbfc9f073239bdce3f4fe397deae2c623
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.documentsui.model;
18
19import static com.android.documentsui.model.DocumentInfo.getCursorInt;
20import static com.android.documentsui.model.DocumentInfo.getCursorLong;
21import static com.android.documentsui.model.DocumentInfo.getCursorString;
22
23import android.content.Context;
24import android.database.Cursor;
25import android.graphics.drawable.Drawable;
26import android.os.Parcel;
27import android.os.Parcelable;
28import android.provider.DocumentsContract.Root;
29import android.text.TextUtils;
30
31import com.android.documentsui.IconUtils;
32import com.android.documentsui.R;
33
34import java.io.DataInputStream;
35import java.io.DataOutputStream;
36import java.io.IOException;
37import java.net.ProtocolException;
38import java.util.Objects;
39
40/**
41 * Representation of a {@link Root}.
42 */
43public class RootInfo implements Durable, Parcelable {
44    private static final int VERSION_INIT = 1;
45    private static final int VERSION_DROP_TYPE = 2;
46
47    public String authority;
48    public String rootId;
49    public int flags;
50    public int icon;
51    public String title;
52    public String summary;
53    public String documentId;
54    public long availableBytes;
55    public String mimeTypes;
56
57    /** Derived fields that aren't persisted */
58    public String derivedPackageName;
59    public String[] derivedMimeTypes;
60    public int derivedIcon;
61
62    public RootInfo() {
63        reset();
64    }
65
66    @Override
67    public void reset() {
68        authority = null;
69        rootId = null;
70        flags = 0;
71        icon = 0;
72        title = null;
73        summary = null;
74        documentId = null;
75        availableBytes = -1;
76        mimeTypes = null;
77
78        derivedPackageName = null;
79        derivedMimeTypes = null;
80        derivedIcon = 0;
81    }
82
83    @Override
84    public void read(DataInputStream in) throws IOException {
85        final int version = in.readInt();
86        switch (version) {
87            case VERSION_DROP_TYPE:
88                authority = DurableUtils.readNullableString(in);
89                rootId = DurableUtils.readNullableString(in);
90                flags = in.readInt();
91                icon = in.readInt();
92                title = DurableUtils.readNullableString(in);
93                summary = DurableUtils.readNullableString(in);
94                documentId = DurableUtils.readNullableString(in);
95                availableBytes = in.readLong();
96                mimeTypes = DurableUtils.readNullableString(in);
97                deriveFields();
98                break;
99            default:
100                throw new ProtocolException("Unknown version " + version);
101        }
102    }
103
104    @Override
105    public void write(DataOutputStream out) throws IOException {
106        out.writeInt(VERSION_DROP_TYPE);
107        DurableUtils.writeNullableString(out, authority);
108        DurableUtils.writeNullableString(out, rootId);
109        out.writeInt(flags);
110        out.writeInt(icon);
111        DurableUtils.writeNullableString(out, title);
112        DurableUtils.writeNullableString(out, summary);
113        DurableUtils.writeNullableString(out, documentId);
114        out.writeLong(availableBytes);
115        DurableUtils.writeNullableString(out, mimeTypes);
116    }
117
118    @Override
119    public int describeContents() {
120        return 0;
121    }
122
123    @Override
124    public void writeToParcel(Parcel dest, int flags) {
125        DurableUtils.writeToParcel(dest, this);
126    }
127
128    public static final Creator<RootInfo> CREATOR = new Creator<RootInfo>() {
129        @Override
130        public RootInfo createFromParcel(Parcel in) {
131            final RootInfo root = new RootInfo();
132            DurableUtils.readFromParcel(in, root);
133            return root;
134        }
135
136        @Override
137        public RootInfo[] newArray(int size) {
138            return new RootInfo[size];
139        }
140    };
141
142    public static RootInfo fromRootsCursor(String authority, Cursor cursor) {
143        final RootInfo root = new RootInfo();
144        root.authority = authority;
145        root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID);
146        root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS);
147        root.icon = getCursorInt(cursor, Root.COLUMN_ICON);
148        root.title = getCursorString(cursor, Root.COLUMN_TITLE);
149        root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY);
150        root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
151        root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
152        root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
153        root.deriveFields();
154        return root;
155    }
156
157    private void deriveFields() {
158        derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
159
160        // TODO: remove these special case icons
161        if (isExternalStorage()) {
162            derivedIcon = R.drawable.ic_root_sdcard;
163        } else if (isDownloads()) {
164            derivedIcon = R.drawable.ic_root_download;
165        } else if (isImages()) {
166            derivedIcon = R.drawable.ic_doc_image;
167        } else if (isVideos()) {
168            derivedIcon = R.drawable.ic_doc_video;
169        } else if (isAudio()) {
170            derivedIcon = R.drawable.ic_doc_audio;
171        }
172    }
173
174    public boolean isRecents() {
175        return authority == null && rootId == null;
176    }
177
178    public boolean isExternalStorage() {
179        return "com.android.externalstorage.documents".equals(authority);
180    }
181
182    public boolean isDownloads() {
183        return "com.android.providers.downloads.documents".equals(authority);
184    }
185
186    public boolean isImages() {
187        return "com.android.providers.media.documents".equals(authority)
188                && "images_root".equals(rootId);
189    }
190
191    public boolean isVideos() {
192        return "com.android.providers.media.documents".equals(authority)
193                && "videos_root".equals(rootId);
194    }
195
196    public boolean isAudio() {
197        return "com.android.providers.media.documents".equals(authority)
198                && "audio_root".equals(rootId);
199    }
200
201    @Override
202    public String toString() {
203        return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
204    }
205
206    public Drawable loadIcon(Context context) {
207        if (derivedIcon != 0) {
208            return context.getResources().getDrawable(derivedIcon);
209        } else {
210            return IconUtils.loadPackageIcon(context, authority, icon);
211        }
212    }
213
214    public Drawable loadGridIcon(Context context) {
215        if (derivedIcon != 0) {
216            return IconUtils.applyTint(context, derivedIcon,
217                    android.R.attr.textColorPrimaryInverse);
218        } else {
219            return IconUtils.loadPackageIcon(context, authority, icon);
220        }
221    }
222
223    public Drawable loadToolbarIcon(Context context) {
224        if (derivedIcon != 0) {
225            return IconUtils.applyTint(context, derivedIcon,
226                    android.R.attr.colorControlNormal);
227        } else {
228            return IconUtils.loadPackageIcon(context, authority, icon);
229        }
230    }
231
232    @Override
233    public boolean equals(Object o) {
234        if (o instanceof RootInfo) {
235            final RootInfo root = (RootInfo) o;
236            return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
237        } else {
238            return false;
239        }
240    }
241
242    @Override
243    public int hashCode() {
244        return Objects.hash(authority, rootId);
245    }
246
247    public String getDirectoryString() {
248        return !TextUtils.isEmpty(summary) ? summary : title;
249    }
250}
251