blob: 78dba6abb623a03124bfba043505ea7a3c10da3d [file] [log] [blame]
/*
* 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;
}
}