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