1 /* 2 * Copyright (C) 2022 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.mediapc.cts.common; 18 19 import com.android.compatibility.common.util.ReportLog; 20 import com.android.compatibility.common.util.ResultType; 21 import com.android.compatibility.common.util.ResultUnit; 22 23 import com.google.auto.value.AutoValue; 24 import com.google.common.collect.ImmutableMap; 25 26 import java.util.HashMap; 27 import java.util.Map; 28 import java.util.function.BiPredicate; 29 30 /** 31 * A specific measurement for a Performance Class requirement. 32 */ 33 @AutoValue 34 public abstract class RequiredMeasurement<T> { 35 private static final String TAG = RequiredMeasurement.class.getSimpleName(); 36 37 private T measuredValue; // Note this is not part of the equals calculations 38 private boolean measuredValueSet = false; 39 builder()40 public static <T> Builder<T> builder() { 41 return new AutoValue_RequiredMeasurement.Builder<T>(); 42 } 43 id()44 public abstract String id(); 45 46 /** 47 * Tests if the measured value satisfies the expected value(eg >=) 48 * measuredValue, expectedValue 49 */ predicate()50 public abstract BiPredicate<T, T> predicate(); 51 52 /** 53 * Maps MPC level to the expected value. 54 */ expectedValues()55 public abstract ImmutableMap<Integer, T> expectedValues(); 56 setMeasuredValue(T measuredValue)57 public void setMeasuredValue(T measuredValue) { 58 this.measuredValueSet = true; 59 this.measuredValue = measuredValue; 60 } 61 62 @AutoValue.Builder 63 public static abstract class Builder<T> { 64 setId(String id)65 public abstract Builder<T> setId(String id); 66 setPredicate(BiPredicate<T, T> predicate)67 public abstract Builder<T> setPredicate(BiPredicate<T, T> predicate); 68 expectedValuesBuilder()69 public abstract ImmutableMap.Builder<Integer, T> expectedValuesBuilder(); 70 addRequiredValue(Integer performanceClass, T expectedValue)71 public Builder<T> addRequiredValue(Integer performanceClass, T expectedValue) { 72 this.expectedValuesBuilder().put(performanceClass, expectedValue); 73 return this; 74 } 75 build()76 public abstract RequiredMeasurement<T> build(); 77 } 78 meetsPerformanceClass(int mediaPerformanceClass)79 public final RequirementConstants.Result meetsPerformanceClass(int mediaPerformanceClass) 80 throws IllegalStateException { 81 82 if (!this.measuredValueSet) { 83 throw new IllegalStateException("measured value not set for required measurement " 84 + this.id()); 85 } 86 87 if (!this.expectedValues().containsKey(mediaPerformanceClass)) { 88 return RequirementConstants.Result.NA; 89 } else if (this.measuredValue == null || !this.predicate().test(this.measuredValue, 90 this.expectedValues().get(mediaPerformanceClass))) { 91 return RequirementConstants.Result.UNMET; 92 } else { 93 return RequirementConstants.Result.MET; 94 } 95 } 96 97 /** 98 * @return map PerfomenaceClass to result if that performance class has been met 99 */ getPerformanceClass()100 public Map<Integer, RequirementConstants.Result> getPerformanceClass() { 101 Map<Integer, RequirementConstants.Result> perfClassResults = new HashMap<>(); 102 for (Integer pc: this.expectedValues().keySet()) { 103 perfClassResults.put(pc, this.meetsPerformanceClass(pc)); 104 } 105 return perfClassResults; 106 } 107 108 @Override toString()109 public final String toString() { 110 return "Required Measurement with:" 111 + "\n\tId: " + this.id() 112 + "\n\tPredicate: " + this.predicate() 113 + "\n\tMeasured Value: " + this.measuredValue 114 + "\n\tExpected Values: " + this.expectedValues(); 115 } 116 writeValue(ReportLog log)117 public void writeValue(ReportLog log) throws IllegalStateException { 118 119 if (!this.measuredValueSet) { 120 throw new IllegalStateException("measured value not set for required measurement " 121 + this.id()); 122 } 123 124 if (this.measuredValue == null) { 125 log.addValue(this.id(), "<nullptr>", ResultType.NEUTRAL, ResultUnit.NONE); 126 } else if (this.measuredValue instanceof Integer) { 127 log.addValue(this.id(), (int)this.measuredValue, ResultType.NEUTRAL, ResultUnit.NONE); 128 } else if (this.measuredValue instanceof Long) { 129 log.addValue(this.id(), (long)this.measuredValue, ResultType.NEUTRAL, ResultUnit.NONE); 130 } else if (this.measuredValue instanceof Float) { 131 log.addValue(this.id(), (float)this.measuredValue, ResultType.NEUTRAL, ResultUnit.NONE); 132 } else if (this.measuredValue instanceof Double) { 133 log.addValue(this.id(), (double)this.measuredValue, ResultType.NEUTRAL, 134 ResultUnit.NONE); 135 } else if (this.measuredValue instanceof Boolean) { 136 log.addValue(this.id(), (boolean)this.measuredValue, ResultType.NEUTRAL, 137 ResultUnit.NONE); 138 } else if (this.measuredValue instanceof String) { 139 log.addValue(this.id(), (String)this.measuredValue, ResultType.NEUTRAL, 140 ResultUnit.NONE); 141 } else { 142 // reporting all other types as Strings using toString() 143 log.addValue(this.id(), this.measuredValue.toString(), ResultType.NEUTRAL, 144 ResultUnit.NONE); 145 } 146 } 147 } 148