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 static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE; 19 20 import static java.util.Objects.requireNonNull; 21 22 import android.annotation.NonNull; 23 import android.annotation.SystemApi; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 28 29 import java.time.Instant; 30 import java.util.Objects; 31 32 /** 33 * Change in wear-out information. 34 * 35 * Contains information about the first cycle during which the system detected a change 36 * in wear-out information of the flash storage. 37 * 38 * @hide 39 */ 40 @SystemApi 41 public final class WearEstimateChange implements Parcelable { 42 public static final Parcelable.Creator<WearEstimateChange> CREATOR = 43 new Parcelable.Creator<WearEstimateChange>() { 44 public WearEstimateChange createFromParcel(Parcel in) { 45 return new WearEstimateChange(in); 46 } 47 48 public WearEstimateChange[] newArray(int size) { 49 return new WearEstimateChange[size]; 50 } 51 }; 52 53 /** 54 * The previous wear estimate. 55 */ 56 public final @NonNull WearEstimate oldEstimate; 57 58 /** 59 * The new wear estimate. 60 */ 61 public final @NonNull WearEstimate newEstimate; 62 63 /** 64 * Total CarService uptime when this change was detected. 65 */ 66 public final long uptimeAtChange; 67 68 /** 69 * Wall-clock time when this change was detected. 70 */ 71 public final @NonNull Instant dateAtChange; 72 73 /** 74 * Whether this change was within the vendor range for acceptable flash degradation. 75 */ 76 public final boolean isAcceptableDegradation; 77 WearEstimateChange(WearEstimate oldEstimate, WearEstimate newEstimate, long uptimeAtChange, Instant dateAtChange, boolean isAcceptableDegradation)78 public WearEstimateChange(WearEstimate oldEstimate, 79 WearEstimate newEstimate, 80 long uptimeAtChange, 81 Instant dateAtChange, 82 boolean isAcceptableDegradation) { 83 if (uptimeAtChange < 0) { 84 throw new IllegalArgumentException("uptimeAtChange must be >= 0"); 85 } 86 this.oldEstimate = requireNonNull(oldEstimate); 87 this.newEstimate = requireNonNull(newEstimate); 88 this.uptimeAtChange = uptimeAtChange; 89 this.dateAtChange = Instant.ofEpochSecond(requireNonNull(dateAtChange).getEpochSecond()); 90 this.isAcceptableDegradation = isAcceptableDegradation; 91 } 92 WearEstimateChange(Parcel in)93 public WearEstimateChange(Parcel in) { 94 oldEstimate = in.readParcelable(WearEstimate.class.getClassLoader()); 95 newEstimate = in.readParcelable(WearEstimate.class.getClassLoader()); 96 uptimeAtChange = in.readLong(); 97 long secs = in.readLong(); 98 int nanos = in.readInt(); 99 dateAtChange = Instant.ofEpochSecond(secs, nanos); 100 isAcceptableDegradation = in.readInt() == 1; 101 } 102 103 @Override 104 @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE) describeContents()105 public int describeContents() { 106 return 0; 107 } 108 109 @Override writeToParcel(Parcel dest, int flags)110 public void writeToParcel(Parcel dest, int flags) { 111 dest.writeParcelable(oldEstimate, flags); 112 dest.writeParcelable(newEstimate, flags); 113 dest.writeLong(uptimeAtChange); 114 dest.writeLong(dateAtChange.getEpochSecond()); 115 dest.writeInt(dateAtChange.getNano()); 116 dest.writeInt(isAcceptableDegradation ? 1 : 0); 117 } 118 119 @Override equals(Object other)120 public boolean equals(Object other) { 121 if (other instanceof WearEstimateChange) { 122 WearEstimateChange wo = (WearEstimateChange) other; 123 return wo.isAcceptableDegradation == isAcceptableDegradation 124 && wo.uptimeAtChange == uptimeAtChange 125 && wo.dateAtChange.equals(dateAtChange) 126 && wo.oldEstimate.equals(oldEstimate) 127 && wo.newEstimate.equals(newEstimate); 128 } 129 return false; 130 } 131 132 @Override hashCode()133 public int hashCode() { 134 return Objects.hash(oldEstimate, 135 newEstimate, 136 uptimeAtChange, 137 dateAtChange, 138 isAcceptableDegradation); 139 } 140 141 @Override toString()142 public String toString() { 143 return String.format( 144 "wear change{old level=%s, new level=%s, uptime=%d, date=%s, acceptable=%s}", 145 oldEstimate, 146 newEstimate, 147 uptimeAtChange, 148 dateAtChange, 149 isAcceptableDegradation ? "yes" : "no"); 150 } 151 152 } 153