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 derivedPackageName;
     59     public String[] derivedMimeTypes;
     60     public int derivedIcon;
     61 
     62     public RootInfo() {
     63         reset();
     64     }
     65 
     66     @Override
     67     public void reset() {
     68         authority = null;
     69         rootId = null;
     70         flags = 0;
     71         icon = 0;
     72         title = null;
     73         summary = null;
     74         documentId = null;
     75         availableBytes = -1;
     76         mimeTypes = null;
     77 
     78         derivedPackageName = null;
     79         derivedMimeTypes = null;
     80         derivedIcon = 0;
     81     }
     82 
     83     @Override
     84     public void read(DataInputStream in) throws IOException {
     85         final int version = in.readInt();
     86         switch (version) {
     87             case VERSION_DROP_TYPE:
     88                 authority = DurableUtils.readNullableString(in);
     89                 rootId = DurableUtils.readNullableString(in);
     90                 flags = in.readInt();
     91                 icon = in.readInt();
     92                 title = DurableUtils.readNullableString(in);
     93                 summary = DurableUtils.readNullableString(in);
     94                 documentId = DurableUtils.readNullableString(in);
     95                 availableBytes = in.readLong();
     96                 mimeTypes = DurableUtils.readNullableString(in);
     97                 deriveFields();
     98                 break;
     99             default:
    100                 throw new ProtocolException("Unknown version " + version);
    101         }
    102     }
    103 
    104     @Override
    105     public void write(DataOutputStream out) throws IOException {
    106         out.writeInt(VERSION_DROP_TYPE);
    107         DurableUtils.writeNullableString(out, authority);
    108         DurableUtils.writeNullableString(out, rootId);
    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.flags = getCursorInt(cursor, Root.COLUMN_FLAGS);
    147         root.icon = getCursorInt(cursor, Root.COLUMN_ICON);
    148         root.title = getCursorString(cursor, Root.COLUMN_TITLE);
    149         root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY);
    150         root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
    151         root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
    152         root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
    153         root.deriveFields();
    154         return root;
    155     }
    156 
    157     private void deriveFields() {
    158         derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
    159 
    160         // TODO: remove these special case icons
    161         if (isExternalStorage()) {
    162             derivedIcon = R.drawable.ic_root_sdcard;
    163         } else if (isDownloads()) {
    164             derivedIcon = R.drawable.ic_root_download;
    165         } else if (isImages()) {
    166             derivedIcon = R.drawable.ic_doc_image;
    167         } else if (isVideos()) {
    168             derivedIcon = R.drawable.ic_doc_video;
    169         } else if (isAudio()) {
    170             derivedIcon = R.drawable.ic_doc_audio;
    171         }
    172     }
    173 
    174     public boolean isRecents() {
    175         return authority == null && rootId == null;
    176     }
    177 
    178     public boolean isExternalStorage() {
    179         return "com.android.externalstorage.documents".equals(authority);
    180     }
    181 
    182     public boolean isDownloads() {
    183         return "com.android.providers.downloads.documents".equals(authority);
    184     }
    185 
    186     public boolean isImages() {
    187         return "com.android.providers.media.documents".equals(authority)
    188                 && "images_root".equals(rootId);
    189     }
    190 
    191     public boolean isVideos() {
    192         return "com.android.providers.media.documents".equals(authority)
    193                 && "videos_root".equals(rootId);
    194     }
    195 
    196     public boolean isAudio() {
    197         return "com.android.providers.media.documents".equals(authority)
    198                 && "audio_root".equals(rootId);
    199     }
    200 
    201     @Override
    202     public String toString() {
    203         return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
    204     }
    205 
    206     public Drawable loadIcon(Context context) {
    207         if (derivedIcon != 0) {
    208             return context.getDrawable(derivedIcon);
    209         } else {
    210             return IconUtils.loadPackageIcon(context, authority, icon);
    211         }
    212     }
    213 
    214     public Drawable loadDrawerIcon(Context context) {
    215         if (derivedIcon != 0) {
    216             return IconUtils.applyTintColor(context, derivedIcon, R.color.item_root_icon);
    217         } else {
    218             return IconUtils.loadPackageIcon(context, authority, icon);
    219         }
    220     }
    221 
    222     public Drawable loadGridIcon(Context context) {
    223         if (derivedIcon != 0) {
    224             return IconUtils.applyTintAttr(context, derivedIcon,
    225                     android.R.attr.textColorPrimaryInverse);
    226         } else {
    227             return IconUtils.loadPackageIcon(context, authority, icon);
    228         }
    229     }
    230 
    231     public Drawable loadToolbarIcon(Context context) {
    232         if (derivedIcon != 0) {
    233             return IconUtils.applyTintAttr(context, derivedIcon,
    234                     android.R.attr.colorControlNormal);
    235         } else {
    236             return IconUtils.loadPackageIcon(context, authority, icon);
    237         }
    238     }
    239 
    240     @Override
    241     public boolean equals(Object o) {
    242         if (o instanceof RootInfo) {
    243             final RootInfo root = (RootInfo) o;
    244             return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
    245         } else {
    246             return false;
    247         }
    248     }
    249 
    250     @Override
    251     public int hashCode() {
    252         return Objects.hash(authority, rootId);
    253     }
    254 
    255     public String getDirectoryString() {
    256         return !TextUtils.isEmpty(summary) ? summary : title;
    257     }
    258 }
    259