1724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey/* 2724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project 3724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * 4724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * you may not use this file except in compliance with the License. 6724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * You may obtain a copy of the License at 7724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * 8724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * 10724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * See the License for the specific language governing permissions and 14724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * limitations under the License. 15724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey */ 16724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey 17d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKaypackage com.android.documentsui.base; 18724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey 19d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport static com.android.documentsui.base.DocumentInfo.getCursorInt; 20d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport static com.android.documentsui.base.DocumentInfo.getCursorLong; 21d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport static com.android.documentsui.base.DocumentInfo.getCursorString; 2230535bce902104c97bbf70783d684ee673cb7637Steve McKayimport static com.android.documentsui.base.Shared.VERBOSE; 23d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport static com.android.documentsui.base.Shared.compareToIgnoreCaseNullable; 24724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey 2555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKayimport android.annotation.IntDef; 26a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tanimport android.annotation.Nullable; 27724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkeyimport android.content.Context; 28724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkeyimport android.database.Cursor; 29724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkeyimport android.graphics.drawable.Drawable; 3031e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKayimport android.net.Uri; 31a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport android.os.Parcel; 32a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport android.os.Parcelable; 3331e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKayimport android.provider.DocumentsContract; 34724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkeyimport android.provider.DocumentsContract.Root; 35a35ac2dd16a64014a524d1441fb20d5a02b40836Jeff Sharkeyimport android.text.TextUtils; 366695fdf0f06e13d500ebea00093185a864c384f8Steve McKayimport android.util.Log; 37724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey 380f5ec83eeee1d68f344c036cdff0c31ff68e6ee8Steve McKayimport com.android.documentsui.DocumentsAccess; 395629ec5989006bfc4ad3cb19a92163d581ff02e6Jeff Sharkeyimport com.android.documentsui.IconUtils; 4006c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkeyimport com.android.documentsui.R; 415629ec5989006bfc4ad3cb19a92163d581ff02e6Jeff Sharkey 42a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport java.io.DataInputStream; 43a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport java.io.DataOutputStream; 44a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tanimport java.io.FileNotFoundException; 45a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport java.io.IOException; 4655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKayimport java.lang.annotation.Retention; 4755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKayimport java.lang.annotation.RetentionPolicy; 48a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport java.net.ProtocolException; 49d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkeyimport java.util.Objects; 50d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey 51724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey/** 52724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * Representation of a {@link Root}. 53724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey */ 5455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKaypublic class RootInfo implements Durable, Parcelable, Comparable<RootInfo> { 556695fdf0f06e13d500ebea00093185a864c384f8Steve McKay 566695fdf0f06e13d500ebea00093185a864c384f8Steve McKay private static final String TAG = "RootInfo"; 57a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey private static final int VERSION_INIT = 1; 589dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey private static final int VERSION_DROP_TYPE = 2; 59a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 6085c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa // The values of these constants determine the sort order of various roots in the RootsFragment. 6150254fee5f12df77409db0e5bcfbc663ebccdde9Jeff Sharkey @IntDef(flag = false, value = { 6255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_IMAGES, 6355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_VIDEO, 6455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_AUDIO, 6555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_RECENTS, 6655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_DOWNLOADS, 6755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_LOCAL, 6855c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_MTP, 696695fdf0f06e13d500ebea00093185a864c384f8Steve McKay TYPE_SD, 706695fdf0f06e13d500ebea00093185a864c384f8Steve McKay TYPE_USB, 7155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_OTHER 7255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay }) 7355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay @Retention(RetentionPolicy.SOURCE) 7455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay public @interface RootType {} 7585c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_IMAGES = 1; 7685c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_VIDEO = 2; 7785c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_AUDIO = 3; 7885c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_RECENTS = 4; 7985c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_DOWNLOADS = 5; 8085c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_LOCAL = 6; 819fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono public static final int TYPE_MTP = 7; 826695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public static final int TYPE_SD = 8; 836695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public static final int TYPE_USB = 9; 846695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public static final int TYPE_OTHER = 10; 8585c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa 86724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String authority; 87724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String rootId; 88724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public int flags; 89724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public int icon; 90724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String title; 91724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String summary; 92724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String documentId; 93724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public long availableBytes; 94a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public String mimeTypes; 95a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 96a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey /** Derived fields that aren't persisted */ 97a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public String[] derivedMimeTypes; 98a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public int derivedIcon; 9955c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay public @RootType int derivedType; 1005668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin // Currently, we are not persisting this and we should be asking Provider whether a Root 1015668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin // is in the process of eject. Provider does not have this available yet. 1025668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin public transient boolean ejecting; 103a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 104a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public RootInfo() { 105a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey reset(); 106a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 107a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 108a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 109a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public void reset() { 110a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey authority = null; 111a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey rootId = null; 112a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey flags = 0; 113a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey icon = 0; 114a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey title = null; 115a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey summary = null; 116a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey documentId = null; 117a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey availableBytes = -1; 118a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey mimeTypes = null; 1195668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin ejecting = false; 120a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 121a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey derivedMimeTypes = null; 122a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey derivedIcon = 0; 12385c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = 0; 124a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 125a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 126a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 127a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public void read(DataInputStream in) throws IOException { 128a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey final int version = in.readInt(); 129a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey switch (version) { 1309dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey case VERSION_DROP_TYPE: 131a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey authority = DurableUtils.readNullableString(in); 132a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey rootId = DurableUtils.readNullableString(in); 133a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey flags = in.readInt(); 134a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey icon = in.readInt(); 135a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey title = DurableUtils.readNullableString(in); 136a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey summary = DurableUtils.readNullableString(in); 137a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey documentId = DurableUtils.readNullableString(in); 138a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey availableBytes = in.readLong(); 139a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey mimeTypes = DurableUtils.readNullableString(in); 140a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey deriveFields(); 141a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey break; 142a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey default: 143a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey throw new ProtocolException("Unknown version " + version); 144a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 145a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 146a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 147a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 148a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public void write(DataOutputStream out) throws IOException { 1499dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey out.writeInt(VERSION_DROP_TYPE); 150a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, authority); 151a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, rootId); 152a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey out.writeInt(flags); 153a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey out.writeInt(icon); 154a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, title); 155a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, summary); 156a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, documentId); 157a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey out.writeLong(availableBytes); 158a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, mimeTypes); 159a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 160a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 161a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 162a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public int describeContents() { 163a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey return 0; 164a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 165a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 166a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 167a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public void writeToParcel(Parcel dest, int flags) { 168a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeToParcel(dest, this); 169a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 170a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 171a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public static final Creator<RootInfo> CREATOR = new Creator<RootInfo>() { 172a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 173a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public RootInfo createFromParcel(Parcel in) { 174a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey final RootInfo root = new RootInfo(); 175a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.readFromParcel(in, root); 176a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey return root; 177a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 178a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 179a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 180a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public RootInfo[] newArray(int size) { 181a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey return new RootInfo[size]; 182a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 183a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey }; 184724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey 185724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public static RootInfo fromRootsCursor(String authority, Cursor cursor) { 186724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey final RootInfo root = new RootInfo(); 187724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.authority = authority; 188724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID); 189724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS); 190724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.icon = getCursorInt(cursor, Root.COLUMN_ICON); 191724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.title = getCursorString(cursor, Root.COLUMN_TITLE); 192724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY); 193724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID); 194724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES); 195a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES); 196a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey root.deriveFields(); 197a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey return root; 198a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 199e1a2ceef30fe9c514152c3fab3cedcb99bdb68dfJeff Sharkey 200a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey private void deriveFields() { 201a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null; 202e1a2ceef30fe9c514152c3fab3cedcb99bdb68dfJeff Sharkey 20312ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay if (isHome()) { 20412ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay derivedType = TYPE_LOCAL; 2056695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_root_documents; 2066695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } else if (isMtp()) { 2076695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedType = TYPE_MTP; 2086695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_usb_storage; 2096695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } else if (isUsb()) { 2106695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedType = TYPE_USB; 2116695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_usb_storage; 2126695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } else if (isSd()) { 2136695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedType = TYPE_SD; 2146695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_sd_storage; 21512ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay } else if (isExternalStorage()) { 21685c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_LOCAL; 2176695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_root_smartphone; 2189dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else if (isDownloads()) { 21985c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_DOWNLOADS; 2206695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_root_download; 2219dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else if (isImages()) { 22285c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_IMAGES; 223fc84b34edff91524af63c82dcf8cc2e97ee76f75Ben Lin derivedIcon = R.drawable.image_root_icon; 2249dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else if (isVideos()) { 22585c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_VIDEO; 226fc84b34edff91524af63c82dcf8cc2e97ee76f75Ben Lin derivedIcon = R.drawable.video_root_icon; 2279dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else if (isAudio()) { 22885c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_AUDIO; 229fc84b34edff91524af63c82dcf8cc2e97ee76f75Ben Lin derivedIcon = R.drawable.audio_root_icon; 23085c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa } else if (isRecents()) { 23185c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_RECENTS; 23285c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa } else { 23312ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay derivedType = TYPE_OTHER; 23406c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey } 2356695fdf0f06e13d500ebea00093185a864c384f8Steve McKay 23630535bce902104c97bbf70783d684ee673cb7637Steve McKay if (VERBOSE) Log.v(TAG, "Derived fields: " + this); 2379dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2389dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 23931e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay public Uri getUri() { 24031e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay return DocumentsContract.buildRootUri(authority, rootId); 24131e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay } 24231e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay 2439dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isRecents() { 2449dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey return authority == null && rootId == null; 2459dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2469dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 24712ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay public boolean isHome() { 24812ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay // Note that "home" is the expected root id for the auto-created 24912ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay // user home directory on external storage. The "home" value should 25012ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay // match ExternalStorageProvider.ROOT_ID_HOME. 25112ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay return isExternalStorage() && "home".equals(rootId); 25212ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay } 25312ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay 2549dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isExternalStorage() { 2558659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay return Providers.AUTHORITY_STORAGE.equals(authority); 2569dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2579dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2589dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isDownloads() { 2598659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay return Providers.AUTHORITY_DOWNLOADS.equals(authority); 2609dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2619dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2629dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isImages() { 2638659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay return Providers.AUTHORITY_MEDIA.equals(authority) 2648659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay && Providers.ROOT_ID_IMAGES.equals(rootId); 2659dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2669dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2679dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isVideos() { 2688659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay return Providers.AUTHORITY_MEDIA.equals(authority) 2698659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay && Providers.ROOT_ID_VIDEOS.equals(rootId); 2709dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2719dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2729dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isAudio() { 2738659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay return Providers.AUTHORITY_MEDIA.equals(authority) 2748659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay && Providers.ROOT_ID_AUDIO.equals(rootId); 275a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 27606c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey 2779fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono public boolean isMtp() { 2788659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay return Providers.AUTHORITY_MTP.equals(authority); 2799fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono } 2809fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono 2819fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono public boolean isLibrary() { 2821aeb3955403a44ef58082de11c26890ca98070e7Steve McKay return derivedType == TYPE_IMAGES 2831aeb3955403a44ef58082de11c26890ca98070e7Steve McKay || derivedType == TYPE_VIDEO 2841aeb3955403a44ef58082de11c26890ca98070e7Steve McKay || derivedType == TYPE_AUDIO 2851aeb3955403a44ef58082de11c26890ca98070e7Steve McKay || derivedType == TYPE_RECENTS; 2869fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono } 2879fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono 28836787540589e768fce222629a75e951904383250Steve McKay public boolean hasSettings() { 28936787540589e768fce222629a75e951904383250Steve McKay return (flags & Root.FLAG_HAS_SETTINGS) != 0; 29036787540589e768fce222629a75e951904383250Steve McKay } 29136787540589e768fce222629a75e951904383250Steve McKay 292323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay public boolean supportsChildren() { 293323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay return (flags & Root.FLAG_SUPPORTS_IS_CHILD) != 0; 294323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay } 295323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay 296323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay public boolean supportsCreate() { 297323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay return (flags & Root.FLAG_SUPPORTS_CREATE) != 0; 298323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay } 299323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay 3001aeb3955403a44ef58082de11c26890ca98070e7Steve McKay public boolean supportsRecents() { 3011aeb3955403a44ef58082de11c26890ca98070e7Steve McKay return (flags & Root.FLAG_SUPPORTS_RECENTS) != 0; 3021aeb3955403a44ef58082de11c26890ca98070e7Steve McKay } 3031aeb3955403a44ef58082de11c26890ca98070e7Steve McKay 3041aeb3955403a44ef58082de11c26890ca98070e7Steve McKay public boolean supportsSearch() { 3051aeb3955403a44ef58082de11c26890ca98070e7Steve McKay return (flags & Root.FLAG_SUPPORTS_SEARCH) != 0; 3061aeb3955403a44ef58082de11c26890ca98070e7Steve McKay } 3071aeb3955403a44ef58082de11c26890ca98070e7Steve McKay 3085668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin public boolean supportsEject() { 3095668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin return (flags & Root.FLAG_SUPPORTS_EJECT) != 0; 3105668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin } 3115668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin 312bffe6601327a4cb2eb79c8d8e2bf08cabcb8e56bAga Wronska public boolean isAdvanced() { 313bffe6601327a4cb2eb79c8d8e2bf08cabcb8e56bAga Wronska return (flags & Root.FLAG_ADVANCED) != 0; 314bffe6601327a4cb2eb79c8d8e2bf08cabcb8e56bAga Wronska } 315bffe6601327a4cb2eb79c8d8e2bf08cabcb8e56bAga Wronska 316323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay public boolean isLocalOnly() { 317323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay return (flags & Root.FLAG_LOCAL_ONLY) != 0; 318323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay } 319323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay 320323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay public boolean isEmpty() { 321323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay return (flags & Root.FLAG_EMPTY) != 0; 322323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay } 323323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay 3246695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public boolean isSd() { 3256695fdf0f06e13d500ebea00093185a864c384f8Steve McKay return (flags & Root.FLAG_REMOVABLE_SD) != 0; 3266695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } 3276695fdf0f06e13d500ebea00093185a864c384f8Steve McKay 3286695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public boolean isUsb() { 3296695fdf0f06e13d500ebea00093185a864c384f8Steve McKay return (flags & Root.FLAG_REMOVABLE_USB) != 0; 3306695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } 3316695fdf0f06e13d500ebea00093185a864c384f8Steve McKay 332724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public Drawable loadIcon(Context context) { 333a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey if (derivedIcon != 0) { 33461791445af80ab126478e4bc956fe5d44086cf38Alan Viverette return context.getDrawable(derivedIcon); 33506c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey } else { 33606c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey return IconUtils.loadPackageIcon(context, authority, icon); 33706c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey } 338724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey } 339d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey 3407e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey public Drawable loadDrawerIcon(Context context) { 3417e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey if (derivedIcon != 0) { 3427e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey return IconUtils.applyTintColor(context, derivedIcon, R.color.item_root_icon); 3437e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey } else { 3447e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey return IconUtils.loadPackageIcon(context, authority, icon); 3457e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey } 3467e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey } 3477e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey 3485668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin public Drawable loadEjectIcon(Context context) { 3495668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin return IconUtils.applyTintColor(context, R.drawable.ic_eject, R.color.item_eject_icon); 3505668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin } 3515668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin 352d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey @Override 353d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey public boolean equals(Object o) { 354405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay if (o == null) { 355d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey return false; 356d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey } 357405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay 358405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay if (this == o) { 359405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay return true; 360405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay } 361405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay 362405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay if (o instanceof RootInfo) { 363405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay RootInfo other = (RootInfo) o; 364405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay return Objects.equals(authority, other.authority) 365405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay && Objects.equals(rootId, other.rootId); 366405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay } 367405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay 368405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay return false; 369d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey } 370d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey 371d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey @Override 372d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey public int hashCode() { 373d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey return Objects.hash(authority, rootId); 374d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey } 375d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey 37631e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay @Override 37755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay public int compareTo(RootInfo other) { 37855c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay // Sort by root type, then title, then summary. 37955c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay int score = derivedType - other.derivedType; 38055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay if (score != 0) { 38155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay return score; 38255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay } 38355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay 38455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay score = compareToIgnoreCaseNullable(title, other.title); 38555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay if (score != 0) { 38655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay return score; 38755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay } 38855c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay 38955c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay return compareToIgnoreCaseNullable(summary, other.summary); 39055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay } 39155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay 39255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay @Override 39331e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay public String toString() { 3946695fdf0f06e13d500ebea00093185a864c384f8Steve McKay return "Root{" 3956695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + "authority=" + authority 3966695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", rootId=" + rootId 3976695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", title=" + title 3986695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", isUsb=" + isUsb() 3996695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", isSd=" + isSd() 4006695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", isMtp=" + isMtp() 4018659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay + "} @ " 4028659cbccc6fbab79fb6855abe9cb31ee8171b37eSteve McKay + getUri(); 40331e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay } 40431e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay 4056a0a5688a3c250f18c895ab80af5e6093e7d38d1Steve McKay public String toDebugString() { 4066a0a5688a3c250f18c895ab80af5e6093e7d38d1Steve McKay return (TextUtils.isEmpty(summary)) 4076a0a5688a3c250f18c895ab80af5e6093e7d38d1Steve McKay ? "\"" + title + "\" @ " + getUri() 4086a0a5688a3c250f18c895ab80af5e6093e7d38d1Steve McKay : "\"" + title + " (" + summary + ")\" @ " + getUri(); 4096a0a5688a3c250f18c895ab80af5e6093e7d38d1Steve McKay } 4106a0a5688a3c250f18c895ab80af5e6093e7d38d1Steve McKay 411d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey public String getDirectoryString() { 412a35ac2dd16a64014a524d1441fb20d5a02b40836Jeff Sharkey return !TextUtils.isEmpty(summary) ? summary : title; 413d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey } 414724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey} 415