1 /* 2 * Copyright (C) 2017 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 package android.car.storagemonitoring; 17 18 import android.annotation.IntRange; 19 import android.annotation.SystemApi; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 import android.util.JsonReader; 23 import android.util.JsonWriter; 24 import java.io.IOException; 25 import java.util.Objects; 26 import org.json.JSONException; 27 import org.json.JSONObject; 28 29 /** 30 * Wear-out information for flash storage. 31 * 32 * Contains a lower-bound estimate of the wear of "type A" (SLC) and "type B" (MLC) storage. 33 * 34 * Current technology offers wear data in increments of 10% (i.e. from 0 == new device up to 35 * 100 == worn-out device). It is possible for a storage device to only support one type of memory 36 * cell, in which case it is expected that the storage type not supported will have UNKNOWN wear. 37 * 38 * @hide 39 */ 40 @SystemApi 41 public class WearEstimate implements Parcelable { 42 public static final int UNKNOWN = -1; 43 44 /** @hide */ 45 public static final WearEstimate UNKNOWN_ESTIMATE = new WearEstimate(UNKNOWN, UNKNOWN); 46 47 public static final Parcelable.Creator<WearEstimate> CREATOR = 48 new Parcelable.Creator<WearEstimate>() { 49 public WearEstimate createFromParcel(Parcel in) { 50 return new WearEstimate(in); 51 } 52 53 public WearEstimate[] newArray(int size) { 54 return new WearEstimate[size]; 55 } 56 }; 57 58 /** 59 * Wear estimate data for "type A" storage. 60 */ 61 @IntRange(from=-1, to=100) 62 public final int typeA; 63 64 /** 65 * Wear estimate data for "type B" storage. 66 */ 67 @IntRange(from=-1, to=100) 68 public final int typeB; 69 70 private static final int validateWearValue(int value) { 71 if (value == UNKNOWN) return value; 72 if ((value >= 0) && (value <= 100)) return value; 73 throw new IllegalArgumentException(value + " is not a valid wear estimate"); 74 } 75 76 public WearEstimate(int typeA, int typeB) { 77 this.typeA = validateWearValue(typeA); 78 this.typeB = validateWearValue(typeB); 79 } 80 81 public WearEstimate(Parcel in) { 82 typeA = validateWearValue(in.readInt()); 83 typeB = validateWearValue(in.readInt()); 84 } 85 86 public WearEstimate(JsonReader in) throws IOException { 87 int typeA = UNKNOWN; 88 int typeB = UNKNOWN; 89 in.beginObject(); 90 while (in.hasNext()) { 91 switch (in.nextName()) { 92 case "wearEstimateTypeA": 93 typeA = validateWearValue(in.nextInt()); 94 break; 95 case "wearEstimateTypeB": 96 typeB = validateWearValue(in.nextInt()); 97 break; 98 } 99 } 100 in.endObject(); 101 this.typeA = typeA; 102 this.typeB = typeB; 103 } 104 105 /** @hide */ 106 public WearEstimate(JSONObject in) throws JSONException { 107 typeA = in.getInt("wearEstimateTypeA"); 108 typeB = in.getInt("wearEstimateTypeB"); 109 } 110 111 @Override 112 public int describeContents() { 113 return 0; 114 } 115 116 @Override 117 public void writeToParcel(Parcel dest, int flags) { 118 dest.writeInt(typeA); 119 dest.writeInt(typeB); 120 } 121 122 public void writeToJson(JsonWriter jsonWriter) throws IOException { 123 jsonWriter.beginObject(); 124 jsonWriter.name("wearEstimateTypeA").value(typeA); 125 jsonWriter.name("wearEstimateTypeB").value(typeB); 126 jsonWriter.endObject(); 127 } 128 129 @Override 130 public boolean equals(Object other) { 131 if (other instanceof WearEstimate) { 132 WearEstimate wo = (WearEstimate)other; 133 return wo.typeA == typeA && wo.typeB == typeB; 134 } 135 return false; 136 } 137 138 @Override 139 public int hashCode() { 140 return Objects.hash(typeA, typeB); 141 } 142 143 private static final String wearValueToString(int value) { 144 if (value == UNKNOWN) return "unknown"; 145 return value + "%"; 146 } 147 148 @Override 149 public String toString() { 150 return "type A: " + wearValueToString(typeA) + ", type B: " + wearValueToString(typeB); 151 } 152 } 153