Home | History | Annotate | Download | only in model
      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 
     17 package com.android.documentsui.model;
     18 
     19 import static com.android.documentsui.model.DocumentInfo.getCursorInt;
     20 import static com.android.documentsui.model.DocumentInfo.getCursorLong;
     21 import static com.android.documentsui.model.DocumentInfo.getCursorString;
     22 
     23 import android.content.Context;
     24 import android.database.Cursor;
     25 import android.graphics.drawable.Drawable;
     26 import android.os.Parcel;
     27 import android.os.Parcelable;
     28 import android.provider.DocumentsContract.Root;
     29 import android.text.TextUtils;
     30 
     31 import com.android.documentsui.IconUtils;
     32 import com.android.documentsui.R;
     33 
     34 import java.io.DataInputStream;
     35 import java.io.DataOutputStream;
     36 import java.io.IOException;
     37 import java.net.ProtocolException;
     38 import java.util.Objects;
     39 
     40 /**
     41  * Representation of a {@link Root}.
     42  */
     43 public class RootInfo implements Durable, Parcelable {
     44     private static final int VERSION_INIT = 1;
     45     private static final int VERSION_DROP_TYPE = 2;
     46 
     47     public String authority;
     48     public String rootId;
     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[] derivedMimeTypes;
     59     public int derivedIcon;
     60 
     61     public RootInfo() {
     62         reset();
     63     }
     64 
     65     @Override
     66     public void reset() {
     67         authority = null;
     68         rootId = null;
     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_DROP_TYPE:
     86                 authority = DurableUtils.readNullableString(in);
     87                 rootId = DurableUtils.readNullableString(in);
     88                 flags = in.readInt();
     89                 icon = in.readInt();
     90                 title = DurableUtils.readNullableString(in);
     91                 summary = DurableUtils.readNullableString(in);
     92                 documentId = DurableUtils.readNullableString(in);
     93                 availableBytes = in.readLong();
     94                 mimeTypes = DurableUtils.readNullableString(in);
     95                 deriveFields();
     96                 break;
     97             default:
     98                 throw new ProtocolException("Unknown version " + version);
     99         }
    100     }
    101 
    102     @Override
    103     public void write(DataOutputStream out) throws IOException {
    104         out.writeInt(VERSION_DROP_TYPE);
    105         DurableUtils.writeNullableString(out, authority);
    106         DurableUtils.writeNullableString(out, rootId);
    107         out.writeInt(flags);
    108         out.writeInt(icon);
    109         DurableUtils.writeNullableString(out, title);
    110         DurableUtils.writeNullableString(out, summary);
    111         DurableUtils.writeNullableString(out, documentId);
    112         out.writeLong(availableBytes);
    113         DurableUtils.writeNullableString(out, mimeTypes);
    114     }
    115 
    116     @Override
    117     public int describeContents() {
    118         return 0;
    119     }
    120 
    121     @Override
    122     public void writeToParcel(Parcel dest, int flags) {
    123         DurableUtils.writeToParcel(dest, this);
    124     }
    125 
    126     public static final Creator<RootInfo> CREATOR = new Creator<RootInfo>() {
    127         @Override
    128         public RootInfo createFromParcel(Parcel in) {
    129             final RootInfo root = new RootInfo();
    130             DurableUtils.readFromParcel(in, root);
    131             return root;
    132         }
    133 
    134         @Override
    135         public RootInfo[] newArray(int size) {
    136             return new RootInfo[size];
    137         }
    138     };
    139 
    140     public static RootInfo fromRootsCursor(String authority, Cursor cursor) {
    141         final RootInfo root = new RootInfo();
    142         root.authority = authority;
    143         root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID);
    144         root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS);
    145         root.icon = getCursorInt(cursor, Root.COLUMN_ICON);
    146         root.title = getCursorString(cursor, Root.COLUMN_TITLE);
    147         root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY);
    148         root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
    149         root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
    150         root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
    151         root.deriveFields();
    152         return root;
    153     }
    154 
    155     private void deriveFields() {
    156         derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
    157 
    158         // TODO: remove these special case icons
    159         if (isExternalStorage()) {
    160             derivedIcon = R.drawable.ic_root_sdcard;
    161         } else if (isDownloads()) {
    162             derivedIcon = R.drawable.ic_root_download;
    163         } else if (isImages()) {
    164             derivedIcon = R.drawable.ic_doc_image;
    165         } else if (isVideos()) {
    166             derivedIcon = R.drawable.ic_doc_video;
    167         } else if (isAudio()) {
    168             derivedIcon = R.drawable.ic_doc_audio;
    169         }
    170     }
    171 
    172     public boolean isRecents() {
    173         return authority == null && rootId == null;
    174     }
    175 
    176     public boolean isExternalStorage() {
    177         return "com.android.externalstorage.documents".equals(authority);
    178     }
    179 
    180     public boolean isDownloads() {
    181         return "com.android.providers.downloads.documents".equals(authority);
    182     }
    183 
    184     public boolean isImages() {
    185         return "com.android.providers.media.documents".equals(authority)
    186                 && "images_root".equals(rootId);
    187     }
    188 
    189     public boolean isVideos() {
    190         return "com.android.providers.media.documents".equals(authority)
    191                 && "videos_root".equals(rootId);
    192     }
    193 
    194     public boolean isAudio() {
    195         return "com.android.providers.media.documents".equals(authority)
    196                 && "audio_root".equals(rootId);
    197     }
    198 
    199     @Override
    200     public String toString() {
    201         return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
    202     }
    203 
    204     public Drawable loadIcon(Context context) {
    205         if (derivedIcon != 0) {
    206             return context.getDrawable(derivedIcon);
    207         } else {
    208             return IconUtils.loadPackageIcon(context, authority, icon);
    209         }
    210     }
    211 
    212     public Drawable loadDrawerIcon(Context context) {
    213         if (derivedIcon != 0) {
    214             return IconUtils.applyTintColor(context, derivedIcon, R.color.item_root_icon);
    215         } else {
    216             return IconUtils.loadPackageIcon(context, authority, icon);
    217         }
    218     }
    219 
    220     public Drawable loadGridIcon(Context context) {
    221         if (derivedIcon != 0) {
    222             return IconUtils.applyTintAttr(context, derivedIcon,
    223                     android.R.attr.textColorPrimaryInverse);
    224         } else {
    225             return IconUtils.loadPackageIcon(context, authority, icon);
    226         }
    227     }
    228 
    229     public Drawable loadToolbarIcon(Context context) {
    230         if (derivedIcon != 0) {
    231             return IconUtils.applyTintAttr(context, derivedIcon,
    232                     android.R.attr.colorControlNormal);
    233         } else {
    234             return IconUtils.loadPackageIcon(context, authority, icon);
    235         }
    236     }
    237 
    238     @Override
    239     public boolean equals(Object o) {
    240         if (o instanceof RootInfo) {
    241             final RootInfo root = (RootInfo) o;
    242             return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
    243         } else {
    244             return false;
    245         }
    246     }
    247 
    248     @Override
    249     public int hashCode() {
    250         return Objects.hash(authority, rootId);
    251     }
    252 
    253     public String getDirectoryString() {
    254         return !TextUtils.isEmpty(summary) ? summary : title;
    255     }
    256 }
    257