RootInfo.java revision a9ce049db87259e302e2368d2a4a1c11a94fd831
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
46    public String authority;
47    public String rootId;
48    public int rootType;
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        rootType = 0;
71        flags = 0;
72        icon = 0;
73        title = null;
74        summary = null;
75        documentId = null;
76        availableBytes = -1;
77        mimeTypes = null;
78
79        derivedPackageName = null;
80        derivedMimeTypes = null;
81        derivedIcon = 0;
82    }
83
84    @Override
85    public void read(DataInputStream in) throws IOException {
86        final int version = in.readInt();
87        switch (version) {
88            case VERSION_INIT:
89                authority = DurableUtils.readNullableString(in);
90                rootId = DurableUtils.readNullableString(in);
91                rootType = in.readInt();
92                flags = in.readInt();
93                icon = in.readInt();
94                title = DurableUtils.readNullableString(in);
95                summary = DurableUtils.readNullableString(in);
96                documentId = DurableUtils.readNullableString(in);
97                availableBytes = in.readLong();
98                mimeTypes = DurableUtils.readNullableString(in);
99                deriveFields();
100                break;
101            default:
102                throw new ProtocolException("Unknown version " + version);
103        }
104    }
105
106    @Override
107    public void write(DataOutputStream out) throws IOException {
108        out.writeInt(VERSION_INIT);
109        DurableUtils.writeNullableString(out, authority);
110        DurableUtils.writeNullableString(out, rootId);
111        out.writeInt(rootType);
112        out.writeInt(flags);
113        out.writeInt(icon);
114        DurableUtils.writeNullableString(out, title);
115        DurableUtils.writeNullableString(out, summary);
116        DurableUtils.writeNullableString(out, documentId);
117        out.writeLong(availableBytes);
118        DurableUtils.writeNullableString(out, mimeTypes);
119    }
120
121    @Override
122    public int describeContents() {
123        return 0;
124    }
125
126    @Override
127    public void writeToParcel(Parcel dest, int flags) {
128        DurableUtils.writeToParcel(dest, this);
129    }
130
131    public static final Creator<RootInfo> CREATOR = new Creator<RootInfo>() {
132        @Override
133        public RootInfo createFromParcel(Parcel in) {
134            final RootInfo root = new RootInfo();
135            DurableUtils.readFromParcel(in, root);
136            return root;
137        }
138
139        @Override
140        public RootInfo[] newArray(int size) {
141            return new RootInfo[size];
142        }
143    };
144
145    public static RootInfo fromRootsCursor(String authority, Cursor cursor) {
146        final RootInfo root = new RootInfo();
147        root.authority = authority;
148        root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID);
149        root.rootType = getCursorInt(cursor, Root.COLUMN_ROOT_TYPE);
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 ("com.android.externalstorage.documents".equals(authority)) {
166            if ("documents".equals(rootId)) {
167                derivedIcon = R.drawable.ic_doc_text;
168            } else {
169                derivedIcon = R.drawable.ic_root_sdcard;
170            }
171        }
172        if ("com.android.providers.downloads.documents".equals(authority)) {
173            derivedIcon = R.drawable.ic_root_download;
174        }
175        if ("com.android.providers.media.documents".equals(authority)) {
176            if ("images_root".equals(rootId)) {
177                derivedIcon = R.drawable.ic_doc_image;
178            } else if ("videos_root".equals(rootId)) {
179                derivedIcon = R.drawable.ic_doc_video;
180            } else if ("audio_root".equals(rootId)) {
181                derivedIcon = R.drawable.ic_doc_audio;
182            }
183        }
184    }
185
186    @Override
187    public String toString() {
188        return "Root{title=" + title + ", rootId=" + rootId + "}";
189    }
190
191    public Drawable loadIcon(Context context) {
192        if (derivedIcon != 0) {
193            return context.getResources().getDrawable(derivedIcon);
194        } else {
195            return IconUtils.loadPackageIcon(context, authority, icon);
196        }
197    }
198
199    @Override
200    public boolean equals(Object o) {
201        if (o instanceof RootInfo) {
202            final RootInfo root = (RootInfo) o;
203            return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
204        } else {
205            return false;
206        }
207    }
208
209    @Override
210    public int hashCode() {
211        return Objects.hash(authority, rootId);
212    }
213
214    public String getDirectoryString() {
215        return !TextUtils.isEmpty(summary) ? summary : title;
216    }
217}
218