Add PersistableBundle ndk and AIDL type
Add the new APersistableBundle NDK type for the new AIDL
PersistableBundle.
Test: atest CtsNdkBinderTestCases
Bug: 306401400
Change-Id: I6b9204d8b36f224de610338d2184e73f16ca56d0
diff --git a/libs/binder/ndk/persistable_bundle.cpp b/libs/binder/ndk/persistable_bundle.cpp
new file mode 100644
index 0000000..404611c
--- /dev/null
+++ b/libs/binder/ndk/persistable_bundle.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android/binder_libbinder.h>
+#include <android/persistable_bundle.h>
+#include <binder/PersistableBundle.h>
+#include <log/log.h>
+#include <persistable_bundle_internal.h>
+#include <string.h>
+
+#include <set>
+
+__BEGIN_DECLS
+
+struct APersistableBundle {
+ APersistableBundle(const APersistableBundle& pBundle) : mPBundle(pBundle.mPBundle) {}
+ APersistableBundle(const android::os::PersistableBundle& pBundle) : mPBundle(pBundle) {}
+ APersistableBundle() = default;
+ android::os::PersistableBundle mPBundle;
+};
+
+APersistableBundle* _Nullable APersistableBundle_new() {
+ return new (std::nothrow) APersistableBundle();
+}
+
+APersistableBundle* _Nullable APersistableBundle_dup(const APersistableBundle* pBundle) {
+ if (pBundle) {
+ return new APersistableBundle(*pBundle);
+ } else {
+ return new APersistableBundle();
+ }
+}
+
+void APersistableBundle_delete(APersistableBundle* pBundle) {
+ free(pBundle);
+}
+
+bool APersistableBundle_isEqual(const APersistableBundle* lhs, const APersistableBundle* rhs) {
+ if (lhs && rhs) {
+ return lhs->mPBundle == rhs->mPBundle;
+ } else if (lhs == rhs) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+binder_status_t APersistableBundle_readFromParcel(const AParcel* parcel,
+ APersistableBundle* _Nullable* outPBundle) {
+ if (!parcel || !outPBundle) return STATUS_BAD_VALUE;
+ APersistableBundle* newPBundle = APersistableBundle_new();
+ if (newPBundle == nullptr) return STATUS_NO_MEMORY;
+ binder_status_t status =
+ newPBundle->mPBundle.readFromParcel(AParcel_viewPlatformParcel(parcel));
+ if (status == STATUS_OK) {
+ *outPBundle = newPBundle;
+ }
+ return status;
+}
+
+binder_status_t APersistableBundle_writeToParcel(const APersistableBundle* pBundle,
+ AParcel* parcel) {
+ if (!parcel || !pBundle) return STATUS_BAD_VALUE;
+ return pBundle->mPBundle.writeToParcel(AParcel_viewPlatformParcel(parcel));
+}
+
+int32_t APersistableBundle_size(APersistableBundle* pBundle) {
+ size_t size = pBundle->mPBundle.size();
+ LOG_ALWAYS_FATAL_IF(size > INT32_MAX,
+ "The APersistableBundle has gotten too large! There will be an overflow in "
+ "the reported size.");
+ return pBundle->mPBundle.size();
+}
+int32_t APersistableBundle_erase(APersistableBundle* pBundle, const char* key) {
+ return pBundle->mPBundle.erase(android::String16(key));
+}
+void APersistableBundle_putBoolean(APersistableBundle* pBundle, const char* key, bool val) {
+ pBundle->mPBundle.putBoolean(android::String16(key), val);
+}
+void APersistableBundle_putInt(APersistableBundle* pBundle, const char* key, int32_t val) {
+ pBundle->mPBundle.putInt(android::String16(key), val);
+}
+void APersistableBundle_putLong(APersistableBundle* pBundle, const char* key, int64_t val) {
+ pBundle->mPBundle.putLong(android::String16(key), val);
+}
+void APersistableBundle_putDouble(APersistableBundle* pBundle, const char* key, double val) {
+ pBundle->mPBundle.putDouble(android::String16(key), val);
+}
+void APersistableBundle_putString(APersistableBundle* pBundle, const char* key, const char* val) {
+ pBundle->mPBundle.putString(android::String16(key), android::String16(val));
+}
+void APersistableBundle_putBooleanVector(APersistableBundle* pBundle, const char* key,
+ const bool* vec, int32_t num) {
+ LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
+ std::vector<bool> newVec(num);
+ for (int32_t i = 0; i < num; i++) {
+ newVec[i] = vec[i];
+ }
+ pBundle->mPBundle.putBooleanVector(android::String16(key), newVec);
+}
+void APersistableBundle_putIntVector(APersistableBundle* pBundle, const char* key,
+ const int32_t* vec, int32_t num) {
+ LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
+ std::vector<int32_t> newVec(num);
+ for (int32_t i = 0; i < num; i++) {
+ newVec[i] = vec[i];
+ }
+ pBundle->mPBundle.putIntVector(android::String16(key), newVec);
+}
+void APersistableBundle_putLongVector(APersistableBundle* pBundle, const char* key,
+ const int64_t* vec, int32_t num) {
+ LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
+ std::vector<int64_t> newVec(num);
+ for (int32_t i = 0; i < num; i++) {
+ newVec[i] = vec[i];
+ }
+ pBundle->mPBundle.putLongVector(android::String16(key), newVec);
+}
+void APersistableBundle_putDoubleVector(APersistableBundle* pBundle, const char* key,
+ const double* vec, int32_t num) {
+ LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
+ std::vector<double> newVec(num);
+ for (int32_t i = 0; i < num; i++) {
+ newVec[i] = vec[i];
+ }
+ pBundle->mPBundle.putDoubleVector(android::String16(key), newVec);
+}
+void APersistableBundle_putStringVector(APersistableBundle* pBundle, const char* key,
+ const char* const* vec, int32_t num) {
+ LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
+ std::vector<android::String16> newVec(num);
+ for (int32_t i = 0; i < num; i++) {
+ newVec[i] = android::String16(vec[i]);
+ }
+ pBundle->mPBundle.putStringVector(android::String16(key), newVec);
+}
+void APersistableBundle_putPersistableBundle(APersistableBundle* pBundle, const char* key,
+ const APersistableBundle* val) {
+ pBundle->mPBundle.putPersistableBundle(android::String16(key), val->mPBundle);
+}
+bool APersistableBundle_getBoolean(const APersistableBundle* pBundle, const char* key, bool* val) {
+ return pBundle->mPBundle.getBoolean(android::String16(key), val);
+}
+bool APersistableBundle_getInt(const APersistableBundle* pBundle, const char* key, int32_t* val) {
+ return pBundle->mPBundle.getInt(android::String16(key), val);
+}
+bool APersistableBundle_getLong(const APersistableBundle* pBundle, const char* key, int64_t* val) {
+ return pBundle->mPBundle.getLong(android::String16(key), val);
+}
+bool APersistableBundle_getDouble(const APersistableBundle* pBundle, const char* key, double* val) {
+ return pBundle->mPBundle.getDouble(android::String16(key), val);
+}
+int32_t APersistableBundle_getString(const APersistableBundle* pBundle, const char* key, char** val,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ android::String16 outVal;
+ bool ret = pBundle->mPBundle.getString(android::String16(key), &outVal);
+ if (ret) {
+ android::String8 tmp8(outVal);
+ *val = stringAllocator(tmp8.bytes() + 1, context);
+ if (*val) {
+ strncpy(*val, tmp8.c_str(), tmp8.bytes() + 1);
+ return tmp8.bytes();
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
+int32_t APersistableBundle_getBooleanVector(const APersistableBundle* pBundle, const char* key,
+ bool* buffer, int32_t bufferSizeBytes) {
+ std::vector<bool> newVec;
+ pBundle->mPBundle.getBooleanVector(android::String16(key), &newVec);
+ return getVecInternal<bool>(newVec, buffer, bufferSizeBytes);
+}
+int32_t APersistableBundle_getIntVector(const APersistableBundle* pBundle, const char* key,
+ int32_t* buffer, int32_t bufferSizeBytes) {
+ std::vector<int32_t> newVec;
+ pBundle->mPBundle.getIntVector(android::String16(key), &newVec);
+ return getVecInternal<int32_t>(newVec, buffer, bufferSizeBytes);
+}
+int32_t APersistableBundle_getLongVector(const APersistableBundle* pBundle, const char* key,
+ int64_t* buffer, int32_t bufferSizeBytes) {
+ std::vector<int64_t> newVec;
+ pBundle->mPBundle.getLongVector(android::String16(key), &newVec);
+ return getVecInternal<int64_t>(newVec, buffer, bufferSizeBytes);
+}
+int32_t APersistableBundle_getDoubleVector(const APersistableBundle* pBundle, const char* key,
+ double* buffer, int32_t bufferSizeBytes) {
+ std::vector<double> newVec;
+ pBundle->mPBundle.getDoubleVector(android::String16(key), &newVec);
+ return getVecInternal<double>(newVec, buffer, bufferSizeBytes);
+}
+int32_t APersistableBundle_getStringVector(const APersistableBundle* pBundle, const char* key,
+ char** vec, int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::vector<android::String16> newVec;
+ pBundle->mPBundle.getStringVector(android::String16(key), &newVec);
+ return getStringsInternal<std::vector<android::String16>>(newVec, vec, bufferSizeBytes,
+ stringAllocator, context);
+}
+bool APersistableBundle_getPersistableBundle(const APersistableBundle* pBundle, const char* key,
+ APersistableBundle** outBundle) {
+ APersistableBundle* bundle = APersistableBundle_new();
+ bool ret = pBundle->mPBundle.getPersistableBundle(android::String16(key), &bundle->mPBundle);
+ if (ret) {
+ *outBundle = bundle;
+ return true;
+ }
+ return false;
+}
+int32_t APersistableBundle_getBooleanKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getBooleanKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getIntKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getIntKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getLongKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getLongKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getDoubleKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getDoubleKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getStringKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getStringKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getBooleanVectorKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getBooleanVectorKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getIntVectorKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getIntVectorKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getLongVectorKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getLongVectorKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getDoubleVectorKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getDoubleVectorKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getStringVectorKeys(const APersistableBundle* pBundle, char** outKeys,
+ int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator,
+ void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getStringVectorKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+int32_t APersistableBundle_getPersistableBundleKeys(
+ const APersistableBundle* pBundle, char** outKeys, int32_t bufferSizeBytes,
+ APersistableBundle_stringAllocator stringAllocator, void* context) {
+ std::set<android::String16> ret = pBundle->mPBundle.getPersistableBundleKeys();
+ return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
+ stringAllocator, context);
+}
+
+__END_DECLS