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 74 #define DEFINE_ALLOC_VECTOR_METHODS(Suffix,Type,NewType) \ 75 const hidl_vec<Type> *EphemeralStorage::allocTemporary ## Suffix ## Vector( \ 76 JNIEnv *env, Type ## Array arrayObj) { \ 77 Type ## Array obj = (Type ## Array)env->NewGlobalRef(arrayObj); \ 78 jsize len = env->GetArrayLength(obj); \ 79 const Type *val = env->Get ## NewType ## ArrayElements(obj, NULL); \ 80 \ 81 Item item; \ 82 item.mType = TYPE_ ## Suffix ## _ARRAY; \ 83 item.mObj = obj; \ 84 item.mPtr = (void *)val; \ 85 mItems.push_back(item); \ 86 \ 87 void *vecPtr = allocTemporaryStorage(sizeof(hidl_vec<Type>)); \ 88 \ 89 hidl_vec<Type> *vec = new (vecPtr) hidl_vec<Type>; \ 90 vec->setToExternal(const_cast<Type *>(val), len); \ 91 \ 92 return vec; \ 93 } 94 95 DEFINE_ALLOC_VECTOR_METHODS(Int8,jbyte,Byte) 96 DEFINE_ALLOC_VECTOR_METHODS(Int16,jshort,Short) 97 DEFINE_ALLOC_VECTOR_METHODS(Int32,jint,Int) 98 DEFINE_ALLOC_VECTOR_METHODS(Int64,jlong,Long) 99 DEFINE_ALLOC_VECTOR_METHODS(Float,jfloat,Float) 100 DEFINE_ALLOC_VECTOR_METHODS(Double,jdouble,Double) 101 102 #define DEFINE_RELEASE_ARRAY_CASE(Suffix,Type,NewType) \ 103 case TYPE_ ## Suffix ## _ARRAY: \ 104 { \ 105 env->Release ## NewType ## ArrayElements( \ 106 (Type ## Array)item.mObj, \ 107 (Type *)item.mPtr, \ 108 0 /* mode */); \ 109 \ 110 env->DeleteGlobalRef(item.mObj); \ 111 break; \ 112 } 113 114 void EphemeralStorage::release(JNIEnv *env) { 115 for (size_t i = mItems.size(); i--;) { 116 const Item &item = mItems[i]; 117 118 switch (item.mType) { 119 case TYPE_STRING_ARRAY: 120 { 121 delete[] static_cast<hidl_string *>(item.mPtr); 122 break; 123 } 124 125 case TYPE_STORAGE: 126 { 127 free(item.mPtr); 128 break; 129 } 130 131 case TYPE_STRING: 132 { 133 env->ReleaseStringUTFChars( 134 (jstring)item.mObj, (const char *)item.mPtr); 135 136 env->DeleteGlobalRef(item.mObj); 137 break; 138 } 139 140 DEFINE_RELEASE_ARRAY_CASE(Int8,jbyte,Byte) 141 DEFINE_RELEASE_ARRAY_CASE(Int16,jshort,Short) 142 DEFINE_RELEASE_ARRAY_CASE(Int32,jint,Int) 143 DEFINE_RELEASE_ARRAY_CASE(Int64,jlong,Long) 144 DEFINE_RELEASE_ARRAY_CASE(Float,jfloat,Float) 145 DEFINE_RELEASE_ARRAY_CASE(Double,jdouble,Double) 146 147 default: 148 CHECK(!"Should not be here"); 149 } 150 } 151 152 mItems.clear(); 153 } 154 155 } // namespace android 156 157