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 AMR (Adaptive Multi-Rate) codec parameters.
32  *
33  * @hide
34  */
35 public final class AmrParams implements Parcelable {
36     /** 4.75 kbps for AMR / 6.6 kbps for AMR-WB */
37     public static final int AMR_MODE_0 = 1 << 0;
38     /** 5.15 kbps for AMR / 8.855 kbps for AMR-WB */
39     public static final int AMR_MODE_1 = 1 << 1;
40     /** 5.9 kbps for AMR / 12.65 kbps for AMR-WB */
41     public static final int AMR_MODE_2 = 1 << 2;
42     /** 6.7 kbps for AMR / 14.25 kbps for AMR-WB */
43     public static final int AMR_MODE_3 = 1 << 3;
44     /** 7.4 kbps for AMR / 15.85 kbps for AMR-WB */
45     public static final int AMR_MODE_4 = 1 << 4;
46     /** 7.95 kbps for AMR / 18.25 kbps for AMR-WB */
47     public static final int AMR_MODE_5 = 1 << 5;
48     /** 10.2 kbps for AMR / 19.85 kbps for AMR-WB */
49     public static final int AMR_MODE_6 = 1 << 6;
50     /** 12.2 kbps for AMR / 23.05 kbps for AMR-WB */
51     public static final int AMR_MODE_7 = 1 << 7;
52     /** Silence frame for AMR / 23.85 kbps for AMR-WB */
53     public static final int AMR_MODE_8 = 1 << 8;
54 
55     /** @hide */
56     @IntDef(
57         value = {
58            AMR_MODE_0,
59            AMR_MODE_1,
60            AMR_MODE_2,
61            AMR_MODE_3,
62            AMR_MODE_4,
63            AMR_MODE_5,
64            AMR_MODE_6,
65            AMR_MODE_7,
66            AMR_MODE_8,
67     })
68     @Retention(RetentionPolicy.SOURCE)
69     public @interface AmrMode {}
70 
71     /** mode-set: AMR codec mode to represent the bit rate */
72     private final @AmrMode int amrMode;
73     /**
74      * octet-align: If it's set to true then all fields in the AMR/AMR-WB header
75      * shall be aligned to octet boundaries by adding padding bits.
76      */
77     private final boolean octetAligned;
78     /**
79      * max-red: It’s the maximum duration in milliseconds that elapses between the
80      * primary (first) transmission of a frame and any redundant transmission that
81      * the sender will use. This parameter allows a receiver to have a bounded delay
82      * when redundancy is used. Allowed values are between 0 (no redundancy will be
83      * used) and 65535. If the parameter is omitted, no limitation on the use of
84      * redundancy is present. See RFC 4867
85      */
86     private final int maxRedundancyMillis;
87 
88     /** @hide **/
AmrParams(Parcel in)89     public AmrParams(Parcel in) {
90         amrMode = in.readInt();
91         octetAligned = in.readBoolean();
92         maxRedundancyMillis = in.readInt();
93     }
94 
AmrParams(@mrMode int amrMode, boolean octetAligned, int maxRedundancyMillis)95     private AmrParams(@AmrMode int amrMode, boolean octetAligned, int maxRedundancyMillis) {
96         this.amrMode = amrMode;
97         this.octetAligned = octetAligned;
98         this.maxRedundancyMillis = maxRedundancyMillis;
99     }
100 
101     /** @hide **/
getAmrMode()102     public @AmrMode int getAmrMode() {
103         return amrMode;
104     }
105 
106     /** @hide **/
getOctetAligned()107     public boolean getOctetAligned() {
108         return octetAligned;
109     }
110 
111     /** @hide **/
getMaxRedundancyMillis()112     public int getMaxRedundancyMillis() {
113         return maxRedundancyMillis;
114     }
115 
116     @NonNull
117     @Override
toString()118     public String toString() {
119         return "AmrParams: {amrMode=" + amrMode
120                 + ", octetAligned=" + octetAligned
121                 + ", maxRedundancyMillis=" + maxRedundancyMillis
122                 + " }";
123     }
124 
125     @Override
hashCode()126     public int hashCode() {
127         return Objects.hash(amrMode, octetAligned, maxRedundancyMillis);
128     }
129 
130     @Override
equals(@ullable Object o)131     public boolean equals(@Nullable Object o) {
132         if (o == null || !(o instanceof AmrParams) || hashCode() != o.hashCode()) {
133             return false;
134         }
135 
136         if (this == o) {
137             return true;
138         }
139 
140         AmrParams s = (AmrParams) o;
141 
142         return (amrMode == s.amrMode
143                 && octetAligned == s.octetAligned
144                 && maxRedundancyMillis == s.maxRedundancyMillis);
145     }
146 
147     /**
148      * {@link Parcelable#describeContents}
149      */
describeContents()150     public int describeContents() {
151         return 0;
152     }
153 
154     /**
155      * {@link Parcelable#writeToParcel}
156      */
writeToParcel(Parcel dest, int flags)157     public void writeToParcel(Parcel dest, int flags) {
158         dest.writeInt(amrMode);
159         dest.writeBoolean(octetAligned);
160         dest.writeInt(maxRedundancyMillis);
161     }
162 
163     public static final @NonNull Parcelable.Creator<AmrParams>
164         CREATOR = new Parcelable.Creator() {
165         public AmrParams createFromParcel(Parcel in) {
166             // TODO use builder class so it will validate
167             return new AmrParams(in);
168         }
169 
170         public AmrParams[] newArray(int size) {
171             return new AmrParams[size];
172         }
173     };
174 
175     /**
176      * Provides a convenient way to set the fields of a {@link AmrParams}
177      * when creating a new instance.
178      */
179     public static final class Builder {
180         private @AmrMode int amrMode;
181         private boolean octetAligned;
182         private int maxRedundancyMillis;
183 
184         /**
185          * Default constructor for Builder.
186          */
Builder()187         public Builder() {
188         }
189 
190         /**
191          * Set the AMR codec mode to represent the bit rate
192          *
193          * @param amrMode AMR codec mode
194          * @return The same instance of the builder.
195          */
setAmrMode(final @AmrMode int amrMode)196         public @NonNull Builder setAmrMode(final @AmrMode int amrMode) {
197             this.amrMode = amrMode;
198             return this;
199         }
200 
201         /**
202          * Set whether octet aligned or not for AMR/AMR-WB headers
203          *
204          * @param octetAligned {@code true} means octets shall be aligned for AMR/AMR-WB header
205          * @return The same instance of the builder.
206          */
setOctetAligned(final boolean octetAligned)207         public @NonNull Builder setOctetAligned(final boolean octetAligned) {
208             this.octetAligned = octetAligned;
209             return this;
210         }
211 
212         /**
213          * Set the maximum redundany in milliseconds.
214          *
215          * max-red: It’s the maximum duration in milliseconds that elapses between the
216          * primary (first) transmission of a frame and any redundant transmission that
217          * the sender will use. This parameter allows a receiver to have a bounded delay
218          * when redundancy is used. Allowed values are between 0 (no redundancy will be
219          * used) and 65535. If the parameter is omitted, no limitation on the use of
220          * redundancy is present. See RFC 4867.
221          *
222          * @param maxRedundancyMillis the maximum duration in milliseconds.
223          * @return The same instance of the builder.
224          */
setMaxRedundancyMillis(final int maxRedundancyMillis)225         public @NonNull Builder setMaxRedundancyMillis(final int maxRedundancyMillis) {
226             this.maxRedundancyMillis = maxRedundancyMillis;
227             return this;
228         }
229 
230         /**
231          * Build the AmrParams.
232          *
233          * @return the AmrParams object.
234          */
build()235         public @NonNull AmrParams build() {
236             // TODO validation
237             return new AmrParams(amrMode, octetAligned, maxRedundancyMillis);
238         }
239     }
240 }
241 
242