• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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;
18 
19 import android.annotation.ElapsedRealtimeLong;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.annotation.SystemApi;
23 import android.os.Bundle;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 
27 import java.util.Objects;
28 
29 /**
30  * This class represents the quality report that bluetooth framework sends
31  * whenever there's a bad voice quality is detected from their side.
32  * It is sent as part of a call event via {@link Call#sendCallEvent(String, Bundle)}
33  * associated with extra EXTRA_BLUETOOTH_CALL_QUALITY_REPORT.
34  * Note that this report will be sent only during an active voice/voip call.
35  * @hide
36  */
37 @SystemApi
38 public final class BluetoothCallQualityReport implements Parcelable {
39 
40     /**
41      * Event that is sent via {@link Call#sendCallEvent(String, Bundle)} for a call quality report
42      */
43     public static final String EVENT_BLUETOOTH_CALL_QUALITY_REPORT =
44             "android.telecom.event.BLUETOOTH_CALL_QUALITY_REPORT";
45 
46     /**
47      * Extra key sent with {@link Call#sendCallEvent(String, Bundle)}
48      */
49     public static final String EXTRA_BLUETOOTH_CALL_QUALITY_REPORT =
50             "android.telecom.extra.BLUETOOTH_CALL_QUALITY_REPORT";
51 
52     private final long mSentTimestampMillis;
53     private final boolean mChoppyVoice;
54     private final int mRssiDbm;
55     private final int mSnrDb;
56     private final int mRetransmittedPacketsCount;
57     private final int mPacketsNotReceivedCount;
58     private final int mNegativeAcknowledgementCount;
59 
60     /**
61      * @return Time in milliseconds since the epoch. Designates when report was sent.
62      * Used to determine whether this report arrived too late to be useful.
63      */
getSentTimestampMillis()64     public @ElapsedRealtimeLong long getSentTimestampMillis() {
65         return mSentTimestampMillis;
66     }
67 
68     /**
69      * When the bluetooth controller detects factors that cause choppy voice,
70      * the controller reports an (e)SCO Voice Choppy event to the host
71      * @return {@code true} when we receive (e)SCO Voice Choppy event from the controller
72      */
isChoppyVoice()73     public boolean isChoppyVoice() {
74         return mChoppyVoice;
75     }
76 
77     /**
78      * @return Received Signal Strength Indication (RSSI) value in dBm.
79      * This value shall be an absolute received signal strength value.
80      */
getRssiDbm()81     public @IntRange(from = -127, to = 20) int getRssiDbm() {
82         return mRssiDbm;
83     }
84 
85     /**
86      * @return Signal-to-Noise Ratio (SNR) value in dB.
87      * The controller shall provide the average SNR of all the channels currently used by the link.
88      */
getSnrDb()89     public int getSnrDb() {
90         return mSnrDb;
91     }
92 
93     /**
94      * @return The number of retransmissions since the last event.
95      * This count shall be reset after it is reported.
96      */
getRetransmittedPacketsCount()97     public @IntRange(from = 0) int getRetransmittedPacketsCount() {
98         return mRetransmittedPacketsCount;
99     }
100 
101     /**
102      * @return No RX count since the last event.
103      * The count increases when no packet is received at the scheduled time slot or the received
104      * packet is corrupted.
105      * This count shall be reset after it is reported.
106      */
getPacketsNotReceivedCount()107     public @IntRange(from = 0) int getPacketsNotReceivedCount() {
108         return mPacketsNotReceivedCount;
109     }
110 
111     /**
112      * @return NAK (Negative Acknowledge) count since the last event.
113      * This count shall be reset after it is reported.
114      */
getNegativeAcknowledgementCount()115     public @IntRange(from = 0) int getNegativeAcknowledgementCount() {
116         return mNegativeAcknowledgementCount;
117     }
118 
119     //
120     // Parcelable implementation
121     //
122 
123     @Override
describeContents()124     public int describeContents() {
125         return 0;
126     }
127 
128     @Override
writeToParcel(@onNull Parcel out, int flags)129     public void writeToParcel(@NonNull Parcel out, int flags) {
130         out.writeLong(mSentTimestampMillis);
131         out.writeBoolean(mChoppyVoice);
132         out.writeInt(mRssiDbm);
133         out.writeInt(mSnrDb);
134         out.writeInt(mRetransmittedPacketsCount);
135         out.writeInt(mPacketsNotReceivedCount);
136         out.writeInt(mNegativeAcknowledgementCount);
137     }
138 
139     public static final @android.annotation.NonNull Creator<BluetoothCallQualityReport> CREATOR =
140             new Creator<BluetoothCallQualityReport>() {
141                 @Override
142                 public BluetoothCallQualityReport createFromParcel(Parcel in) {
143                     return new BluetoothCallQualityReport(in);
144                 }
145 
146                 @Override
147                 public BluetoothCallQualityReport[] newArray(int size) {
148                     return new BluetoothCallQualityReport[size];
149                 }
150             };
151 
152     @Override
equals(Object o)153     public boolean equals(Object o) {
154         if (this == o) return true;
155         if (o == null || getClass() != o.getClass()) return false;
156         BluetoothCallQualityReport that = (BluetoothCallQualityReport) o;
157         return mSentTimestampMillis == that.mSentTimestampMillis
158                 && mChoppyVoice == that.mChoppyVoice && mRssiDbm == that.mRssiDbm
159                 && mSnrDb == that.mSnrDb
160                 && mRetransmittedPacketsCount == that.mRetransmittedPacketsCount
161                 && mPacketsNotReceivedCount == that.mPacketsNotReceivedCount
162                 && mNegativeAcknowledgementCount == that.mNegativeAcknowledgementCount;
163     }
164 
165     @Override
hashCode()166     public int hashCode() {
167         return Objects.hash(mSentTimestampMillis, mChoppyVoice, mRssiDbm, mSnrDb,
168                 mRetransmittedPacketsCount, mPacketsNotReceivedCount,
169                 mNegativeAcknowledgementCount);
170     }
171 
172     /**
173      * Builder class for {@link ConnectionRequest}
174      */
175     public static final class Builder {
176         private long mSentTimestampMillis;
177         private boolean mChoppyVoice;
178         private int mRssiDbm;
179         private int mSnrDb;
180         private int mRetransmittedPacketsCount;
181         private int mPacketsNotReceivedCount;
182         private int mNegativeAcknowledgementCount;
183 
Builder()184         public Builder() { }
185 
186         /**
187          * Set the time when report was sent in milliseconds since the epoch.
188          * @param sentTimestampMillis
189          */
setSentTimestampMillis(long sentTimestampMillis)190         public @NonNull Builder setSentTimestampMillis(long sentTimestampMillis) {
191             mSentTimestampMillis = sentTimestampMillis;
192             return this;
193         }
194 
195         /**
196          * Set if bluetooth hardware detects voice is choppy
197          * @param choppyVoice
198          */
setChoppyVoice(boolean choppyVoice)199         public @NonNull Builder setChoppyVoice(boolean choppyVoice) {
200             mChoppyVoice = choppyVoice;
201             return this;
202         }
203 
204         /**
205          * Set Received Signal Strength Indication (RSSI) value in dBm.
206          * @param rssiDbm
207          */
setRssiDbm(int rssiDbm)208         public @NonNull Builder setRssiDbm(int rssiDbm) {
209             mRssiDbm = rssiDbm;
210             return this;
211         }
212 
213         /**
214          * Set Signal-to-Noise Ratio (SNR) value in dB.
215          * @param snrDb
216          */
setSnrDb(int snrDb)217         public @NonNull Builder setSnrDb(int snrDb) {
218             mSnrDb = snrDb;
219             return this;
220         }
221 
222         /**
223          * Set The number of retransmissions since the last event.
224          * @param retransmittedPacketsCount
225          */
setRetransmittedPacketsCount( int retransmittedPacketsCount)226         public @NonNull Builder setRetransmittedPacketsCount(
227                 int retransmittedPacketsCount) {
228             mRetransmittedPacketsCount = retransmittedPacketsCount;
229             return this;
230         }
231 
232         /**
233          * Set No RX count since the last event.
234          * @param packetsNotReceivedCount
235          */
setPacketsNotReceivedCount( int packetsNotReceivedCount)236         public @NonNull Builder setPacketsNotReceivedCount(
237                 int packetsNotReceivedCount) {
238             mPacketsNotReceivedCount = packetsNotReceivedCount;
239             return this;
240         }
241 
242         /**
243          * Set NAK (Negative Acknowledge) count since the last event.
244          * @param negativeAcknowledgementCount
245          */
setNegativeAcknowledgementCount( int negativeAcknowledgementCount)246         public @NonNull Builder setNegativeAcknowledgementCount(
247                 int negativeAcknowledgementCount) {
248             mNegativeAcknowledgementCount = negativeAcknowledgementCount;
249             return this;
250         }
251 
252         /**
253          * Build the {@link BluetoothCallQualityReport}
254          * @return Result of the builder
255          */
build()256         public @NonNull BluetoothCallQualityReport build() {
257             return new BluetoothCallQualityReport(this);
258         }
259     }
260 
BluetoothCallQualityReport(Parcel in)261     private BluetoothCallQualityReport(Parcel in) {
262         mSentTimestampMillis = in.readLong();
263         mChoppyVoice = in.readBoolean();
264         mRssiDbm = in.readInt();
265         mSnrDb = in.readInt();
266         mRetransmittedPacketsCount = in.readInt();
267         mPacketsNotReceivedCount = in.readInt();
268         mNegativeAcknowledgementCount = in.readInt();
269     }
270 
BluetoothCallQualityReport(Builder builder)271     private BluetoothCallQualityReport(Builder builder) {
272         mSentTimestampMillis = builder.mSentTimestampMillis;
273         mChoppyVoice = builder.mChoppyVoice;
274         mRssiDbm = builder.mRssiDbm;
275         mSnrDb = builder.mSnrDb;
276         mRetransmittedPacketsCount = builder.mRetransmittedPacketsCount;
277         mPacketsNotReceivedCount = builder.mPacketsNotReceivedCount;
278         mNegativeAcknowledgementCount = builder.mNegativeAcknowledgementCount;
279     }
280 }
281