1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define LOG_TAG "Cts-NdkBinderTest"
17 
18 #include <android/persistable_bundle.h>
19 #include <gtest/gtest.h>
20 
21 #include "utilities.h"
22 
23 class NdkBinderTest_APersistableBundle : public NdkBinderTest {};
24 
TEST_F(NdkBinderTest_APersistableBundle,NewDelete)25 TEST_F(NdkBinderTest_APersistableBundle, NewDelete) {
26   APersistableBundle* bundle = APersistableBundle_new();
27   EXPECT_NE(nullptr, bundle);
28   APersistableBundle_delete(bundle);
29 }
30 
TEST_F(NdkBinderTest_APersistableBundle,NewDupDelete)31 TEST_F(NdkBinderTest_APersistableBundle, NewDupDelete) {
32   APersistableBundle* bundle = APersistableBundle_new();
33   ASSERT_NE(nullptr, bundle);
34   APersistableBundle* dup = APersistableBundle_dup(bundle);
35   EXPECT_NE(nullptr, dup);
36   EXPECT_NE(bundle, dup);
37 }
38 
TEST_F(NdkBinderTest_APersistableBundle,ToFromParcel)39 TEST_F(NdkBinderTest_APersistableBundle, ToFromParcel) {
40   APersistableBundle* bundle = APersistableBundle_new();
41   ASSERT_NE(nullptr, bundle);
42   AParcel* parcel = AParcel_create();
43   // put anything in the bundle
44   APersistableBundle_putBoolean(bundle, "a", true);
45   EXPECT_OK(APersistableBundle_writeToParcel(bundle, parcel));
46   APersistableBundle* readBundle = nullptr;
47   EXPECT_OK(APersistableBundle_readFromParcel(parcel, &readBundle));
48   // make sure that anything is in the new bundle
49   bool val = false;
50   EXPECT_TRUE(APersistableBundle_getBoolean(bundle, "a", &val));
51   EXPECT_TRUE(val);
52 }
53 
TEST_F(NdkBinderTest_APersistableBundle,IsEqual)54 TEST_F(NdkBinderTest_APersistableBundle, IsEqual) {
55   APersistableBundle* bundle = APersistableBundle_new();
56   ASSERT_NE(nullptr, bundle);
57   APersistableBundle* otherBundle = APersistableBundle_new();
58   ASSERT_NE(nullptr, otherBundle);
59   EXPECT_TRUE(APersistableBundle_isEqual(bundle, otherBundle));
60 
61   APersistableBundle_putBoolean(bundle, "a", true);
62   EXPECT_FALSE(APersistableBundle_isEqual(bundle, otherBundle));
63 
64   APersistableBundle_putBoolean(otherBundle, "a", true);
65   EXPECT_TRUE(APersistableBundle_isEqual(bundle, otherBundle));
66 
67   APersistableBundle_putBoolean(otherBundle, "a", false);
68   EXPECT_FALSE(APersistableBundle_isEqual(bundle, otherBundle));
69 }
70 
TEST_F(NdkBinderTest_APersistableBundle,Size)71 TEST_F(NdkBinderTest_APersistableBundle, Size) {
72   APersistableBundle* bundle = APersistableBundle_new();
73   ASSERT_NE(nullptr, bundle);
74   EXPECT_EQ(0, APersistableBundle_size(bundle));
75   APersistableBundle_putBoolean(bundle, "a", true);
76   EXPECT_EQ(1, APersistableBundle_size(bundle));
77 }
78 
79 const bool kBoolVal = true;
80 const int32_t kIntVal = 11111;
81 const int64_t kLongVal = 12345;
82 const double kDoubleVal = 54321;
83 const std::string kStringVal = "cool";
84 const int32_t kNumBools = 3;
85 const bool kBoolVVal[] = {true, false, true};
86 const std::vector<int32_t> kIntVVal = {1111, -2222, 3333};
87 const std::vector<int64_t> kLongVVal = {11111, -22222, 33333};
88 const std::vector<double> kDoubleVVal = {111111, -222222, 333333};
89 const int kNumStrings = 3;
90 const char* kStringVVal[] = {"hello", "monkey", "!"};
91 
TEST_F(NdkBinderTest_APersistableBundle,Erase)92 TEST_F(NdkBinderTest_APersistableBundle, Erase) {
93   APersistableBundle* bundle = APersistableBundle_new();
94   ASSERT_NE(nullptr, bundle);
95   APersistableBundle_putBoolean(bundle, "a", true);
96   EXPECT_EQ(1, APersistableBundle_size(bundle));
97   APersistableBundle_putIntVector(bundle, "b", kIntVVal.data(), kIntVVal.size());
98   EXPECT_EQ(2, APersistableBundle_size(bundle));
99   // erase does nothing if entry doesn't exist
100   EXPECT_EQ(0, APersistableBundle_erase(bundle, "nothing"));
101   EXPECT_EQ(2, APersistableBundle_size(bundle));
102   // erase works on a single entry
103   EXPECT_EQ(1, APersistableBundle_erase(bundle, "a"));
104   EXPECT_EQ(1, APersistableBundle_size(bundle));
105   // erase works on multiple entries
106   EXPECT_EQ(1, APersistableBundle_erase(bundle, "b"));
107   EXPECT_EQ(0, APersistableBundle_size(bundle));
108 }
109 
110 // allocate a buffer for a string
stringAllocator(int32_t bufferSizeBytes,void *)111 static char* stringAllocator(int32_t bufferSizeBytes, void*) {
112   return (char*)malloc(bufferSizeBytes);
113 }
114 
TEST_F(NdkBinderTest_APersistableBundle,PutAndGetAllTheThings)115 TEST_F(NdkBinderTest_APersistableBundle, PutAndGetAllTheThings) {
116   APersistableBundle* bundle = APersistableBundle_new();
117   ASSERT_NE(nullptr, bundle);
118   // put all supported types && verify
119   APersistableBundle_putBoolean(bundle, "bool", kBoolVal);
120   APersistableBundle_putInt(bundle, "int", kIntVal);
121   APersistableBundle_putLong(bundle, "long", kLongVal);
122   APersistableBundle_putDouble(bundle, "double", kDoubleVal);
123   APersistableBundle_putString(bundle, "string", kStringVal.c_str());
124   APersistableBundle_putBooleanVector(bundle, "boolv", kBoolVVal, kNumBools);
125   APersistableBundle_putIntVector(bundle, "intv", kIntVVal.data(), kIntVVal.size());
126   APersistableBundle_putLongVector(bundle, "longv", kLongVVal.data(), kLongVVal.size());
127   APersistableBundle_putDoubleVector(bundle, "doublev", kDoubleVVal.data(), kDoubleVVal.size());
128   APersistableBundle_putStringVector(bundle, "stringv", kStringVVal, kNumStrings);
129   APersistableBundle* innerBundle = APersistableBundle_new();
130   APersistableBundle_putBoolean(innerBundle, "bool", kBoolVal);
131   APersistableBundle_putInt(innerBundle, "int", kIntVal);
132   APersistableBundle_putPersistableBundle(bundle, "pbundle", innerBundle);
133   bool outBool = false;
134   int32_t outInt = 0;
135   int64_t outLong = 0;
136   double outDouble = 0;
137   char* outString = nullptr;
138   bool* outBoolV = nullptr;
139   int32_t* outIntV = nullptr;
140   int64_t* outLongV = nullptr;
141   double* outDoubleV = nullptr;
142   char** outStringV = nullptr;
143   APersistableBundle* outInnerBundle;
144   EXPECT_TRUE(APersistableBundle_getBoolean(bundle, "bool", &outBool));
145   EXPECT_EQ(outBool, kBoolVal);
146   EXPECT_TRUE(APersistableBundle_getInt(bundle, "int", &outInt));
147   EXPECT_EQ(outInt, kIntVal);
148   EXPECT_TRUE(APersistableBundle_getLong(bundle, "long", &outLong));
149   EXPECT_EQ(outLong, kLongVal);
150   EXPECT_TRUE(APersistableBundle_getDouble(bundle, "double", &outDouble));
151   EXPECT_EQ(outDouble, kDoubleVal);
152   EXPECT_EQ(APersistableBundle_getString(bundle, "string", &outString, &stringAllocator, nullptr),
153             kStringVal.size());
154   EXPECT_EQ(outString, kStringVal);
155 
156   int32_t sizeBytes = APersistableBundle_getBooleanVector(bundle, "boolv", outBoolV, 0);
157   EXPECT_GT(sizeBytes, 0);
158   outBoolV = (bool*)malloc(sizeBytes);
159   sizeBytes = APersistableBundle_getBooleanVector(bundle, "boolv", outBoolV, sizeBytes);
160   for (int32_t i = 0; i < kNumBools; i++) {
161     EXPECT_EQ(outBoolV[i], kBoolVVal[i]);
162   }
163   free(outBoolV);
164 
165   sizeBytes = APersistableBundle_getIntVector(bundle, "intv", outIntV, 0);
166   EXPECT_GT(sizeBytes, 0);
167   outIntV = (int32_t*)malloc(sizeBytes);
168   sizeBytes = APersistableBundle_getIntVector(bundle, "intv", outIntV, sizeBytes);
169   for (int32_t i = 0; i < kIntVVal.size(); i++) {
170     EXPECT_EQ(outIntV[i], kIntVVal[i]);
171   }
172   free(outIntV);
173 
174   sizeBytes = APersistableBundle_getLongVector(bundle, "longv", outLongV, 0);
175   EXPECT_GT(sizeBytes, 0);
176   outLongV = (int64_t*)malloc(sizeBytes);
177   sizeBytes = APersistableBundle_getLongVector(bundle, "longv", outLongV, sizeBytes);
178   for (int32_t i = 0; i < kLongVVal.size(); i++) {
179     EXPECT_EQ(outLongV[i], kLongVVal[i]);
180   }
181   free(outLongV);
182 
183   sizeBytes = APersistableBundle_getDoubleVector(bundle, "doublev", outDoubleV, 0);
184   EXPECT_GT(sizeBytes, 0);
185   outDoubleV = (double*)malloc(sizeBytes);
186   sizeBytes = APersistableBundle_getDoubleVector(bundle, "doublev", outDoubleV, sizeBytes);
187   for (int32_t i = 0; i < kDoubleVVal.size(); i++) {
188     EXPECT_EQ(outDoubleV[i], kDoubleVVal[i]);
189   }
190   free(outDoubleV);
191 
192   sizeBytes = APersistableBundle_getDoubleVector(bundle, "doublev", outDoubleV, 0);
193   EXPECT_GT(sizeBytes, 0);
194   outDoubleV = (double*)malloc(sizeBytes);
195   sizeBytes = APersistableBundle_getDoubleVector(bundle, "doublev", outDoubleV, sizeBytes);
196   for (int32_t i = 0; i < kDoubleVVal.size(); i++) {
197     EXPECT_EQ(outDoubleV[i], kDoubleVVal[i]);
198   }
199   free(outDoubleV);
200 
201   sizeBytes = APersistableBundle_getStringVector(bundle, "stringv", outStringV, 0, &stringAllocator,
202                                                  nullptr);
203   EXPECT_GT(sizeBytes, 0);
204   outStringV = (char**)malloc(sizeBytes);
205   sizeBytes = APersistableBundle_getStringVector(bundle, "stringv", outStringV, sizeBytes,
206                                                  &stringAllocator, nullptr);
207   for (int32_t i = 0; i < kNumStrings; i++) {
208     EXPECT_EQ(0, std::strcmp(outStringV[i], kStringVVal[i]));
209     free(outStringV[i]);
210   }
211   free(outStringV);
212 
213   EXPECT_TRUE(APersistableBundle_getPersistableBundle(bundle, "pbundle", &outInnerBundle));
214   EXPECT_TRUE(APersistableBundle_isEqual(innerBundle, outInnerBundle));
215 }
216 
TEST_F(NdkBinderTest_APersistableBundle,WrongKeyBool)217 TEST_F(NdkBinderTest_APersistableBundle, WrongKeyBool) {
218   APersistableBundle* bundle = APersistableBundle_new();
219   ASSERT_NE(nullptr, bundle);
220 
221   bool outBool = false;
222   EXPECT_FALSE(APersistableBundle_getBoolean(bundle, "not the right key", &outBool));
223 }
224 
TEST_F(NdkBinderTest_APersistableBundle,WrongKeyString)225 TEST_F(NdkBinderTest_APersistableBundle, WrongKeyString) {
226   APersistableBundle* bundle = APersistableBundle_new();
227   ASSERT_NE(nullptr, bundle);
228 
229   char* outString = nullptr;
230   EXPECT_EQ(APersistableBundle_getString(bundle, "not the right key", &outString, &stringAllocator,
231                                          nullptr),
232             APERSISTABLEBUNDLE_KEY_NOT_FOUND);
233 }
234 
TEST_F(NdkBinderTest_APersistableBundle,WrongKeyVector)235 TEST_F(NdkBinderTest_APersistableBundle, WrongKeyVector) {
236   APersistableBundle* bundle = APersistableBundle_new();
237   ASSERT_NE(nullptr, bundle);
238 
239   bool* outBools = nullptr;
240   EXPECT_EQ(APersistableBundle_getBooleanVector(bundle, "not the right key", outBools, 0),
241             APERSISTABLEBUNDLE_KEY_NOT_FOUND);
242 }
243 
TEST_F(NdkBinderTest_APersistableBundle,EmptyStringVal)244 TEST_F(NdkBinderTest_APersistableBundle, EmptyStringVal) {
245   APersistableBundle* bundle = APersistableBundle_new();
246   ASSERT_NE(nullptr, bundle);
247 
248   APersistableBundle_putString(bundle, "key", "");
249   char* outString = nullptr;
250   EXPECT_EQ(APersistableBundle_getString(bundle, "key", &outString, &stringAllocator, nullptr), 0);
251 }
252 
TEST_F(NdkBinderTest_APersistableBundle,EmptyVectorVal)253 TEST_F(NdkBinderTest_APersistableBundle, EmptyVectorVal) {
254   APersistableBundle* bundle = APersistableBundle_new();
255   ASSERT_NE(nullptr, bundle);
256 
257   // empty vector is size 0
258   const bool inEmptyBools[] = {};
259   APersistableBundle_putBooleanVector(bundle, "key", inEmptyBools, 0);
260   bool* outBools = nullptr;
261   EXPECT_EQ(APersistableBundle_getBooleanVector(bundle, "key", outBools, 0), 0);
262 }
263 
TEST_F(NdkBinderTest_APersistableBundle,EmptyStringKeys)264 TEST_F(NdkBinderTest_APersistableBundle, EmptyStringKeys) {
265   int32_t sizeBytes = sizeof(char*);
266   char** outKeys = (char**)malloc(sizeBytes);
267   APersistableBundle* bundle = APersistableBundle_new();
268   ASSERT_NE(nullptr, bundle);
269 
270   // No keys yet, should be size 0
271   int32_t outSizeBytes =
272       APersistableBundle_getBooleanKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
273   ASSERT_EQ(outSizeBytes, 0);
274 
275   // Empty string as a key needs an entry like any other key
276   APersistableBundle_putBoolean(bundle, "", kBoolVal);
277   outSizeBytes =
278       APersistableBundle_getBooleanKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
279   ASSERT_EQ(outSizeBytes, sizeof(char*));
280   EXPECT_EQ(0, std::strcmp("", outKeys[0]));
281 }
282 
failAllocator(int32_t,void *)283 static char* failAllocator(int32_t, void*) {
284   return nullptr;
285 }
286 
TEST_F(NdkBinderTest_APersistableBundle,FailAllocatorKeys)287 TEST_F(NdkBinderTest_APersistableBundle, FailAllocatorKeys) {
288   int32_t sizeBytes = sizeof(char*);
289   char** outKeys = (char**)malloc(sizeBytes);
290   APersistableBundle* bundle = APersistableBundle_new();
291   ASSERT_NE(nullptr, bundle);
292 
293   APersistableBundle_putBoolean(bundle, "This will fail to allocate", kBoolVal);
294   int32_t outSizeBytes =
295       APersistableBundle_getBooleanKeys(bundle, outKeys, sizeBytes, &failAllocator, nullptr);
296   EXPECT_EQ(outSizeBytes, APERSISTABLEBUNDLE_ALLOCATOR_FAILED);
297 }
298 
299 // Check bytes and string arrays for equality and free all of the outKeys
checkAndFree(int32_t inBytes,int32_t outBytes,const char ** inKeys,char ** outKeys,int numKeys)300 inline void checkAndFree(int32_t inBytes, int32_t outBytes, const char** inKeys, char** outKeys,
301                          int numKeys) {
302   ASSERT_EQ(inBytes, outBytes);
303   for (int32_t i = 0; i < numKeys; i++) {
304     EXPECT_EQ(0, std::strcmp(inKeys[i], outKeys[i]));
305     free(outKeys[i]);
306   }
307 }
308 
TEST_F(NdkBinderTest_APersistableBundle,getKeys)309 TEST_F(NdkBinderTest_APersistableBundle, getKeys) {
310   // We will use three keys per, so we know the size of the buffer
311   const int numKeys = 3;
312   int32_t sizeBytes = numKeys * sizeof(char*);
313   char** outKeys = (char**)malloc(sizeBytes);
314   const char* keys[] = {"key1", "key2", "key3"};
315   APersistableBundle* bundle = APersistableBundle_new();
316   ASSERT_NE(nullptr, bundle);
317 
318   for (int32_t i = 0; i < numKeys; i++) {
319     APersistableBundle_putBoolean(bundle, keys[i], kBoolVal);
320   }
321   int32_t outSizeBytes =
322       APersistableBundle_getBooleanKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
323   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
324 
325   for (int32_t i = 0; i < numKeys; i++) {
326     APersistableBundle_putInt(bundle, keys[i], kIntVal);
327   }
328   outSizeBytes =
329       APersistableBundle_getIntKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
330   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
331 
332   for (int32_t i = 0; i < numKeys; i++) {
333     APersistableBundle_putLong(bundle, keys[i], kLongVal);
334   }
335   outSizeBytes =
336       APersistableBundle_getLongKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
337   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
338 
339   for (int32_t i = 0; i < numKeys; i++) {
340     APersistableBundle_putDouble(bundle, keys[i], kDoubleVal);
341   }
342   outSizeBytes =
343       APersistableBundle_getDoubleKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
344   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
345 
346   for (int32_t i = 0; i < numKeys; i++) {
347     APersistableBundle_putString(bundle, keys[i], kStringVal.c_str());
348   }
349   outSizeBytes =
350       APersistableBundle_getStringKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
351   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
352 
353   for (int32_t i = 0; i < numKeys; i++) {
354     APersistableBundle_putBooleanVector(bundle, keys[i], kBoolVVal, kNumBools);
355   }
356   outSizeBytes = APersistableBundle_getBooleanVectorKeys(bundle, outKeys, sizeBytes,
357                                                          &stringAllocator, nullptr);
358   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
359 
360   for (int32_t i = 0; i < numKeys; i++) {
361     APersistableBundle_putIntVector(bundle, keys[i], kIntVVal.data(), kIntVVal.size());
362   }
363   outSizeBytes =
364       APersistableBundle_getIntVectorKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
365   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
366 
367   for (int32_t i = 0; i < numKeys; i++) {
368     APersistableBundle_putLongVector(bundle, keys[i], kLongVVal.data(), kLongVVal.size());
369   }
370   outSizeBytes =
371       APersistableBundle_getLongVectorKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
372   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
373 
374   for (int32_t i = 0; i < numKeys; i++) {
375     APersistableBundle_putDoubleVector(bundle, keys[i], kDoubleVVal.data(), kDoubleVVal.size());
376   }
377   outSizeBytes =
378       APersistableBundle_getDoubleVectorKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
379   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
380 
381   for (int32_t i = 0; i < numKeys; i++) {
382     APersistableBundle_putStringVector(bundle, keys[i], kStringVVal, kNumStrings);
383   }
384   outSizeBytes =
385       APersistableBundle_getStringVectorKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
386   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
387 
388   APersistableBundle* innerBundle = APersistableBundle_new();
389   for (int32_t i = 0; i < numKeys; i++) {
390     APersistableBundle_putPersistableBundle(bundle, keys[i], innerBundle);
391   }
392   outSizeBytes = APersistableBundle_getPersistableBundleKeys(bundle, outKeys, sizeBytes,
393                                                              &stringAllocator, nullptr);
394   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
395 }
396