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