1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ANIUTIL_MEMORY_H 17 #define ANIUTIL_MEMORY_H 18 19 #include <ani.h> 20 #include <refbase.h> 21 22 #include <memory> 23 #include <string> 24 25 namespace OHOS { 26 namespace AniUtil { 27 28 class NativeObject { 29 public: 30 virtual ~NativeObject() = default; 31 }; 32 33 34 template <typename T> 35 class StdSharedPtrHolder : public NativeObject { 36 public: StdSharedPtrHolder(const std::shared_ptr<T> & sptr)37 StdSharedPtrHolder(const std::shared_ptr<T> &sptr) : sptr_(sptr) 38 { 39 } 40 Get()41 std::shared_ptr<T> Get() 42 { 43 return sptr_; 44 } 45 GetOrDefault()46 std::shared_ptr<T> GetOrDefault() 47 { 48 if (!sptr_) { 49 sptr_ = std::make_shared<T>(); 50 } 51 return sptr_; 52 } 53 54 private: 55 std::shared_ptr<T> sptr_; 56 }; 57 58 59 template <typename T> 60 class OhSharedPtrHolder : public NativeObject { 61 public: OhSharedPtrHolder(const OHOS::sptr<T> & sptr)62 OhSharedPtrHolder(const OHOS::sptr<T> &sptr) : sptr_(sptr) 63 { 64 } 65 Get()66 OHOS::sptr<T> Get() 67 { 68 return sptr_; 69 } 70 GetOrDefault()71 OHOS::sptr<T> GetOrDefault() 72 { 73 if (!sptr_) { 74 sptr_ = OHOS::sptr<T>::MakeSptr(); 75 } 76 return sptr_; 77 } 78 79 private: 80 OHOS::sptr<T> sptr_; 81 }; 82 83 84 class NativePtrWrapper { 85 public: 86 NativePtrWrapper(ani_env *env, ani_object object, const char* propName = "nativePtr") env_(env)87 : env_(env), obj_(object), propName_(propName) 88 { 89 } 90 91 template<typename T> Wrap(T * nativePtr)92 ani_status Wrap(T* nativePtr) 93 { 94 return env_->Object_SetFieldByName_Long(obj_, propName_.c_str(), reinterpret_cast<ani_long>(nativePtr)); 95 } 96 97 template<typename T> Unwrap()98 T* Unwrap() 99 { 100 ani_long nativePtr; 101 if (ANI_OK != env_->Object_GetFieldByName_Long(obj_, propName_.c_str(), &nativePtr)) { 102 return nullptr; 103 } 104 return reinterpret_cast<T*>(nativePtr); 105 } 106 107 private: 108 ani_env *env_ = nullptr; 109 ani_object obj_ = nullptr; 110 std::string propName_; 111 }; 112 113 114 class NativePtrCleaner { 115 public: Clean(ani_env * env,ani_object object)116 static void Clean([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object) 117 { 118 ani_long ptr = 0; 119 if (ANI_OK != env->Object_GetFieldByName_Long(object, "targetPtr", &ptr)) { 120 return; 121 } 122 delete reinterpret_cast<NativeObject *>(ptr); 123 } 124 NativePtrCleaner(ani_env * env)125 NativePtrCleaner(ani_env *env) 126 : env_(env) 127 { 128 } 129 Bind(ani_class cls)130 ani_status Bind(ani_class cls) 131 { 132 std::array methods = { 133 ani_native_function { "clean", nullptr, reinterpret_cast<void *>(NativePtrCleaner::Clean) }, 134 }; 135 136 if (ANI_OK != env_->Class_BindNativeMethods(cls, methods.data(), methods.size())) { 137 return (ani_status)ANI_ERROR; 138 }; 139 140 return ANI_OK; 141 } 142 143 private: 144 ani_env *env_ = nullptr; 145 }; 146 147 } // namespace AniUtil 148 } // namespace OHOS 149 150 #endif 151