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 /** The FLAG_STUB_VISIBLE is set from vold, which gets the flag from outside (e.g., ChromeOS) */ 54 public static final int FLAG_STUB_VISIBLE = 1 << 6; 55 56 public final String id; 57 @UnsupportedAppUsage 58 public final int flags; 59 @UnsupportedAppUsage 60 public long size; 61 @UnsupportedAppUsage 62 public String label; 63 /** Hacky; don't rely on this count */ 64 public int volumeCount; 65 public String sysPath; 66 DiskInfo(String id, int flags)67 public DiskInfo(String id, int flags) { 68 this.id = Preconditions.checkNotNull(id); 69 this.flags = flags; 70 } 71 72 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) DiskInfo(Parcel parcel)73 public DiskInfo(Parcel parcel) { 74 id = parcel.readString(); 75 flags = parcel.readInt(); 76 size = parcel.readLong(); 77 label = parcel.readString(); 78 volumeCount = parcel.readInt(); 79 sysPath = parcel.readString(); 80 } 81 82 @UnsupportedAppUsage getId()83 public @NonNull String getId() { 84 return id; 85 } 86 isInteresting(String label)87 private boolean isInteresting(String label) { 88 if (TextUtils.isEmpty(label)) { 89 return false; 90 } 91 if (label.equalsIgnoreCase("ata")) { 92 return false; 93 } 94 if (label.toLowerCase().contains("generic")) { 95 return false; 96 } 97 if (label.toLowerCase().startsWith("usb")) { 98 return false; 99 } 100 if (label.toLowerCase().startsWith("multiple")) { 101 return false; 102 } 103 return true; 104 } 105 106 @UnsupportedAppUsage getDescription()107 public @Nullable String getDescription() { 108 final Resources res = Resources.getSystem(); 109 if ((flags & FLAG_SD) != 0) { 110 if (isInteresting(label)) { 111 return res.getString(com.android.internal.R.string.storage_sd_card_label, label); 112 } else { 113 return res.getString(com.android.internal.R.string.storage_sd_card); 114 } 115 } else if ((flags & FLAG_USB) != 0) { 116 if (isInteresting(label)) { 117 return res.getString(com.android.internal.R.string.storage_usb_drive_label, label); 118 } else { 119 return res.getString(com.android.internal.R.string.storage_usb_drive); 120 } 121 } else { 122 return null; 123 } 124 } 125 getShortDescription()126 public @Nullable String getShortDescription() { 127 final Resources res = Resources.getSystem(); 128 if (isSd()) { 129 return res.getString(com.android.internal.R.string.storage_sd_card); 130 } else if (isUsb()) { 131 return res.getString(com.android.internal.R.string.storage_usb_drive); 132 } else { 133 return null; 134 } 135 } 136 137 @UnsupportedAppUsage isAdoptable()138 public boolean isAdoptable() { 139 return (flags & FLAG_ADOPTABLE) != 0; 140 } 141 142 @UnsupportedAppUsage isDefaultPrimary()143 public boolean isDefaultPrimary() { 144 return (flags & FLAG_DEFAULT_PRIMARY) != 0; 145 } 146 147 @UnsupportedAppUsage isSd()148 public boolean isSd() { 149 return (flags & FLAG_SD) != 0; 150 } 151 152 @UnsupportedAppUsage isUsb()153 public boolean isUsb() { 154 return (flags & FLAG_USB) != 0; 155 } 156 isStubVisible()157 public boolean isStubVisible() { 158 return (flags & FLAG_STUB_VISIBLE) != 0; 159 } 160 161 @Override toString()162 public String toString() { 163 final CharArrayWriter writer = new CharArrayWriter(); 164 dump(new IndentingPrintWriter(writer, " ", 80)); 165 return writer.toString(); 166 } 167 dump(IndentingPrintWriter pw)168 public void dump(IndentingPrintWriter pw) { 169 pw.println("DiskInfo{" + id + "}:"); 170 pw.increaseIndent(); 171 pw.printPair("flags", DebugUtils.flagsToString(getClass(), "FLAG_", flags)); 172 pw.printPair("size", size); 173 pw.printPair("label", label); 174 pw.println(); 175 pw.printPair("sysPath", sysPath); 176 pw.decreaseIndent(); 177 pw.println(); 178 } 179 180 @Override clone()181 public DiskInfo clone() { 182 final Parcel temp = Parcel.obtain(); 183 try { 184 writeToParcel(temp, 0); 185 temp.setDataPosition(0); 186 return CREATOR.createFromParcel(temp); 187 } finally { 188 temp.recycle(); 189 } 190 } 191 192 @Override equals(@ullable Object o)193 public boolean equals(@Nullable Object o) { 194 if (o instanceof DiskInfo) { 195 return Objects.equals(id, ((DiskInfo) o).id); 196 } else { 197 return false; 198 } 199 } 200 201 @Override hashCode()202 public int hashCode() { 203 return id.hashCode(); 204 } 205 206 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 207 public static final @android.annotation.NonNull Creator<DiskInfo> CREATOR = new Creator<DiskInfo>() { 208 @Override 209 public DiskInfo createFromParcel(Parcel in) { 210 return new DiskInfo(in); 211 } 212 213 @Override 214 public DiskInfo[] newArray(int size) { 215 return new DiskInfo[size]; 216 } 217 }; 218 219 @Override describeContents()220 public int describeContents() { 221 return 0; 222 } 223 224 @Override writeToParcel(Parcel parcel, int flags)225 public void writeToParcel(Parcel parcel, int flags) { 226 parcel.writeString(id); 227 parcel.writeInt(this.flags); 228 parcel.writeLong(size); 229 parcel.writeString(label); 230 parcel.writeInt(volumeCount); 231 parcel.writeString(sysPath); 232 } 233 } 234