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

Commit 8ae351b7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "OOB: Implement generateLocalOobData API" am: c04e8272 am: a1391084

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Bluetooth/+/1662839

Change-Id: Ie640092c55b69e8e97063d3fe4060490f0226ca4
parents 6f8efdf5 a1391084
Loading
Loading
Loading
Loading
+95 −8
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ namespace android {

const jint INVALID_FD = -1;

static jmethodID method_oobDataReceivedCallback;
static jmethodID method_stateChangeCallback;
static jmethodID method_adapterPropertyChangedCallback;
static jmethodID method_devicePropertyChangedCallback;
@@ -401,6 +402,73 @@ static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
                               (jint)pairing_variant, pass_key);
}

static jobject createClassicOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) {
  jclass oobDataClass = env->FindClass("android/bluetooth/OobData");
  jmethodID staticCreatorMethod = env->GetStaticMethodID(
      oobDataClass, "createClassicBuilder",
      "([B[B[B)Landroid/bluetooth/OobData$ClassicBuilder;");

  jbyteArray confirmationHash = env->NewByteArray(OOB_C_SIZE);
  env->SetByteArrayRegion(confirmationHash, 0, OOB_C_SIZE,
                          reinterpret_cast<jbyte*>(oob_data.c));

  jbyteArray oobDataLength = env->NewByteArray(OOB_DATA_LEN_SIZE);
  env->SetByteArrayRegion(confirmationHash, 0, OOB_DATA_LEN_SIZE,
                          reinterpret_cast<jbyte*>(oob_data.oob_data_length));

  jbyteArray address = env->NewByteArray(OOB_ADDRESS_SIZE);
  env->SetByteArrayRegion(confirmationHash, 0, OOB_ADDRESS_SIZE,
                          reinterpret_cast<jbyte*>(oob_data.address));

  jobject oobDataClassicBuilder =
      env->CallStaticObjectMethod(oobDataClass, staticCreatorMethod,
                                  confirmationHash, oobDataLength, address);

  jclass oobDataClassicBuilderClass =
      env->FindClass("android/bluetooth/OobData$ClassicBuilder");

  jmethodID setRMethod =
      env->GetMethodID(oobDataClassicBuilderClass, "setRandomizerHash",
                       "([B)Landroid/bluetooth/OobData$ClassicBuilder;");
  jbyteArray randomizerHash = env->NewByteArray(OOB_R_SIZE);
  env->SetByteArrayRegion(randomizerHash, 0, OOB_R_SIZE,
                          reinterpret_cast<jbyte*>(oob_data.r));

  oobDataClassicBuilder =
      env->CallObjectMethod(oobDataClassicBuilder, setRMethod, randomizerHash);

  jmethodID buildMethod = env->GetMethodID(oobDataClassicBuilderClass, "build",
                                           "()Landroid/bluetooth/OobData;");

  return env->CallObjectMethod(oobDataClassicBuilder, buildMethod);
}

static jobject createLeOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) {
  // TODO(184377951): Connect dots for LE generateLocalOobData()
  ALOGE("%s: unimplemented", __func__);
  return nullptr;
}

static void generate_local_oob_data_callback(tBT_TRANSPORT transport,
                                             bt_oob_data_t oob_data) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (transport == TRANSPORT_BREDR) {
    sCallbackEnv->CallVoidMethod(
        sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport,
        ((oob_data.is_valid)
             ? createClassicOobDataObject(sCallbackEnv.get(), oob_data)
             : nullptr));
  } else {
    sCallbackEnv->CallVoidMethod(
        sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport,
        ((oob_data.is_valid)
             ? createLeOobDataObject(sCallbackEnv.get(), oob_data)
             : nullptr));
  }
}

static void link_quality_report_callback(
    uint64_t timestamp, int report_id, int rssi, int snr,
    int retransmission_count, int packets_not_receive_count,
@@ -487,7 +555,7 @@ static bt_callbacks_t sBluetoothCallbacks = {
    bond_state_changed_callback,  acl_state_changed_callback,
    callback_thread_event,        dut_mode_recv_callback,
    le_test_mode_recv_callback,   energy_info_recv_callback,
    link_quality_report_callback};
    link_quality_report_callback, generate_local_oob_data_callback};

// The callback to call when the wake alarm fires.
static alarm_cb sAlarmCallback;
@@ -673,6 +741,10 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
  sJniCallbacksField = env->GetFieldID(
      clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;");

  method_oobDataReceivedCallback =
      env->GetMethodID(jniCallbackClass, "oobDataReceivedCallback",
                       "(ILandroid/bluetooth/OobData;)V");

  method_stateChangeCallback =
      env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");

@@ -1057,6 +1129,20 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData,
  return JNI_TRUE;
}

static void generateLocalOobDataNative(JNIEnv* env, jobject obj,
                                       jint transport) {
  // No BT interface? Can't do anything.
  if (!sBluetoothInterface) return;

  if (sBluetoothInterface->generate_local_oob_data(transport) !=
      BT_STATUS_SUCCESS) {
    ALOGE("%s: Call to generate_local_oob_data failed!", __func__);
    bt_oob_data_t oob_data;
    oob_data.is_valid = false;
    generate_local_oob_data_callback(transport, oob_data);
  }
}

static jboolean createBondOutOfBandNative(JNIEnv* env, jobject obj,
                                          jbyteArray address, jint transport,
                                          jobject p192Data, jobject p256Data) {
@@ -1536,6 +1622,7 @@ static JNINativeMethod sMethods[] = {
     (void*)createBondOutOfBandNative},
    {"removeBondNative", "([B)Z", (void*)removeBondNative},
    {"cancelBondNative", "([B)Z", (void*)cancelBondNative},
    {"generateLocalOobDataNative", "(I)V", (void*)generateLocalOobDataNative},
    {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative},
    {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative},
    {"sspReplyNative", "([BIZI)Z", (void*)sspReplyNative},
+75 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothConnectionCallback;
import android.bluetooth.IBluetoothMetadataListener;
import android.bluetooth.IBluetoothOobDataCallback;
import android.bluetooth.IBluetoothSocketManager;
import android.bluetooth.OobData;
import android.bluetooth.UidTraffic;
@@ -115,6 +116,7 @@ import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -1590,6 +1592,26 @@ public class AdapterService extends Service {
            return deviceProp != null && deviceProp.isBondingInitiatedLocally();
        }

        @Override
        public void generateLocalOobData(int transport, IBluetoothOobDataCallback callback) {
            AdapterService service = getService();
            if (service == null || !callerIsSystemOrActiveOrManagedUser(service,
                    TAG, "generateLocalOobData")) {
                return;
            }
            enforceBluetoothPrivilegedPermission(service);
            if (transport == BluetoothDevice.TRANSPORT_LE) {
                // TODO(184377951): LE isn't yet supported, coming soon
                try {
                    callback.onError(BluetoothAdapter.OOB_ERROR_UNKNOWN);
                } catch (RemoteException e) {
                    Log.e(TAG, "Failed to call callback");
                }
                return;
            }
            service.generateLocalOobData(transport, callback);
        }

        @Override
        public long getSupportedProfiles() {
            AdapterService service = getService();
@@ -2443,6 +2465,56 @@ public class AdapterService extends Service {
        return true;
    }

    private final ArrayDeque<IBluetoothOobDataCallback> mOobDataCallbackQueue =
            new ArrayDeque<>();

    /**
     * Fetches the local OOB data to give out to remote.
     *
     * @param transport - specify data transport.
     * @param callback - callback used to receive the requested {@link Oobdata}; null will be
     * ignored silently.
     *
     * @hide
     */
    public synchronized void generateLocalOobData(int transport,
            IBluetoothOobDataCallback callback) {
        if (callback == null) {
            Log.e(TAG, "'callback' argument must not be null!");
            return;
        }
        if (mOobDataCallbackQueue.peek() != null) {
            try {
                callback.onError(BluetoothAdapter.OOB_ERROR_ANOTHER_ACTIVE_REQUEST);
                return;
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to make callback", e);
            }
        }
        mOobDataCallbackQueue.offer(callback);
        generateLocalOobDataNative(transport);
    }

    /* package */ synchronized void notifyOobDataCallback(int transport, OobData oobData) {
        if (mOobDataCallbackQueue.peek() == null) {
            Log.e(TAG, "Failed to make callback, no callback exists");
            return;
        }
        if (oobData == null) {
            try {
                mOobDataCallbackQueue.poll().onError(BluetoothAdapter.OOB_ERROR_UNKNOWN);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to make callback", e);
            }
        } else {
            try {
                mOobDataCallbackQueue.poll().onOobData(transport, oobData);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to make callback", e);
            }
        }
    }

    public boolean isQuietModeEnabled() {
        debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode);
        return mQuietmode;
@@ -3469,6 +3541,9 @@ public class AdapterService extends Service {
    /*package*/
    native boolean cancelBondNative(byte[] address);

    /*package*/
    native void generateLocalOobDataNative(int transport);

    /*package*/
    native boolean sdpSearchNative(byte[] address, byte[] uuid);

+6 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.bluetooth.btservice;

import android.bluetooth.OobData;

final class JniCallbacks {

    private RemoteDevices mRemoteDevices;
@@ -81,6 +83,10 @@ final class JniCallbacks {
        mAdapterProperties.adapterPropertyChangedCallback(types, val);
    }

    void oobDataReceivedCallback(int transport, OobData oobData) {
        mAdapterService.notifyOobDataCallback(transport, oobData);
    }

    void linkQualityReportCallback(
            long timestamp,
            int report_id,