1 /* 2 * Copyright (C) 2023 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.telecom.cts.apps; 18 19 import static android.telecom.Call.STATE_ACTIVE; 20 import static android.telecom.Call.STATE_AUDIO_PROCESSING; 21 import static android.telecom.Call.STATE_CONNECTING; 22 import static android.telecom.Call.STATE_DIALING; 23 import static android.telecom.Call.STATE_DISCONNECTED; 24 import static android.telecom.Call.STATE_DISCONNECTING; 25 import static android.telecom.Call.STATE_HOLDING; 26 import static android.telecom.Call.STATE_NEW; 27 import static android.telecom.Call.STATE_RINGING; 28 import static android.telecom.Call.STATE_SELECT_PHONE_ACCOUNT; 29 import static android.telecom.Call.STATE_SIMULATED_RINGING; 30 31 import static org.junit.Assert.fail; 32 33 import android.telecom.Call; 34 import android.util.Log; 35 36 import java.util.List; 37 import java.util.Objects; 38 39 public class WaitForInCallService { 40 private static final String DID_NOT_BIND_IN_TIME_ERR_MSG = 41 "InCallServiceVerifier did NOT bind in time"; 42 private static final String CALL_COUNT_WAS_NOT_INCREMENTED_ERR_MSG = 43 "Call Count was not incremented in time"; 44 45 private static final String NEW_ID_NOT_FOUND_MSG = 46 "New call was not found in time"; 47 verifyCallState(InCallServiceMethods verifierMethods, String id, int targetCallState)48 public static void verifyCallState(InCallServiceMethods verifierMethods, 49 String id, int targetCallState) { 50 List<Call> mCalls = verifierMethods.getOngoingCalls(); 51 Call targetCall = getCallWithId(mCalls, id); 52 boolean containsCall = targetCall != null; 53 54 if ((targetCallState == STATE_DISCONNECTED 55 || targetCallState == STATE_DISCONNECTING) && !containsCall) { 56 return; 57 } 58 if (!containsCall) { 59 fail("call " + id + " is not in map - it may have been dropped"); 60 } 61 assertCallState(targetCall, targetCallState); 62 } 63 verifyCallExtras( InCallServiceMethods verifierMethods, String id, String extraToVerify, boolean expected)64 public static void verifyCallExtras( 65 InCallServiceMethods verifierMethods, 66 String id, 67 String extraToVerify, 68 boolean expected) { 69 List<Call> mCalls = verifierMethods.getOngoingCalls(); 70 Call targetCall = getCallWithId(mCalls, id); 71 boolean containsCall = targetCall != null; 72 73 if (!containsCall) { 74 fail("call " + id + " is not in map - it may have been dropped"); 75 } 76 if (expected) { 77 assertCallExtra(targetCall, extraToVerify); 78 } else if (targetCall.getDetails() != null 79 && targetCall.getDetails().getExtras() != null 80 && targetCall.getDetails().getExtras().getBoolean(extraToVerify, false)) { 81 fail("call " + id + " should not have contained the " + extraToVerify + "extra"); 82 } 83 } 84 waitForInCallServiceBinding(InCallServiceMethods verifierMethods)85 public static void waitForInCallServiceBinding(InCallServiceMethods verifierMethods) { 86 WaitUntil.waitUntilConditionIsTrueOrTimeout( 87 new Condition() { 88 @Override 89 public Object expected() { 90 return true; 91 } 92 93 @Override 94 public Object actual() { 95 return verifierMethods.isBound(); 96 } 97 }, 98 WaitUntil.DEFAULT_TIMEOUT_MS, 99 DID_NOT_BIND_IN_TIME_ERR_MSG 100 ); 101 } 102 waitUntilExpectCallCount(InCallServiceMethods verifierMethods, int expectedCallCount)103 public static void waitUntilExpectCallCount(InCallServiceMethods verifierMethods, 104 int expectedCallCount) { 105 WaitUntil.waitUntilConditionIsTrueOrTimeout( 106 new Condition() { 107 @Override 108 public Object expected() { 109 return expectedCallCount; 110 } 111 112 @Override 113 public Object actual() { 114 return verifierMethods.getCurrentCallCount(); 115 } 116 }, 117 WaitUntil.DEFAULT_TIMEOUT_MS, 118 CALL_COUNT_WAS_NOT_INCREMENTED_ERR_MSG 119 ); 120 } 121 waitUntilNewCallId(InCallServiceMethods verifierMethods, String idToExclude)122 public static void waitUntilNewCallId(InCallServiceMethods verifierMethods, 123 String idToExclude) { 124 WaitUntil.waitUntilConditionIsTrueOrTimeout( 125 new Condition() { 126 @Override 127 public Object expected() { 128 return true; 129 } 130 131 @Override 132 public Object actual() { 133 return !Objects.equals( 134 verifierMethods.getLastAddedCall().getDetails().getId(), 135 idToExclude); 136 } 137 }, 138 WaitUntil.DEFAULT_TIMEOUT_MS, 139 NEW_ID_NOT_FOUND_MSG 140 ); 141 } 142 143 /*********************************************************** 144 / private methods 145 /***********************************************************/ getCallWithId(List<Call> calls, String id)146 private static Call getCallWithId(List<Call> calls, String id) { 147 for (Call call : calls) { 148 if (call.getDetails().getId().equals(id)) { 149 return call; 150 } 151 } 152 return null; 153 } 154 assertCallState(final Call call, final int targetState)155 private static void assertCallState(final Call call, final int targetState) { 156 WaitUntil.waitUntilConditionIsTrueOrTimeout( 157 new Condition() { 158 @Override 159 public Object expected() { 160 return targetState; 161 } 162 163 @Override 164 public Object actual() { 165 Log.i("tomsDebug", String.format("checking call=[%s]", call)); 166 return call.getState(); 167 } 168 }, WaitUntil.DEFAULT_TIMEOUT_MS, 169 "Expected CallState=[" + stateToString(targetState) + "];" 170 + " actual CallState[" + stateToString(call.getState()) + "]" 171 ); 172 } 173 assertCallExtra(final Call call, String extraToVerify)174 private static void assertCallExtra(final Call call, String extraToVerify) { 175 WaitUntil.waitUntilConditionIsTrueOrTimeout( 176 new Condition() { 177 @Override 178 public Object expected() { 179 return true; 180 } 181 182 @Override 183 public Object actual() { 184 boolean extrasPresent = 185 call.getDetails() != null && call.getDetails().getExtras() != null; 186 return extrasPresent 187 && call.getDetails().getExtras().getBoolean(extraToVerify, false); 188 } 189 }, 190 WaitUntil.DEFAULT_TIMEOUT_MS, 191 "Expected call to contain extra(" 192 + extraToVerify 193 + ")=[true];" 194 + " actual extra(" 195 + extraToVerify 196 + ")=[false]"); 197 } 198 stateToString(int state)199 private static String stateToString(int state) { 200 switch (state) { 201 case STATE_NEW: 202 return "NEW"; 203 case STATE_RINGING: 204 return "RINGING"; 205 case STATE_DIALING: 206 return "DIALING"; 207 case STATE_ACTIVE: 208 return "ACTIVE"; 209 case STATE_HOLDING: 210 return "HOLDING"; 211 case STATE_DISCONNECTED: 212 return "DISCONNECTED"; 213 case STATE_CONNECTING: 214 return "CONNECTING"; 215 case STATE_DISCONNECTING: 216 return "DISCONNECTING"; 217 case STATE_SELECT_PHONE_ACCOUNT: 218 return "SELECT_PHONE_ACCOUNT"; 219 case STATE_SIMULATED_RINGING: 220 return "SIMULATED_RINGING"; 221 case STATE_AUDIO_PROCESSING: 222 return "AUDIO_PROCESSING"; 223 default: 224 Log.i("tomsLog", String.format("Unknown state %d", state)); 225 return "UNKNOWN"; 226 } 227 } 228 } 229