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

Commit 7a67441a authored by Sarvesh Kalwit's avatar Sarvesh Kalwit Committed by Gerrit Code Review
Browse files

Merge "Add MSFT extension support to JNI layer" into main

parents 4c4cb3da 039d579a
Loading
Loading
Loading
Loading
+152 −0
Original line number Diff line number Diff line
@@ -180,6 +180,9 @@ static jmethodID method_onBatchScanThresholdCrossed;
static jmethodID method_createOnTrackAdvFoundLostObject;
static jmethodID method_onTrackAdvFoundLost;
static jmethodID method_onScanParamSetupCompleted;
static jmethodID method_onMsftAdvMonitorAdd;
static jmethodID method_onMsftAdvMonitorRemove;
static jmethodID method_onMsftAdvMonitorEnable;

/**
 * Periodic scanner callback methods
@@ -1877,6 +1880,142 @@ static void gattClientScanFilterEnableNative(JNIEnv* /* env */, jobject /* objec
  sScanner->ScanFilterEnable(enable, base::Bind(&scan_enable_cb, client_if));
}

void msft_monitor_add_cb(int filter_index, uint8_t monitor_handle, uint8_t status) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
    return;
  }
  sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onMsftAdvMonitorAdd, filter_index,
                               monitor_handle, status);
}

void msft_monitor_remove_cb(int filter_index, uint8_t status) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
    return;
  }
  sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onMsftAdvMonitorRemove, filter_index,
                               status);
}

void msft_monitor_enable_cb(uint8_t status) {
  std::shared_lock<std::shared_mutex> lock(callbacks_mutex);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid() || !mScanCallbacksObj) {
    return;
  }
  sCallbackEnv->CallVoidMethod(mScanCallbacksObj, method_onMsftAdvMonitorEnable, status);
}

static bool gattClientIsMsftSupportedNative(JNIEnv* /* env */, jobject /* object */) {
  return sScanner && sScanner->IsMsftSupported();
}

static void gattClientMsftAdvMonitorAddNative(JNIEnv* env, jobject /* object*/,
                                              jobject msft_adv_monitor,
                                              jobjectArray msft_adv_monitor_patterns,
                                              jobject msft_adv_monitor_address, jint filter_index) {
  if (!sScanner) {
    return;
  }

  jclass msftAdvMonitorClazz = env->GetObjectClass(msft_adv_monitor);
  jfieldID rssiThresholdHighFid = env->GetFieldID(msftAdvMonitorClazz, "rssi_threshold_high", "B");
  jfieldID rssiThresholdLowFid = env->GetFieldID(msftAdvMonitorClazz, "rssi_threshold_low", "B");
  jfieldID rssiThresholdLowTimeIntervalFid =
          env->GetFieldID(msftAdvMonitorClazz, "rssi_threshold_low_time_interval", "B");
  jfieldID rssiSamplingPeriodFid =
          env->GetFieldID(msftAdvMonitorClazz, "rssi_sampling_period", "B");
  jfieldID conditionTypeFid = env->GetFieldID(msftAdvMonitorClazz, "condition_type", "B");

  jclass msftAdvMonitorAddressClazz = env->GetObjectClass(msft_adv_monitor_address);
  jfieldID addrTypeFid = env->GetFieldID(msftAdvMonitorAddressClazz, "addr_type", "B");
  jfieldID bdAddrFid = env->GetFieldID(msftAdvMonitorAddressClazz, "bd_addr", "Ljava/lang/String;");

  MsftAdvMonitor native_msft_adv_monitor{};
  ScopedLocalRef<jobject> msft_adv_monitor_object(env, msft_adv_monitor);
  native_msft_adv_monitor.rssi_threshold_high =
          env->GetByteField(msft_adv_monitor_object.get(), rssiThresholdHighFid);
  native_msft_adv_monitor.rssi_threshold_low =
          env->GetByteField(msft_adv_monitor_object.get(), rssiThresholdLowFid);
  native_msft_adv_monitor.rssi_threshold_low_time_interval =
          env->GetByteField(msft_adv_monitor_object.get(), rssiThresholdLowTimeIntervalFid);
  native_msft_adv_monitor.rssi_sampling_period =
          env->GetByteField(msft_adv_monitor_object.get(), rssiSamplingPeriodFid);
  native_msft_adv_monitor.condition_type =
          env->GetByteField(msft_adv_monitor_object.get(), conditionTypeFid);

  MsftAdvMonitorAddress native_msft_adv_monitor_address{};
  ScopedLocalRef<jobject> msft_adv_monitor_address_object(env, msftAdvMonitorAddressClazz);
  native_msft_adv_monitor_address.addr_type =
          env->GetByteField(msft_adv_monitor_address_object.get(), addrTypeFid);
  native_msft_adv_monitor_address.bd_addr = str2addr(
          env, (jstring)env->GetObjectField(msft_adv_monitor_address_object.get(), bdAddrFid));
  native_msft_adv_monitor.addr_info = native_msft_adv_monitor_address;

  int numPatterns = env->GetArrayLength(msft_adv_monitor_patterns);
  if (numPatterns == 0) {
    sScanner->MsftAdvMonitorAdd(std::move(native_msft_adv_monitor),
                                base::Bind(&msft_monitor_add_cb, filter_index));
    return;
  }

  jclass msftAdvMonitorPatternClazz =
          env->GetObjectClass(env->GetObjectArrayElement(msft_adv_monitor_patterns, 0));
  jfieldID adTypeFid = env->GetFieldID(msftAdvMonitorPatternClazz, "ad_type", "B");
  jfieldID startByteFid = env->GetFieldID(msftAdvMonitorPatternClazz, "start_byte", "B");
  jfieldID patternFid = env->GetFieldID(msftAdvMonitorPatternClazz, "pattern", "[B");

  std::vector<MsftAdvMonitorPattern> patterns;
  for (int i = 0; i < numPatterns; i++) {
    MsftAdvMonitorPattern native_msft_adv_monitor_pattern{};
    ScopedLocalRef<jobject> msft_adv_monitor_pattern_object(
            env, env->GetObjectArrayElement(msft_adv_monitor_patterns, i));
    native_msft_adv_monitor_pattern.ad_type =
            env->GetByteField(msft_adv_monitor_pattern_object.get(), adTypeFid);
    native_msft_adv_monitor_pattern.start_byte =
            env->GetByteField(msft_adv_monitor_pattern_object.get(), startByteFid);

    ScopedLocalRef<jbyteArray> patternByteArray(
            env,
            (jbyteArray)env->GetObjectField(msft_adv_monitor_pattern_object.get(), patternFid));
    if (patternByteArray.get() != nullptr) {
      jbyte* patternBytes = env->GetByteArrayElements(patternByteArray.get(), NULL);
      if (patternBytes == NULL) {
        jniThrowIOException(env, EINVAL);
        return;
      }
      for (int j = 0; j < env->GetArrayLength(patternByteArray.get()); j++) {
        native_msft_adv_monitor_pattern.pattern.push_back(patternBytes[j]);
      }
    }

    patterns.push_back(native_msft_adv_monitor_pattern);
  }
  native_msft_adv_monitor.patterns = patterns;

  sScanner->MsftAdvMonitorAdd(std::move(native_msft_adv_monitor),
                              base::Bind(&msft_monitor_add_cb, filter_index));
}

static void gattClientMsftAdvMonitorRemoveNative(JNIEnv* /* env */, jobject /* object */,
                                                 int filter_index, int monitor_handle) {
  if (!sScanner) {
    return;
  }
  sScanner->MsftAdvMonitorRemove(monitor_handle, base::Bind(&msft_monitor_remove_cb, filter_index));
}

static void gattClientMsftAdvMonitorEnableNative(JNIEnv* /* env */, jobject /* object */,
                                                 jboolean enable) {
  if (!sScanner) {
    return;
  }
  sScanner->MsftAdvMonitorEnable(enable, base::Bind(&msft_monitor_enable_cb));
}

static void gattClientConfigureMTUNative(JNIEnv* /* env */, jobject /* object */, jint conn_id,
                                         jint mtu) {
  if (!sGattIf) {
@@ -2699,6 +2838,16 @@ static int register_com_android_bluetooth_gatt_scan(JNIEnv* env) {
          {"gattClientScanFilterClearNative", "(II)V", (void*)gattClientScanFilterClearNative},
          {"gattClientScanFilterEnableNative", "(IZ)V", (void*)gattClientScanFilterEnableNative},
          {"gattSetScanParametersNative", "(IIII)V", (void*)gattSetScanParametersNative},
          // MSFT HCI Extension functions.
          {"gattClientIsMsftSupportedNative", "()Z", (void*)gattClientIsMsftSupportedNative},
          {"gattClientMsftAdvMonitorAddNative",
           "(Lcom/android/bluetooth/le_scan/MsftAdvMonitor$Monitor;[Lcom/android/bluetooth/le_scan/"
           "MsftAdvMonitor$Pattern;Lcom/android/bluetooth/le_scan/MsftAdvMonitor$Address;I)V",
           (void*)gattClientMsftAdvMonitorAddNative},
          {"gattClientMsftAdvMonitorRemoveNative", "(II)V",
           (void*)gattClientMsftAdvMonitorRemoveNative},
          {"gattClientMsftAdvMonitorEnableNative", "(Z)V",
           (void*)gattClientMsftAdvMonitorEnableNative},
  };
  const int result = REGISTER_NATIVE_METHODS(
          env, "com/android/bluetooth/le_scan/ScanNativeInterface", methods);
@@ -2725,6 +2874,9 @@ static int register_com_android_bluetooth_gatt_scan(JNIEnv* env) {
          {"onTrackAdvFoundLost", "(Lcom/android/bluetooth/le_scan/AdvtFilterOnFoundOnLostInfo;)V",
           &method_onTrackAdvFoundLost},
          {"onScanParamSetupCompleted", "(II)V", &method_onScanParamSetupCompleted},
          {"onMsftAdvMonitorAdd", "(III)V", &method_onMsftAdvMonitorAdd},
          {"onMsftAdvMonitorRemove", "(II)V", &method_onMsftAdvMonitorRemove},
          {"onMsftAdvMonitorEnable", "(I)V", &method_onMsftAdvMonitorEnable},
  };
  GET_JAVA_METHODS(env, "com/android/bluetooth/le_scan/ScanNativeInterface", javaMethods);
  return 0;
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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 com.android.bluetooth.le_scan;

class MsftAdvMonitor {
    static class Monitor {
        public byte rssi_threshold_high;
        public byte rssi_threshold_low;
        public byte rssi_threshold_low_time_interval;
        public byte rssi_sampling_period;
        public byte condition_type;
    }

    static class Pattern {
        public byte ad_type;
        public byte start_byte;
        public byte[] pattern;
    }

    static class Address {
        byte addr_type;
        String bd_addr;
    }
}
+19 −0
Original line number Diff line number Diff line
@@ -98,6 +98,19 @@ public class ScanNativeInterface {

    private native void gattClientScanFilterEnableNative(int clientIf, boolean enable);

    /************************** MSFT scan related native methods *****************************/
    private native boolean gattClientIsMsftSupportedNative();

    private native void gattClientMsftAdvMonitorAddNative(
            MsftAdvMonitor.Monitor msft_adv_monitor,
            MsftAdvMonitor.Pattern[] msft_adv_monitor_patterns,
            MsftAdvMonitor.Address msft_adv_monitor_address,
            int filter_index);

    private native void gattClientMsftAdvMonitorRemoveNative(int filter_index, int monitor_handle);

    private native void gattClientMsftAdvMonitorEnableNative(boolean enable);

    /************************** Batch related native methods *********************************/
    private native void gattClientConfigBatchScanStorageNative(
            int clientIf,
@@ -371,4 +384,10 @@ public class ScanNativeInterface {
        }
        mScanHelper.onScanParamSetupCompleted(status, scannerId);
    }

    void onMsftAdvMonitorAdd(int filter_index, int monitor_handle, int status) {}

    void onMsftAdvMonitorRemove(int filter_index, int status) {}

    void onMsftAdvMonitorEnable(int status) {}
}
+3 −3
Original line number Diff line number Diff line
@@ -287,13 +287,13 @@ void BleScannerInterfaceImpl::MsftAdvMonitorEnable(bool enable, MsftAdvMonitorEn
void BleScannerInterfaceImpl::OnMsftAdvMonitorAdd(uint8_t monitor_handle,
                                                  bluetooth::hci::ErrorCode status) {
  log::info("in shim layer");
  msft_callbacks_.Add.Run(monitor_handle, (uint8_t)status);
  do_in_jni_thread(base::BindOnce(msft_callbacks_.Add, monitor_handle, (uint8_t)status));
}

/** Callback of removing MSFT filter */
void BleScannerInterfaceImpl::OnMsftAdvMonitorRemove(bluetooth::hci::ErrorCode status) {
  log::info("in shim layer");
  msft_callbacks_.Remove.Run((uint8_t)status);
  do_in_jni_thread(base::BindOnce(msft_callbacks_.Remove, (uint8_t)status));
}

/** Callback of enabling / disabling MSFT scan filter */
@@ -307,7 +307,7 @@ void BleScannerInterfaceImpl::OnMsftAdvMonitorEnable(bool enable,
                   : bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL);
  }

  msft_callbacks_.Enable.Run((uint8_t)status);
  do_in_jni_thread(base::BindOnce(msft_callbacks_.Enable, (uint8_t)status));
}

/** Sets the LE scan interval and window in units of N*0.625 msec */