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