Home | History | Annotate | Download | only in storagemonitoring
      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