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