RootInfo.java revision a847d79310320ae8adbedb281123a0f879c2fc6e
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 int lightIcon;
52    public String title;
53    public String summary;
54    public String documentId;
55    public long availableBytes;
56    public String mimeTypes;
57
58    /** Derived fields that aren't persisted */
59    public String derivedPackageName;
60    public String[] derivedMimeTypes;
61    public int derivedIcon;
62    public int derivedLightIcon;
63
64    public RootInfo() {
65        reset();
66    }
67
68    @Override
69    public void reset() {
70        authority = null;
71        rootId = null;
72        flags = 0;
73        icon = 0;
74        lightIcon = 0;
75        title = null;
76        summary = null;
77        documentId = null;
78        availableBytes = -1;
79        mimeTypes = null;
80
81        derivedPackageName = null;
82        derivedMimeTypes = null;
83        derivedIcon = 0;
84        derivedLightIcon = 0;
85    }
86
87    @Override
88    public void read(DataInputStream in) throws IOException {
89        final int version = in.readInt();
90        switch (version) {
91            case VERSION_DROP_TYPE:
92                authority = DurableUtils.readNullableString(in);
93                rootId = DurableUtils.readNullableString(in);
94                flags = in.readInt();
95                icon = in.readInt();
96                title = DurableUtils.readNullableString(in);
97                summary = DurableUtils.readNullableString(in);
98                documentId = DurableUtils.readNullableString(in);
99                availableBytes = in.readLong();
100                mimeTypes = DurableUtils.readNullableString(in);
101                deriveFields();
102                break;
103            default:
104                throw new ProtocolException("Unknown version " + version);
105        }
106    }
107
108    @Override
109    public void write(DataOutputStream out) throws IOException {
110        out.writeInt(VERSION_DROP_TYPE);
111        DurableUtils.writeNullableString(out, authority);
112        DurableUtils.writeNullableString(out, rootId);
113        out.writeInt(flags);
114        out.writeInt(icon);
115        DurableUtils.writeNullableString(out, title);
116        DurableUtils.writeNullableString(out, summary);
117        DurableUtils.writeNullableString(out, documentId);
118        out.writeLong(availableBytes);
119        DurableUtils.writeNullableString(out, mimeTypes);
120    }
121
122    @Override
123    public int describeContents() {
124        return 0;
125    }
126
127    @Override
128    public void writeToParcel(Parcel dest, int flags) {
129        DurableUtils.writeToParcel(dest, this);
130    }
131
132    public static final Creator<RootInfo> CREATOR = new Creator<RootInfo>() {
133        @Override
134        public RootInfo createFromParcel(Parcel in) {
135            final RootInfo root = new RootInfo();
136            DurableUtils.readFromParcel(in, root);
137            return root;
138        }
139
140        @Override
141        public RootInfo[] newArray(int size) {
142            return new RootInfo[size];
143        }
144    };
145
146    public static RootInfo fromRootsCursor(String authority, Cursor cursor) {
147        final RootInfo root = new RootInfo();
148        root.authority = authority;
149        root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID);
150        root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS);
151        root.icon = getCursorInt(cursor, Root.COLUMN_ICON);
152        root.title = getCursorString(cursor, Root.COLUMN_TITLE);
153        root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY);
154        root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
155        root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
156        root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
157        root.deriveFields();
158        return root;
159    }
160
161    private void deriveFields() {
162        derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
163
164        // TODO: remove these special case icons
165        if (isExternalStorage()) {
166            derivedIcon = R.drawable.ic_root_sdcard_dark;
167            derivedLightIcon = R.drawable.ic_root_sdcard_light;
168        } else if (isDownloads()) {
169            derivedIcon = R.drawable.ic_root_download_dark;
170            derivedLightIcon = R.drawable.ic_root_download_light;
171        } else if (isImages()) {
172            derivedIcon = R.drawable.ic_doc_image_dark;
173            derivedLightIcon = R.drawable.ic_doc_image_light;
174        } else if (isVideos()) {
175            derivedIcon = R.drawable.ic_doc_video_dark;
176            derivedLightIcon = R.drawable.ic_doc_video_light;
177        } else if (isAudio()) {
178            derivedIcon = R.drawable.ic_doc_audio_dark;
179            derivedLightIcon = R.drawable.ic_doc_audio_light;
180        }
181    }
182
183    public boolean isRecents() {
184        return authority == null && rootId == null;
185    }
186
187    public boolean isExternalStorage() {
188        return "com.android.externalstorage.documents".equals(authority);
189    }
190
191    public boolean isDownloads() {
192        return "com.android.providers.downloads.documents".equals(authority);
193    }
194
195    public boolean isImages() {
196        return "com.android.providers.media.documents".equals(authority)
197                && "images_root".equals(rootId);
198    }
199
200    public boolean isVideos() {
201        return "com.android.providers.media.documents".equals(authority)
202                && "videos_root".equals(rootId);
203    }
204
205    public boolean isAudio() {
206        return "com.android.providers.media.documents".equals(authority)
207                && "audio_root".equals(rootId);
208    }
209
210    @Override
211    public String toString() {
212        return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
213    }
214
215    public Drawable loadIcon(Context context) {
216        if (derivedIcon != 0) {
217            return context.getResources().getDrawable(derivedIcon);
218        } else {
219            return IconUtils.loadPackageIcon(context, authority, icon);
220        }
221    }
222
223    public Drawable loadLightIcon(Context context) {
224        if (derivedLightIcon != 0) {
225            return context.getResources().getDrawable(derivedLightIcon);
226        } else if (lightIcon != 0) {
227            return IconUtils.loadPackageIcon(context, authority, lightIcon);
228        } else {
229            return loadIcon(context);
230        }
231    }
232
233    @Override
234    public boolean equals(Object o) {
235        if (o instanceof RootInfo) {
236            final RootInfo root = (RootInfo) o;
237            return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
238        } else {
239            return false;
240        }
241    }
242
243    @Override
244    public int hashCode() {
245        return Objects.hash(authority, rootId);
246    }
247
248    public String getDirectoryString() {
249        return !TextUtils.isEmpty(summary) ? summary : title;
250    }
251}
252