Andreas Huber | dab5fc6 | 2016-08-15 09:25:02 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2016 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 | |
| 17 | #define LOG_TAG "EphemeralStorage" |
| 18 | //#define LOG_NDEBUG 0 |
| 19 | |
| 20 | #include <android-base/logging.h> |
| 21 | |
| 22 | #include "EphemeralStorage.h" |
| 23 | |
| 24 | using ::android::hardware::hidl_string; |
| 25 | using ::android::hardware::hidl_vec; |
| 26 | |
| 27 | namespace android { |
| 28 | |
| 29 | EphemeralStorage::EphemeralStorage() { |
| 30 | } |
| 31 | |
| 32 | EphemeralStorage::~EphemeralStorage() { |
| 33 | CHECK(mItems.empty()) |
| 34 | << "All item storage should have been released by now."; |
| 35 | } |
| 36 | |
| 37 | hidl_string *EphemeralStorage::allocStringArray(size_t size) { |
| 38 | Item item; |
| 39 | item.mType = TYPE_STRING_ARRAY; |
| 40 | item.mObj = NULL; |
| 41 | item.mPtr = new hidl_string[size]; |
| 42 | mItems.push_back(item); |
| 43 | |
| 44 | return static_cast<hidl_string *>(item.mPtr); |
| 45 | } |
| 46 | |
| 47 | void *EphemeralStorage::allocTemporaryStorage(size_t size) { |
| 48 | Item item; |
| 49 | item.mType = TYPE_STORAGE; |
| 50 | item.mObj = NULL; |
| 51 | item.mPtr = malloc(size); |
| 52 | mItems.push_back(item); |
| 53 | |
| 54 | return item.mPtr; |
| 55 | } |
| 56 | |
| 57 | const hidl_string *EphemeralStorage::allocTemporaryString( |
| 58 | JNIEnv *env, jstring stringObj) { |
| 59 | jstring obj = (jstring)env->NewGlobalRef(stringObj); |
| 60 | const char *val = env->GetStringUTFChars(obj, NULL); |
| 61 | |
| 62 | Item item; |
| 63 | item.mType = TYPE_STRING; |
| 64 | item.mObj = obj; |
| 65 | item.mPtr = (void *)val; |
| 66 | mItems.push_back(item); |
| 67 | |
| 68 | hidl_string *s = allocStringArray(1 /* size */); |
| 69 | s->setToExternal((char *)val, strlen(val)); |
| 70 | |
| 71 | return s; |
| 72 | } |
| 73 | |
Nirav Atre | 9850dd9 | 2018-07-24 17:03:44 -0700 | [diff] [blame^] | 74 | native_handle_t *EphemeralStorage::allocTemporaryNativeHandle( |
| 75 | int numFds, int numInts) { |
| 76 | Item item; |
| 77 | item.mType = TYPE_NATIVE_HANDLE; |
| 78 | item.mObj = nullptr; |
| 79 | item.mPtr = native_handle_create(numFds, numInts); |
| 80 | mItems.push_back(item); |
| 81 | |
| 82 | return static_cast<native_handle_t*>(item.mPtr); |
| 83 | } |
| 84 | |
Andreas Huber | dab5fc6 | 2016-08-15 09:25:02 -0700 | [diff] [blame] | 85 | #define DEFINE_ALLOC_VECTOR_METHODS(Suffix,Type,NewType) \ |
| 86 | const hidl_vec<Type> *EphemeralStorage::allocTemporary ## Suffix ## Vector( \ |
| 87 | JNIEnv *env, Type ## Array arrayObj) { \ |
| 88 | Type ## Array obj = (Type ## Array)env->NewGlobalRef(arrayObj); \ |
| 89 | jsize len = env->GetArrayLength(obj); \ |
| 90 | const Type *val = env->Get ## NewType ## ArrayElements(obj, NULL); \ |
| 91 | \ |
| 92 | Item item; \ |
| 93 | item.mType = TYPE_ ## Suffix ## _ARRAY; \ |
| 94 | item.mObj = obj; \ |
| 95 | item.mPtr = (void *)val; \ |
| 96 | mItems.push_back(item); \ |
| 97 | \ |
Andreas Huber | 9266f99 | 2016-08-25 11:21:21 -0700 | [diff] [blame] | 98 | void *vecPtr = allocTemporaryStorage(sizeof(hidl_vec<Type>)); \ |
Andreas Huber | dab5fc6 | 2016-08-15 09:25:02 -0700 | [diff] [blame] | 99 | \ |
Andreas Huber | 9266f99 | 2016-08-25 11:21:21 -0700 | [diff] [blame] | 100 | hidl_vec<Type> *vec = new (vecPtr) hidl_vec<Type>; \ |
Andreas Huber | dab5fc6 | 2016-08-15 09:25:02 -0700 | [diff] [blame] | 101 | vec->setToExternal(const_cast<Type *>(val), len); \ |
| 102 | \ |
| 103 | return vec; \ |
| 104 | } |
| 105 | |
Andreas Huber | dab5fc6 | 2016-08-15 09:25:02 -0700 | [diff] [blame] | 106 | DEFINE_ALLOC_VECTOR_METHODS(Int8,jbyte,Byte) |
| 107 | DEFINE_ALLOC_VECTOR_METHODS(Int16,jshort,Short) |
| 108 | DEFINE_ALLOC_VECTOR_METHODS(Int32,jint,Int) |
| 109 | DEFINE_ALLOC_VECTOR_METHODS(Int64,jlong,Long) |
| 110 | DEFINE_ALLOC_VECTOR_METHODS(Float,jfloat,Float) |
| 111 | DEFINE_ALLOC_VECTOR_METHODS(Double,jdouble,Double) |
| 112 | |
| 113 | #define DEFINE_RELEASE_ARRAY_CASE(Suffix,Type,NewType) \ |
| 114 | case TYPE_ ## Suffix ## _ARRAY: \ |
| 115 | { \ |
| 116 | env->Release ## NewType ## ArrayElements( \ |
| 117 | (Type ## Array)item.mObj, \ |
| 118 | (Type *)item.mPtr, \ |
| 119 | 0 /* mode */); \ |
| 120 | \ |
| 121 | env->DeleteGlobalRef(item.mObj); \ |
| 122 | break; \ |
| 123 | } |
| 124 | |
Ivan Lozano | 9a2094d | 2017-11-08 09:48:11 -0800 | [diff] [blame] | 125 | __attribute__((no_sanitize("unsigned-integer-overflow"))) |
Andreas Huber | dab5fc6 | 2016-08-15 09:25:02 -0700 | [diff] [blame] | 126 | void EphemeralStorage::release(JNIEnv *env) { |
| 127 | for (size_t i = mItems.size(); i--;) { |
| 128 | const Item &item = mItems[i]; |
| 129 | |
| 130 | switch (item.mType) { |
| 131 | case TYPE_STRING_ARRAY: |
| 132 | { |
| 133 | delete[] static_cast<hidl_string *>(item.mPtr); |
| 134 | break; |
| 135 | } |
| 136 | |
| 137 | case TYPE_STORAGE: |
| 138 | { |
| 139 | free(item.mPtr); |
| 140 | break; |
| 141 | } |
| 142 | |
| 143 | case TYPE_STRING: |
| 144 | { |
| 145 | env->ReleaseStringUTFChars( |
| 146 | (jstring)item.mObj, (const char *)item.mPtr); |
| 147 | |
| 148 | env->DeleteGlobalRef(item.mObj); |
| 149 | break; |
| 150 | } |
| 151 | |
| 152 | DEFINE_RELEASE_ARRAY_CASE(Int8,jbyte,Byte) |
| 153 | DEFINE_RELEASE_ARRAY_CASE(Int16,jshort,Short) |
| 154 | DEFINE_RELEASE_ARRAY_CASE(Int32,jint,Int) |
| 155 | DEFINE_RELEASE_ARRAY_CASE(Int64,jlong,Long) |
| 156 | DEFINE_RELEASE_ARRAY_CASE(Float,jfloat,Float) |
| 157 | DEFINE_RELEASE_ARRAY_CASE(Double,jdouble,Double) |
| 158 | |
Nirav Atre | 9850dd9 | 2018-07-24 17:03:44 -0700 | [diff] [blame^] | 159 | case TYPE_NATIVE_HANDLE: |
| 160 | { |
| 161 | int err = native_handle_delete(static_cast<native_handle_t *>(item.mPtr)); |
| 162 | CHECK(err == 0); |
| 163 | break; |
| 164 | } |
| 165 | |
Andreas Huber | dab5fc6 | 2016-08-15 09:25:02 -0700 | [diff] [blame] | 166 | default: |
| 167 | CHECK(!"Should not be here"); |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | mItems.clear(); |
| 172 | } |
| 173 | |
| 174 | } // namespace android |
| 175 | |