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.telephony.imsmedia; 18 19 import android.annotation.IntDef; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 23 import androidx.annotation.NonNull; 24 import androidx.annotation.Nullable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * The class represents RTP (Real Time Control) configuration for text stream. 32 * 33 * @hide 34 */ 35 public final class TextConfig extends RtpConfig { 36 37 public static final int TEXT_CODEC_NONE = 0; 38 // text codec - T140 - RFC 4103 39 public static final int TEXT_T140 = 1; 40 // text codec - T140 - RFC 4103 with redundancy 41 public static final int TEXT_T140_RED = 2; 42 43 /** @hide */ 44 @IntDef( 45 flag = true, 46 value = { 47 TEXT_CODEC_NONE, 48 TEXT_T140, 49 TEXT_T140_RED, 50 }) 51 @Retention(RetentionPolicy.SOURCE) 52 public @interface CodecType {} 53 54 private final @CodecType int mCodecType; 55 private final int mBitrate; 56 private final byte mRedundantPayload; 57 private final byte mRedundantLevel; 58 private final boolean mKeepRedundantLevel; 59 60 /** @hide */ TextConfig(Parcel in)61 TextConfig(Parcel in) { 62 super(RtpConfig.TYPE_TEXT, in); 63 mCodecType = in.readInt(); 64 mBitrate = in.readInt(); 65 mRedundantPayload = in.readByte(); 66 mRedundantLevel = in.readByte(); 67 mKeepRedundantLevel = in.readBoolean(); 68 } 69 70 /** @hide */ TextConfig(Builder builder)71 TextConfig(Builder builder) { 72 super(RtpConfig.TYPE_TEXT, builder); 73 mCodecType = builder.mCodecType; 74 mBitrate = builder.mBitrate; 75 mRedundantPayload = builder.mRedundantPayload; 76 mRedundantLevel = builder.mRedundantLevel; 77 mKeepRedundantLevel = builder.mKeepRedundantLevel; 78 } 79 80 /** @hide **/ getCodecType()81 public int getCodecType() { 82 return this.mCodecType; 83 } 84 85 /** @hide **/ getBitrate()86 public int getBitrate() { 87 return this.mBitrate; 88 } 89 90 /** @hide **/ getRedundantPayload()91 public byte getRedundantPayload() { 92 return this.mRedundantPayload; 93 } 94 95 /** @hide **/ getRedundantLevel()96 public byte getRedundantLevel() { 97 return this.mRedundantLevel; 98 } 99 100 /** @hide **/ getKeepRedundantLevel()101 public boolean getKeepRedundantLevel() { 102 return this.mKeepRedundantLevel; 103 } 104 105 @NonNull 106 @Override toString()107 public String toString() { 108 return super.toString() + " TextConfig: {mCodecType=" + mCodecType 109 + ", mBitrate=" + mBitrate 110 + ", mRedundantPayload =" + mRedundantPayload 111 + ", mRedundantLevel =" + mRedundantLevel 112 + ", mKeepRedundantLevel =" + mKeepRedundantLevel 113 + " }"; 114 } 115 116 @Override hashCode()117 public int hashCode() { 118 return Objects.hash(super.hashCode(), 119 mCodecType, 120 mBitrate, 121 mRedundantPayload, 122 mRedundantLevel, 123 mKeepRedundantLevel); 124 } 125 126 @Override equals(@ullable Object o)127 public boolean equals(@Nullable Object o) { 128 if (o == null || !(o instanceof TextConfig) || hashCode() != o.hashCode()) { 129 return false; 130 } 131 132 if (this == o) { 133 return true; 134 } 135 136 TextConfig s = (TextConfig) o; 137 138 if (!super.equals(s)) { 139 return false; 140 } 141 142 return (mCodecType == s.mCodecType 143 && mBitrate == s.mBitrate 144 && mRedundantPayload == s.mRedundantPayload 145 && mRedundantLevel == s.mRedundantLevel 146 && mKeepRedundantLevel == s.mKeepRedundantLevel); 147 } 148 149 /** 150 * {@link Parcelable#describeContents} 151 */ describeContents()152 public int describeContents() { 153 return 0; 154 } 155 156 /** 157 * {@link Parcelable#writeToParcel} 158 */ writeToParcel(Parcel dest, int flags)159 public void writeToParcel(Parcel dest, int flags) { 160 super.writeToParcel(dest, RtpConfig.TYPE_TEXT); 161 dest.writeInt(mCodecType); 162 dest.writeInt(mBitrate); 163 dest.writeByte(mRedundantPayload); 164 dest.writeByte(mRedundantLevel); 165 dest.writeBoolean(mKeepRedundantLevel); 166 } 167 168 public static final @NonNull Parcelable.Creator<TextConfig> 169 CREATOR = new Parcelable.Creator() { 170 public TextConfig createFromParcel(Parcel in) { 171 in.readInt(); //skip 172 return new TextConfig(in); 173 } 174 175 public TextConfig[] newArray(int size) { 176 return new TextConfig[size]; 177 } 178 }; 179 180 /** 181 * Provides a convenient way to set the fields of a {@link TextConfig} 182 * when creating a new instance. 183 */ 184 public static final class Builder extends RtpConfig.AbstractBuilder<Builder> { 185 private @CodecType int mCodecType; 186 private int mBitrate; 187 private byte mRedundantPayload; 188 private byte mRedundantLevel; 189 private boolean mKeepRedundantLevel; 190 191 /** 192 * Default constructor for Builder. 193 */ Builder()194 public Builder() { 195 } 196 197 @Override self()198 Builder self() { 199 return this; 200 } 201 202 /** 203 * Sets text Codec type. It can be T.140 and RED. 204 * @param mCodecType codec type, see {@link CodecType} 205 */ setCodecType(final @CodecType int mCodecType)206 public Builder setCodecType(final @CodecType int mCodecType) { 207 this.mCodecType = mCodecType; 208 return this; 209 } 210 211 /** 212 * Sets text bitrate of encoding streaming 213 * @param bitrate mBitrate per second 214 */ setBitrate(final int bitrate)215 public Builder setBitrate(final int bitrate) { 216 this.mBitrate = bitrate; 217 return this; 218 } 219 220 /** 221 * Set negotiated text redundancy payload number for RED payload 222 * @param payload text redundancy payload number 223 */ setRedundantPayload(final byte payload)224 public Builder setRedundantPayload(final byte payload) { 225 this.mRedundantPayload = payload; 226 return this; 227 } 228 229 /** 230 * Set text redundancy level of the T.140 payload 231 * @param level text redundancy level 232 */ setRedundantLevel(final byte level)233 public Builder setRedundantLevel(final byte level) { 234 this.mRedundantLevel = level; 235 return this; 236 } 237 238 /** 239 * The option for sending empty redundant payload when the codec type is sending T.140 and 240 * RED payload 241 * @param enable {@code true} enables sending empty redundant payload 242 * {@code false} otherwise. 243 */ setKeepRedundantLevel(final boolean enable)244 public Builder setKeepRedundantLevel(final boolean enable) { 245 this.mKeepRedundantLevel = enable; 246 return this; 247 } 248 249 /** 250 * Build the TextConfig. 251 * 252 * @return the TextConfig object. 253 */ build()254 public @NonNull TextConfig build() { 255 // TODO validation 256 return new TextConfig(this); 257 } 258 } 259 } 260 261