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 #include <android/binder_libbinder.h>
17 #include <android/persistable_bundle.h>
18 #include <binder/PersistableBundle.h>
19 #include <log/log.h>
20 #include <persistable_bundle_internal.h>
21 #include <string.h>
22 
23 #include <set>
24 
25 __BEGIN_DECLS
26 
27 struct APersistableBundle {
APersistableBundleAPersistableBundle28     APersistableBundle(const APersistableBundle& pBundle) : mPBundle(pBundle.mPBundle) {}
APersistableBundleAPersistableBundle29     APersistableBundle(const android::os::PersistableBundle& pBundle) : mPBundle(pBundle) {}
30     APersistableBundle() = default;
31     android::os::PersistableBundle mPBundle;
32 };
33 
APersistableBundle_new()34 APersistableBundle* _Nullable APersistableBundle_new() {
35     return new (std::nothrow) APersistableBundle();
36 }
37 
APersistableBundle_dup(const APersistableBundle * pBundle)38 APersistableBundle* _Nullable APersistableBundle_dup(const APersistableBundle* pBundle) {
39     if (pBundle) {
40         return new APersistableBundle(*pBundle);
41     } else {
42         return new APersistableBundle();
43     }
44 }
45 
APersistableBundle_delete(APersistableBundle * pBundle)46 void APersistableBundle_delete(APersistableBundle* pBundle) {
47     free(pBundle);
48 }
49 
APersistableBundle_isEqual(const APersistableBundle * lhs,const APersistableBundle * rhs)50 bool APersistableBundle_isEqual(const APersistableBundle* lhs, const APersistableBundle* rhs) {
51     if (lhs && rhs) {
52         return lhs->mPBundle == rhs->mPBundle;
53     } else if (lhs == rhs) {
54         return true;
55     } else {
56         return false;
57     }
58 }
59 
APersistableBundle_readFromParcel(const AParcel * parcel,APersistableBundle * _Nullable * outPBundle)60 binder_status_t APersistableBundle_readFromParcel(const AParcel* parcel,
61                                                   APersistableBundle* _Nullable* outPBundle) {
62     if (!parcel || !outPBundle) return STATUS_BAD_VALUE;
63     APersistableBundle* newPBundle = APersistableBundle_new();
64     if (newPBundle == nullptr) return STATUS_NO_MEMORY;
65     binder_status_t status =
66             newPBundle->mPBundle.readFromParcel(AParcel_viewPlatformParcel(parcel));
67     if (status == STATUS_OK) {
68         *outPBundle = newPBundle;
69     }
70     return status;
71 }
72 
APersistableBundle_writeToParcel(const APersistableBundle * pBundle,AParcel * parcel)73 binder_status_t APersistableBundle_writeToParcel(const APersistableBundle* pBundle,
74                                                  AParcel* parcel) {
75     if (!parcel || !pBundle) return STATUS_BAD_VALUE;
76     return pBundle->mPBundle.writeToParcel(AParcel_viewPlatformParcel(parcel));
77 }
78 
APersistableBundle_size(const APersistableBundle * pBundle)79 int32_t APersistableBundle_size(const APersistableBundle* pBundle) {
80     size_t size = pBundle->mPBundle.size();
81     LOG_ALWAYS_FATAL_IF(size > INT32_MAX,
82                         "The APersistableBundle has gotten too large! There will be an overflow in "
83                         "the reported size.");
84     return pBundle->mPBundle.size();
85 }
APersistableBundle_erase(APersistableBundle * pBundle,const char * key)86 int32_t APersistableBundle_erase(APersistableBundle* pBundle, const char* key) {
87     return pBundle->mPBundle.erase(android::String16(key));
88 }
APersistableBundle_putBoolean(APersistableBundle * pBundle,const char * key,bool val)89 void APersistableBundle_putBoolean(APersistableBundle* pBundle, const char* key, bool val) {
90     pBundle->mPBundle.putBoolean(android::String16(key), val);
91 }
APersistableBundle_putInt(APersistableBundle * pBundle,const char * key,int32_t val)92 void APersistableBundle_putInt(APersistableBundle* pBundle, const char* key, int32_t val) {
93     pBundle->mPBundle.putInt(android::String16(key), val);
94 }
APersistableBundle_putLong(APersistableBundle * pBundle,const char * key,int64_t val)95 void APersistableBundle_putLong(APersistableBundle* pBundle, const char* key, int64_t val) {
96     pBundle->mPBundle.putLong(android::String16(key), val);
97 }
APersistableBundle_putDouble(APersistableBundle * pBundle,const char * key,double val)98 void APersistableBundle_putDouble(APersistableBundle* pBundle, const char* key, double val) {
99     pBundle->mPBundle.putDouble(android::String16(key), val);
100 }
APersistableBundle_putString(APersistableBundle * pBundle,const char * key,const char * val)101 void APersistableBundle_putString(APersistableBundle* pBundle, const char* key, const char* val) {
102     pBundle->mPBundle.putString(android::String16(key), android::String16(val));
103 }
APersistableBundle_putBooleanVector(APersistableBundle * pBundle,const char * key,const bool * vec,int32_t num)104 void APersistableBundle_putBooleanVector(APersistableBundle* pBundle, const char* key,
105                                          const bool* vec, int32_t num) {
106     LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
107     std::vector<bool> newVec(num);
108     for (int32_t i = 0; i < num; i++) {
109         newVec[i] = vec[i];
110     }
111     pBundle->mPBundle.putBooleanVector(android::String16(key), newVec);
112 }
APersistableBundle_putIntVector(APersistableBundle * pBundle,const char * key,const int32_t * vec,int32_t num)113 void APersistableBundle_putIntVector(APersistableBundle* pBundle, const char* key,
114                                      const int32_t* vec, int32_t num) {
115     LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
116     std::vector<int32_t> newVec(num);
117     for (int32_t i = 0; i < num; i++) {
118         newVec[i] = vec[i];
119     }
120     pBundle->mPBundle.putIntVector(android::String16(key), newVec);
121 }
APersistableBundle_putLongVector(APersistableBundle * pBundle,const char * key,const int64_t * vec,int32_t num)122 void APersistableBundle_putLongVector(APersistableBundle* pBundle, const char* key,
123                                       const int64_t* vec, int32_t num) {
124     LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
125     std::vector<int64_t> newVec(num);
126     for (int32_t i = 0; i < num; i++) {
127         newVec[i] = vec[i];
128     }
129     pBundle->mPBundle.putLongVector(android::String16(key), newVec);
130 }
APersistableBundle_putDoubleVector(APersistableBundle * pBundle,const char * key,const double * vec,int32_t num)131 void APersistableBundle_putDoubleVector(APersistableBundle* pBundle, const char* key,
132                                         const double* vec, int32_t num) {
133     LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
134     std::vector<double> newVec(num);
135     for (int32_t i = 0; i < num; i++) {
136         newVec[i] = vec[i];
137     }
138     pBundle->mPBundle.putDoubleVector(android::String16(key), newVec);
139 }
APersistableBundle_putStringVector(APersistableBundle * pBundle,const char * key,const char * const * vec,int32_t num)140 void APersistableBundle_putStringVector(APersistableBundle* pBundle, const char* key,
141                                         const char* const* vec, int32_t num) {
142     LOG_ALWAYS_FATAL_IF(num < 0, "Negative number of elements is invalid.");
143     std::vector<android::String16> newVec(num);
144     for (int32_t i = 0; i < num; i++) {
145         newVec[i] = android::String16(vec[i]);
146     }
147     pBundle->mPBundle.putStringVector(android::String16(key), newVec);
148 }
APersistableBundle_putPersistableBundle(APersistableBundle * pBundle,const char * key,const APersistableBundle * val)149 void APersistableBundle_putPersistableBundle(APersistableBundle* pBundle, const char* key,
150                                              const APersistableBundle* val) {
151     pBundle->mPBundle.putPersistableBundle(android::String16(key), val->mPBundle);
152 }
APersistableBundle_getBoolean(const APersistableBundle * pBundle,const char * key,bool * val)153 bool APersistableBundle_getBoolean(const APersistableBundle* pBundle, const char* key, bool* val) {
154     return pBundle->mPBundle.getBoolean(android::String16(key), val);
155 }
APersistableBundle_getInt(const APersistableBundle * pBundle,const char * key,int32_t * val)156 bool APersistableBundle_getInt(const APersistableBundle* pBundle, const char* key, int32_t* val) {
157     return pBundle->mPBundle.getInt(android::String16(key), val);
158 }
APersistableBundle_getLong(const APersistableBundle * pBundle,const char * key,int64_t * val)159 bool APersistableBundle_getLong(const APersistableBundle* pBundle, const char* key, int64_t* val) {
160     return pBundle->mPBundle.getLong(android::String16(key), val);
161 }
APersistableBundle_getDouble(const APersistableBundle * pBundle,const char * key,double * val)162 bool APersistableBundle_getDouble(const APersistableBundle* pBundle, const char* key, double* val) {
163     return pBundle->mPBundle.getDouble(android::String16(key), val);
164 }
APersistableBundle_getString(const APersistableBundle * pBundle,const char * key,char ** val,APersistableBundle_stringAllocator stringAllocator,void * context)165 int32_t APersistableBundle_getString(const APersistableBundle* pBundle, const char* key, char** val,
166                                      APersistableBundle_stringAllocator stringAllocator,
167                                      void* context) {
168     android::String16 outVal;
169     bool ret = pBundle->mPBundle.getString(android::String16(key), &outVal);
170     if (!ret) return APERSISTABLEBUNDLE_KEY_NOT_FOUND;
171     android::String8 tmp8(outVal);
172     *val = stringAllocator(tmp8.bytes() + 1, context);
173     if (*val) {
174         strncpy(*val, tmp8.c_str(), tmp8.bytes() + 1);
175         return tmp8.bytes();
176     } else {
177         return APERSISTABLEBUNDLE_ALLOCATOR_FAILED;
178     }
179 }
APersistableBundle_getBooleanVector(const APersistableBundle * pBundle,const char * key,bool * buffer,int32_t bufferSizeBytes)180 int32_t APersistableBundle_getBooleanVector(const APersistableBundle* pBundle, const char* key,
181                                             bool* buffer, int32_t bufferSizeBytes) {
182     std::vector<bool> newVec;
183     bool ret = pBundle->mPBundle.getBooleanVector(android::String16(key), &newVec);
184     if (!ret) return APERSISTABLEBUNDLE_KEY_NOT_FOUND;
185     return getVecInternal<bool>(newVec, buffer, bufferSizeBytes);
186 }
APersistableBundle_getIntVector(const APersistableBundle * pBundle,const char * key,int32_t * buffer,int32_t bufferSizeBytes)187 int32_t APersistableBundle_getIntVector(const APersistableBundle* pBundle, const char* key,
188                                         int32_t* buffer, int32_t bufferSizeBytes) {
189     std::vector<int32_t> newVec;
190     bool ret = pBundle->mPBundle.getIntVector(android::String16(key), &newVec);
191     if (!ret) return APERSISTABLEBUNDLE_KEY_NOT_FOUND;
192     return getVecInternal<int32_t>(newVec, buffer, bufferSizeBytes);
193 }
APersistableBundle_getLongVector(const APersistableBundle * pBundle,const char * key,int64_t * buffer,int32_t bufferSizeBytes)194 int32_t APersistableBundle_getLongVector(const APersistableBundle* pBundle, const char* key,
195                                          int64_t* buffer, int32_t bufferSizeBytes) {
196     std::vector<int64_t> newVec;
197     bool ret = pBundle->mPBundle.getLongVector(android::String16(key), &newVec);
198     if (!ret) return APERSISTABLEBUNDLE_KEY_NOT_FOUND;
199     return getVecInternal<int64_t>(newVec, buffer, bufferSizeBytes);
200 }
APersistableBundle_getDoubleVector(const APersistableBundle * pBundle,const char * key,double * buffer,int32_t bufferSizeBytes)201 int32_t APersistableBundle_getDoubleVector(const APersistableBundle* pBundle, const char* key,
202                                            double* buffer, int32_t bufferSizeBytes) {
203     std::vector<double> newVec;
204     bool ret = pBundle->mPBundle.getDoubleVector(android::String16(key), &newVec);
205     if (!ret) return APERSISTABLEBUNDLE_KEY_NOT_FOUND;
206     return getVecInternal<double>(newVec, buffer, bufferSizeBytes);
207 }
APersistableBundle_getStringVector(const APersistableBundle * pBundle,const char * key,char ** vec,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)208 int32_t APersistableBundle_getStringVector(const APersistableBundle* pBundle, const char* key,
209                                            char** vec, int32_t bufferSizeBytes,
210                                            APersistableBundle_stringAllocator stringAllocator,
211                                            void* context) {
212     std::vector<android::String16> newVec;
213     bool ret = pBundle->mPBundle.getStringVector(android::String16(key), &newVec);
214     if (!ret) return APERSISTABLEBUNDLE_KEY_NOT_FOUND;
215     return getStringsInternal<std::vector<android::String16>>(newVec, vec, bufferSizeBytes,
216                                                               stringAllocator, context);
217 }
APersistableBundle_getPersistableBundle(const APersistableBundle * pBundle,const char * key,APersistableBundle ** outBundle)218 bool APersistableBundle_getPersistableBundle(const APersistableBundle* pBundle, const char* key,
219                                              APersistableBundle** outBundle) {
220     APersistableBundle* bundle = APersistableBundle_new();
221     bool ret = pBundle->mPBundle.getPersistableBundle(android::String16(key), &bundle->mPBundle);
222     if (ret) {
223         *outBundle = bundle;
224         return true;
225     }
226     return false;
227 }
APersistableBundle_getBooleanKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)228 int32_t APersistableBundle_getBooleanKeys(const APersistableBundle* pBundle, char** outKeys,
229                                           int32_t bufferSizeBytes,
230                                           APersistableBundle_stringAllocator stringAllocator,
231                                           void* context) {
232     std::set<android::String16> ret = pBundle->mPBundle.getBooleanKeys();
233     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
234                                                            stringAllocator, context);
235 }
APersistableBundle_getIntKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)236 int32_t APersistableBundle_getIntKeys(const APersistableBundle* pBundle, char** outKeys,
237                                       int32_t bufferSizeBytes,
238                                       APersistableBundle_stringAllocator stringAllocator,
239                                       void* context) {
240     std::set<android::String16> ret = pBundle->mPBundle.getIntKeys();
241     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
242                                                            stringAllocator, context);
243 }
APersistableBundle_getLongKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)244 int32_t APersistableBundle_getLongKeys(const APersistableBundle* pBundle, char** outKeys,
245                                        int32_t bufferSizeBytes,
246                                        APersistableBundle_stringAllocator stringAllocator,
247                                        void* context) {
248     std::set<android::String16> ret = pBundle->mPBundle.getLongKeys();
249     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
250                                                            stringAllocator, context);
251 }
APersistableBundle_getDoubleKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)252 int32_t APersistableBundle_getDoubleKeys(const APersistableBundle* pBundle, char** outKeys,
253                                          int32_t bufferSizeBytes,
254                                          APersistableBundle_stringAllocator stringAllocator,
255                                          void* context) {
256     std::set<android::String16> ret = pBundle->mPBundle.getDoubleKeys();
257     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
258                                                            stringAllocator, context);
259 }
APersistableBundle_getStringKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)260 int32_t APersistableBundle_getStringKeys(const APersistableBundle* pBundle, char** outKeys,
261                                          int32_t bufferSizeBytes,
262                                          APersistableBundle_stringAllocator stringAllocator,
263                                          void* context) {
264     std::set<android::String16> ret = pBundle->mPBundle.getStringKeys();
265     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
266                                                            stringAllocator, context);
267 }
APersistableBundle_getBooleanVectorKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)268 int32_t APersistableBundle_getBooleanVectorKeys(const APersistableBundle* pBundle, char** outKeys,
269                                                 int32_t bufferSizeBytes,
270                                                 APersistableBundle_stringAllocator stringAllocator,
271                                                 void* context) {
272     std::set<android::String16> ret = pBundle->mPBundle.getBooleanVectorKeys();
273     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
274                                                            stringAllocator, context);
275 }
APersistableBundle_getIntVectorKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)276 int32_t APersistableBundle_getIntVectorKeys(const APersistableBundle* pBundle, char** outKeys,
277                                             int32_t bufferSizeBytes,
278                                             APersistableBundle_stringAllocator stringAllocator,
279                                             void* context) {
280     std::set<android::String16> ret = pBundle->mPBundle.getIntVectorKeys();
281     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
282                                                            stringAllocator, context);
283 }
APersistableBundle_getLongVectorKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)284 int32_t APersistableBundle_getLongVectorKeys(const APersistableBundle* pBundle, char** outKeys,
285                                              int32_t bufferSizeBytes,
286                                              APersistableBundle_stringAllocator stringAllocator,
287                                              void* context) {
288     std::set<android::String16> ret = pBundle->mPBundle.getLongVectorKeys();
289     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
290                                                            stringAllocator, context);
291 }
APersistableBundle_getDoubleVectorKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)292 int32_t APersistableBundle_getDoubleVectorKeys(const APersistableBundle* pBundle, char** outKeys,
293                                                int32_t bufferSizeBytes,
294                                                APersistableBundle_stringAllocator stringAllocator,
295                                                void* context) {
296     std::set<android::String16> ret = pBundle->mPBundle.getDoubleVectorKeys();
297     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
298                                                            stringAllocator, context);
299 }
APersistableBundle_getStringVectorKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)300 int32_t APersistableBundle_getStringVectorKeys(const APersistableBundle* pBundle, char** outKeys,
301                                                int32_t bufferSizeBytes,
302                                                APersistableBundle_stringAllocator stringAllocator,
303                                                void* context) {
304     std::set<android::String16> ret = pBundle->mPBundle.getStringVectorKeys();
305     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
306                                                            stringAllocator, context);
307 }
APersistableBundle_getPersistableBundleKeys(const APersistableBundle * pBundle,char ** outKeys,int32_t bufferSizeBytes,APersistableBundle_stringAllocator stringAllocator,void * context)308 int32_t APersistableBundle_getPersistableBundleKeys(
309         const APersistableBundle* pBundle, char** outKeys, int32_t bufferSizeBytes,
310         APersistableBundle_stringAllocator stringAllocator, void* context) {
311     std::set<android::String16> ret = pBundle->mPBundle.getPersistableBundleKeys();
312     return getStringsInternal<std::set<android::String16>>(ret, outKeys, bufferSizeBytes,
313                                                            stringAllocator, context);
314 }
315 
316 __END_DECLS
317