blob: ae5644d7fc3b755cfd7a91b0c12aaadfa33a7624 [file] [log] [blame]
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -07001/*
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;
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -070024import android.database.Cursor;
25import android.graphics.drawable.Drawable;
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070026import android.os.Parcel;
27import android.os.Parcelable;
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -070028import android.provider.DocumentsContract.Root;
Jeff Sharkey4ec97392013-09-10 12:04:26 -070029import android.text.TextUtils;
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -070030
Jeff Sharkey0b14db32013-09-04 18:03:18 -070031import com.android.documentsui.IconUtils;
Jeff Sharkey6d97d3c2013-09-06 10:43:45 -070032import com.android.documentsui.R;
Jeff Sharkey0b14db32013-09-04 18:03:18 -070033
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070034import java.io.DataInputStream;
35import java.io.DataOutputStream;
36import java.io.IOException;
37import java.net.ProtocolException;
Jeff Sharkey251097b2013-09-02 15:07:28 -070038import java.util.Objects;
39
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -070040/**
41 * Representation of a {@link Root}.
42 */
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070043public class RootInfo implements Durable, Parcelable {
44 private static final int VERSION_INIT = 1;
Jeff Sharkey6efba222013-09-27 16:44:11 -070045 private static final int VERSION_DROP_TYPE = 2;
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070046
Ben Kwa0c643082015-10-09 07:48:00 -070047 // The values of these constants determine the sort order of various roots in the RootsFragment.
48 public static final int TYPE_IMAGES = 1;
49 public static final int TYPE_VIDEO = 2;
50 public static final int TYPE_AUDIO = 3;
51 public static final int TYPE_RECENTS = 4;
52 public static final int TYPE_DOWNLOADS = 5;
53 public static final int TYPE_LOCAL = 6;
Daichi Hironoabf39742015-10-23 08:36:10 +090054 public static final int TYPE_MTP = 7;
Steve McKayc6a4cd82015-11-18 14:56:50 -080055 public static final int TYPE_OTHER = 8;
Ben Kwa0c643082015-10-09 07:48:00 -070056
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -070057 public String authority;
58 public String rootId;
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -070059 public int flags;
60 public int icon;
61 public String title;
62 public String summary;
63 public String documentId;
64 public long availableBytes;
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070065 public String mimeTypes;
66
67 /** Derived fields that aren't persisted */
68 public String[] derivedMimeTypes;
69 public int derivedIcon;
Ben Kwa0c643082015-10-09 07:48:00 -070070 public int derivedType;
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070071
72 public RootInfo() {
73 reset();
74 }
75
76 @Override
77 public void reset() {
78 authority = null;
79 rootId = null;
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070080 flags = 0;
81 icon = 0;
82 title = null;
83 summary = null;
84 documentId = null;
85 availableBytes = -1;
86 mimeTypes = null;
87
88 derivedMimeTypes = null;
89 derivedIcon = 0;
Ben Kwa0c643082015-10-09 07:48:00 -070090 derivedType = 0;
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070091 }
92
93 @Override
94 public void read(DataInputStream in) throws IOException {
95 final int version = in.readInt();
96 switch (version) {
Jeff Sharkey6efba222013-09-27 16:44:11 -070097 case VERSION_DROP_TYPE:
Jeff Sharkeyd182bb62013-09-07 14:45:03 -070098 authority = DurableUtils.readNullableString(in);
99 rootId = DurableUtils.readNullableString(in);
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700100 flags = in.readInt();
101 icon = in.readInt();
102 title = DurableUtils.readNullableString(in);
103 summary = DurableUtils.readNullableString(in);
104 documentId = DurableUtils.readNullableString(in);
105 availableBytes = in.readLong();
106 mimeTypes = DurableUtils.readNullableString(in);
107 deriveFields();
108 break;
109 default:
110 throw new ProtocolException("Unknown version " + version);
111 }
112 }
113
114 @Override
115 public void write(DataOutputStream out) throws IOException {
Jeff Sharkey6efba222013-09-27 16:44:11 -0700116 out.writeInt(VERSION_DROP_TYPE);
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700117 DurableUtils.writeNullableString(out, authority);
118 DurableUtils.writeNullableString(out, rootId);
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700119 out.writeInt(flags);
120 out.writeInt(icon);
121 DurableUtils.writeNullableString(out, title);
122 DurableUtils.writeNullableString(out, summary);
123 DurableUtils.writeNullableString(out, documentId);
124 out.writeLong(availableBytes);
125 DurableUtils.writeNullableString(out, mimeTypes);
126 }
127
128 @Override
129 public int describeContents() {
130 return 0;
131 }
132
133 @Override
134 public void writeToParcel(Parcel dest, int flags) {
135 DurableUtils.writeToParcel(dest, this);
136 }
137
138 public static final Creator<RootInfo> CREATOR = new Creator<RootInfo>() {
139 @Override
140 public RootInfo createFromParcel(Parcel in) {
141 final RootInfo root = new RootInfo();
142 DurableUtils.readFromParcel(in, root);
143 return root;
144 }
145
146 @Override
147 public RootInfo[] newArray(int size) {
148 return new RootInfo[size];
149 }
150 };
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -0700151
152 public static RootInfo fromRootsCursor(String authority, Cursor cursor) {
153 final RootInfo root = new RootInfo();
154 root.authority = authority;
155 root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID);
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -0700156 root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS);
157 root.icon = getCursorInt(cursor, Root.COLUMN_ICON);
158 root.title = getCursorString(cursor, Root.COLUMN_TITLE);
159 root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY);
160 root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
161 root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700162 root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
163 root.deriveFields();
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -0700164 return root;
165 }
166
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700167 private void deriveFields() {
168 derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
169
170 // TODO: remove these special case icons
Steve McKayc6a4cd82015-11-18 14:56:50 -0800171 if (isHome()) {
172 derivedIcon = R.drawable.ic_root_home;
173 derivedType = TYPE_LOCAL;
174 } else if (isExternalStorage()) {
Jeff Sharkeyc29dd612014-08-08 13:08:56 -0700175 derivedIcon = R.drawable.ic_root_sdcard;
Ben Kwa0c643082015-10-09 07:48:00 -0700176 derivedType = TYPE_LOCAL;
Jeff Sharkey6efba222013-09-27 16:44:11 -0700177 } else if (isDownloads()) {
Jeff Sharkeyc29dd612014-08-08 13:08:56 -0700178 derivedIcon = R.drawable.ic_root_download;
Ben Kwa0c643082015-10-09 07:48:00 -0700179 derivedType = TYPE_DOWNLOADS;
Jeff Sharkey6efba222013-09-27 16:44:11 -0700180 } else if (isImages()) {
Jeff Sharkeyc29dd612014-08-08 13:08:56 -0700181 derivedIcon = R.drawable.ic_doc_image;
Ben Kwa0c643082015-10-09 07:48:00 -0700182 derivedType = TYPE_IMAGES;
Jeff Sharkey6efba222013-09-27 16:44:11 -0700183 } else if (isVideos()) {
Jeff Sharkeyc29dd612014-08-08 13:08:56 -0700184 derivedIcon = R.drawable.ic_doc_video;
Ben Kwa0c643082015-10-09 07:48:00 -0700185 derivedType = TYPE_VIDEO;
Jeff Sharkey6efba222013-09-27 16:44:11 -0700186 } else if (isAudio()) {
Jeff Sharkeyc29dd612014-08-08 13:08:56 -0700187 derivedIcon = R.drawable.ic_doc_audio;
Ben Kwa0c643082015-10-09 07:48:00 -0700188 derivedType = TYPE_AUDIO;
189 } else if (isRecents()) {
190 derivedType = TYPE_RECENTS;
Daichi Hironoabf39742015-10-23 08:36:10 +0900191 } else if (isMtp()) {
192 derivedType = TYPE_MTP;
Ben Kwa0c643082015-10-09 07:48:00 -0700193 } else {
Steve McKayc6a4cd82015-11-18 14:56:50 -0800194 derivedType = TYPE_OTHER;
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700195 }
Jeff Sharkey6efba222013-09-27 16:44:11 -0700196 }
197
198 public boolean isRecents() {
199 return authority == null && rootId == null;
200 }
201
Steve McKayc6a4cd82015-11-18 14:56:50 -0800202 public boolean isHome() {
203 // Note that "home" is the expected root id for the auto-created
204 // user home directory on external storage. The "home" value should
205 // match ExternalStorageProvider.ROOT_ID_HOME.
206 return isExternalStorage() && "home".equals(rootId);
207 }
208
Jeff Sharkey6efba222013-09-27 16:44:11 -0700209 public boolean isExternalStorage() {
210 return "com.android.externalstorage.documents".equals(authority);
211 }
212
213 public boolean isDownloads() {
214 return "com.android.providers.downloads.documents".equals(authority);
215 }
216
217 public boolean isImages() {
218 return "com.android.providers.media.documents".equals(authority)
219 && "images_root".equals(rootId);
220 }
221
222 public boolean isVideos() {
223 return "com.android.providers.media.documents".equals(authority)
224 && "videos_root".equals(rootId);
225 }
226
227 public boolean isAudio() {
228 return "com.android.providers.media.documents".equals(authority)
229 && "audio_root".equals(rootId);
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700230 }
231
Daichi Hironoabf39742015-10-23 08:36:10 +0900232 public boolean isMtp() {
233 return "com.android.mtp.documents".equals(authority);
234 }
235
236 public boolean isLibrary() {
237 return derivedType == TYPE_IMAGES || derivedType == TYPE_VIDEO || derivedType == TYPE_AUDIO
238 || derivedType == TYPE_RECENTS || derivedType == TYPE_DOWNLOADS;
239 }
240
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700241 @Override
242 public String toString() {
Jeff Sharkey5545f562013-09-21 13:57:33 -0700243 return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700244 }
245
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -0700246 public Drawable loadIcon(Context context) {
Jeff Sharkeyd182bb62013-09-07 14:45:03 -0700247 if (derivedIcon != 0) {
Alan Viverette03d30a52014-08-14 12:59:10 -0700248 return context.getDrawable(derivedIcon);
Jeff Sharkey6d97d3c2013-09-06 10:43:45 -0700249 } else {
250 return IconUtils.loadPackageIcon(context, authority, icon);
251 }
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -0700252 }
Jeff Sharkey251097b2013-09-02 15:07:28 -0700253
Jeff Sharkeycbce4702014-08-29 15:38:27 -0700254 public Drawable loadDrawerIcon(Context context) {
255 if (derivedIcon != 0) {
256 return IconUtils.applyTintColor(context, derivedIcon, R.color.item_root_icon);
257 } else {
258 return IconUtils.loadPackageIcon(context, authority, icon);
259 }
260 }
261
Jeff Sharkeyc29dd612014-08-08 13:08:56 -0700262 public Drawable loadToolbarIcon(Context context) {
263 if (derivedIcon != 0) {
Jeff Sharkeycbce4702014-08-29 15:38:27 -0700264 return IconUtils.applyTintAttr(context, derivedIcon,
Jeff Sharkeyc29dd612014-08-08 13:08:56 -0700265 android.R.attr.colorControlNormal);
266 } else {
267 return IconUtils.loadPackageIcon(context, authority, icon);
Jeff Sharkeya847d792014-07-29 17:33:36 -0700268 }
269 }
270
Jeff Sharkey251097b2013-09-02 15:07:28 -0700271 @Override
272 public boolean equals(Object o) {
273 if (o instanceof RootInfo) {
274 final RootInfo root = (RootInfo) o;
275 return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
276 } else {
277 return false;
278 }
279 }
280
281 @Override
282 public int hashCode() {
283 return Objects.hash(authority, rootId);
284 }
285
286 public String getDirectoryString() {
Jeff Sharkey4ec97392013-09-10 12:04:26 -0700287 return !TextUtils.isEmpty(summary) ? summary : title;
Jeff Sharkey251097b2013-09-02 15:07:28 -0700288 }
Jeff Sharkeyae9b51b2013-08-31 15:02:20 -0700289}