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