| /* | |
| * 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; | |
| } | |
| } |