1dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber/* 2dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * Copyright (C) 2016 The Android Open Source Project 3dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * 4dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * you may not use this file except in compliance with the License. 6dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * You may obtain a copy of the License at 7dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * 8dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * 10dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * Unless required by applicable law or agreed to in writing, software 11dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * See the License for the specific language governing permissions and 14dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * limitations under the License. 15dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber */ 16dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 17dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define LOG_TAG "EphemeralStorage" 18dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber//#define LOG_NDEBUG 0 19dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 20dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include <android-base/logging.h> 21dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 22dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include "EphemeralStorage.h" 23dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 24dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberusing ::android::hardware::hidl_string; 25dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberusing ::android::hardware::hidl_vec; 26dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 27dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubernamespace android { 28dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 29dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberEphemeralStorage::EphemeralStorage() { 30dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} 31dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 32dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberEphemeralStorage::~EphemeralStorage() { 33dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber CHECK(mItems.empty()) 34dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber << "All item storage should have been released by now."; 35dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} 36dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 37dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberhidl_string *EphemeralStorage::allocStringArray(size_t size) { 38dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber Item item; 39dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mType = TYPE_STRING_ARRAY; 40dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mObj = NULL; 41dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mPtr = new hidl_string[size]; 42dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber mItems.push_back(item); 43dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 44dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber return static_cast<hidl_string *>(item.mPtr); 45dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} 46dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 47dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubervoid *EphemeralStorage::allocTemporaryStorage(size_t size) { 48dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber Item item; 49dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mType = TYPE_STORAGE; 50dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mObj = NULL; 51dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mPtr = malloc(size); 52dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber mItems.push_back(item); 53dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 54dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber return item.mPtr; 55dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} 56dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 57dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberconst hidl_string *EphemeralStorage::allocTemporaryString( 58dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber JNIEnv *env, jstring stringObj) { 59dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber jstring obj = (jstring)env->NewGlobalRef(stringObj); 60dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber const char *val = env->GetStringUTFChars(obj, NULL); 61dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 62dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber Item item; 63dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mType = TYPE_STRING; 64dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mObj = obj; 65dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mPtr = (void *)val; 66dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber mItems.push_back(item); 67dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 68dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber hidl_string *s = allocStringArray(1 /* size */); 69dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber s->setToExternal((char *)val, strlen(val)); 70dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 71dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber return s; 72dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} 73dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 74dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define DEFINE_ALLOC_VECTOR_METHODS(Suffix,Type,NewType) \ 75dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberconst hidl_vec<Type> *EphemeralStorage::allocTemporary ## Suffix ## Vector( \ 76dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber JNIEnv *env, Type ## Array arrayObj) { \ 77dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber Type ## Array obj = (Type ## Array)env->NewGlobalRef(arrayObj); \ 78dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber jsize len = env->GetArrayLength(obj); \ 79dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber const Type *val = env->Get ## NewType ## ArrayElements(obj, NULL); \ 80dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber \ 81dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber Item item; \ 82dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mType = TYPE_ ## Suffix ## _ARRAY; \ 83dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mObj = obj; \ 84dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber item.mPtr = (void *)val; \ 85dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber mItems.push_back(item); \ 86dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber \ 879266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber void *vecPtr = allocTemporaryStorage(sizeof(hidl_vec<Type>)); \ 88dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber \ 899266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber hidl_vec<Type> *vec = new (vecPtr) hidl_vec<Type>; \ 90dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber vec->setToExternal(const_cast<Type *>(val), len); \ 91dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber \ 92dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber return vec; \ 93dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} 94dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 95dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_ALLOC_VECTOR_METHODS(Int8,jbyte,Byte) 96dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_ALLOC_VECTOR_METHODS(Int16,jshort,Short) 97dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_ALLOC_VECTOR_METHODS(Int32,jint,Int) 98dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_ALLOC_VECTOR_METHODS(Int64,jlong,Long) 99dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_ALLOC_VECTOR_METHODS(Float,jfloat,Float) 100dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_ALLOC_VECTOR_METHODS(Double,jdouble,Double) 101dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 102dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define DEFINE_RELEASE_ARRAY_CASE(Suffix,Type,NewType) \ 103dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber case TYPE_ ## Suffix ## _ARRAY: \ 104dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber { \ 105dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber env->Release ## NewType ## ArrayElements( \ 106dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber (Type ## Array)item.mObj, \ 107dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber (Type *)item.mPtr, \ 108dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 0 /* mode */); \ 109dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber \ 110dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber env->DeleteGlobalRef(item.mObj); \ 111dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber break; \ 112dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber } 113dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 1149a2094d10956b41b659733b60eb814d5aac43d4cIvan Lozano__attribute__((no_sanitize("unsigned-integer-overflow"))) 115dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubervoid EphemeralStorage::release(JNIEnv *env) { 116dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber for (size_t i = mItems.size(); i--;) { 117dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber const Item &item = mItems[i]; 118dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 119dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber switch (item.mType) { 120dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber case TYPE_STRING_ARRAY: 121dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber { 122dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber delete[] static_cast<hidl_string *>(item.mPtr); 123dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber break; 124dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber } 125dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 126dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber case TYPE_STORAGE: 127dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber { 128dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber free(item.mPtr); 129dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber break; 130dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber } 131dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 132dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber case TYPE_STRING: 133dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber { 134dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber env->ReleaseStringUTFChars( 135dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber (jstring)item.mObj, (const char *)item.mPtr); 136dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 137dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber env->DeleteGlobalRef(item.mObj); 138dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber break; 139dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber } 140dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 141dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber DEFINE_RELEASE_ARRAY_CASE(Int8,jbyte,Byte) 142dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber DEFINE_RELEASE_ARRAY_CASE(Int16,jshort,Short) 143dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber DEFINE_RELEASE_ARRAY_CASE(Int32,jint,Int) 144dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber DEFINE_RELEASE_ARRAY_CASE(Int64,jlong,Long) 145dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber DEFINE_RELEASE_ARRAY_CASE(Float,jfloat,Float) 146dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber DEFINE_RELEASE_ARRAY_CASE(Double,jdouble,Double) 147dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 148dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber default: 149dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber CHECK(!"Should not be here"); 150dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber } 151dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber } 152dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 153dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber mItems.clear(); 154dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} 155dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 156dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} // namespace android 157dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber 158