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