1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <lib/shared/ibinder/ibinder.h> 19 #include <lk/macros.h> 20 #include <utils/StrongPointer.h> 21 22 #define IBINDER_DEFINE_IFACE_CONTAINER(aidl_iface, iface) \ 23 struct iface##_container { \ 24 android::sp<aidl_iface> binder; \ 25 struct iface cbinder; \ 26 std::atomic<uint32_t> ref_count; \ 27 }; 28 29 #define IBINDER_DEFINE_PARCELABLE_CONTAINER(parcel_type, parcel_struct) \ 30 struct parcel_struct##_container { \ 31 parcel_type* parcel; \ 32 struct parcel_struct cparcel; \ 33 std::atomic<uint32_t> ref_count; \ 34 }; 35 36 #define IBINDER_DEFINE_ADD_REF_IFACE(iface) \ 37 void iface##_add_ref(struct iface* self) { \ 38 auto container = containerof(self, struct iface##_container, cbinder); \ 39 container->ref_count.fetch_add(1, std::memory_order_relaxed); \ 40 } 41 42 #define IBINDER_DEFINE_ADD_REF_PARCELABLE(parcel_struct) \ 43 void parcel_struct##_add_ref(struct parcel_struct* self) { \ 44 auto container = \ 45 containerof(self, struct parcel_struct##_container, cparcel); \ 46 container->ref_count.fetch_add(1, std::memory_order_relaxed); \ 47 } 48 49 #define IBINDER_DEFINE_RELEASE_IFACE(iface) \ 50 void iface##_release(struct iface** pself) { \ 51 assert(pself != nullptr); \ 52 assert(*pself != nullptr); \ 53 auto container = \ 54 containerof(*pself, struct iface##_container, cbinder); \ 55 \ 56 if (container->ref_count.fetch_sub(1, std::memory_order_release) == \ 57 1) { \ 58 std::atomic_thread_fence(std::memory_order_acquire); \ 59 delete container; \ 60 } \ 61 *pself = nullptr; \ 62 } 63 64 #define IBINDER_DEFINE_RELEASE_PARCELABLE(parcel_struct) \ 65 void parcel_struct##_release(struct parcel_struct** pself) { \ 66 assert(pself != nullptr); \ 67 assert(*pself != nullptr); \ 68 auto container = containerof(*pself, struct parcel_struct##_container, \ 69 cparcel); \ 70 \ 71 if (container->ref_count.fetch_sub(1, std::memory_order_release) == \ 72 1) { \ 73 std::atomic_thread_fence(std::memory_order_acquire); \ 74 delete container->parcel; \ 75 delete container; \ 76 } \ 77 *pself = nullptr; \ 78 } 79 80 #define IBINDER_DEFINE_GET_CPP_IFACE(aidl, iface) \ 81 android::sp<aidl>& iface##_to_##aidl(struct iface* self) { \ 82 auto container = containerof(self, struct iface##_container, cbinder); \ 83 return container->binder; \ 84 } 85 86 #define IBINDER_DEFINE_GET_CPP_PARCELABLE(parcel_type, parcel_struct) \ 87 parcel_type* parcel_struct##_to_##parcel_type( \ 88 struct parcel_struct* self) { \ 89 auto container = \ 90 containerof(self, struct parcel_struct##_container, cparcel); \ 91 return container->parcel; \ 92 } 93 94 #define IBINDER_DEFINE_IFACE(aidl_iface, iface) \ 95 IBINDER_DEFINE_IFACE_CONTAINER(aidl_iface, iface); \ 96 IBINDER_DEFINE_ADD_REF_IFACE(iface); \ 97 IBINDER_DEFINE_RELEASE_IFACE(iface); \ 98 IBINDER_DEFINE_GET_CPP_IFACE(aidl_iface, iface); 99 100 #define IBINDER_DEFINE_PARCELABLE(parcel_type, parcel) \ 101 static inline parcel parcel##_builder(); \ 102 IBINDER_DEFINE_PARCELABLE_CONTAINER(parcel_type, parcel); \ 103 IBINDER_DEFINE_ADD_REF_PARCELABLE(parcel); \ 104 IBINDER_DEFINE_RELEASE_PARCELABLE(parcel); \ 105 IBINDER_DEFINE_GET_CPP_PARCELABLE(parcel_type, parcel) 106