1 /* 2 * Copyright (C) 2016 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 com.android.cts.verifier.sensors.sixdof.Utils.TestPhase; 18 19 20 import com.android.cts.verifier.sensors.sixdof.Dialogs.BaseResultsDialog; 21 import com.android.cts.verifier.sensors.sixdof.Utils.Manager; 22 import com.android.cts.verifier.sensors.sixdof.Utils.MathsUtils; 23 import com.android.cts.verifier.sensors.sixdof.Utils.TestReport; 24 import com.android.cts.verifier.sensors.sixdof.Utils.Path.ReferencePath; 25 import com.android.cts.verifier.sensors.sixdof.Utils.Path.RobustnessPath; 26 import com.android.cts.verifier.sensors.sixdof.Utils.Path.PathUtilityClasses.RotationData; 27 28 import android.util.Log; 29 30 import java.util.ArrayList; 31 import java.util.HashMap; 32 33 /** 34 * Handles all the Robustness test related features. 35 */ 36 public class RobustnessTest extends Test { 37 private static final float MAXIMUM_PERCENT_ROTATION_FAILURE = 50f; 38 private boolean mResultsGiven = false; 39 private ArrayList<Long> mTimeDifferences = new ArrayList<>(); 40 private float mDistanceOfPathToFail; 41 42 /** 43 * Created a new robustness path which is to be used in this test. 44 * 45 * @param referencePath Reference the the reference path. 46 * @param testReport The test report object to record the tests. 47 * @param manager The manager to call when the test is done. 48 */ RobustnessTest(ReferencePath referencePath, TestReport testReport, Manager manager, int openGlRotation)49 public RobustnessTest(ReferencePath referencePath, TestReport testReport, Manager manager, 50 int openGlRotation) { 51 super(referencePath, testReport, manager, "Robustness Test"); 52 mTestPath = new RobustnessPath(openGlRotation); 53 float mPathTotalDistance = 0; 54 for (float distance : mReferencePathDistances) { 55 mPathTotalDistance += distance; 56 } 57 mDistanceOfPathToFail = (MAXIMUM_PERCENT_ROTATION_FAILURE / 100f) * mPathTotalDistance; 58 } 59 60 /** 61 * Implementation of the abstract method which check whether the test is complete. 62 */ 63 @Override runAdditionalMethods()64 protected void runAdditionalMethods() { 65 if (mTestPath.getPathMarkersSize() == MAX_MARKER_NUMBER && !mResultsGiven) { 66 mResultsGiven = true; 67 executeRobustnessTests(); 68 } 69 } 70 71 /** 72 * Starts the robustness tests. 73 */ executeRobustnessTests()74 private void executeRobustnessTests() { 75 HashMap<BaseResultsDialog.ResultType, Boolean> robustnessTestResults; 76 robustnessTestResults = executeTests(true, true); 77 robustnessTestResults.put(BaseResultsDialog.ResultType.TIME, timerTest()); 78 robustnessTestResults.put(BaseResultsDialog.ResultType.ROTATION, rotationTest()); 79 mManager.onRobustnessTestCompleted(robustnessTestResults); 80 } 81 82 /** 83 * Test to check whether the waypoint was placed in the appropriate time. 84 * 85 * @return true if all waypoint times were met, fail if a waypoint was placed after the time 86 * expired 87 */ timerTest()88 private boolean timerTest() { 89 calculateTimeBetweenMarkers(); 90 boolean state = true; 91 for (int i = 0; i < mTimeDifferences.size(); i++) { 92 if (mTimeDifferences.get(i) > RobustnessPath.TIME_TO_ADD_MARKER) { 93 recordTimerTestResults(i); 94 state = false; 95 } 96 } 97 return state; 98 } 99 100 /** 101 * Calculates the time it took to place a waypoint. 102 */ calculateTimeBetweenMarkers()103 private void calculateTimeBetweenMarkers() { 104 long timeDifference; 105 ArrayList<Long> markerTimeStamps = ((RobustnessPath) mTestPath).getMarkerTimeStamp(); 106 for (int i = 1; i < ((RobustnessPath) mTestPath).getMarkerTimeStampSize(); i++) { 107 timeDifference = markerTimeStamps.get(i) - markerTimeStamps.get(i - 1); 108 mTimeDifferences.add(timeDifference); 109 } 110 } 111 112 /** 113 * Formats the failed times into a string to add it to the test report. 114 * 115 * @param markerLocation The marker location which failed the test. Used to get the data needed 116 * for the test report 117 */ recordTimerTestResults(int markerLocation)118 private void recordTimerTestResults(int markerLocation) { 119 long failedTime = mTimeDifferences.get(markerLocation); 120 String markerToPlace = MathsUtils.coordinatesToString( 121 mTestPath.getPathMarkers().get(markerLocation).getCoordinates()); 122 String testDetails = 123 "Timer test: Marker placement was too slow that timer expired. Target time: " 124 + RobustnessPath.TIME_TO_ADD_MARKER / 1000 + " Completed time: " + Math.abs(failedTime) / 1000 + 125 " Marker: " + markerLocation + " Coordinates:" + markerToPlace + "\n"; 126 Log.e("Timer Result", testDetails); 127 mTestReport.setFailDetails(testDetails); 128 } 129 130 /** 131 * Test to check whether the rotation test has passed based on the percent of failed rotations. 132 * 133 * @return true if the test passes, false if the test fails 134 */ rotationTest()135 private boolean rotationTest() { 136 float failedRotations = ((RobustnessPath) mTestPath).getFailedRotationsSize(); 137 float totalRotations = ((RobustnessPath) mTestPath).getRobustnessPathRotationsSize(); 138 float percentage = (failedRotations / totalRotations) * 100; 139 if (totalRotations == 0) { 140 Log.e("rotationResult", "Total was 0"); 141 return false; 142 } 143 if (percentage > MAXIMUM_PERCENT_ROTATION_FAILURE) { 144 Log.d("rotationResult", "failed"); 145 recordRotationTestResults(percentage, failedRotations, totalRotations); 146 return false; 147 } else { 148 Log.d("getFailedRotationSize", "" + failedRotations); 149 Log.d("total", "" + totalRotations); 150 Log.d("rotationResult", "passed "); 151 Log.d("rotationResult", "" + percentage); 152 return true; 153 } 154 } 155 156 /** 157 * Formats the failed rotations into a string to add it to the test report. 158 * 159 * @param percentFailed Percentage of failed rotations 160 * @param failedRotations number of failed rotations 161 * @param totalRotations number of rotations made 162 */ recordRotationTestResults(float percentFailed, float failedRotations, float totalRotations)163 private void recordRotationTestResults(float percentFailed, float failedRotations, float totalRotations) { 164 String testDetails = 165 "Rotation test: Rotation fails were too great. Target rotation percent: " 166 + MAXIMUM_PERCENT_ROTATION_FAILURE + " GivenRotation percent: " + percentFailed + 167 " Failed rotation: " + failedRotations + " Total rotations:" + totalRotations + "\n"; 168 Log.e("Timer Result", testDetails); 169 mTestReport.setFailDetails(testDetails); 170 } 171 172 /** 173 * gets the result of comparing the current rotation 174 * 175 * @param rotationQuaternion The quaternions of the current rotation 176 * @param location The location of the point with the rotation 177 * @return The rotation about the current rotation 178 */ getRotationData(float[] rotationQuaternion, float[] location)179 public RotationData getRotationData(float[] rotationQuaternion, float[] location) { 180 RotationData rotation = ((RobustnessPath) mTestPath).handleRotation( 181 rotationQuaternion, location, mReferencePath.getPathMarkers(), mDistanceOfPathToFail); 182 if (rotation == null) { 183 if (!mResultsGiven) { 184 mResultsGiven = true; 185 HashMap<BaseResultsDialog.ResultType, Boolean> testFailed = new HashMap<>(); 186 testFailed.put(BaseResultsDialog.ResultType.WAYPOINT, false); 187 testFailed.put(BaseResultsDialog.ResultType.PATH, false); 188 testFailed.put(BaseResultsDialog.ResultType.TIME, false); 189 testFailed.put(BaseResultsDialog.ResultType.ROTATION, false); 190 String testDetails = "Test terminated as it its impossible to pass the remaining rotations"; 191 Log.e("Rotation test:", mDistanceOfPathToFail + ""); 192 Log.e("Rotation test:", testDetails); 193 mTestReport.setFailDetails(testDetails); 194 mManager.onRobustnessTestCompleted(testFailed); 195 } 196 return null; 197 } else { 198 return rotation; 199 } 200 201 } 202 203 /** 204 * Returns the time remaining for the user to place the marker 205 */ getTimeRemaining()206 public long getTimeRemaining() { 207 return ((RobustnessPath) mTestPath).calculateTimeRemaining(); 208 } 209 } 210