RootInfo.java revision d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8
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; 22d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport static com.android.documentsui.base.Shared.DEBUG; 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 385629ec5989006bfc4ad3cb19a92163d581ff02e6Jeff Sharkeyimport com.android.documentsui.IconUtils; 3906c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkeyimport com.android.documentsui.R; 405629ec5989006bfc4ad3cb19a92163d581ff02e6Jeff Sharkey 41a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport java.io.DataInputStream; 42a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport java.io.DataOutputStream; 43a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tanimport java.io.FileNotFoundException; 44a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport java.io.IOException; 4555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKayimport java.lang.annotation.Retention; 4655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKayimport java.lang.annotation.RetentionPolicy; 47a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkeyimport java.net.ProtocolException; 48d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkeyimport java.util.Objects; 49d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey 50724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey/** 51724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey * Representation of a {@link Root}. 52724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey */ 5355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKaypublic class RootInfo implements Durable, Parcelable, Comparable<RootInfo> { 546695fdf0f06e13d500ebea00093185a864c384f8Steve McKay 556695fdf0f06e13d500ebea00093185a864c384f8Steve McKay private static final String TAG = "RootInfo"; 56a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey private static final int VERSION_INIT = 1; 579dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey private static final int VERSION_DROP_TYPE = 2; 58a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 5985c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa // The values of these constants determine the sort order of various roots in the RootsFragment. 6050254fee5f12df77409db0e5bcfbc663ebccdde9Jeff Sharkey @IntDef(flag = false, value = { 6155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_IMAGES, 6255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_VIDEO, 6355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_AUDIO, 6455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_RECENTS, 6555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_DOWNLOADS, 6655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_LOCAL, 6755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_MTP, 686695fdf0f06e13d500ebea00093185a864c384f8Steve McKay TYPE_SD, 696695fdf0f06e13d500ebea00093185a864c384f8Steve McKay TYPE_USB, 7055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay TYPE_OTHER 7155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay }) 7255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay @Retention(RetentionPolicy.SOURCE) 7355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay public @interface RootType {} 7485c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_IMAGES = 1; 7585c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_VIDEO = 2; 7685c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_AUDIO = 3; 7785c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_RECENTS = 4; 7885c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_DOWNLOADS = 5; 7985c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa public static final int TYPE_LOCAL = 6; 809fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono public static final int TYPE_MTP = 7; 816695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public static final int TYPE_SD = 8; 826695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public static final int TYPE_USB = 9; 836695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public static final int TYPE_OTHER = 10; 8485c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa 85724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String authority; 86724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String rootId; 87724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public int flags; 88724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public int icon; 89724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String title; 90724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String summary; 91724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public String documentId; 92724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public long availableBytes; 93a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public String mimeTypes; 94a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 95a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey /** Derived fields that aren't persisted */ 96a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public String[] derivedMimeTypes; 97a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public int derivedIcon; 9855c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay public @RootType int derivedType; 995668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin // Currently, we are not persisting this and we should be asking Provider whether a Root 1005668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin // is in the process of eject. Provider does not have this available yet. 1015668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin public transient boolean ejecting; 102a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 103a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public RootInfo() { 104a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey reset(); 105a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 106a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 107a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 108a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public void reset() { 109a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey authority = null; 110a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey rootId = null; 111a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey flags = 0; 112a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey icon = 0; 113a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey title = null; 114a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey summary = null; 115a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey documentId = null; 116a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey availableBytes = -1; 117a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey mimeTypes = null; 1185668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin ejecting = false; 119a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 120a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey derivedMimeTypes = null; 121a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey derivedIcon = 0; 12285c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = 0; 123a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 124a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 125a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 126a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public void read(DataInputStream in) throws IOException { 127a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey final int version = in.readInt(); 128a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey switch (version) { 1299dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey case VERSION_DROP_TYPE: 130a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey authority = DurableUtils.readNullableString(in); 131a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey rootId = DurableUtils.readNullableString(in); 132a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey flags = in.readInt(); 133a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey icon = in.readInt(); 134a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey title = DurableUtils.readNullableString(in); 135a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey summary = DurableUtils.readNullableString(in); 136a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey documentId = DurableUtils.readNullableString(in); 137a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey availableBytes = in.readLong(); 138a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey mimeTypes = DurableUtils.readNullableString(in); 139a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey deriveFields(); 140a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey break; 141a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey default: 142a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey throw new ProtocolException("Unknown version " + version); 143a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 144a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 145a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 146a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 147a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public void write(DataOutputStream out) throws IOException { 1489dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey out.writeInt(VERSION_DROP_TYPE); 149a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, authority); 150a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, rootId); 151a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey out.writeInt(flags); 152a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey out.writeInt(icon); 153a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, title); 154a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, summary); 155a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, documentId); 156a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey out.writeLong(availableBytes); 157a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeNullableString(out, mimeTypes); 158a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 159a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 160a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 161a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public int describeContents() { 162a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey return 0; 163a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 164a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 165a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 166a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public void writeToParcel(Parcel dest, int flags) { 167a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.writeToParcel(dest, this); 168a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 169a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 170a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public static final Creator<RootInfo> CREATOR = new Creator<RootInfo>() { 171a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 172a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public RootInfo createFromParcel(Parcel in) { 173a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey final RootInfo root = new RootInfo(); 174a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey DurableUtils.readFromParcel(in, root); 175a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey return root; 176a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 177a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey 178a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey @Override 179a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey public RootInfo[] newArray(int size) { 180a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey return new RootInfo[size]; 181a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 182a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey }; 183724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey 184724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public static RootInfo fromRootsCursor(String authority, Cursor cursor) { 185724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey final RootInfo root = new RootInfo(); 186724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.authority = authority; 187724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID); 188724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS); 189724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.icon = getCursorInt(cursor, Root.COLUMN_ICON); 190724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.title = getCursorString(cursor, Root.COLUMN_TITLE); 191724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY); 192724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID); 193724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES); 194a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES); 195a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey root.deriveFields(); 196a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey return root; 197a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 198e1a2ceef30fe9c514152c3fab3cedcb99bdb68dfJeff Sharkey 199a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey private void deriveFields() { 200a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null; 201e1a2ceef30fe9c514152c3fab3cedcb99bdb68dfJeff Sharkey 20212ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay if (isHome()) { 20312ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay derivedType = TYPE_LOCAL; 2046695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_root_documents; 2056695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } else if (isMtp()) { 2066695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedType = TYPE_MTP; 2076695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_usb_storage; 2086695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } else if (isUsb()) { 2096695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedType = TYPE_USB; 2106695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_usb_storage; 2116695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } else if (isSd()) { 2126695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedType = TYPE_SD; 2136695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_sd_storage; 21412ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay } else if (isExternalStorage()) { 21585c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_LOCAL; 2166695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_root_smartphone; 2179dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else if (isDownloads()) { 21885c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_DOWNLOADS; 2196695fdf0f06e13d500ebea00093185a864c384f8Steve McKay derivedIcon = R.drawable.ic_root_download; 2209dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else if (isImages()) { 22185c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_IMAGES; 222f8ed15b0ceebb6d0a2cf2bd97fdc6a3981dfc980Daniel Nishi derivedIcon = com.android.internal.R.drawable.ic_doc_image; 2239dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else if (isVideos()) { 22485c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_VIDEO; 225f8ed15b0ceebb6d0a2cf2bd97fdc6a3981dfc980Daniel Nishi derivedIcon = com.android.internal.R.drawable.ic_doc_video; 2269dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } else if (isAudio()) { 22785c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_AUDIO; 228f8ed15b0ceebb6d0a2cf2bd97fdc6a3981dfc980Daniel Nishi derivedIcon = com.android.internal.R.drawable.ic_doc_audio; 22985c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa } else if (isRecents()) { 23085c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa derivedType = TYPE_RECENTS; 23185c8cdd2e79e96f719932db64b61d3c51d4aeefcBen Kwa } else { 23212ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay derivedType = TYPE_OTHER; 23306c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey } 2346695fdf0f06e13d500ebea00093185a864c384f8Steve McKay 235c88f83c0a58581c1da3da28b218b319a2b03c468Steve McKay if (DEBUG) Log.v(TAG, "Deriving fields: " + this); 2369dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2379dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 23831e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay public Uri getUri() { 23931e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay return DocumentsContract.buildRootUri(authority, rootId); 24031e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay } 24131e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay 2429dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isRecents() { 2439dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey return authority == null && rootId == null; 2449dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2459dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 24612ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay public boolean isHome() { 24712ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay // Note that "home" is the expected root id for the auto-created 24812ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay // user home directory on external storage. The "home" value should 24912ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay // match ExternalStorageProvider.ROOT_ID_HOME. 25012ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay return isExternalStorage() && "home".equals(rootId); 25112ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay } 25212ef53e81e604a0668bc09747577c1686c90d2fbSteve McKay 2539dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isExternalStorage() { 2549dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey return "com.android.externalstorage.documents".equals(authority); 2559dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2569dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2579dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isDownloads() { 2589dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey return "com.android.providers.downloads.documents".equals(authority); 2599dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2609dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2619dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isImages() { 2629dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey return "com.android.providers.media.documents".equals(authority) 2639dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey && "images_root".equals(rootId); 2649dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2659dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2669dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isVideos() { 2679dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey return "com.android.providers.media.documents".equals(authority) 2689dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey && "videos_root".equals(rootId); 2699dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey } 2709dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey 2719dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey public boolean isAudio() { 2729dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey return "com.android.providers.media.documents".equals(authority) 2739dd02629d12d05c2e77780dc6b9fcc7639192de6Jeff Sharkey && "audio_root".equals(rootId); 274a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey } 27506c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey 2769fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono public boolean isMtp() { 2779fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono return "com.android.mtp.documents".equals(authority); 2789fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono } 2799fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono 2809fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono public boolean isLibrary() { 2811aeb3955403a44ef58082de11c26890ca98070e7Steve McKay return derivedType == TYPE_IMAGES 2821aeb3955403a44ef58082de11c26890ca98070e7Steve McKay || derivedType == TYPE_VIDEO 2831aeb3955403a44ef58082de11c26890ca98070e7Steve McKay || derivedType == TYPE_AUDIO 2841aeb3955403a44ef58082de11c26890ca98070e7Steve McKay || derivedType == TYPE_RECENTS; 2859fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono } 2869fb33890e10dac56ced4559b4d325ba1a7470dc6Daichi Hirono 28736787540589e768fce222629a75e951904383250Steve McKay public boolean hasSettings() { 28836787540589e768fce222629a75e951904383250Steve McKay return (flags & Root.FLAG_HAS_SETTINGS) != 0; 28936787540589e768fce222629a75e951904383250Steve McKay } 29036787540589e768fce222629a75e951904383250Steve McKay 291323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay public boolean supportsChildren() { 292323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay return (flags & Root.FLAG_SUPPORTS_IS_CHILD) != 0; 293323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay } 294323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay 295323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay public boolean supportsCreate() { 296323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay return (flags & Root.FLAG_SUPPORTS_CREATE) != 0; 297323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay } 298323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay 2991aeb3955403a44ef58082de11c26890ca98070e7Steve McKay public boolean supportsRecents() { 3001aeb3955403a44ef58082de11c26890ca98070e7Steve McKay return (flags & Root.FLAG_SUPPORTS_RECENTS) != 0; 3011aeb3955403a44ef58082de11c26890ca98070e7Steve McKay } 3021aeb3955403a44ef58082de11c26890ca98070e7Steve McKay 3031aeb3955403a44ef58082de11c26890ca98070e7Steve McKay public boolean supportsSearch() { 3041aeb3955403a44ef58082de11c26890ca98070e7Steve McKay return (flags & Root.FLAG_SUPPORTS_SEARCH) != 0; 3051aeb3955403a44ef58082de11c26890ca98070e7Steve McKay } 3061aeb3955403a44ef58082de11c26890ca98070e7Steve McKay 3075668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin public boolean supportsEject() { 3085668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin return (flags & Root.FLAG_SUPPORTS_EJECT) != 0; 3095668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin } 3105668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin 311bffe6601327a4cb2eb79c8d8e2bf08cabcb8e56bAga Wronska public boolean isAdvanced() { 312bffe6601327a4cb2eb79c8d8e2bf08cabcb8e56bAga Wronska return (flags & Root.FLAG_ADVANCED) != 0; 313bffe6601327a4cb2eb79c8d8e2bf08cabcb8e56bAga Wronska } 314bffe6601327a4cb2eb79c8d8e2bf08cabcb8e56bAga Wronska 315323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay public boolean isLocalOnly() { 316323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay return (flags & Root.FLAG_LOCAL_ONLY) != 0; 317323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay } 318323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay 319323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay public boolean isEmpty() { 320323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay return (flags & Root.FLAG_EMPTY) != 0; 321323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay } 322323dffb4cffde781d325ddd3a36da9ed7b5bfec6Steve McKay 3236695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public boolean isSd() { 3246695fdf0f06e13d500ebea00093185a864c384f8Steve McKay return (flags & Root.FLAG_REMOVABLE_SD) != 0; 3256695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } 3266695fdf0f06e13d500ebea00093185a864c384f8Steve McKay 3276695fdf0f06e13d500ebea00093185a864c384f8Steve McKay public boolean isUsb() { 3286695fdf0f06e13d500ebea00093185a864c384f8Steve McKay return (flags & Root.FLAG_REMOVABLE_USB) != 0; 3296695fdf0f06e13d500ebea00093185a864c384f8Steve McKay } 3306695fdf0f06e13d500ebea00093185a864c384f8Steve McKay 331724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey public Drawable loadIcon(Context context) { 332a4d1f2200ddfb0d12145fba8457c47e8051c84f7Jeff Sharkey if (derivedIcon != 0) { 33361791445af80ab126478e4bc956fe5d44086cf38Alan Viverette return context.getDrawable(derivedIcon); 33406c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey } else { 33506c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey return IconUtils.loadPackageIcon(context, authority, icon); 33606c4187080497dffbcdb438aa45b262eb37706b1Jeff Sharkey } 337724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey } 338d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey 3397e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey public Drawable loadDrawerIcon(Context context) { 3407e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey if (derivedIcon != 0) { 3417e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey return IconUtils.applyTintColor(context, derivedIcon, R.color.item_root_icon); 3427e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey } else { 3437e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey return IconUtils.loadPackageIcon(context, authority, icon); 3447e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey } 3457e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey } 3467e544619f6518dd5eeed8262604edfc08942471fJeff Sharkey 3475668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin public Drawable loadEjectIcon(Context context) { 3485668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin return IconUtils.applyTintColor(context, R.drawable.ic_eject, R.color.item_eject_icon); 3495668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin } 3505668b866d52a4f8907474922dc9b1ba1b4db85a3Ben Lin 351a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan /** 352a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan * Gets the {@link DocumentInfo} of the root folder of this root. 353a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan */ 354a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan public @Nullable DocumentInfo getRootDocumentBlocking(Context context) { 355a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan try { 356a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan final Uri uri = DocumentsContract.buildDocumentUri(authority, documentId); 357a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan return DocumentInfo.fromUri(context.getContentResolver(), uri); 358a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan } catch (FileNotFoundException e) { 359a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan Log.w(TAG, "Failed to find root", e); 360a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan return null; 361a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan } 362a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan } 363a5588b65d55bc1b8b5ba943f8b660db26a7eac5cGarfield, Tan 364d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey @Override 365d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey public boolean equals(Object o) { 366405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay if (o == null) { 367d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey return false; 368d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey } 369405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay 370405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay if (this == o) { 371405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay return true; 372405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay } 373405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay 374405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay if (o instanceof RootInfo) { 375405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay RootInfo other = (RootInfo) o; 376405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay return Objects.equals(authority, other.authority) 377405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay && Objects.equals(rootId, other.rootId); 378405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay } 379405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay 380405142a83f58ccf9c2c3ba66951aa714075b3932Steve McKay return false; 381d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey } 382d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey 383d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey @Override 384d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey public int hashCode() { 385d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey return Objects.hash(authority, rootId); 386d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey } 387d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey 38831e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay @Override 38955c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay public int compareTo(RootInfo other) { 39055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay // Sort by root type, then title, then summary. 39155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay int score = derivedType - other.derivedType; 39255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay if (score != 0) { 39355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay return score; 39455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay } 39555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay 39655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay score = compareToIgnoreCaseNullable(title, other.title); 39755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay if (score != 0) { 39855c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay return score; 39955c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay } 40055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay 40155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay return compareToIgnoreCaseNullable(summary, other.summary); 40255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay } 40355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay 40455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay @Override 40531e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay public String toString() { 4066695fdf0f06e13d500ebea00093185a864c384f8Steve McKay return "Root{" 4076695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + "authority=" + authority 4086695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", rootId=" + rootId 4096695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", title=" + title 4106695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", isUsb=" + isUsb() 4116695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", isSd=" + isSd() 4126695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + ", isMtp=" + isMtp() 4136695fdf0f06e13d500ebea00093185a864c384f8Steve McKay + "}"; 41431e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay } 41531e104f83db7dae9e8620ef1d3151f9a580e6dcbSteve McKay 416d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey public String getDirectoryString() { 417a35ac2dd16a64014a524d1441fb20d5a02b40836Jeff Sharkey return !TextUtils.isEmpty(summary) ? summary : title; 418d82b26b58a0950a0dd3522e630bd87fe85290ab2Jeff Sharkey } 419724deeb5558a517471e9bf7168b456e6daec62f8Jeff Sharkey} 420