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