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.Nullable; 20 import android.compat.annotation.UnsupportedAppUsage; 21 import android.content.Context; 22 import android.os.Build; 23 import android.os.Environment; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.os.UserHandle; 27 import android.util.DebugUtils; 28 import android.util.TimeUtils; 29 30 import com.android.internal.util.IndentingPrintWriter; 31 import com.android.internal.util.Preconditions; 32 33 import java.io.File; 34 import java.util.Locale; 35 import java.util.Objects; 36 37 /** 38 * Metadata for a storage volume which may not be currently present. 39 * 40 * @hide 41 */ 42 public class VolumeRecord implements Parcelable { 43 public static final String EXTRA_FS_UUID = 44 "android.os.storage.extra.FS_UUID"; 45 46 public static final int USER_FLAG_INITED = 1 << 0; 47 public static final int USER_FLAG_SNOOZED = 1 << 1; 48 49 public final int type; 50 public final String fsUuid; 51 public String partGuid; 52 public String nickname; 53 public int userFlags; 54 public long createdMillis; 55 public long lastSeenMillis; 56 public long lastTrimMillis; 57 public long lastBenchMillis; 58 VolumeRecord(int type, String fsUuid)59 public VolumeRecord(int type, String fsUuid) { 60 this.type = type; 61 this.fsUuid = Preconditions.checkNotNull(fsUuid); 62 } 63 64 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) VolumeRecord(Parcel parcel)65 public VolumeRecord(Parcel parcel) { 66 type = parcel.readInt(); 67 fsUuid = parcel.readString(); 68 partGuid = parcel.readString(); 69 nickname = parcel.readString(); 70 userFlags = parcel.readInt(); 71 createdMillis = parcel.readLong(); 72 lastSeenMillis = parcel.readLong(); 73 lastTrimMillis = parcel.readLong(); 74 lastBenchMillis = parcel.readLong(); 75 } 76 getType()77 public int getType() { 78 return type; 79 } 80 getFsUuid()81 public String getFsUuid() { 82 return fsUuid; 83 } 84 getNormalizedFsUuid()85 public String getNormalizedFsUuid() { 86 return fsUuid != null ? fsUuid.toLowerCase(Locale.US) : null; 87 } 88 getNickname()89 public String getNickname() { 90 return nickname; 91 } 92 isInited()93 public boolean isInited() { 94 return (userFlags & USER_FLAG_INITED) != 0; 95 } 96 isSnoozed()97 public boolean isSnoozed() { 98 return (userFlags & USER_FLAG_SNOOZED) != 0; 99 } 100 buildStorageVolume(Context context)101 public StorageVolume buildStorageVolume(Context context) { 102 final String id = "unknown:" + fsUuid; 103 final File userPath = new File("/dev/null"); 104 final File internalPath = new File("/dev/null"); 105 final boolean primary = false; 106 final boolean removable = true; 107 final boolean emulated = false; 108 final boolean externallyManaged = false; 109 final boolean allowMassStorage = false; 110 final long maxFileSize = 0; 111 final UserHandle user = new UserHandle(UserHandle.USER_NULL); 112 final String envState = Environment.MEDIA_UNKNOWN; 113 114 String description = nickname; 115 if (description == null) { 116 description = context.getString(android.R.string.unknownName); 117 } 118 119 return new StorageVolume(id, userPath, internalPath, description, primary, removable, 120 emulated, externallyManaged, allowMassStorage, maxFileSize, user, null /* uuid */, 121 fsUuid, envState); 122 } 123 dump(IndentingPrintWriter pw)124 public void dump(IndentingPrintWriter pw) { 125 pw.println("VolumeRecord:"); 126 pw.increaseIndent(); 127 pw.printPair("type", DebugUtils.valueToString(VolumeInfo.class, "TYPE_", type)); 128 pw.printPair("fsUuid", fsUuid); 129 pw.printPair("partGuid", partGuid); 130 pw.println(); 131 pw.printPair("nickname", nickname); 132 pw.printPair("userFlags", 133 DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags)); 134 pw.println(); 135 pw.printPair("createdMillis", TimeUtils.formatForLogging(createdMillis)); 136 pw.printPair("lastSeenMillis", TimeUtils.formatForLogging(lastSeenMillis)); 137 pw.printPair("lastTrimMillis", TimeUtils.formatForLogging(lastTrimMillis)); 138 pw.printPair("lastBenchMillis", TimeUtils.formatForLogging(lastBenchMillis)); 139 pw.decreaseIndent(); 140 pw.println(); 141 } 142 143 @Override clone()144 public VolumeRecord clone() { 145 final Parcel temp = Parcel.obtain(); 146 try { 147 writeToParcel(temp, 0); 148 temp.setDataPosition(0); 149 return CREATOR.createFromParcel(temp); 150 } finally { 151 temp.recycle(); 152 } 153 } 154 155 @Override equals(@ullable Object o)156 public boolean equals(@Nullable Object o) { 157 if (o instanceof VolumeRecord) { 158 return Objects.equals(fsUuid, ((VolumeRecord) o).fsUuid); 159 } else { 160 return false; 161 } 162 } 163 164 @Override hashCode()165 public int hashCode() { 166 return fsUuid.hashCode(); 167 } 168 169 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 170 public static final @android.annotation.NonNull Creator<VolumeRecord> CREATOR = new Creator<VolumeRecord>() { 171 @Override 172 public VolumeRecord createFromParcel(Parcel in) { 173 return new VolumeRecord(in); 174 } 175 176 @Override 177 public VolumeRecord[] newArray(int size) { 178 return new VolumeRecord[size]; 179 } 180 }; 181 182 @Override describeContents()183 public int describeContents() { 184 return 0; 185 } 186 187 @Override writeToParcel(Parcel parcel, int flags)188 public void writeToParcel(Parcel parcel, int flags) { 189 parcel.writeInt(type); 190 parcel.writeString(fsUuid); 191 parcel.writeString(partGuid); 192 parcel.writeString(nickname); 193 parcel.writeInt(userFlags); 194 parcel.writeLong(createdMillis); 195 parcel.writeLong(lastSeenMillis); 196 parcel.writeLong(lastTrimMillis); 197 parcel.writeLong(lastBenchMillis); 198 } 199 } 200