1 /*
2  * Copyright (C) 2015 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 android.os.storage;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.res.Resources;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.text.TextUtils;
25 import android.util.DebugUtils;
26 
27 import com.android.internal.util.IndentingPrintWriter;
28 import com.android.internal.util.Preconditions;
29 
30 import java.io.CharArrayWriter;
31 import java.util.Objects;
32 
33 /**
34  * Information about a physical disk which may contain one or more
35  * {@link VolumeInfo}.
36  *
37  * @hide
38  */
39 public class DiskInfo implements Parcelable {
40     public static final String ACTION_DISK_SCANNED =
41             "android.os.storage.action.DISK_SCANNED";
42     public static final String EXTRA_DISK_ID =
43             "android.os.storage.extra.DISK_ID";
44     public static final String EXTRA_VOLUME_COUNT =
45             "android.os.storage.extra.VOLUME_COUNT";
46 
47     public static final int FLAG_ADOPTABLE = 1 << 0;
48     public static final int FLAG_DEFAULT_PRIMARY = 1 << 1;
49     public static final int FLAG_SD = 1 << 2;
50     public static final int FLAG_USB = 1 << 3;
51 
52     public final String id;
53     public final int flags;
54     public long size;
55     public String label;
56     /** Hacky; don't rely on this count */
57     public int volumeCount;
58     public String sysPath;
59 
DiskInfo(String id, int flags)60     public DiskInfo(String id, int flags) {
61         this.id = Preconditions.checkNotNull(id);
62         this.flags = flags;
63     }
64 
DiskInfo(Parcel parcel)65     public DiskInfo(Parcel parcel) {
66         id = parcel.readString();
67         flags = parcel.readInt();
68         size = parcel.readLong();
69         label = parcel.readString();
70         volumeCount = parcel.readInt();
71         sysPath = parcel.readString();
72     }
73 
getId()74     public @NonNull String getId() {
75         return id;
76     }
77 
isInteresting(String label)78     private boolean isInteresting(String label) {
79         if (TextUtils.isEmpty(label)) {
80             return false;
81         }
82         if (label.equalsIgnoreCase("ata")) {
83             return false;
84         }
85         if (label.toLowerCase().contains("generic")) {
86             return false;
87         }
88         if (label.toLowerCase().startsWith("usb")) {
89             return false;
90         }
91         if (label.toLowerCase().startsWith("multiple")) {
92             return false;
93         }
94         return true;
95     }
96 
getDescription()97     public @Nullable String getDescription() {
98         final Resources res = Resources.getSystem();
99         if ((flags & FLAG_SD) != 0) {
100             if (isInteresting(label)) {
101                 return res.getString(com.android.internal.R.string.storage_sd_card_label, label);
102             } else {
103                 return res.getString(com.android.internal.R.string.storage_sd_card);
104             }
105         } else if ((flags & FLAG_USB) != 0) {
106             if (isInteresting(label)) {
107                 return res.getString(com.android.internal.R.string.storage_usb_drive_label, label);
108             } else {
109                 return res.getString(com.android.internal.R.string.storage_usb_drive);
110             }
111         } else {
112             return null;
113         }
114     }
115 
getShortDescription()116     public @Nullable String getShortDescription() {
117         final Resources res = Resources.getSystem();
118         if (isSd()) {
119             return res.getString(com.android.internal.R.string.storage_sd_card);
120         } else if (isUsb()) {
121             return res.getString(com.android.internal.R.string.storage_usb_drive);
122         } else {
123             return null;
124         }
125     }
126 
isAdoptable()127     public boolean isAdoptable() {
128         return (flags & FLAG_ADOPTABLE) != 0;
129     }
130 
isDefaultPrimary()131     public boolean isDefaultPrimary() {
132         return (flags & FLAG_DEFAULT_PRIMARY) != 0;
133     }
134 
isSd()135     public boolean isSd() {
136         return (flags & FLAG_SD) != 0;
137     }
138 
isUsb()139     public boolean isUsb() {
140         return (flags & FLAG_USB) != 0;
141     }
142 
143     @Override
toString()144     public String toString() {
145         final CharArrayWriter writer = new CharArrayWriter();
146         dump(new IndentingPrintWriter(writer, "    ", 80));
147         return writer.toString();
148     }
149 
dump(IndentingPrintWriter pw)150     public void dump(IndentingPrintWriter pw) {
151         pw.println("DiskInfo{" + id + "}:");
152         pw.increaseIndent();
153         pw.printPair("flags", DebugUtils.flagsToString(getClass(), "FLAG_", flags));
154         pw.printPair("size", size);
155         pw.printPair("label", label);
156         pw.println();
157         pw.printPair("sysPath", sysPath);
158         pw.decreaseIndent();
159         pw.println();
160     }
161 
162     @Override
clone()163     public DiskInfo clone() {
164         final Parcel temp = Parcel.obtain();
165         try {
166             writeToParcel(temp, 0);
167             temp.setDataPosition(0);
168             return CREATOR.createFromParcel(temp);
169         } finally {
170             temp.recycle();
171         }
172     }
173 
174     @Override
equals(Object o)175     public boolean equals(Object o) {
176         if (o instanceof DiskInfo) {
177             return Objects.equals(id, ((DiskInfo) o).id);
178         } else {
179             return false;
180         }
181     }
182 
183     @Override
hashCode()184     public int hashCode() {
185         return id.hashCode();
186     }
187 
188     public static final Creator<DiskInfo> CREATOR = new Creator<DiskInfo>() {
189         @Override
190         public DiskInfo createFromParcel(Parcel in) {
191             return new DiskInfo(in);
192         }
193 
194         @Override
195         public DiskInfo[] newArray(int size) {
196             return new DiskInfo[size];
197         }
198     };
199 
200     @Override
describeContents()201     public int describeContents() {
202         return 0;
203     }
204 
205     @Override
writeToParcel(Parcel parcel, int flags)206     public void writeToParcel(Parcel parcel, int flags) {
207         parcel.writeString(id);
208         parcel.writeInt(this.flags);
209         parcel.writeLong(size);
210         parcel.writeString(label);
211         parcel.writeInt(volumeCount);
212         parcel.writeString(sysPath);
213     }
214 }
215