/* * 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 #include #include #include 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 inline std::ostream& operator<<(std::ostream& out, std::vector 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); PRINT(IntVector, std::vector); PRINT(LongVector, std::vector); PRINT(DoubleVector, std::vector); PRINT(StringVector, std::vector); 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 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, true, true); TEST_PUT_AND_GET(IntVector, std::vector, 1, 2); TEST_PUT_AND_GET(LongVector, std::vector, 1, 2); TEST_PUT_AND_GET(DoubleVector, std::vector, 4.2, 5.9); TEST_PUT_AND_GET(StringVector, std::vector, 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); }