xref: /aosp_15_r20/cts/tests/tests/binder_ndk/libbinder_ndk_test/test_persistable_bundle.cpp (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
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   EXPECT_NE(nullptr, bundle);
269 
270   if (bundle) {
271     // No keys yet, should be size 0
272     int32_t outSizeBytes =
273         APersistableBundle_getBooleanKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
274     EXPECT_EQ(outSizeBytes, 0);
275 
276     // Empty string as a key needs an entry like any other key
277     APersistableBundle_putBoolean(bundle, "", kBoolVal);
278     outSizeBytes =
279         APersistableBundle_getBooleanKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
280     EXPECT_EQ(outSizeBytes, sizeof(char*));
281     EXPECT_EQ(0, std::strcmp("", outKeys[0]));
282   }
283   free(outKeys[0]);
284   free(outKeys);
285 }
286 
failAllocator(int32_t,void *)287 static char* failAllocator(int32_t, void*) {
288   return nullptr;
289 }
290 
TEST_F(NdkBinderTest_APersistableBundle,FailAllocatorKeys)291 TEST_F(NdkBinderTest_APersistableBundle, FailAllocatorKeys) {
292   int32_t sizeBytes = sizeof(char*);
293   char** outKeys = (char**)malloc(sizeBytes);
294   APersistableBundle* bundle = APersistableBundle_new();
295   EXPECT_NE(nullptr, bundle);
296 
297   if (bundle) {
298     APersistableBundle_putBoolean(bundle, "This will fail to allocate", kBoolVal);
299     int32_t outSizeBytes =
300         APersistableBundle_getBooleanKeys(bundle, outKeys, sizeBytes, &failAllocator, nullptr);
301     EXPECT_EQ(outSizeBytes, APERSISTABLEBUNDLE_ALLOCATOR_FAILED);
302   }
303   free(outKeys);
304 }
305 
306 // 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)307 inline void checkAndFree(int32_t inBytes, int32_t outBytes, const char** inKeys, char** outKeys,
308                          int numKeys) {
309   ASSERT_EQ(inBytes, outBytes);
310   for (int32_t i = 0; i < numKeys; i++) {
311     EXPECT_EQ(0, std::strcmp(inKeys[i], outKeys[i]));
312     free(outKeys[i]);
313   }
314 }
315 
TEST_F(NdkBinderTest_APersistableBundle,getKeys)316 TEST_F(NdkBinderTest_APersistableBundle, getKeys) {
317   // We will use three keys per, so we know the size of the buffer
318   const int numKeys = 3;
319   int32_t sizeBytes = numKeys * sizeof(char*);
320   char** outKeys = (char**)malloc(sizeBytes);
321   const char* keys[] = {"key1", "key2", "key3"};
322   APersistableBundle* bundle = APersistableBundle_new();
323   ASSERT_NE(nullptr, bundle);
324 
325   for (int32_t i = 0; i < numKeys; i++) {
326     APersistableBundle_putBoolean(bundle, keys[i], kBoolVal);
327   }
328   int32_t outSizeBytes =
329       APersistableBundle_getBooleanKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
330   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
331 
332   for (int32_t i = 0; i < numKeys; i++) {
333     APersistableBundle_putInt(bundle, keys[i], kIntVal);
334   }
335   outSizeBytes =
336       APersistableBundle_getIntKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
337   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
338 
339   for (int32_t i = 0; i < numKeys; i++) {
340     APersistableBundle_putLong(bundle, keys[i], kLongVal);
341   }
342   outSizeBytes =
343       APersistableBundle_getLongKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
344   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
345 
346   for (int32_t i = 0; i < numKeys; i++) {
347     APersistableBundle_putDouble(bundle, keys[i], kDoubleVal);
348   }
349   outSizeBytes =
350       APersistableBundle_getDoubleKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
351   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
352 
353   for (int32_t i = 0; i < numKeys; i++) {
354     APersistableBundle_putString(bundle, keys[i], kStringVal.c_str());
355   }
356   outSizeBytes =
357       APersistableBundle_getStringKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
358   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
359 
360   for (int32_t i = 0; i < numKeys; i++) {
361     APersistableBundle_putBooleanVector(bundle, keys[i], kBoolVVal, kNumBools);
362   }
363   outSizeBytes = APersistableBundle_getBooleanVectorKeys(bundle, outKeys, sizeBytes,
364                                                          &stringAllocator, nullptr);
365   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
366 
367   for (int32_t i = 0; i < numKeys; i++) {
368     APersistableBundle_putIntVector(bundle, keys[i], kIntVVal.data(), kIntVVal.size());
369   }
370   outSizeBytes =
371       APersistableBundle_getIntVectorKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
372   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
373 
374   for (int32_t i = 0; i < numKeys; i++) {
375     APersistableBundle_putLongVector(bundle, keys[i], kLongVVal.data(), kLongVVal.size());
376   }
377   outSizeBytes =
378       APersistableBundle_getLongVectorKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
379   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
380 
381   for (int32_t i = 0; i < numKeys; i++) {
382     APersistableBundle_putDoubleVector(bundle, keys[i], kDoubleVVal.data(), kDoubleVVal.size());
383   }
384   outSizeBytes =
385       APersistableBundle_getDoubleVectorKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
386   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
387 
388   for (int32_t i = 0; i < numKeys; i++) {
389     APersistableBundle_putStringVector(bundle, keys[i], kStringVVal, kNumStrings);
390   }
391   outSizeBytes =
392       APersistableBundle_getStringVectorKeys(bundle, outKeys, sizeBytes, &stringAllocator, nullptr);
393   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
394 
395   APersistableBundle* innerBundle = APersistableBundle_new();
396   for (int32_t i = 0; i < numKeys; i++) {
397     APersistableBundle_putPersistableBundle(bundle, keys[i], innerBundle);
398   }
399   outSizeBytes = APersistableBundle_getPersistableBundleKeys(bundle, outKeys, sizeBytes,
400                                                              &stringAllocator, nullptr);
401   checkAndFree(sizeBytes, outSizeBytes, keys, outKeys, numKeys);
402   free(outKeys);
403 }
404