Add default implementation for Bluetooth Gatt Offload

Bug: 425735093
Test: m android.hardware.bluetooth.gatt-service.default
Change-Id: I17893ec94eac43862c0ed573fcb746cedcaebf3c
diff --git a/bluetooth/gatt/aidl/default/Android.bp b/bluetooth/gatt/aidl/default/Android.bp
new file mode 100644
index 0000000..e9330f3
--- /dev/null
+++ b/bluetooth/gatt/aidl/default/Android.bp
@@ -0,0 +1,48 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+    name: "android.hardware.bluetooth.gatt-service.default",
+    relative_install_path: "hw",
+    init_rc: ["bluetooth-gatt-service-default.rc"],
+    vintf_fragments: [":manifest_android.hardware.bluetooth.gatt-service.default.xml"],
+    vendor: true,
+    srcs: [
+        "BluetoothGatt.cpp",
+        "service.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.bluetooth.gatt-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libhidlbase",
+        "libutils",
+        "liblog",
+    ],
+}
+
+cc_fuzz {
+    name: "android.hardware.bluetooth.gatt-service_fuzzer",
+    team: "trendy_team_bluetooth",
+    defaults: ["service_fuzzer_defaults"],
+    srcs: [
+        "fuzzer.cpp",
+        "BluetoothGatt.cpp",
+    ],
+    static_libs: [
+        "android.hardware.bluetooth.gatt-V1-ndk",
+        "android.hardware.contexthub-V4-ndk",
+        "liblog",
+    ],
+    fuzz_config: {
+        cc: [
+            "jaydenk@google.com",
+        ],
+    },
+}
+
+filegroup {
+    name: "manifest_android.hardware.bluetooth.gatt-service.default.xml",
+    srcs: ["bluetooth-gatt-service-default.xml"],
+}
diff --git a/bluetooth/gatt/aidl/default/BluetoothGatt.cpp b/bluetooth/gatt/aidl/default/BluetoothGatt.cpp
new file mode 100644
index 0000000..d243dee
--- /dev/null
+++ b/bluetooth/gatt/aidl/default/BluetoothGatt.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2025 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.
+ */
+
+#include "BluetoothGatt.h"
+
+namespace aidl::android::hardware::bluetooth::gatt::impl {
+
+BluetoothGatt::BluetoothGatt() {}
+BluetoothGatt::~BluetoothGatt() {}
+
+::ndk::ScopedAStatus BluetoothGatt::init(
+    const std::shared_ptr<IBluetoothGattCallback>& in_callback) {
+  if (in_callback == nullptr) {
+    return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE);
+  }
+  callback_ = in_callback;
+  return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus BluetoothGatt::getGattCapabilities(
+    GattCapabilities* _aidl_return) {
+  _aidl_return->supportedGattClientProperties = 0;
+  _aidl_return->supportedGattServerProperties = 0;
+  return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus BluetoothGatt::registerService(
+    int32_t /* in_sessionId */, int32_t /* in_aclConnectionHandle */,
+    int32_t /* in_attMtu */, IBluetoothGatt::Role /* in_role */,
+    const Uuid& /* in_serviceUuid */,
+    const std::vector<GattCharacteristic>& /* in_characteristics */,
+    const ::aidl::android::hardware::contexthub::
+        EndpointId& /* in_endpointId */) {
+  return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+::ndk::ScopedAStatus BluetoothGatt::unregisterService(
+    int32_t /* in_sessionId */) {
+  return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+::ndk::ScopedAStatus BluetoothGatt::clearServices(
+    int32_t /* in_aclConnectionHandle */) {
+  return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+}  // namespace aidl::android::hardware::bluetooth::gatt::impl
\ No newline at end of file
diff --git a/bluetooth/gatt/aidl/default/BluetoothGatt.h b/bluetooth/gatt/aidl/default/BluetoothGatt.h
new file mode 100644
index 0000000..99c0327
--- /dev/null
+++ b/bluetooth/gatt/aidl/default/BluetoothGatt.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2025 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.
+ */
+
+#include <aidl/android/hardware/bluetooth/gatt/BnBluetoothGatt.h>
+
+namespace aidl::android::hardware::bluetooth::gatt::impl {
+
+class BluetoothGatt : public BnBluetoothGatt {
+ public:
+  BluetoothGatt();
+  ~BluetoothGatt();
+
+  ::ndk::ScopedAStatus init(
+      const std::shared_ptr<
+          ::aidl::android::hardware::bluetooth::gatt::IBluetoothGattCallback>&
+          in_callback) override;
+  ::ndk::ScopedAStatus getGattCapabilities(
+      ::aidl::android::hardware::bluetooth::gatt::GattCapabilities*
+          _aidl_return) override;
+  ::ndk::ScopedAStatus registerService(
+      int32_t in_sessionId, int32_t in_aclConnectionHandle, int32_t in_attMtu,
+      ::aidl::android::hardware::bluetooth::gatt::IBluetoothGatt::Role in_role,
+      const ::aidl::android::hardware::bluetooth::gatt::Uuid& in_serviceUuid,
+      const std::vector<
+          ::aidl::android::hardware::bluetooth::gatt::GattCharacteristic>&
+          in_characteristics,
+      const ::aidl::android::hardware::contexthub::EndpointId& in_endpointId)
+      override;
+  ::ndk::ScopedAStatus unregisterService(int32_t in_sessionId) override;
+  ::ndk::ScopedAStatus clearServices(int32_t in_aclConnectionHandle) override;
+
+ private:
+  std::shared_ptr<IBluetoothGattCallback> callback_;
+};
+
+}  // namespace aidl::android::hardware::bluetooth::gatt::impl
\ No newline at end of file
diff --git a/bluetooth/gatt/aidl/default/bluetooth-gatt-service-default.rc b/bluetooth/gatt/aidl/default/bluetooth-gatt-service-default.rc
new file mode 100644
index 0000000..188c06e
--- /dev/null
+++ b/bluetooth/gatt/aidl/default/bluetooth-gatt-service-default.rc
@@ -0,0 +1,4 @@
+service vendor.bluetooth.gatt-default /vendor/bin/hw/android.hardware.bluetooth.gatt-service.default
+    class hal
+    user nobody
+    group nobody
\ No newline at end of file
diff --git a/bluetooth/gatt/aidl/default/bluetooth-gatt-service-default.xml b/bluetooth/gatt/aidl/default/bluetooth-gatt-service-default.xml
new file mode 100644
index 0000000..cb94e25
--- /dev/null
+++ b/bluetooth/gatt/aidl/default/bluetooth-gatt-service-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.bluetooth.gatt</name>
+        <version>1</version>
+        <fqname>IBluetoothGatt/default</fqname>
+    </hal>
+</manifest>
\ No newline at end of file
diff --git a/bluetooth/gatt/aidl/default/fuzzer.cpp b/bluetooth/gatt/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..a785f20
--- /dev/null
+++ b/bluetooth/gatt/aidl/default/fuzzer.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2025 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.
+ */
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "BluetoothGatt.h"
+
+using ::aidl::android::hardware::bluetooth::gatt::impl::BluetoothGatt;
+using ::android::fuzzService;
+using ::ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  auto bluetoothGattAidl = SharedRefBase::make<BluetoothGatt>();
+
+  fuzzService(bluetoothGattAidl->asBinder().get(),
+              FuzzedDataProvider(data, size));
+
+  return 0;
+}
\ No newline at end of file
diff --git a/bluetooth/gatt/aidl/default/service.cpp b/bluetooth/gatt/aidl/default/service.cpp
new file mode 100644
index 0000000..1b8e127
--- /dev/null
+++ b/bluetooth/gatt/aidl/default/service.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2025 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.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.gatt.service.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "BluetoothGatt.h"
+
+using ::aidl::android::hardware::bluetooth::gatt::impl::BluetoothGatt;
+
+int main(int /* argc */, char** /* argv */) {
+  ALOGI("Starting IBluetoothGatt service");
+  if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+    ALOGE("Failed to set thread pool max thread count");
+    return EXIT_FAILURE;
+  }
+
+  std::shared_ptr<BluetoothGatt> service =
+      ndk::SharedRefBase::make<BluetoothGatt>();
+  std::string instance = std::string() + BluetoothGatt::descriptor + "/default";
+  auto result =
+      AServiceManager_addService(service->asBinder().get(), instance.c_str());
+  if (result != STATUS_OK) {
+    ALOGE("Could not register as a service!");
+    return EXIT_FAILURE;
+  }
+  ABinderProcess_joinThreadPool();
+  return EXIT_SUCCESS;
+}
\ No newline at end of file