1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2024 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <binder/PersistableBundle.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <numeric>
21*38e8c45fSAndroid Build Coastguard Worker
22*38e8c45fSAndroid Build Coastguard Worker using android::OK;
23*38e8c45fSAndroid Build Coastguard Worker using android::Parcel;
24*38e8c45fSAndroid Build Coastguard Worker using android::status_t;
25*38e8c45fSAndroid Build Coastguard Worker using android::String16;
26*38e8c45fSAndroid Build Coastguard Worker using android::String8;
27*38e8c45fSAndroid Build Coastguard Worker using android::os::PersistableBundle;
28*38e8c45fSAndroid Build Coastguard Worker
29*38e8c45fSAndroid Build Coastguard Worker namespace android {
30*38e8c45fSAndroid Build Coastguard Worker
to_string(String16 const & str)31*38e8c45fSAndroid Build Coastguard Worker inline std::string to_string(String16 const& str) {
32*38e8c45fSAndroid Build Coastguard Worker return String8{str}.c_str();
33*38e8c45fSAndroid Build Coastguard Worker }
34*38e8c45fSAndroid Build Coastguard Worker
35*38e8c45fSAndroid Build Coastguard Worker namespace os {
36*38e8c45fSAndroid Build Coastguard Worker
37*38e8c45fSAndroid Build Coastguard Worker template <typename T>
operator <<(std::ostream & out,std::vector<T> const & vec)38*38e8c45fSAndroid Build Coastguard Worker inline std::ostream& operator<<(std::ostream& out, std::vector<T> const& vec) {
39*38e8c45fSAndroid Build Coastguard Worker using std::to_string;
40*38e8c45fSAndroid Build Coastguard Worker auto str =
41*38e8c45fSAndroid Build Coastguard Worker std::accumulate(vec.begin(), vec.end(), std::string{},
42*38e8c45fSAndroid Build Coastguard Worker [](std::string const& a, auto const& b) { return a + to_string(b); });
43*38e8c45fSAndroid Build Coastguard Worker return out << str;
44*38e8c45fSAndroid Build Coastguard Worker }
45*38e8c45fSAndroid Build Coastguard Worker
operator <<(std::ostream & out,PersistableBundle const & pb)46*38e8c45fSAndroid Build Coastguard Worker inline std::ostream& operator<<(std::ostream& out, PersistableBundle const& pb) {
47*38e8c45fSAndroid Build Coastguard Worker #define PRINT(TYPENAME, TYPE) \
48*38e8c45fSAndroid Build Coastguard Worker for (auto const& key : pb.get##TYPENAME##Keys()) { \
49*38e8c45fSAndroid Build Coastguard Worker TYPE val{}; \
50*38e8c45fSAndroid Build Coastguard Worker pb.get##TYPENAME(key, &val); \
51*38e8c45fSAndroid Build Coastguard Worker out << #TYPE " " << key << ": " << val << std::endl; \
52*38e8c45fSAndroid Build Coastguard Worker }
53*38e8c45fSAndroid Build Coastguard Worker
54*38e8c45fSAndroid Build Coastguard Worker out << "size: " << pb.size() << std::endl;
55*38e8c45fSAndroid Build Coastguard Worker PRINT(Boolean, bool);
56*38e8c45fSAndroid Build Coastguard Worker PRINT(Int, int);
57*38e8c45fSAndroid Build Coastguard Worker PRINT(Long, int64_t);
58*38e8c45fSAndroid Build Coastguard Worker PRINT(Double, double);
59*38e8c45fSAndroid Build Coastguard Worker PRINT(String, String16);
60*38e8c45fSAndroid Build Coastguard Worker PRINT(BooleanVector, std::vector<bool>);
61*38e8c45fSAndroid Build Coastguard Worker PRINT(IntVector, std::vector<int32_t>);
62*38e8c45fSAndroid Build Coastguard Worker PRINT(LongVector, std::vector<int64_t>);
63*38e8c45fSAndroid Build Coastguard Worker PRINT(DoubleVector, std::vector<double>);
64*38e8c45fSAndroid Build Coastguard Worker PRINT(StringVector, std::vector<String16>);
65*38e8c45fSAndroid Build Coastguard Worker PRINT(PersistableBundle, PersistableBundle);
66*38e8c45fSAndroid Build Coastguard Worker
67*38e8c45fSAndroid Build Coastguard Worker #undef PRINT
68*38e8c45fSAndroid Build Coastguard Worker
69*38e8c45fSAndroid Build Coastguard Worker return out;
70*38e8c45fSAndroid Build Coastguard Worker }
71*38e8c45fSAndroid Build Coastguard Worker
72*38e8c45fSAndroid Build Coastguard Worker } // namespace os
73*38e8c45fSAndroid Build Coastguard Worker } // namespace android
74*38e8c45fSAndroid Build Coastguard Worker
75*38e8c45fSAndroid Build Coastguard Worker static const String16 kKey{"key"};
76*38e8c45fSAndroid Build Coastguard Worker
createSimplePersistableBundle()77*38e8c45fSAndroid Build Coastguard Worker static PersistableBundle createSimplePersistableBundle() {
78*38e8c45fSAndroid Build Coastguard Worker PersistableBundle pb{};
79*38e8c45fSAndroid Build Coastguard Worker pb.putInt(kKey, 64);
80*38e8c45fSAndroid Build Coastguard Worker return pb;
81*38e8c45fSAndroid Build Coastguard Worker }
82*38e8c45fSAndroid Build Coastguard Worker
83*38e8c45fSAndroid Build Coastguard Worker #define TEST_PUT_AND_GET(TYPENAME, TYPE, ...) \
84*38e8c45fSAndroid Build Coastguard Worker TEST(PersistableBundle, PutAndGet##TYPENAME) { \
85*38e8c45fSAndroid Build Coastguard Worker TYPE const expected{__VA_ARGS__}; \
86*38e8c45fSAndroid Build Coastguard Worker PersistableBundle pb{}; \
87*38e8c45fSAndroid Build Coastguard Worker \
88*38e8c45fSAndroid Build Coastguard Worker pb.put##TYPENAME(kKey, expected); \
89*38e8c45fSAndroid Build Coastguard Worker \
90*38e8c45fSAndroid Build Coastguard Worker std::set<String16> expectedKeys{kKey}; \
91*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(pb.get##TYPENAME##Keys(), expectedKeys); \
92*38e8c45fSAndroid Build Coastguard Worker \
93*38e8c45fSAndroid Build Coastguard Worker TYPE val{}; \
94*38e8c45fSAndroid Build Coastguard Worker EXPECT_TRUE(pb.get##TYPENAME(kKey, &val)); \
95*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(val, expected); \
96*38e8c45fSAndroid Build Coastguard Worker }
97*38e8c45fSAndroid Build Coastguard Worker
98*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(Boolean, bool, true);
99*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(Int, int, 64);
100*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(Long, int64_t, 42);
101*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(Double, double, 42.64);
102*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(String, String16, String16{"foo"});
103*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(BooleanVector, std::vector<bool>, true, true);
104*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(IntVector, std::vector<int32_t>, 1, 2);
105*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(LongVector, std::vector<int64_t>, 1, 2);
106*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(DoubleVector, std::vector<double>, 4.2, 5.9);
107*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(StringVector, std::vector<String16>, String16{"foo"}, String16{"bar"});
108*38e8c45fSAndroid Build Coastguard Worker TEST_PUT_AND_GET(PersistableBundle, PersistableBundle, createSimplePersistableBundle());
109*38e8c45fSAndroid Build Coastguard Worker
TEST(PersistableBundle,ParcelAndUnparcel)110*38e8c45fSAndroid Build Coastguard Worker TEST(PersistableBundle, ParcelAndUnparcel) {
111*38e8c45fSAndroid Build Coastguard Worker PersistableBundle expected = createSimplePersistableBundle();
112*38e8c45fSAndroid Build Coastguard Worker PersistableBundle out{};
113*38e8c45fSAndroid Build Coastguard Worker
114*38e8c45fSAndroid Build Coastguard Worker Parcel p{};
115*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(expected.writeToParcel(&p), 0);
116*38e8c45fSAndroid Build Coastguard Worker p.setDataPosition(0);
117*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(out.readFromParcel(&p), 0);
118*38e8c45fSAndroid Build Coastguard Worker
119*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(expected, out);
120*38e8c45fSAndroid Build Coastguard Worker }
121*38e8c45fSAndroid Build Coastguard Worker
TEST(PersistableBundle,OverwriteKey)122*38e8c45fSAndroid Build Coastguard Worker TEST(PersistableBundle, OverwriteKey) {
123*38e8c45fSAndroid Build Coastguard Worker PersistableBundle pb{};
124*38e8c45fSAndroid Build Coastguard Worker
125*38e8c45fSAndroid Build Coastguard Worker pb.putInt(kKey, 64);
126*38e8c45fSAndroid Build Coastguard Worker pb.putDouble(kKey, 0.5);
127*38e8c45fSAndroid Build Coastguard Worker
128*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(pb.getIntKeys().size(), 0);
129*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(pb.getDoubleKeys().size(), 1);
130*38e8c45fSAndroid Build Coastguard Worker
131*38e8c45fSAndroid Build Coastguard Worker double out;
132*38e8c45fSAndroid Build Coastguard Worker EXPECT_TRUE(pb.getDouble(kKey, &out));
133*38e8c45fSAndroid Build Coastguard Worker EXPECT_EQ(out, 0.5);
134*38e8c45fSAndroid Build Coastguard Worker }
135