| /* | 
 |  * Copyright (C) 2020 The Android Open Source Project | 
 |  * | 
 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 |  * you may not use this file except in compliance with the License. | 
 |  * You may obtain a copy of the License at | 
 |  * | 
 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 |  * | 
 |  * Unless required by applicable law or agreed to in writing, software | 
 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 |  * See the License for the specific language governing permissions and | 
 |  * limitations under the License. | 
 |  */ | 
 |  | 
 | package android.telecom; | 
 |  | 
 | import android.annotation.ElapsedRealtimeLong; | 
 | import android.annotation.IntRange; | 
 | import android.annotation.NonNull; | 
 | import android.annotation.SystemApi; | 
 | import android.os.Bundle; | 
 | import android.os.Parcel; | 
 | import android.os.Parcelable; | 
 |  | 
 | import java.util.Objects; | 
 |  | 
 | /** | 
 |  * This class represents the quality report that bluetooth framework sends | 
 |  * whenever there's a bad voice quality is detected from their side. | 
 |  * It is sent as part of a call event via {@link Call#sendCallEvent(String, Bundle)} | 
 |  * associated with extra EXTRA_BLUETOOTH_CALL_QUALITY_REPORT. | 
 |  * Note that this report will be sent only during an active voice/voip call. | 
 |  * @hide | 
 |  */ | 
 | @SystemApi | 
 | public final class BluetoothCallQualityReport implements Parcelable { | 
 |  | 
 |     /** | 
 |      * Event that is sent via {@link Call#sendCallEvent(String, Bundle)} for a call quality report | 
 |      */ | 
 |     public static final String EVENT_BLUETOOTH_CALL_QUALITY_REPORT = | 
 |             "android.telecom.event.BLUETOOTH_CALL_QUALITY_REPORT"; | 
 |  | 
 |     /** | 
 |      * Extra key sent with {@link Call#sendCallEvent(String, Bundle)} | 
 |      */ | 
 |     public static final String EXTRA_BLUETOOTH_CALL_QUALITY_REPORT = | 
 |             "android.telecom.extra.BLUETOOTH_CALL_QUALITY_REPORT"; | 
 |  | 
 |     private final long mSentTimestampMillis; | 
 |     private final boolean mChoppyVoice; | 
 |     private final int mRssiDbm; | 
 |     private final int mSnrDb; | 
 |     private final int mRetransmittedPacketsCount; | 
 |     private final int mPacketsNotReceivedCount; | 
 |     private final int mNegativeAcknowledgementCount; | 
 |  | 
 |     /** | 
 |      * @return Time in milliseconds since the epoch. Designates when report was sent. | 
 |      * Used to determine whether this report arrived too late to be useful. | 
 |      */ | 
 |     public @ElapsedRealtimeLong long getSentTimestampMillis() { | 
 |         return mSentTimestampMillis; | 
 |     } | 
 |  | 
 |     /** | 
 |      * When the bluetooth controller detects factors that cause choppy voice, | 
 |      * the controller reports an (e)SCO Voice Choppy event to the host | 
 |      * @return {@code true} when we receive (e)SCO Voice Choppy event from the controller | 
 |      */ | 
 |     public boolean isChoppyVoice() { | 
 |         return mChoppyVoice; | 
 |     } | 
 |  | 
 |     /** | 
 |      * @return Received Signal Strength Indication (RSSI) value in dBm. | 
 |      * This value shall be an absolute received signal strength value. | 
 |      */ | 
 |     public @IntRange(from = -127, to = 20) int getRssiDbm() { | 
 |         return mRssiDbm; | 
 |     } | 
 |  | 
 |     /** | 
 |      * @return Signal-to-Noise Ratio (SNR) value in dB. | 
 |      * The controller shall provide the average SNR of all the channels currently used by the link. | 
 |      */ | 
 |     public int getSnrDb() { | 
 |         return mSnrDb; | 
 |     } | 
 |  | 
 |     /** | 
 |      * @return The number of retransmissions since the last event. | 
 |      * This count shall be reset after it is reported. | 
 |      */ | 
 |     public @IntRange(from = 0) int getRetransmittedPacketsCount() { | 
 |         return mRetransmittedPacketsCount; | 
 |     } | 
 |  | 
 |     /** | 
 |      * @return No RX count since the last event. | 
 |      * The count increases when no packet is received at the scheduled time slot or the received | 
 |      * packet is corrupted. | 
 |      * This count shall be reset after it is reported. | 
 |      */ | 
 |     public @IntRange(from = 0) int getPacketsNotReceivedCount() { | 
 |         return mPacketsNotReceivedCount; | 
 |     } | 
 |  | 
 |     /** | 
 |      * @return NAK (Negative Acknowledge) count since the last event. | 
 |      * This count shall be reset after it is reported. | 
 |      */ | 
 |     public @IntRange(from = 0) int getNegativeAcknowledgementCount() { | 
 |         return mNegativeAcknowledgementCount; | 
 |     } | 
 |  | 
 |     // | 
 |     // Parcelable implementation | 
 |     // | 
 |  | 
 |     @Override | 
 |     public int describeContents() { | 
 |         return 0; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public void writeToParcel(@NonNull Parcel out, int flags) { | 
 |         out.writeLong(mSentTimestampMillis); | 
 |         out.writeBoolean(mChoppyVoice); | 
 |         out.writeInt(mRssiDbm); | 
 |         out.writeInt(mSnrDb); | 
 |         out.writeInt(mRetransmittedPacketsCount); | 
 |         out.writeInt(mPacketsNotReceivedCount); | 
 |         out.writeInt(mNegativeAcknowledgementCount); | 
 |     } | 
 |  | 
 |     public static final @android.annotation.NonNull Creator<BluetoothCallQualityReport> CREATOR = | 
 |             new Creator<BluetoothCallQualityReport>() { | 
 |                 @Override | 
 |                 public BluetoothCallQualityReport createFromParcel(Parcel in) { | 
 |                     return new BluetoothCallQualityReport(in); | 
 |                 } | 
 |  | 
 |                 @Override | 
 |                 public BluetoothCallQualityReport[] newArray(int size) { | 
 |                     return new BluetoothCallQualityReport[size]; | 
 |                 } | 
 |             }; | 
 |  | 
 |     @Override | 
 |     public boolean equals(Object o) { | 
 |         if (this == o) return true; | 
 |         if (o == null || getClass() != o.getClass()) return false; | 
 |         BluetoothCallQualityReport that = (BluetoothCallQualityReport) o; | 
 |         return mSentTimestampMillis == that.mSentTimestampMillis | 
 |                 && mChoppyVoice == that.mChoppyVoice && mRssiDbm == that.mRssiDbm | 
 |                 && mSnrDb == that.mSnrDb | 
 |                 && mRetransmittedPacketsCount == that.mRetransmittedPacketsCount | 
 |                 && mPacketsNotReceivedCount == that.mPacketsNotReceivedCount | 
 |                 && mNegativeAcknowledgementCount == that.mNegativeAcknowledgementCount; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public int hashCode() { | 
 |         return Objects.hash(mSentTimestampMillis, mChoppyVoice, mRssiDbm, mSnrDb, | 
 |                 mRetransmittedPacketsCount, mPacketsNotReceivedCount, | 
 |                 mNegativeAcknowledgementCount); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Builder class for {@link ConnectionRequest} | 
 |      */ | 
 |     public static final class Builder { | 
 |         private long mSentTimestampMillis; | 
 |         private boolean mChoppyVoice; | 
 |         private int mRssiDbm; | 
 |         private int mSnrDb; | 
 |         private int mRetransmittedPacketsCount; | 
 |         private int mPacketsNotReceivedCount; | 
 |         private int mNegativeAcknowledgementCount; | 
 |  | 
 |         public Builder() { } | 
 |  | 
 |         /** | 
 |          * Set the time when report was sent in milliseconds since the epoch. | 
 |          * @param sentTimestampMillis | 
 |          */ | 
 |         public @NonNull Builder setSentTimestampMillis(long sentTimestampMillis) { | 
 |             mSentTimestampMillis = sentTimestampMillis; | 
 |             return this; | 
 |         } | 
 |  | 
 |         /** | 
 |          * Set if bluetooth hardware detects voice is choppy | 
 |          * @param choppyVoice | 
 |          */ | 
 |         public @NonNull Builder setChoppyVoice(boolean choppyVoice) { | 
 |             mChoppyVoice = choppyVoice; | 
 |             return this; | 
 |         } | 
 |  | 
 |         /** | 
 |          * Set Received Signal Strength Indication (RSSI) value in dBm. | 
 |          * @param rssiDbm | 
 |          */ | 
 |         public @NonNull Builder setRssiDbm(int rssiDbm) { | 
 |             mRssiDbm = rssiDbm; | 
 |             return this; | 
 |         } | 
 |  | 
 |         /** | 
 |          * Set Signal-to-Noise Ratio (SNR) value in dB. | 
 |          * @param snrDb | 
 |          */ | 
 |         public @NonNull Builder setSnrDb(int snrDb) { | 
 |             mSnrDb = snrDb; | 
 |             return this; | 
 |         } | 
 |  | 
 |         /** | 
 |          * Set The number of retransmissions since the last event. | 
 |          * @param retransmittedPacketsCount | 
 |          */ | 
 |         public @NonNull Builder setRetransmittedPacketsCount( | 
 |                 int retransmittedPacketsCount) { | 
 |             mRetransmittedPacketsCount = retransmittedPacketsCount; | 
 |             return this; | 
 |         } | 
 |  | 
 |         /** | 
 |          * Set No RX count since the last event. | 
 |          * @param packetsNotReceivedCount | 
 |          */ | 
 |         public @NonNull Builder setPacketsNotReceivedCount( | 
 |                 int packetsNotReceivedCount) { | 
 |             mPacketsNotReceivedCount = packetsNotReceivedCount; | 
 |             return this; | 
 |         } | 
 |  | 
 |         /** | 
 |          * Set NAK (Negative Acknowledge) count since the last event. | 
 |          * @param negativeAcknowledgementCount | 
 |          */ | 
 |         public @NonNull Builder setNegativeAcknowledgementCount( | 
 |                 int negativeAcknowledgementCount) { | 
 |             mNegativeAcknowledgementCount = negativeAcknowledgementCount; | 
 |             return this; | 
 |         } | 
 |  | 
 |         /** | 
 |          * Build the {@link BluetoothCallQualityReport} | 
 |          * @return Result of the builder | 
 |          */ | 
 |         public @NonNull BluetoothCallQualityReport build() { | 
 |             return new BluetoothCallQualityReport(this); | 
 |         } | 
 |     } | 
 |  | 
 |     private BluetoothCallQualityReport(Parcel in) { | 
 |         mSentTimestampMillis = in.readLong(); | 
 |         mChoppyVoice = in.readBoolean(); | 
 |         mRssiDbm = in.readInt(); | 
 |         mSnrDb = in.readInt(); | 
 |         mRetransmittedPacketsCount = in.readInt(); | 
 |         mPacketsNotReceivedCount = in.readInt(); | 
 |         mNegativeAcknowledgementCount = in.readInt(); | 
 |     } | 
 |  | 
 |     private BluetoothCallQualityReport(Builder builder) { | 
 |         mSentTimestampMillis = builder.mSentTimestampMillis; | 
 |         mChoppyVoice = builder.mChoppyVoice; | 
 |         mRssiDbm = builder.mRssiDbm; | 
 |         mSnrDb = builder.mSnrDb; | 
 |         mRetransmittedPacketsCount = builder.mRetransmittedPacketsCount; | 
 |         mPacketsNotReceivedCount = builder.mPacketsNotReceivedCount; | 
 |         mNegativeAcknowledgementCount = builder.mNegativeAcknowledgementCount; | 
 |     } | 
 | } |