xref: /aosp_15_r20/frameworks/native/libs/binder/PersistableBundle.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2015 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 #define LOG_TAG "PersistableBundle"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <binder/PersistableBundle.h>
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <limits>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include <binder/IBinder.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <utils/Errors.h>
27*38e8c45fSAndroid Build Coastguard Worker 
28*38e8c45fSAndroid Build Coastguard Worker #include "ParcelValTypes.h"
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_BOOLEAN;
31*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_INTEGER;
32*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_LONG;
33*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_DOUBLE;
34*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_STRING;
35*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_BOOLEANARRAY;
36*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_INTARRAY;
37*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_LONGARRAY;
38*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_DOUBLEARRAY;
39*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_STRINGARRAY;
40*38e8c45fSAndroid Build Coastguard Worker using android::binder::VAL_PERSISTABLEBUNDLE;
41*38e8c45fSAndroid Build Coastguard Worker 
42*38e8c45fSAndroid Build Coastguard Worker using std::map;
43*38e8c45fSAndroid Build Coastguard Worker using std::set;
44*38e8c45fSAndroid Build Coastguard Worker using std::vector;
45*38e8c45fSAndroid Build Coastguard Worker 
46*38e8c45fSAndroid Build Coastguard Worker enum {
47*38e8c45fSAndroid Build Coastguard Worker     // Keep them in sync with BUNDLE_MAGIC* in frameworks/base/core/java/android/os/BaseBundle.java.
48*38e8c45fSAndroid Build Coastguard Worker     BUNDLE_MAGIC = 0x4C444E42,
49*38e8c45fSAndroid Build Coastguard Worker     BUNDLE_MAGIC_NATIVE = 0x4C444E44,
50*38e8c45fSAndroid Build Coastguard Worker };
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker namespace {
53*38e8c45fSAndroid Build Coastguard Worker template <typename T>
getValue(const android::String16 & key,T * out,const map<android::String16,T> & map)54*38e8c45fSAndroid Build Coastguard Worker bool getValue(const android::String16& key, T* out, const map<android::String16, T>& map) {
55*38e8c45fSAndroid Build Coastguard Worker     const auto& it = map.find(key);
56*38e8c45fSAndroid Build Coastguard Worker     if (it == map.end()) return false;
57*38e8c45fSAndroid Build Coastguard Worker     *out = it->second;
58*38e8c45fSAndroid Build Coastguard Worker     return true;
59*38e8c45fSAndroid Build Coastguard Worker }
60*38e8c45fSAndroid Build Coastguard Worker 
61*38e8c45fSAndroid Build Coastguard Worker template <typename T>
getKeys(const map<android::String16,T> & map)62*38e8c45fSAndroid Build Coastguard Worker set<android::String16> getKeys(const map<android::String16, T>& map) {
63*38e8c45fSAndroid Build Coastguard Worker     if (map.empty()) return set<android::String16>();
64*38e8c45fSAndroid Build Coastguard Worker     set<android::String16> keys;
65*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_value_pair : map) {
66*38e8c45fSAndroid Build Coastguard Worker         keys.emplace(key_value_pair.first);
67*38e8c45fSAndroid Build Coastguard Worker     }
68*38e8c45fSAndroid Build Coastguard Worker     return keys;
69*38e8c45fSAndroid Build Coastguard Worker }
70*38e8c45fSAndroid Build Coastguard Worker }  // namespace
71*38e8c45fSAndroid Build Coastguard Worker 
72*38e8c45fSAndroid Build Coastguard Worker namespace android {
73*38e8c45fSAndroid Build Coastguard Worker 
74*38e8c45fSAndroid Build Coastguard Worker namespace os {
75*38e8c45fSAndroid Build Coastguard Worker 
76*38e8c45fSAndroid Build Coastguard Worker #define RETURN_IF_FAILED(calledOnce)                                     \
77*38e8c45fSAndroid Build Coastguard Worker     {                                                                    \
78*38e8c45fSAndroid Build Coastguard Worker         status_t returnStatus = calledOnce;                              \
79*38e8c45fSAndroid Build Coastguard Worker         if (returnStatus) {                                              \
80*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
81*38e8c45fSAndroid Build Coastguard Worker             return returnStatus;                                         \
82*38e8c45fSAndroid Build Coastguard Worker          }                                                               \
83*38e8c45fSAndroid Build Coastguard Worker     }
84*38e8c45fSAndroid Build Coastguard Worker 
85*38e8c45fSAndroid Build Coastguard Worker #define RETURN_IF_ENTRY_ERASED(map, key)      \
86*38e8c45fSAndroid Build Coastguard Worker     {                                         \
87*38e8c45fSAndroid Build Coastguard Worker         size_t num_erased = (map).erase(key); \
88*38e8c45fSAndroid Build Coastguard Worker         if (num_erased) {                     \
89*38e8c45fSAndroid Build Coastguard Worker             return num_erased;                \
90*38e8c45fSAndroid Build Coastguard Worker         }                                     \
91*38e8c45fSAndroid Build Coastguard Worker     }
92*38e8c45fSAndroid Build Coastguard Worker 
writeToParcel(Parcel * parcel) const93*38e8c45fSAndroid Build Coastguard Worker status_t PersistableBundle::writeToParcel(Parcel* parcel) const {
94*38e8c45fSAndroid Build Coastguard Worker     /*
95*38e8c45fSAndroid Build Coastguard Worker      * Keep implementation in sync with writeToParcelInner() in
96*38e8c45fSAndroid Build Coastguard Worker      * frameworks/base/core/java/android/os/BaseBundle.java.
97*38e8c45fSAndroid Build Coastguard Worker      */
98*38e8c45fSAndroid Build Coastguard Worker 
99*38e8c45fSAndroid Build Coastguard Worker     // Special case for empty bundles.
100*38e8c45fSAndroid Build Coastguard Worker     if (empty()) {
101*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(0));
102*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
103*38e8c45fSAndroid Build Coastguard Worker     }
104*38e8c45fSAndroid Build Coastguard Worker 
105*38e8c45fSAndroid Build Coastguard Worker     size_t length_pos = parcel->dataPosition();
106*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_FAILED(parcel->writeInt32(1));  // dummy, will hold length
107*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_FAILED(parcel->writeInt32(BUNDLE_MAGIC_NATIVE));
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker     size_t start_pos = parcel->dataPosition();
110*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_FAILED(writeToParcelInner(parcel));
111*38e8c45fSAndroid Build Coastguard Worker     size_t end_pos = parcel->dataPosition();
112*38e8c45fSAndroid Build Coastguard Worker 
113*38e8c45fSAndroid Build Coastguard Worker     // Backpatch length. This length value includes the length header.
114*38e8c45fSAndroid Build Coastguard Worker     parcel->setDataPosition(length_pos);
115*38e8c45fSAndroid Build Coastguard Worker     size_t length = end_pos - start_pos;
116*38e8c45fSAndroid Build Coastguard Worker     if (length > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
117*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Parcel length (%zu) too large to store in 32-bit signed int", length);
118*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
119*38e8c45fSAndroid Build Coastguard Worker     }
120*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(length)));
121*38e8c45fSAndroid Build Coastguard Worker     parcel->setDataPosition(end_pos);
122*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
123*38e8c45fSAndroid Build Coastguard Worker }
124*38e8c45fSAndroid Build Coastguard Worker 
readFromParcel(const Parcel * parcel)125*38e8c45fSAndroid Build Coastguard Worker status_t PersistableBundle::readFromParcel(const Parcel* parcel) {
126*38e8c45fSAndroid Build Coastguard Worker     /*
127*38e8c45fSAndroid Build Coastguard Worker      * Keep implementation in sync with readFromParcelInner() in
128*38e8c45fSAndroid Build Coastguard Worker      * frameworks/base/core/java/android/os/BaseBundle.java.
129*38e8c45fSAndroid Build Coastguard Worker      */
130*38e8c45fSAndroid Build Coastguard Worker     int32_t length = parcel->readInt32();
131*38e8c45fSAndroid Build Coastguard Worker     if (length < 0) {
132*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Bad length in parcel: %d", length);
133*38e8c45fSAndroid Build Coastguard Worker         return UNEXPECTED_NULL;
134*38e8c45fSAndroid Build Coastguard Worker     }
135*38e8c45fSAndroid Build Coastguard Worker 
136*38e8c45fSAndroid Build Coastguard Worker     return readFromParcelInner(parcel, static_cast<size_t>(length));
137*38e8c45fSAndroid Build Coastguard Worker }
138*38e8c45fSAndroid Build Coastguard Worker 
empty() const139*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::empty() const {
140*38e8c45fSAndroid Build Coastguard Worker     return size() == 0u;
141*38e8c45fSAndroid Build Coastguard Worker }
142*38e8c45fSAndroid Build Coastguard Worker 
size() const143*38e8c45fSAndroid Build Coastguard Worker size_t PersistableBundle::size() const {
144*38e8c45fSAndroid Build Coastguard Worker     return (mBoolMap.size() +
145*38e8c45fSAndroid Build Coastguard Worker             mIntMap.size() +
146*38e8c45fSAndroid Build Coastguard Worker             mLongMap.size() +
147*38e8c45fSAndroid Build Coastguard Worker             mDoubleMap.size() +
148*38e8c45fSAndroid Build Coastguard Worker             mStringMap.size() +
149*38e8c45fSAndroid Build Coastguard Worker             mBoolVectorMap.size() +
150*38e8c45fSAndroid Build Coastguard Worker             mIntVectorMap.size() +
151*38e8c45fSAndroid Build Coastguard Worker             mLongVectorMap.size() +
152*38e8c45fSAndroid Build Coastguard Worker             mDoubleVectorMap.size() +
153*38e8c45fSAndroid Build Coastguard Worker             mStringVectorMap.size() +
154*38e8c45fSAndroid Build Coastguard Worker             mPersistableBundleMap.size());
155*38e8c45fSAndroid Build Coastguard Worker }
156*38e8c45fSAndroid Build Coastguard Worker 
erase(const String16 & key)157*38e8c45fSAndroid Build Coastguard Worker size_t PersistableBundle::erase(const String16& key) {
158*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mBoolMap, key);
159*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mIntMap, key);
160*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mLongMap, key);
161*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mDoubleMap, key);
162*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mStringMap, key);
163*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mBoolVectorMap, key);
164*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mIntVectorMap, key);
165*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mLongVectorMap, key);
166*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mDoubleVectorMap, key);
167*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_ENTRY_ERASED(mStringVectorMap, key);
168*38e8c45fSAndroid Build Coastguard Worker     return mPersistableBundleMap.erase(key);
169*38e8c45fSAndroid Build Coastguard Worker }
170*38e8c45fSAndroid Build Coastguard Worker 
putBoolean(const String16 & key,bool value)171*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putBoolean(const String16& key, bool value) {
172*38e8c45fSAndroid Build Coastguard Worker     erase(key);
173*38e8c45fSAndroid Build Coastguard Worker     mBoolMap[key] = value;
174*38e8c45fSAndroid Build Coastguard Worker }
175*38e8c45fSAndroid Build Coastguard Worker 
putInt(const String16 & key,int32_t value)176*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putInt(const String16& key, int32_t value) {
177*38e8c45fSAndroid Build Coastguard Worker     erase(key);
178*38e8c45fSAndroid Build Coastguard Worker     mIntMap[key] = value;
179*38e8c45fSAndroid Build Coastguard Worker }
180*38e8c45fSAndroid Build Coastguard Worker 
putLong(const String16 & key,int64_t value)181*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putLong(const String16& key, int64_t value) {
182*38e8c45fSAndroid Build Coastguard Worker     erase(key);
183*38e8c45fSAndroid Build Coastguard Worker     mLongMap[key] = value;
184*38e8c45fSAndroid Build Coastguard Worker }
185*38e8c45fSAndroid Build Coastguard Worker 
putDouble(const String16 & key,double value)186*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putDouble(const String16& key, double value) {
187*38e8c45fSAndroid Build Coastguard Worker     erase(key);
188*38e8c45fSAndroid Build Coastguard Worker     mDoubleMap[key] = value;
189*38e8c45fSAndroid Build Coastguard Worker }
190*38e8c45fSAndroid Build Coastguard Worker 
putString(const String16 & key,const String16 & value)191*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putString(const String16& key, const String16& value) {
192*38e8c45fSAndroid Build Coastguard Worker     erase(key);
193*38e8c45fSAndroid Build Coastguard Worker     mStringMap[key] = value;
194*38e8c45fSAndroid Build Coastguard Worker }
195*38e8c45fSAndroid Build Coastguard Worker 
putBooleanVector(const String16 & key,const vector<bool> & value)196*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putBooleanVector(const String16& key, const vector<bool>& value) {
197*38e8c45fSAndroid Build Coastguard Worker     erase(key);
198*38e8c45fSAndroid Build Coastguard Worker     mBoolVectorMap[key] = value;
199*38e8c45fSAndroid Build Coastguard Worker }
200*38e8c45fSAndroid Build Coastguard Worker 
putIntVector(const String16 & key,const vector<int32_t> & value)201*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putIntVector(const String16& key, const vector<int32_t>& value) {
202*38e8c45fSAndroid Build Coastguard Worker     erase(key);
203*38e8c45fSAndroid Build Coastguard Worker     mIntVectorMap[key] = value;
204*38e8c45fSAndroid Build Coastguard Worker }
205*38e8c45fSAndroid Build Coastguard Worker 
putLongVector(const String16 & key,const vector<int64_t> & value)206*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putLongVector(const String16& key, const vector<int64_t>& value) {
207*38e8c45fSAndroid Build Coastguard Worker     erase(key);
208*38e8c45fSAndroid Build Coastguard Worker     mLongVectorMap[key] = value;
209*38e8c45fSAndroid Build Coastguard Worker }
210*38e8c45fSAndroid Build Coastguard Worker 
putDoubleVector(const String16 & key,const vector<double> & value)211*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putDoubleVector(const String16& key, const vector<double>& value) {
212*38e8c45fSAndroid Build Coastguard Worker     erase(key);
213*38e8c45fSAndroid Build Coastguard Worker     mDoubleVectorMap[key] = value;
214*38e8c45fSAndroid Build Coastguard Worker }
215*38e8c45fSAndroid Build Coastguard Worker 
putStringVector(const String16 & key,const vector<String16> & value)216*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putStringVector(const String16& key, const vector<String16>& value) {
217*38e8c45fSAndroid Build Coastguard Worker     erase(key);
218*38e8c45fSAndroid Build Coastguard Worker     mStringVectorMap[key] = value;
219*38e8c45fSAndroid Build Coastguard Worker }
220*38e8c45fSAndroid Build Coastguard Worker 
putPersistableBundle(const String16 & key,const PersistableBundle & value)221*38e8c45fSAndroid Build Coastguard Worker void PersistableBundle::putPersistableBundle(const String16& key, const PersistableBundle& value) {
222*38e8c45fSAndroid Build Coastguard Worker     erase(key);
223*38e8c45fSAndroid Build Coastguard Worker     mPersistableBundleMap[key] = value;
224*38e8c45fSAndroid Build Coastguard Worker }
225*38e8c45fSAndroid Build Coastguard Worker 
getBoolean(const String16 & key,bool * out) const226*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getBoolean(const String16& key, bool* out) const {
227*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mBoolMap);
228*38e8c45fSAndroid Build Coastguard Worker }
229*38e8c45fSAndroid Build Coastguard Worker 
getInt(const String16 & key,int32_t * out) const230*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getInt(const String16& key, int32_t* out) const {
231*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mIntMap);
232*38e8c45fSAndroid Build Coastguard Worker }
233*38e8c45fSAndroid Build Coastguard Worker 
getLong(const String16 & key,int64_t * out) const234*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getLong(const String16& key, int64_t* out) const {
235*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mLongMap);
236*38e8c45fSAndroid Build Coastguard Worker }
237*38e8c45fSAndroid Build Coastguard Worker 
getDouble(const String16 & key,double * out) const238*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getDouble(const String16& key, double* out) const {
239*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mDoubleMap);
240*38e8c45fSAndroid Build Coastguard Worker }
241*38e8c45fSAndroid Build Coastguard Worker 
getString(const String16 & key,String16 * out) const242*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getString(const String16& key, String16* out) const {
243*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mStringMap);
244*38e8c45fSAndroid Build Coastguard Worker }
245*38e8c45fSAndroid Build Coastguard Worker 
getBooleanVector(const String16 & key,vector<bool> * out) const246*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getBooleanVector(const String16& key, vector<bool>* out) const {
247*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mBoolVectorMap);
248*38e8c45fSAndroid Build Coastguard Worker }
249*38e8c45fSAndroid Build Coastguard Worker 
getIntVector(const String16 & key,vector<int32_t> * out) const250*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getIntVector(const String16& key, vector<int32_t>* out) const {
251*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mIntVectorMap);
252*38e8c45fSAndroid Build Coastguard Worker }
253*38e8c45fSAndroid Build Coastguard Worker 
getLongVector(const String16 & key,vector<int64_t> * out) const254*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getLongVector(const String16& key, vector<int64_t>* out) const {
255*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mLongVectorMap);
256*38e8c45fSAndroid Build Coastguard Worker }
257*38e8c45fSAndroid Build Coastguard Worker 
getDoubleVector(const String16 & key,vector<double> * out) const258*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getDoubleVector(const String16& key, vector<double>* out) const {
259*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mDoubleVectorMap);
260*38e8c45fSAndroid Build Coastguard Worker }
261*38e8c45fSAndroid Build Coastguard Worker 
getStringVector(const String16 & key,vector<String16> * out) const262*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getStringVector(const String16& key, vector<String16>* out) const {
263*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mStringVectorMap);
264*38e8c45fSAndroid Build Coastguard Worker }
265*38e8c45fSAndroid Build Coastguard Worker 
getPersistableBundle(const String16 & key,PersistableBundle * out) const266*38e8c45fSAndroid Build Coastguard Worker bool PersistableBundle::getPersistableBundle(const String16& key, PersistableBundle* out) const {
267*38e8c45fSAndroid Build Coastguard Worker     return getValue(key, out, mPersistableBundleMap);
268*38e8c45fSAndroid Build Coastguard Worker }
269*38e8c45fSAndroid Build Coastguard Worker 
getBooleanKeys() const270*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getBooleanKeys() const {
271*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mBoolMap);
272*38e8c45fSAndroid Build Coastguard Worker }
273*38e8c45fSAndroid Build Coastguard Worker 
getIntKeys() const274*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getIntKeys() const {
275*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mIntMap);
276*38e8c45fSAndroid Build Coastguard Worker }
277*38e8c45fSAndroid Build Coastguard Worker 
getLongKeys() const278*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getLongKeys() const {
279*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mLongMap);
280*38e8c45fSAndroid Build Coastguard Worker }
281*38e8c45fSAndroid Build Coastguard Worker 
getDoubleKeys() const282*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getDoubleKeys() const {
283*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mDoubleMap);
284*38e8c45fSAndroid Build Coastguard Worker }
285*38e8c45fSAndroid Build Coastguard Worker 
getStringKeys() const286*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getStringKeys() const {
287*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mStringMap);
288*38e8c45fSAndroid Build Coastguard Worker }
289*38e8c45fSAndroid Build Coastguard Worker 
getBooleanVectorKeys() const290*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getBooleanVectorKeys() const {
291*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mBoolVectorMap);
292*38e8c45fSAndroid Build Coastguard Worker }
293*38e8c45fSAndroid Build Coastguard Worker 
getIntVectorKeys() const294*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getIntVectorKeys() const {
295*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mIntVectorMap);
296*38e8c45fSAndroid Build Coastguard Worker }
297*38e8c45fSAndroid Build Coastguard Worker 
getLongVectorKeys() const298*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getLongVectorKeys() const {
299*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mLongVectorMap);
300*38e8c45fSAndroid Build Coastguard Worker }
301*38e8c45fSAndroid Build Coastguard Worker 
getDoubleVectorKeys() const302*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getDoubleVectorKeys() const {
303*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mDoubleVectorMap);
304*38e8c45fSAndroid Build Coastguard Worker }
305*38e8c45fSAndroid Build Coastguard Worker 
getStringVectorKeys() const306*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getStringVectorKeys() const {
307*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mStringVectorMap);
308*38e8c45fSAndroid Build Coastguard Worker }
309*38e8c45fSAndroid Build Coastguard Worker 
getPersistableBundleKeys() const310*38e8c45fSAndroid Build Coastguard Worker set<String16> PersistableBundle::getPersistableBundleKeys() const {
311*38e8c45fSAndroid Build Coastguard Worker     return getKeys(mPersistableBundleMap);
312*38e8c45fSAndroid Build Coastguard Worker }
313*38e8c45fSAndroid Build Coastguard Worker 
writeToParcelInner(Parcel * parcel) const314*38e8c45fSAndroid Build Coastguard Worker status_t PersistableBundle::writeToParcelInner(Parcel* parcel) const {
315*38e8c45fSAndroid Build Coastguard Worker     /*
316*38e8c45fSAndroid Build Coastguard Worker      * To keep this implementation in sync with writeArrayMapInternal() in
317*38e8c45fSAndroid Build Coastguard Worker      * frameworks/base/core/java/android/os/Parcel.java, the number of key
318*38e8c45fSAndroid Build Coastguard Worker      * value pairs must be written into the parcel before writing the key-value
319*38e8c45fSAndroid Build Coastguard Worker      * pairs themselves.
320*38e8c45fSAndroid Build Coastguard Worker      */
321*38e8c45fSAndroid Build Coastguard Worker     size_t num_entries = size();
322*38e8c45fSAndroid Build Coastguard Worker     if (num_entries > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
323*38e8c45fSAndroid Build Coastguard Worker         ALOGE("The size of this PersistableBundle (%zu) too large to store in 32-bit signed int",
324*38e8c45fSAndroid Build Coastguard Worker               num_entries);
325*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
326*38e8c45fSAndroid Build Coastguard Worker     }
327*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(num_entries)));
328*38e8c45fSAndroid Build Coastguard Worker 
329*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mBoolMap) {
330*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
331*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_BOOLEAN));
332*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeBool(key_val_pair.second));
333*38e8c45fSAndroid Build Coastguard Worker     }
334*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mIntMap) {
335*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
336*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_INTEGER));
337*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(key_val_pair.second));
338*38e8c45fSAndroid Build Coastguard Worker     }
339*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mLongMap) {
340*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
341*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_LONG));
342*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt64(key_val_pair.second));
343*38e8c45fSAndroid Build Coastguard Worker     }
344*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mDoubleMap) {
345*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
346*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_DOUBLE));
347*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeDouble(key_val_pair.second));
348*38e8c45fSAndroid Build Coastguard Worker     }
349*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mStringMap) {
350*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
351*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_STRING));
352*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.second));
353*38e8c45fSAndroid Build Coastguard Worker     }
354*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mBoolVectorMap) {
355*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
356*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_BOOLEANARRAY));
357*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeBoolVector(key_val_pair.second));
358*38e8c45fSAndroid Build Coastguard Worker     }
359*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mIntVectorMap) {
360*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
361*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_INTARRAY));
362*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32Vector(key_val_pair.second));
363*38e8c45fSAndroid Build Coastguard Worker     }
364*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mLongVectorMap) {
365*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
366*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_LONGARRAY));
367*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt64Vector(key_val_pair.second));
368*38e8c45fSAndroid Build Coastguard Worker     }
369*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mDoubleVectorMap) {
370*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
371*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_DOUBLEARRAY));
372*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeDoubleVector(key_val_pair.second));
373*38e8c45fSAndroid Build Coastguard Worker     }
374*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mStringVectorMap) {
375*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
376*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_STRINGARRAY));
377*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16Vector(key_val_pair.second));
378*38e8c45fSAndroid Build Coastguard Worker     }
379*38e8c45fSAndroid Build Coastguard Worker     for (const auto& key_val_pair : mPersistableBundleMap) {
380*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
381*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->writeInt32(VAL_PERSISTABLEBUNDLE));
382*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(key_val_pair.second.writeToParcel(parcel));
383*38e8c45fSAndroid Build Coastguard Worker     }
384*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
385*38e8c45fSAndroid Build Coastguard Worker }
386*38e8c45fSAndroid Build Coastguard Worker 
readFromParcelInner(const Parcel * parcel,size_t length)387*38e8c45fSAndroid Build Coastguard Worker status_t PersistableBundle::readFromParcelInner(const Parcel* parcel, size_t length) {
388*38e8c45fSAndroid Build Coastguard Worker     /*
389*38e8c45fSAndroid Build Coastguard Worker      * Note: we don't actually use length for anything other than an empty PersistableBundle
390*38e8c45fSAndroid Build Coastguard Worker      * check, since we do not actually need to copy in an entire Parcel, unlike in the Java
391*38e8c45fSAndroid Build Coastguard Worker      * implementation.
392*38e8c45fSAndroid Build Coastguard Worker      */
393*38e8c45fSAndroid Build Coastguard Worker     if (length == 0) {
394*38e8c45fSAndroid Build Coastguard Worker         // Empty PersistableBundle or end of data.
395*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
396*38e8c45fSAndroid Build Coastguard Worker     }
397*38e8c45fSAndroid Build Coastguard Worker 
398*38e8c45fSAndroid Build Coastguard Worker     int32_t magic;
399*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_FAILED(parcel->readInt32(&magic));
400*38e8c45fSAndroid Build Coastguard Worker     if (magic != BUNDLE_MAGIC && magic != BUNDLE_MAGIC_NATIVE) {
401*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Bad magic number for PersistableBundle: 0x%08x", magic);
402*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
403*38e8c45fSAndroid Build Coastguard Worker     }
404*38e8c45fSAndroid Build Coastguard Worker 
405*38e8c45fSAndroid Build Coastguard Worker     /*
406*38e8c45fSAndroid Build Coastguard Worker      * To keep this implementation in sync with unparcel() in
407*38e8c45fSAndroid Build Coastguard Worker      * frameworks/base/core/java/android/os/BaseBundle.java, the number of
408*38e8c45fSAndroid Build Coastguard Worker      * key-value pairs must be read from the parcel before reading the key-value
409*38e8c45fSAndroid Build Coastguard Worker      * pairs themselves.
410*38e8c45fSAndroid Build Coastguard Worker      */
411*38e8c45fSAndroid Build Coastguard Worker     int32_t num_entries;
412*38e8c45fSAndroid Build Coastguard Worker     RETURN_IF_FAILED(parcel->readInt32(&num_entries));
413*38e8c45fSAndroid Build Coastguard Worker 
414*38e8c45fSAndroid Build Coastguard Worker     for (; num_entries > 0; --num_entries) {
415*38e8c45fSAndroid Build Coastguard Worker         String16 key;
416*38e8c45fSAndroid Build Coastguard Worker         int32_t value_type;
417*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->readString16(&key));
418*38e8c45fSAndroid Build Coastguard Worker         RETURN_IF_FAILED(parcel->readInt32(&value_type));
419*38e8c45fSAndroid Build Coastguard Worker 
420*38e8c45fSAndroid Build Coastguard Worker         /*
421*38e8c45fSAndroid Build Coastguard Worker          * We assume that both the C++ and Java APIs ensure that all keys in a PersistableBundle
422*38e8c45fSAndroid Build Coastguard Worker          * are unique.
423*38e8c45fSAndroid Build Coastguard Worker          */
424*38e8c45fSAndroid Build Coastguard Worker         switch (value_type) {
425*38e8c45fSAndroid Build Coastguard Worker             case VAL_STRING: {
426*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readString16(&mStringMap[key]));
427*38e8c45fSAndroid Build Coastguard Worker                 break;
428*38e8c45fSAndroid Build Coastguard Worker             }
429*38e8c45fSAndroid Build Coastguard Worker             case VAL_INTEGER: {
430*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readInt32(&mIntMap[key]));
431*38e8c45fSAndroid Build Coastguard Worker                 break;
432*38e8c45fSAndroid Build Coastguard Worker             }
433*38e8c45fSAndroid Build Coastguard Worker             case VAL_LONG: {
434*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readInt64(&mLongMap[key]));
435*38e8c45fSAndroid Build Coastguard Worker                 break;
436*38e8c45fSAndroid Build Coastguard Worker             }
437*38e8c45fSAndroid Build Coastguard Worker             case VAL_DOUBLE: {
438*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readDouble(&mDoubleMap[key]));
439*38e8c45fSAndroid Build Coastguard Worker                 break;
440*38e8c45fSAndroid Build Coastguard Worker             }
441*38e8c45fSAndroid Build Coastguard Worker             case VAL_BOOLEAN: {
442*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readBool(&mBoolMap[key]));
443*38e8c45fSAndroid Build Coastguard Worker                 break;
444*38e8c45fSAndroid Build Coastguard Worker             }
445*38e8c45fSAndroid Build Coastguard Worker             case VAL_STRINGARRAY: {
446*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readString16Vector(&mStringVectorMap[key]));
447*38e8c45fSAndroid Build Coastguard Worker                 break;
448*38e8c45fSAndroid Build Coastguard Worker             }
449*38e8c45fSAndroid Build Coastguard Worker             case VAL_INTARRAY: {
450*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readInt32Vector(&mIntVectorMap[key]));
451*38e8c45fSAndroid Build Coastguard Worker                 break;
452*38e8c45fSAndroid Build Coastguard Worker             }
453*38e8c45fSAndroid Build Coastguard Worker             case VAL_LONGARRAY: {
454*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readInt64Vector(&mLongVectorMap[key]));
455*38e8c45fSAndroid Build Coastguard Worker                 break;
456*38e8c45fSAndroid Build Coastguard Worker             }
457*38e8c45fSAndroid Build Coastguard Worker             case VAL_BOOLEANARRAY: {
458*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readBoolVector(&mBoolVectorMap[key]));
459*38e8c45fSAndroid Build Coastguard Worker                 break;
460*38e8c45fSAndroid Build Coastguard Worker             }
461*38e8c45fSAndroid Build Coastguard Worker             case VAL_PERSISTABLEBUNDLE: {
462*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(mPersistableBundleMap[key].readFromParcel(parcel));
463*38e8c45fSAndroid Build Coastguard Worker                 break;
464*38e8c45fSAndroid Build Coastguard Worker             }
465*38e8c45fSAndroid Build Coastguard Worker             case VAL_DOUBLEARRAY: {
466*38e8c45fSAndroid Build Coastguard Worker                 RETURN_IF_FAILED(parcel->readDoubleVector(&mDoubleVectorMap[key]));
467*38e8c45fSAndroid Build Coastguard Worker                 break;
468*38e8c45fSAndroid Build Coastguard Worker             }
469*38e8c45fSAndroid Build Coastguard Worker             default: {
470*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Unrecognized type: %d", value_type);
471*38e8c45fSAndroid Build Coastguard Worker                 return BAD_TYPE;
472*38e8c45fSAndroid Build Coastguard Worker                 break;
473*38e8c45fSAndroid Build Coastguard Worker             }
474*38e8c45fSAndroid Build Coastguard Worker         }
475*38e8c45fSAndroid Build Coastguard Worker     }
476*38e8c45fSAndroid Build Coastguard Worker 
477*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
478*38e8c45fSAndroid Build Coastguard Worker }
479*38e8c45fSAndroid Build Coastguard Worker 
480*38e8c45fSAndroid Build Coastguard Worker }  // namespace os
481*38e8c45fSAndroid Build Coastguard Worker 
482*38e8c45fSAndroid Build Coastguard Worker }  // namespace android
483