blob: 392e0187352e11acbfd600156dc210d04d05722e [file] [log] [blame] [edit]
/*
* Copyright (C) 2024 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 <binder/Parcel.h>
#include <binder/PersistableBundle.h>
#include <gtest/gtest.h>
#include <numeric>
using android::OK;
using android::Parcel;
using android::status_t;
using android::String16;
using android::String8;
using android::os::PersistableBundle;
namespace android {
inline std::string to_string(String16 const& str) {
return String8{str}.c_str();
}
namespace os {
template <typename T>
inline std::ostream& operator<<(std::ostream& out, std::vector<T> const& vec) {
using std::to_string;
auto str =
std::accumulate(vec.begin(), vec.end(), std::string{},
[](std::string const& a, auto const& b) { return a + to_string(b); });
return out << str;
}
inline std::ostream& operator<<(std::ostream& out, PersistableBundle const& pb) {
#define PRINT(TYPENAME, TYPE) \
for (auto const& key : pb.get##TYPENAME##Keys()) { \
TYPE val{}; \
pb.get##TYPENAME(key, &val); \
out << #TYPE " " << key << ": " << val << std::endl; \
}
out << "size: " << pb.size() << std::endl;
PRINT(Boolean, bool);
PRINT(Int, int);
PRINT(Long, int64_t);
PRINT(Double, double);
PRINT(String, String16);
PRINT(BooleanVector, std::vector<bool>);
PRINT(IntVector, std::vector<int32_t>);
PRINT(LongVector, std::vector<int64_t>);
PRINT(DoubleVector, std::vector<double>);
PRINT(StringVector, std::vector<String16>);
PRINT(PersistableBundle, PersistableBundle);
#undef PRINT
return out;
}
} // namespace os
} // namespace android
static const String16 kKey{"key"};
static PersistableBundle createSimplePersistableBundle() {
PersistableBundle pb{};
pb.putInt(kKey, 64);
return pb;
}
#define TEST_PUT_AND_GET(TYPENAME, TYPE, ...) \
TEST(PersistableBundle, PutAndGet##TYPENAME) { \
TYPE const expected{__VA_ARGS__}; \
PersistableBundle pb{}; \
\
pb.put##TYPENAME(kKey, expected); \
\
std::set<String16> expectedKeys{kKey}; \
EXPECT_EQ(pb.get##TYPENAME##Keys(), expectedKeys); \
\
TYPE val{}; \
EXPECT_TRUE(pb.get##TYPENAME(kKey, &val)); \
EXPECT_EQ(val, expected); \
}
TEST_PUT_AND_GET(Boolean, bool, true);
TEST_PUT_AND_GET(Int, int, 64);
TEST_PUT_AND_GET(Long, int64_t, 42);
TEST_PUT_AND_GET(Double, double, 42.64);
TEST_PUT_AND_GET(String, String16, String16{"foo"});
TEST_PUT_AND_GET(BooleanVector, std::vector<bool>, true, true);
TEST_PUT_AND_GET(IntVector, std::vector<int32_t>, 1, 2);
TEST_PUT_AND_GET(LongVector, std::vector<int64_t>, 1, 2);
TEST_PUT_AND_GET(DoubleVector, std::vector<double>, 4.2, 5.9);
TEST_PUT_AND_GET(StringVector, std::vector<String16>, String16{"foo"}, String16{"bar"});
TEST_PUT_AND_GET(PersistableBundle, PersistableBundle, createSimplePersistableBundle());
TEST(PersistableBundle, ParcelAndUnparcel) {
PersistableBundle expected = createSimplePersistableBundle();
PersistableBundle out{};
Parcel p{};
EXPECT_EQ(expected.writeToParcel(&p), 0);
p.setDataPosition(0);
EXPECT_EQ(out.readFromParcel(&p), 0);
EXPECT_EQ(expected, out);
}
TEST(PersistableBundle, OverwriteKey) {
PersistableBundle pb{};
pb.putInt(kKey, 64);
pb.putDouble(kKey, 0.5);
EXPECT_EQ(pb.getIntKeys().size(), 0);
EXPECT_EQ(pb.getDoubleKeys().size(), 1);
double out;
EXPECT_TRUE(pb.getDouble(kKey, &out));
EXPECT_EQ(out, 0.5);
}