Merge "libbinder: remove INT32_MAX definition"
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 643a956..e5646ef 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -73,6 +73,7 @@
// or dessert updates. Instead, apex users should use libbinder_ndk.
apex_available: [
"//apex_available:platform",
+ "com.android.vndk.current",
// TODO(b/139016109) remove these three
"com.android.media.swcodec",
"test_com.android.media.swcodec",
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 684f467..9b47f80 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -505,7 +505,7 @@
}
}
-#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || (defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__))
constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
#else
constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
@@ -746,61 +746,37 @@
return writeUtf8AsUtf16(*str);
}
-namespace {
-
-template<typename T>
-status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val)
-{
- status_t status;
- if (val.size() > std::numeric_limits<int32_t>::max()) {
- status = BAD_VALUE;
- return status;
+status_t Parcel::writeByteVectorInternal(const int8_t* data, size_t size) {
+ if (size > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
}
- status = parcel->writeInt32(val.size());
+ status_t status = writeInt32(size);
if (status != OK) {
return status;
}
- void* data = parcel->writeInplace(val.size());
- if (!data) {
- status = BAD_VALUE;
- return status;
- }
-
- memcpy(data, val.data(), val.size());
- return status;
+ return write(data, size);
}
-template<typename T>
-status_t writeByteVectorInternalPtr(Parcel* parcel,
- const std::unique_ptr<std::vector<T>>& val)
-{
- if (!val) {
- return parcel->writeInt32(-1);
- }
-
- return writeByteVectorInternal(parcel, *val);
-}
-
-} // namespace
-
status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
- return writeByteVectorInternal(this, val);
+ return writeByteVectorInternal(val.data(), val.size());
}
status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
{
- return writeByteVectorInternalPtr(this, val);
+ if (!val) return writeInt32(-1);
+ return writeByteVectorInternal(val->data(), val->size());
}
status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
- return writeByteVectorInternal(this, val);
+ return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
}
status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
{
- return writeByteVectorInternalPtr(this, val);
+ if (!val) return writeInt32(-1);
+ return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
}
status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
@@ -1473,81 +1449,41 @@
return err;
}
-namespace {
-
-template<typename T>
-status_t readByteVectorInternal(const Parcel* parcel,
- std::vector<T>* val) {
- val->clear();
-
- int32_t size;
- status_t status = parcel->readInt32(&size);
-
- if (status != OK) {
- return status;
+status_t Parcel::readByteVectorInternal(int8_t* data, size_t size) const {
+ if (size_t(size) > dataAvail()) {
+ return BAD_VALUE;
}
-
- if (size < 0) {
- status = UNEXPECTED_NULL;
- return status;
- }
- if (size_t(size) > parcel->dataAvail()) {
- status = BAD_VALUE;
- return status;
- }
-
- T* data = const_cast<T*>(reinterpret_cast<const T*>(parcel->readInplace(size)));
- if (!data) {
- status = BAD_VALUE;
- return status;
- }
- val->reserve(size);
- val->insert(val->end(), data, data + size);
-
- return status;
+ return read(data, size);
}
-template<typename T>
-status_t readByteVectorInternalPtr(
- const Parcel* parcel,
- std::unique_ptr<std::vector<T>>* val) {
- const int32_t start = parcel->dataPosition();
- int32_t size;
- status_t status = parcel->readInt32(&size);
- val->reset();
-
- if (status != OK || size < 0) {
- return status;
- }
-
- parcel->setDataPosition(start);
- val->reset(new (std::nothrow) std::vector<T>());
-
- status = readByteVectorInternal(parcel, val->get());
-
- if (status != OK) {
- val->reset();
- }
-
- return status;
-}
-
-} // namespace
-
status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
- return readByteVectorInternal(this, val);
+ if (status_t status = resizeOutVector(val); status != OK) return status;
+ return readByteVectorInternal(val->data(), val->size());
}
status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
- return readByteVectorInternal(this, val);
+ if (status_t status = resizeOutVector(val); status != OK) return status;
+ return readByteVectorInternal(reinterpret_cast<int8_t*>(val->data()), val->size());
}
status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
- return readByteVectorInternalPtr(this, val);
+ if (status_t status = resizeOutVector(val); status != OK) return status;
+ if (val->get() == nullptr) {
+ // resizeOutVector does not create the out vector if size is < 0.
+ // This occurs when writing a null byte vector.
+ return OK;
+ }
+ return readByteVectorInternal((*val)->data(), (*val)->size());
}
status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
- return readByteVectorInternalPtr(this, val);
+ if (status_t status = resizeOutVector(val); status != OK) return status;
+ if (val->get() == nullptr) {
+ // resizeOutVector does not create the out vector if size is < 0.
+ // This occurs when writing a null byte vector.
+ return OK;
+ }
+ return readByteVectorInternal(reinterpret_cast<int8_t*>((*val)->data()), (*val)->size());
}
status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 8726681..0f8abab 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -19,6 +19,7 @@
#include <map> // for legacy reasons
#include <string>
+#include <type_traits>
#include <vector>
#include <android-base/unique_fd.h>
@@ -157,6 +158,18 @@
status_t writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);
status_t writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
+ // Write an Enum vector with underlying type int8_t.
+ // Does not use padding; each byte is contiguous.
+ template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+ status_t writeEnumVector(const std::vector<T>& val);
+ template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+ status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
+ // Write an Enum vector with underlying type != int8_t.
+ template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+ status_t writeEnumVector(const std::vector<T>& val);
+ template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+ status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
+
template<typename T>
status_t writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val);
template<typename T>
@@ -275,6 +288,19 @@
status_t readStrongBinder(sp<IBinder>* val) const;
status_t readNullableStrongBinder(sp<IBinder>* val) const;
+
+ // Read an Enum vector with underlying type int8_t.
+ // Does not use padding; each byte is contiguous.
+ template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+ status_t readEnumVector(std::vector<T>* val) const;
+ template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+ status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
+ // Read an Enum vector with underlying type != int8_t.
+ template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+ status_t readEnumVector(std::vector<T>* val) const;
+ template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+ status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
+
template<typename T>
status_t readParcelableVector(
std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const;
@@ -438,6 +464,19 @@
status_t writeRawNullableParcelable(const Parcelable*
parcelable);
+ template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool> = 0>
+ status_t writeEnum(const T& val);
+ template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool> = 0>
+ status_t writeEnum(const T& val);
+
+ template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool> = 0>
+ status_t readEnum(T* pArg) const;
+ template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool> = 0>
+ status_t readEnum(T* pArg) const;
+
+ status_t writeByteVectorInternal(const int8_t* data, size_t size);
+ status_t readByteVectorInternal(int8_t* data, size_t size) const;
+
template<typename T, typename U>
status_t unsafeReadTypedVector(std::vector<T>* val,
status_t(Parcel::*read_func)(U*) const) const;
@@ -913,6 +952,66 @@
return unsafeWriteTypedVector(*val, &Parcel::writeNullableParcelable<T>);
}
+template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>>
+status_t Parcel::writeEnum(const T& val) {
+ return writeInt32(static_cast<int32_t>(val));
+}
+template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool>>
+status_t Parcel::writeEnum(const T& val) {
+ return writeInt64(static_cast<int64_t>(val));
+}
+
+template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::writeEnumVector(const std::vector<T>& val) {
+ return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) {
+ if (!val) return writeInt32(-1);
+ return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::writeEnumVector(const std::vector<T>& val) {
+ return writeTypedVector(val, &Parcel::writeEnum);
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) {
+ return writeNullableTypedVector(val, &Parcel::writeEnum);
+}
+
+template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>>
+status_t Parcel::readEnum(T* pArg) const {
+ return readInt32(reinterpret_cast<int32_t *>(pArg));
+}
+template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool>>
+status_t Parcel::readEnum(T* pArg) const {
+ return readInt64(reinterpret_cast<int64_t *>(pArg));
+}
+
+template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::readEnumVector(std::vector<T>* val) const {
+ if (status_t status = resizeOutVector(val); status != OK) return status;
+ return readByteVectorInternal(reinterpret_cast<int8_t*>(val->data()), val->size());
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const {
+ if (status_t status = resizeOutVector(val); status != OK) return status;
+ if (val->get() == nullptr) {
+ // resizeOutVector does not create the out vector if size is < 0.
+ // This occurs when writing a null Enum vector.
+ return OK;
+ }
+ return readByteVectorInternal(reinterpret_cast<int8_t*>((*val)->data()), (*val)->size());
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::readEnumVector(std::vector<T>* val) const {
+ return readTypedVector(val, &Parcel::readEnum);
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const {
+ return readNullableTypedVector(val, &Parcel::readEnum);
+}
+
// ---------------------------------------------------------------------------
inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index 2894482..b2f51d3 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -81,7 +81,7 @@
VINTF = 0b111111,
};
-#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || (defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__))
static constexpr Level kLocalStability = Level::VENDOR;
#else
static constexpr Level kLocalStability = Level::SYSTEM;
diff --git a/libs/binder/ndk/include_platform/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h
index b03fce1..924812e 100644
--- a/libs/binder/ndk/include_platform/android/binder_stability.h
+++ b/libs/binder/ndk/include_platform/android/binder_stability.h
@@ -20,7 +20,8 @@
__BEGIN_DECLS
-#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || \
+ (defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__))
/**
* This interface has the stability of the vendor image.
@@ -31,7 +32,8 @@
AIBinder_markVendorStability(binder);
}
-#else // defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#else // defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || (defined(__ANDROID_VNDK__) &&
+ // !defined(__ANDROID_APEX__))
/**
* This interface has the stability of the system image.
@@ -42,7 +44,8 @@
AIBinder_markSystemStability(binder);
}
-#endif // defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#endif // defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || (defined(__ANDROID_VNDK__) &&
+ // !defined(__ANDROID_APEX__))
/**
* This interface has system<->vendor stability