1 /* 2 * Copyright (C) 2018 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.telephony; 18 19 import android.annotation.IntDef; 20 import android.annotation.SystemApi; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 24 import java.lang.annotation.Retention; 25 import java.lang.annotation.RetentionPolicy; 26 import java.util.Objects; 27 28 /** 29 * Parcelable object to handle call quality. 30 * <p> 31 * Currently this supports IMS calls. 32 * <p> 33 * It provides the call quality level, duration, and additional information related to RTP packets, 34 * jitter and delay. 35 * <p> 36 * If there are multiple active calls, the CallQuality will pertain to the call in the foreground. 37 * 38 * @hide 39 */ 40 @SystemApi 41 public final class CallQuality implements Parcelable { 42 43 // Constants representing the call quality level (see #CallQuality); 44 public static final int CALL_QUALITY_EXCELLENT = 0; 45 public static final int CALL_QUALITY_GOOD = 1; 46 public static final int CALL_QUALITY_FAIR = 2; 47 public static final int CALL_QUALITY_POOR = 3; 48 public static final int CALL_QUALITY_BAD = 4; 49 public static final int CALL_QUALITY_NOT_AVAILABLE = 5; 50 51 /** 52 * Call quality 53 * @hide 54 */ 55 @IntDef(prefix = { "CALL_QUALITY_" }, value = { 56 CALL_QUALITY_EXCELLENT, 57 CALL_QUALITY_GOOD, 58 CALL_QUALITY_FAIR, 59 CALL_QUALITY_POOR, 60 CALL_QUALITY_BAD, 61 CALL_QUALITY_NOT_AVAILABLE, 62 }) 63 @Retention(RetentionPolicy.SOURCE) 64 public @interface CallQualityLevel {} 65 66 @CallQualityLevel 67 private int mDownlinkCallQualityLevel; 68 @CallQualityLevel 69 private int mUplinkCallQualityLevel; 70 private int mCallDuration; 71 private int mNumRtpPacketsTransmitted; 72 private int mNumRtpPacketsReceived; 73 private int mNumRtpPacketsTransmittedLost; 74 private int mNumRtpPacketsNotReceived; 75 private int mAverageRelativeJitter; 76 private int mMaxRelativeJitter; 77 private int mAverageRoundTripTime; 78 private int mCodecType; 79 80 /** @hide **/ CallQuality(Parcel in)81 public CallQuality(Parcel in) { 82 mDownlinkCallQualityLevel = in.readInt(); 83 mUplinkCallQualityLevel = in.readInt(); 84 mCallDuration = in.readInt(); 85 mNumRtpPacketsTransmitted = in.readInt(); 86 mNumRtpPacketsReceived = in.readInt(); 87 mNumRtpPacketsTransmittedLost = in.readInt(); 88 mNumRtpPacketsNotReceived = in.readInt(); 89 mAverageRelativeJitter = in.readInt(); 90 mMaxRelativeJitter = in.readInt(); 91 mAverageRoundTripTime = in.readInt(); 92 mCodecType = in.readInt(); 93 } 94 95 /** @hide **/ CallQuality()96 public CallQuality() { 97 } 98 99 /** 100 * Constructor. 101 * 102 * @param callQualityLevel the call quality level (see #CallQualityLevel) 103 * @param callDuration the call duration in milliseconds 104 * @param numRtpPacketsTransmitted RTP packets sent to network 105 * @param numRtpPacketsReceived RTP packets received from network 106 * @param numRtpPacketsTransmittedLost RTP packets which were lost in network and never 107 * transmitted 108 * @param numRtpPacketsNotReceived RTP packets which were lost in network and never recieved 109 * @param averageRelativeJitter average relative jitter in milliseconds 110 * @param maxRelativeJitter maximum relative jitter in milliseconds 111 * @param averageRoundTripTime average round trip delay in milliseconds 112 * @param codecType the codec type 113 */ CallQuality( @allQualityLevel int downlinkCallQualityLevel, @CallQualityLevel int uplinkCallQualityLevel, int callDuration, int numRtpPacketsTransmitted, int numRtpPacketsReceived, int numRtpPacketsTransmittedLost, int numRtpPacketsNotReceived, int averageRelativeJitter, int maxRelativeJitter, int averageRoundTripTime, int codecType)114 public CallQuality( 115 @CallQualityLevel int downlinkCallQualityLevel, 116 @CallQualityLevel int uplinkCallQualityLevel, 117 int callDuration, 118 int numRtpPacketsTransmitted, 119 int numRtpPacketsReceived, 120 int numRtpPacketsTransmittedLost, 121 int numRtpPacketsNotReceived, 122 int averageRelativeJitter, 123 int maxRelativeJitter, 124 int averageRoundTripTime, 125 int codecType) { 126 this.mDownlinkCallQualityLevel = downlinkCallQualityLevel; 127 this.mUplinkCallQualityLevel = uplinkCallQualityLevel; 128 this.mCallDuration = callDuration; 129 this.mNumRtpPacketsTransmitted = numRtpPacketsTransmitted; 130 this.mNumRtpPacketsReceived = numRtpPacketsReceived; 131 this.mNumRtpPacketsTransmittedLost = numRtpPacketsTransmittedLost; 132 this.mNumRtpPacketsNotReceived = numRtpPacketsNotReceived; 133 this.mAverageRelativeJitter = averageRelativeJitter; 134 this.mMaxRelativeJitter = maxRelativeJitter; 135 this.mAverageRoundTripTime = averageRoundTripTime; 136 this.mCodecType = codecType; 137 } 138 139 // getters 140 /** 141 * Returns the downlink CallQualityLevel for a given ongoing call. 142 */ 143 @CallQualityLevel getDownlinkCallQualityLevel()144 public int getDownlinkCallQualityLevel() { 145 return mDownlinkCallQualityLevel; 146 } 147 148 /** 149 * Returns the uplink CallQualityLevel for a given ongoing call. 150 */ 151 @CallQualityLevel getUplinkCallQualityLevel()152 public int getUplinkCallQualityLevel() { 153 return mUplinkCallQualityLevel; 154 } 155 156 /** 157 * Returns the duration of the call, in milliseconds. 158 */ getCallDuration()159 public int getCallDuration() { 160 return mCallDuration; 161 } 162 163 /** 164 * Returns the total number of RTP packets transmitted by this device for a given ongoing call. 165 */ getNumRtpPacketsTransmitted()166 public int getNumRtpPacketsTransmitted() { 167 return mNumRtpPacketsTransmitted; 168 } 169 170 /** 171 * Returns the total number of RTP packets received by this device for a given ongoing call. 172 */ getNumRtpPacketsReceived()173 public int getNumRtpPacketsReceived() { 174 return mNumRtpPacketsReceived; 175 } 176 177 /** 178 * Returns the number of RTP packets which were sent by this device but were lost in the 179 * network before reaching the other party. 180 */ getNumRtpPacketsTransmittedLost()181 public int getNumRtpPacketsTransmittedLost() { 182 return mNumRtpPacketsTransmittedLost; 183 } 184 185 /** 186 * Returns the number of RTP packets which were sent by the other party but were lost in the 187 * network before reaching this device. 188 */ getNumRtpPacketsNotReceived()189 public int getNumRtpPacketsNotReceived() { 190 return mNumRtpPacketsNotReceived; 191 } 192 193 /** 194 * Returns the average relative jitter in milliseconds. Jitter represents the amount of variance 195 * in interarrival time of packets, for example, if two packets are sent 2 milliseconds apart 196 * but received 3 milliseconds apart, the relative jitter between those packets is 1 197 * millisecond. 198 * 199 * <p>See RFC 3550 for more information on jitter calculations. 200 */ getAverageRelativeJitter()201 public int getAverageRelativeJitter() { 202 return mAverageRelativeJitter; 203 } 204 205 /** 206 * Returns the maximum relative jitter for a given ongoing call. Jitter represents the amount of 207 * variance in interarrival time of packets, for example, if two packets are sent 2 milliseconds 208 * apart but received 3 milliseconds apart, the relative jitter between those packets is 1 209 * millisecond. 210 * 211 * <p>See RFC 3550 for more information on jitter calculations. 212 */ getMaxRelativeJitter()213 public int getMaxRelativeJitter() { 214 return mMaxRelativeJitter; 215 } 216 217 /** 218 * Returns the average round trip time in milliseconds. 219 */ getAverageRoundTripTime()220 public int getAverageRoundTripTime() { 221 return mAverageRoundTripTime; 222 } 223 224 /** 225 * Returns the codec type. This value corresponds to the AUDIO_QUALITY_* constants in 226 * {@link ImsStreamMediaProfile}. 227 * 228 * @see ImsStreamMediaProfile#AUDIO_QUALITY_NONE 229 * @see ImsStreamMediaProfile#AUDIO_QUALITY_AMR 230 * @see ImsStreamMediaProfile#AUDIO_QUALITY_AMR_WB 231 * @see ImsStreamMediaProfile#AUDIO_QUALITY_QCELP13K 232 * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVRC 233 * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVRC_B 234 * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVRC_WB 235 * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVRC_NW 236 * @see ImsStreamMediaProfile#AUDIO_QUALITY_GSM_EFR 237 * @see ImsStreamMediaProfile#AUDIO_QUALITY_GSM_FR 238 * @see ImsStreamMediaProfile#AUDIO_QUALITY_GSM_HR 239 * @see ImsStreamMediaProfile#AUDIO_QUALITY_G711U 240 * @see ImsStreamMediaProfile#AUDIO_QUALITY_G723 241 * @see ImsStreamMediaProfile#AUDIO_QUALITY_G711A 242 * @see ImsStreamMediaProfile#AUDIO_QUALITY_G722 243 * @see ImsStreamMediaProfile#AUDIO_QUALITY_G711AB 244 * @see ImsStreamMediaProfile#AUDIO_QUALITY_G729 245 * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVS_NB 246 * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVS_WB 247 * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVS_SWB 248 * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVS_FB 249 */ getCodecType()250 public int getCodecType() { 251 return mCodecType; 252 } 253 254 // Parcelable things 255 @Override toString()256 public String toString() { 257 return "CallQuality: {downlinkCallQualityLevel=" + mDownlinkCallQualityLevel 258 + " uplinkCallQualityLevel=" + mUplinkCallQualityLevel 259 + " callDuration=" + mCallDuration 260 + " numRtpPacketsTransmitted=" + mNumRtpPacketsTransmitted 261 + " numRtpPacketsReceived=" + mNumRtpPacketsReceived 262 + " numRtpPacketsTransmittedLost=" + mNumRtpPacketsTransmittedLost 263 + " numRtpPacketsNotReceived=" + mNumRtpPacketsNotReceived 264 + " averageRelativeJitter=" + mAverageRelativeJitter 265 + " maxRelativeJitter=" + mMaxRelativeJitter 266 + " averageRoundTripTime=" + mAverageRoundTripTime 267 + " codecType=" + mCodecType 268 + "}"; 269 } 270 271 @Override hashCode()272 public int hashCode() { 273 return Objects.hash( 274 mDownlinkCallQualityLevel, 275 mUplinkCallQualityLevel, 276 mCallDuration, 277 mNumRtpPacketsTransmitted, 278 mNumRtpPacketsReceived, 279 mNumRtpPacketsTransmittedLost, 280 mNumRtpPacketsNotReceived, 281 mAverageRelativeJitter, 282 mMaxRelativeJitter, 283 mAverageRoundTripTime, 284 mCodecType); 285 } 286 287 @Override equals(Object o)288 public boolean equals(Object o) { 289 if (o == null || !(o instanceof CallQuality) || hashCode() != o.hashCode()) { 290 return false; 291 } 292 293 if (this == o) { 294 return true; 295 } 296 297 CallQuality s = (CallQuality) o; 298 299 return (mDownlinkCallQualityLevel == s.mDownlinkCallQualityLevel 300 && mUplinkCallQualityLevel == s.mUplinkCallQualityLevel 301 && mCallDuration == s.mCallDuration 302 && mNumRtpPacketsTransmitted == s.mNumRtpPacketsTransmitted 303 && mNumRtpPacketsReceived == s.mNumRtpPacketsReceived 304 && mNumRtpPacketsTransmittedLost == s.mNumRtpPacketsTransmittedLost 305 && mNumRtpPacketsNotReceived == s.mNumRtpPacketsNotReceived 306 && mAverageRelativeJitter == s.mAverageRelativeJitter 307 && mMaxRelativeJitter == s.mMaxRelativeJitter 308 && mAverageRoundTripTime == s.mAverageRoundTripTime 309 && mCodecType == s.mCodecType); 310 } 311 312 /** 313 * {@link Parcelable#describeContents} 314 */ describeContents()315 public @Parcelable.ContentsFlags int describeContents() { 316 return 0; 317 } 318 319 /** 320 * {@link Parcelable#writeToParcel} 321 */ writeToParcel(Parcel dest, @Parcelable.WriteFlags int flags)322 public void writeToParcel(Parcel dest, @Parcelable.WriteFlags int flags) { 323 dest.writeInt(mDownlinkCallQualityLevel); 324 dest.writeInt(mUplinkCallQualityLevel); 325 dest.writeInt(mCallDuration); 326 dest.writeInt(mNumRtpPacketsTransmitted); 327 dest.writeInt(mNumRtpPacketsReceived); 328 dest.writeInt(mNumRtpPacketsTransmittedLost); 329 dest.writeInt(mNumRtpPacketsNotReceived); 330 dest.writeInt(mAverageRelativeJitter); 331 dest.writeInt(mMaxRelativeJitter); 332 dest.writeInt(mAverageRoundTripTime); 333 dest.writeInt(mCodecType); 334 } 335 336 public static final @android.annotation.NonNull Parcelable.Creator<CallQuality> CREATOR = new Parcelable.Creator() { 337 public CallQuality createFromParcel(Parcel in) { 338 return new CallQuality(in); 339 } 340 341 public CallQuality[] newArray(int size) { 342 return new CallQuality[size]; 343 } 344 }; 345 } 346