Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6bfb3c2 authored by Chen Chen's avatar Chen Chen
Browse files

Send Bluetooth call quality report to telephony

Bug: 178232343
Test: manually test the function and check log
tag: #feature

Change-Id: I397915c4a2ec45d4c9b9747c8f7ef5afea50c126
parent 07f9aae1
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ static jmethodID method_sspRequestCallback;
static jmethodID method_bondStateChangeCallback;
static jmethodID method_aclStateChangeCallback;
static jmethodID method_discoveryStateChangeCallback;
static jmethodID method_linkQualityReportCallback;
static jmethodID method_setWakeAlarm;
static jmethodID method_acquireWakeLock;
static jmethodID method_releaseWakeLock;
@@ -387,6 +388,24 @@ static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
                               (jint)pairing_variant, pass_key);
}

static void link_quality_report_callback(
    uint64_t timestamp, int report_id, int rssi, int snr,
    int retransmission_count, int packets_not_receive_count,
    int negative_acknowledgement_count) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  ALOGV("%s: LinkQualityReportCallback: %d %d %d %d %d %d", __func__,
        report_id, rssi, snr, retransmission_count, packets_not_receive_count,
        negative_acknowledgement_count);

  sCallbackEnv->CallVoidMethod(
      sJniCallbacksObj, method_linkQualityReportCallback,
      (jlong)timestamp, (jint)report_id, (jint)rssi, (jint)snr,
      (jint)retransmission_count, (jint)packets_not_receive_count,
      (jint)negative_acknowledgement_count);
}

static void callback_thread_event(bt_cb_thread_evt event) {
  if (event == ASSOCIATE_JVM) {
    JavaVMAttachArgs args;
@@ -454,7 +473,8 @@ static bt_callbacks_t sBluetoothCallbacks = {
    pin_request_callback,        ssp_request_callback,
    bond_state_changed_callback, acl_state_changed_callback,
    callback_thread_event,       dut_mode_recv_callback,
    le_test_mode_recv_callback,  energy_info_recv_callback};
    le_test_mode_recv_callback,  energy_info_recv_callback,
    link_quality_report_callback};

// The callback to call when the wake alarm fires.
static alarm_cb sAlarmCallback;
@@ -663,6 +683,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
  method_aclStateChangeCallback =
      env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V");

  method_linkQualityReportCallback = env->GetMethodID(
      jniCallbackClass, "linkQualityReportCallback", "(JIIIIII)V");

  method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z");
  method_acquireWakeLock =
      env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z");
+47 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ import com.android.bluetooth.pbap.BluetoothPbapService;
import com.android.bluetooth.pbapclient.PbapClientService;
import com.android.bluetooth.sap.SapService;
import com.android.bluetooth.sdp.SdpManager;
import com.android.bluetooth.telephony.BluetoothInCallService;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
@@ -171,6 +172,26 @@ public class AdapterService extends Service {

    private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;

    // Report ID definition
    public enum BqrQualityReportId {
        QUALITY_REPORT_ID_MONITOR_MODE(0x01),
        QUALITY_REPORT_ID_APPROACH_LSTO(0x02),
        QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY(0x03),
        QUALITY_REPORT_ID_SCO_VOICE_CHOPPY(0x04),
        QUALITY_REPORT_ID_ROOT_INFLAMMATION(0x05),
        QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE(0x11),
        QUALITY_REPORT_ID_BT_SCHEDULING_TRACE(0x12),
        QUALITY_REPORT_ID_CONTROLLER_DBG_INFO(0x13);

        private final int value;
        private BqrQualityReportId(int value) {
            this.value = value;
        }
        public int getValue() {
            return value;
        }
    };

    private final ArrayList<DiscoveringPackage> mDiscoveringPackages = new ArrayList<>();

    static {
@@ -718,6 +739,32 @@ public class AdapterService extends Service {
        }
    }

    void linkQualityReportCallback(
            long timestamp,
            int reportId,
            int rssi,
            int snr,
            int retransmissionCount,
            int packetsNotReceiveCount,
            int negativeAcknowledgementCount) {
        BluetoothInCallService bluetoothInCallService = BluetoothInCallService.getInstance();

        if (reportId == BqrQualityReportId.QUALITY_REPORT_ID_SCO_VOICE_CHOPPY.getValue()) {
            if (bluetoothInCallService == null) {
                Log.w(TAG, "No BluetoothInCallService while trying to send BQR."
                        + " timestamp: " + timestamp + " reportId: " + reportId
                        + " rssi: " + rssi + " snr: " + snr
                        + " retransmissionCount: " + retransmissionCount
                        + " packetsNotReceiveCount: " + packetsNotReceiveCount
                        + " negativeAcknowledgementCount: " + negativeAcknowledgementCount);
                return;
            }
            bluetoothInCallService.sendBluetoothCallQualityReport(
                    timestamp, rssi, snr, retransmissionCount,
                    packetsNotReceiveCount, negativeAcknowledgementCount);
        }
    }

    void cleanup() {
        debugLog("cleanup()");
        if (mCleaningUp) {
+13 −0
Original line number Diff line number Diff line
@@ -81,4 +81,17 @@ final class JniCallbacks {
        mAdapterProperties.adapterPropertyChangedCallback(types, val);
    }

    void linkQualityReportCallback(
            long timestamp,
            int report_id,
            int rssi,
            int snr,
            int retransmission_count,
            int packets_not_receive_count,
            int negative_acknowledgement_count) {
        mAdapterService.linkQualityReportCallback(
                timestamp, report_id, rssi, snr, retransmission_count,
                packets_not_receive_count, negative_acknowledgement_count);
    }

}
+30 −0
Original line number Diff line number Diff line
@@ -27,7 +27,9 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.telecom.BluetoothCallQualityReport;
import android.telecom.Call;
import android.telecom.CallAudioState;
import android.telecom.Connection;
@@ -449,6 +451,34 @@ public class BluetoothInCallService extends InCallService {
        }
    }

    public void sendBluetoothCallQualityReport(
            long timestamp,
            int rssi,
            int snr,
            int retransmissionCount,
            int packetsNotReceiveCount,
            int negativeAcknowledgementCount) {
        BluetoothCall call = mCallInfo.getForegroundCall();
        if (mCallInfo.isNullCall(call)) {
            Log.w(TAG, "No foreground call while trying to send BQR");
            return;
        }
        Bundle b = new Bundle();
        b.putParcelable(
                BluetoothCallQualityReport.EXTRA_BLUETOOTH_CALL_QUALITY_REPORT,
                new BluetoothCallQualityReport.Builder()
                        .setSentTimestampMillis(timestamp)
                        .setChoppyVoice(true)
                        .setRssiDbm(rssi)
                        .setSnrDb(snr)
                        .setRetransmittedPacketsCount(retransmissionCount)
                        .setPacketsNotReceivedCount(packetsNotReceiveCount)
                        .setPacketsNotReceivedCount(negativeAcknowledgementCount)
                        .build());
        call.sendCallEvent(
                BluetoothCallQualityReport.EVENT_BLUETOOTH_CALL_QUALITY_REPORT, b);
    }

    @Override
    public void onCallAdded(Call call) {
        super.onCallAdded(call);