| /* |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.mediapc.cts.common; |
| |
| import android.util.Log; |
| |
| import androidx.test.platform.app.InstrumentationRegistry; |
| |
| import com.android.compatibility.common.util.DeviceReportLog; |
| import com.android.compatibility.common.util.ResultType; |
| import com.android.compatibility.common.util.ResultUnit; |
| import com.google.common.annotations.VisibleForTesting; |
| import com.google.common.collect.ImmutableMap; |
| |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| /** |
| * Performance Class Requirement maps and req id to a set of {@link RequiredMeasurement}. |
| */ |
| public abstract class Requirement { |
| private static final String TAG = Requirement.class.getSimpleName(); |
| |
| protected final ImmutableMap<String, RequiredMeasurement<?>> mRequiredMeasurements; |
| protected final String id; |
| |
| protected Requirement(String id, RequiredMeasurement<?>[] reqs) { |
| this.id = id; |
| |
| ImmutableMap.Builder<String, RequiredMeasurement<?>> reqBuilder = |
| ImmutableMap.<String, RequiredMeasurement<?>>builder(); |
| for (RequiredMeasurement<?> r: reqs) { |
| reqBuilder.put(r.id(), r); |
| } |
| this.mRequiredMeasurements = reqBuilder.build(); |
| } |
| |
| public String id() { |
| return this.id; |
| } |
| |
| /** |
| * Finds the highest performance class where at least one RequiremdMeasurement has result |
| * RequirementConstants.Result.MET and none have RequirementConstants.Result.UNMET |
| */ |
| @VisibleForTesting |
| protected int computePerformanceClass() { |
| Map<Integer, RequirementConstants.Result> overallPerfClassResults = new HashMap<>(); |
| |
| for (RequiredMeasurement<?> rm: this.mRequiredMeasurements.values()) { |
| Map<Integer, RequirementConstants.Result> perfClassResults = rm.getPerformanceClass(); |
| |
| for (Integer pc: perfClassResults.keySet()) { |
| RequirementConstants.Result res = perfClassResults.get(pc); |
| |
| // if one or more results are UNMET, mark the performance class as UNMET |
| // otherwise if at least 1 of the results is MET, mark the performance class as MET |
| if (res == RequirementConstants.Result.UNMET) { |
| overallPerfClassResults.put(pc, RequirementConstants.Result.UNMET); |
| } else if (!overallPerfClassResults.containsKey(pc) && |
| res == RequirementConstants.Result.MET) { |
| overallPerfClassResults.put(pc, RequirementConstants.Result.MET); |
| } |
| } |
| } |
| |
| // report the highest performance class that has been MET |
| int perfClass = 0; |
| for (int pc: overallPerfClassResults.keySet()) { |
| if (overallPerfClassResults.get(pc) == RequirementConstants.Result.MET) { |
| perfClass = Math.max(perfClass, pc); |
| } |
| } |
| return perfClass; |
| } |
| |
| @VisibleForTesting |
| protected boolean checkPerformanceClass(int devicePerfClass) { |
| boolean noResultsUnment = true; |
| for (RequiredMeasurement<?> rm: this.mRequiredMeasurements.values()) { |
| RequirementConstants.Result res = rm.meetsPerformanceClass(devicePerfClass); |
| if (res == RequirementConstants.Result.UNMET) { |
| Log.w(Requirement.TAG, rm.toString()); |
| noResultsUnment = false; |
| } else { |
| Log.i(Requirement.TAG, rm.toString()); |
| } |
| } |
| return noResultsUnment; |
| } |
| |
| protected <T> void setMeasuredValue(String measurement, T measuredValue) { |
| RequiredMeasurement<T> rm = |
| (RequiredMeasurement<T>)this.mRequiredMeasurements.get(measurement); |
| rm.setMeasuredValue(measuredValue); |
| } |
| |
| /** |
| * @return whether or not the requirement meets the device's specified performance class |
| */ |
| public boolean writeLogAndCheck(String testName) { |
| int perfClass = this.computePerformanceClass(); |
| |
| DeviceReportLog log = new DeviceReportLog(RequirementConstants.REPORT_LOG_NAME, this.id); |
| log.addValue(RequirementConstants.TN_FIELD_NAME, testName, ResultType.NEUTRAL, |
| ResultUnit.NONE); |
| for (RequiredMeasurement rm: this.mRequiredMeasurements.values()) { |
| rm.writeValue(log); |
| } |
| log.addValue(RequirementConstants.PC_FIELD_NAME, perfClass, ResultType.NEUTRAL, |
| ResultUnit.NONE); |
| log.submit(InstrumentationRegistry.getInstrumentation()); |
| |
| return this.checkPerformanceClass(Utils.getPerfClass()); |
| } |
| } |