RootInfo.java revision d182bb641f228b2d28527a6aa86075f6358ab838
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;
29
30import com.android.documentsui.IconUtils;
31import com.android.documentsui.R;
32
33import java.io.DataInputStream;
34import java.io.DataOutputStream;
35import java.io.IOException;
36import java.net.ProtocolException;
37import java.util.Objects;
38
39/**
40 * Representation of a {@link Root}.
41 */
42public class RootInfo implements Durable, Parcelable {
43    private static final int VERSION_INIT = 1;
44
45    public String authority;
46    public String rootId;
47    public int rootType;
48    public int flags;
49    public int icon;
50    public String title;
51    public String summary;
52    public String documentId;
53    public long availableBytes;
54    public String mimeTypes;
55
56    /** Derived fields that aren't persisted */
57    public String[] derivedMimeTypes;
58    public int derivedIcon;
59
60    public RootInfo() {
61        reset();
62    }
63
64    @Override
65    public void reset() {
66        authority = null;
67        rootId = null;
68        rootType = 0;
69        flags = 0;
70        icon = 0;
71        title = null;
72        summary = null;
73        documentId = null;
74        availableBytes = -1;
75        mimeTypes = null;
76
77        derivedMimeTypes = null;
78        derivedIcon = 0;
79    }
80
81    @Override
82    public void read(DataInputStream in) throws IOException {
83        final int version = in.readInt();
84        switch (version) {
85            case VERSION_INIT:
86                authority = DurableUtils.readNullableString(in);
87                rootId = DurableUtils.readNullableString(in);
88                rootType = in.readInt();
89                flags = in.readInt();
90                icon = in.readInt();
91                title = DurableUtils.readNullableString(in);
92                summary = DurableUtils.readNullableString(in);
93                documentId = DurableUtils.readNullableString(in);
94                availableBytes = in.readLong();
95                mimeTypes = DurableUtils.readNullableString(in);
96                deriveFields();
97                break;
98            default:
99                throw new ProtocolException("Unknown version " + version);
100        }
101    }
102
103    @Override
104    public void write(DataOutputStream out) throws IOException {
105        out.writeInt(VERSION_INIT);
106        DurableUtils.writeNullableString(out, authority);
107        DurableUtils.writeNullableString(out, rootId);
108        out.writeInt(rootType);
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.rootType = getCursorInt(cursor, Root.COLUMN_ROOT_TYPE);
147        root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS);
148        root.icon = getCursorInt(cursor, Root.COLUMN_ICON);
149        root.title = getCursorString(cursor, Root.COLUMN_TITLE);
150        root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY);
151        root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
152        root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
153        root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
154        root.deriveFields();
155        return root;
156    }
157
158    private void deriveFields() {
159        derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
160
161        // TODO: remove these special case icons
162        if ("com.android.externalstorage.documents".equals(authority)) {
163            derivedIcon = R.drawable.ic_root_sdcard;
164        }
165        if ("com.android.providers.downloads.documents".equals(authority)) {
166            derivedIcon = R.drawable.ic_root_download;
167        }
168        if ("com.android.providers.media.documents".equals(authority)) {
169            if ("image".equals(rootId)) {
170                derivedIcon = R.drawable.ic_doc_image;
171            } else if ("audio".equals(rootId)) {
172                derivedIcon = R.drawable.ic_doc_audio;
173            }
174        }
175    }
176
177    @Override
178    public String toString() {
179        return "Root{title=" + title + ", rootId=" + rootId + "}";
180    }
181
182    public Drawable loadIcon(Context context) {
183        if (derivedIcon != 0) {
184            return context.getResources().getDrawable(derivedIcon);
185        } else {
186            return IconUtils.loadPackageIcon(context, authority, icon);
187        }
188    }
189
190    @Override
191    public boolean equals(Object o) {
192        if (o instanceof RootInfo) {
193            final RootInfo root = (RootInfo) o;
194            return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
195        } else {
196            return false;
197        }
198    }
199
200    @Override
201    public int hashCode() {
202        return Objects.hash(authority, rootId);
203    }
204
205    public String getDirectoryString() {
206        return (summary != null) ? summary : title;
207    }
208}
209