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 
     21 #include <limits>
     22 
     23 #include <binder/IBinder.h>
     24 #include <binder/Parcel.h>
     25 #include <log/log.h>
     26 #include <utils/Errors.h>
     27 
     28 using android::BAD_TYPE;
     29 using android::BAD_VALUE;
     30 using android::NO_ERROR;
     31 using android::Parcel;
     32 using android::sp;
     33 using android::status_t;
     34 using android::UNEXPECTED_NULL;
     35 
     36 enum {
     37     // Keep in sync with BUNDLE_MAGIC in frameworks/base/core/java/android/os/BaseBundle.java.
     38     BUNDLE_MAGIC = 0x4C444E42,
     39 };
     40 
     41 enum {
     42     // Keep in sync with frameworks/base/core/java/android/os/Parcel.java.
     43     VAL_STRING = 0,
     44     VAL_INTEGER = 1,
     45     VAL_LONG = 6,
     46     VAL_DOUBLE = 8,
     47     VAL_BOOLEAN = 9,
     48     VAL_STRINGARRAY = 14,
     49     VAL_INTARRAY = 18,
     50     VAL_LONGARRAY = 19,
     51     VAL_BOOLEANARRAY = 23,
     52     VAL_PERSISTABLEBUNDLE = 25,
     53     VAL_DOUBLEARRAY = 28,
     54 };
     55 
     56 namespace {
     57 template <typename T>
     58 bool getValue(const android::String16& key, T* out, const std::map<android::String16, T>& map) {
     59     const auto& it = map.find(key);
     60     if (it == map.end()) return false;
     61     *out = it->second;
     62     return true;
     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 std::vector<bool>& value) {
    192     erase(key);
    193     mBoolVectorMap[key] = value;
    194 }
    195 
    196 void PersistableBundle::putIntVector(const String16& key, const std::vector<int32_t>& value) {
    197     erase(key);
    198     mIntVectorMap[key] = value;
    199 }
    200 
    201 void PersistableBundle::putLongVector(const String16& key, const std::vector<int64_t>& value) {
    202     erase(key);
    203     mLongVectorMap[key] = value;
    204 }
    205 
    206 void PersistableBundle::putDoubleVector(const String16& key, const std::vector<double>& value) {
    207     erase(key);
    208     mDoubleVectorMap[key] = value;
    209 }
    210 
    211 void PersistableBundle::putStringVector(const String16& key, const std::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, std::vector<bool>* out) const {
    242     return getValue(key, out, mBoolVectorMap);
    243 }
    244 
    245 bool PersistableBundle::getIntVector(const String16& key, std::vector<int32_t>* out) const {
    246     return getValue(key, out, mIntVectorMap);
    247 }
    248 
    249 bool PersistableBundle::getLongVector(const String16& key, std::vector<int64_t>* out) const {
    250     return getValue(key, out, mLongVectorMap);
    251 }
    252 
    253 bool PersistableBundle::getDoubleVector(const String16& key, std::vector<double>* out) const {
    254     return getValue(key, out, mDoubleVectorMap);
    255 }
    256 
    257 bool PersistableBundle::getStringVector(const String16& key, std::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 status_t PersistableBundle::writeToParcelInner(Parcel* parcel) const {
    266     /*
    267      * To keep this implementation in sync with writeArrayMapInternal() in
    268      * frameworks/base/core/java/android/os/Parcel.java, the number of key
    269      * value pairs must be written into the parcel before writing the key-value
    270      * pairs themselves.
    271      */
    272     size_t num_entries = size();
    273     if (num_entries > std::numeric_limits<int32_t>::max()) {
    274         ALOGE("The size of this PersistableBundle (%zu) too large to store in 32-bit signed int",
    275               num_entries);
    276         return BAD_VALUE;
    277     }
    278     RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(num_entries)));
    279 
    280     for (const auto& key_val_pair : mBoolMap) {
    281         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    282         RETURN_IF_FAILED(parcel->writeInt32(VAL_BOOLEAN));
    283         RETURN_IF_FAILED(parcel->writeBool(key_val_pair.second));
    284     }
    285     for (const auto& key_val_pair : mIntMap) {
    286         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    287         RETURN_IF_FAILED(parcel->writeInt32(VAL_INTEGER));
    288         RETURN_IF_FAILED(parcel->writeInt32(key_val_pair.second));
    289     }
    290     for (const auto& key_val_pair : mLongMap) {
    291         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    292         RETURN_IF_FAILED(parcel->writeInt32(VAL_LONG));
    293         RETURN_IF_FAILED(parcel->writeInt64(key_val_pair.second));
    294     }
    295     for (const auto& key_val_pair : mDoubleMap) {
    296         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    297         RETURN_IF_FAILED(parcel->writeInt32(VAL_DOUBLE));
    298         RETURN_IF_FAILED(parcel->writeDouble(key_val_pair.second));
    299     }
    300     for (const auto& key_val_pair : mStringMap) {
    301         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    302         RETURN_IF_FAILED(parcel->writeInt32(VAL_STRING));
    303         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.second));
    304     }
    305     for (const auto& key_val_pair : mBoolVectorMap) {
    306         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    307         RETURN_IF_FAILED(parcel->writeInt32(VAL_BOOLEANARRAY));
    308         RETURN_IF_FAILED(parcel->writeBoolVector(key_val_pair.second));
    309     }
    310     for (const auto& key_val_pair : mIntVectorMap) {
    311         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    312         RETURN_IF_FAILED(parcel->writeInt32(VAL_INTARRAY));
    313         RETURN_IF_FAILED(parcel->writeInt32Vector(key_val_pair.second));
    314     }
    315     for (const auto& key_val_pair : mLongVectorMap) {
    316         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    317         RETURN_IF_FAILED(parcel->writeInt32(VAL_LONGARRAY));
    318         RETURN_IF_FAILED(parcel->writeInt64Vector(key_val_pair.second));
    319     }
    320     for (const auto& key_val_pair : mDoubleVectorMap) {
    321         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    322         RETURN_IF_FAILED(parcel->writeInt32(VAL_DOUBLEARRAY));
    323         RETURN_IF_FAILED(parcel->writeDoubleVector(key_val_pair.second));
    324     }
    325     for (const auto& key_val_pair : mStringVectorMap) {
    326         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    327         RETURN_IF_FAILED(parcel->writeInt32(VAL_STRINGARRAY));
    328         RETURN_IF_FAILED(parcel->writeString16Vector(key_val_pair.second));
    329     }
    330     for (const auto& key_val_pair : mPersistableBundleMap) {
    331         RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
    332         RETURN_IF_FAILED(parcel->writeInt32(VAL_PERSISTABLEBUNDLE));
    333         RETURN_IF_FAILED(key_val_pair.second.writeToParcel(parcel));
    334     }
    335     return NO_ERROR;
    336 }
    337 
    338 status_t PersistableBundle::readFromParcelInner(const Parcel* parcel, size_t length) {
    339     /*
    340      * Note: we don't actually use length for anything other than an empty PersistableBundle
    341      * check, since we do not actually need to copy in an entire Parcel, unlike in the Java
    342      * implementation.
    343      */
    344     if (length == 0) {
    345         // Empty PersistableBundle or end of data.
    346         return NO_ERROR;
    347     }
    348 
    349     int32_t magic;
    350     RETURN_IF_FAILED(parcel->readInt32(&magic));
    351     if (magic != BUNDLE_MAGIC) {
    352         ALOGE("Bad magic number for PersistableBundle: 0x%08x", magic);
    353         return BAD_VALUE;
    354     }
    355 
    356     /*
    357      * To keep this implementation in sync with unparcel() in
    358      * frameworks/base/core/java/android/os/BaseBundle.java, the number of
    359      * key-value pairs must be read from the parcel before reading the key-value
    360      * pairs themselves.
    361      */
    362     int32_t num_entries;
    363     RETURN_IF_FAILED(parcel->readInt32(&num_entries));
    364 
    365     for (; num_entries > 0; --num_entries) {
    366         size_t start_pos = parcel->dataPosition();
    367         String16 key;
    368         int32_t value_type;
    369         RETURN_IF_FAILED(parcel->readString16(&key));
    370         RETURN_IF_FAILED(parcel->readInt32(&value_type));
    371 
    372         /*
    373          * We assume that both the C++ and Java APIs ensure that all keys in a PersistableBundle
    374          * are unique.
    375          */
    376         switch (value_type) {
    377             case VAL_STRING: {
    378                 RETURN_IF_FAILED(parcel->readString16(&mStringMap[key]));
    379                 break;
    380             }
    381             case VAL_INTEGER: {
    382                 RETURN_IF_FAILED(parcel->readInt32(&mIntMap[key]));
    383                 break;
    384             }
    385             case VAL_LONG: {
    386                 RETURN_IF_FAILED(parcel->readInt64(&mLongMap[key]));
    387                 break;
    388             }
    389             case VAL_DOUBLE: {
    390                 RETURN_IF_FAILED(parcel->readDouble(&mDoubleMap[key]));
    391                 break;
    392             }
    393             case VAL_BOOLEAN: {
    394                 RETURN_IF_FAILED(parcel->readBool(&mBoolMap[key]));
    395                 break;
    396             }
    397             case VAL_STRINGARRAY: {
    398                 RETURN_IF_FAILED(parcel->readString16Vector(&mStringVectorMap[key]));
    399                 break;
    400             }
    401             case VAL_INTARRAY: {
    402                 RETURN_IF_FAILED(parcel->readInt32Vector(&mIntVectorMap[key]));
    403                 break;
    404             }
    405             case VAL_LONGARRAY: {
    406                 RETURN_IF_FAILED(parcel->readInt64Vector(&mLongVectorMap[key]));
    407                 break;
    408             }
    409             case VAL_BOOLEANARRAY: {
    410                 RETURN_IF_FAILED(parcel->readBoolVector(&mBoolVectorMap[key]));
    411                 break;
    412             }
    413             case VAL_PERSISTABLEBUNDLE: {
    414                 RETURN_IF_FAILED(mPersistableBundleMap[key].readFromParcel(parcel));
    415                 break;
    416             }
    417             case VAL_DOUBLEARRAY: {
    418                 RETURN_IF_FAILED(parcel->readDoubleVector(&mDoubleVectorMap[key]));
    419                 break;
    420             }
    421             default: {
    422                 ALOGE("Unrecognized type: %d", value_type);
    423                 return BAD_TYPE;
    424                 break;
    425             }
    426         }
    427     }
    428 
    429     return NO_ERROR;
    430 }
    431 
    432 }  // namespace os
    433 
    434 }  // namespace android
    435