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 "Value"
     18 
     19 #include <binder/Value.h>
     20 
     21 #include <limits>
     22 
     23 #include <binder/IBinder.h>
     24 #include <binder/Parcel.h>
     25 #include <binder/Map.h>
     26 #include <private/binder/ParcelValTypes.h>
     27 #include <log/log.h>
     28 #include <utils/Errors.h>
     29 
     30 using android::BAD_TYPE;
     31 using android::BAD_VALUE;
     32 using android::NO_ERROR;
     33 using android::UNEXPECTED_NULL;
     34 using android::Parcel;
     35 using android::sp;
     36 using android::status_t;
     37 using std::map;
     38 using std::set;
     39 using std::vector;
     40 using android::binder::Value;
     41 using android::IBinder;
     42 using android::os::PersistableBundle;
     43 using namespace android::binder;
     44 
     45 // ====================================================================
     46 
     47 #define RETURN_IF_FAILED(calledOnce)                                     \
     48     do {                                                                 \
     49         status_t returnStatus = calledOnce;                              \
     50         if (returnStatus) {                                              \
     51             ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
     52             return returnStatus;                                         \
     53          }                                                               \
     54     } while(false)
     55 
     56 // ====================================================================
     57 
     58 /* These `internal_type_ptr()` functions allow this
     59  * class to work without C++ RTTI support. This technique
     60  * only works properly when called directly from this file,
     61  * but that is OK because that is the only place we will
     62  * be calling them from. */
     63 template<class T> const void* internal_type_ptr()
     64 {
     65     static const T *marker;
     66     return (void*)&marker;
     67 }
     68 
     69 /* Allows the type to be specified by the argument
     70  * instead of inside angle brackets. */
     71 template<class T> const void* internal_type_ptr(const T&)
     72 {
     73     return internal_type_ptr<T>();
     74 }
     75 
     76 // ====================================================================
     77 
     78 namespace android {
     79 
     80 namespace binder {
     81 
     82 class Value::ContentBase {
     83 public:
     84     virtual ~ContentBase() = default;
     85     virtual const void* type_ptr() const = 0;
     86     virtual ContentBase * clone() const = 0;
     87     virtual bool operator==(const ContentBase& rhs) const = 0;
     88 
     89 #ifdef LIBBINDER_VALUE_SUPPORTS_TYPE_INFO
     90     virtual const std::type_info &type() const = 0;
     91 #endif
     92 
     93     template<typename T> bool get(T* out) const;
     94 };
     95 
     96 /* This is the actual class that holds the value. */
     97 template<typename T> class Value::Content : public Value::ContentBase {
     98 public:
     99     Content() = default;
    100     Content(const T & value) : mValue(value) { }
    101 
    102     virtual ~Content() = default;
    103 
    104 #ifdef LIBBINDER_VALUE_SUPPORTS_TYPE_INFO
    105     virtual const std::type_info &type() const override
    106     {
    107         return typeid(T);
    108     }
    109 #endif
    110 
    111     virtual const void* type_ptr() const override
    112     {
    113         return internal_type_ptr<T>();
    114     }
    115 
    116     virtual ContentBase * clone() const override
    117     {
    118         return new Content(mValue);
    119     };
    120 
    121     virtual bool operator==(const ContentBase& rhs) const override
    122     {
    123         if (type_ptr() != rhs.type_ptr()) {
    124             return false;
    125         }
    126         return mValue == static_cast<const Content<T>* >(&rhs)->mValue;
    127     }
    128 
    129     T mValue;
    130 };
    131 
    132 template<typename T> bool Value::ContentBase::get(T* out) const
    133 {
    134     if (internal_type_ptr(*out) != type_ptr())
    135     {
    136         return false;
    137     }
    138 
    139     *out = static_cast<const Content<T>*>(this)->mValue;
    140 
    141     return true;
    142 }
    143 
    144 // ====================================================================
    145 
    146 Value::Value() : mContent(NULL)
    147 {
    148 }
    149 
    150 Value::Value(const Value& value)
    151     : mContent(value.mContent ? value.mContent->clone() : NULL)
    152 {
    153 }
    154 
    155 Value::~Value()
    156 {
    157     delete mContent;
    158 }
    159 
    160 bool Value::operator==(const Value& rhs) const
    161 {
    162     const Value& lhs(*this);
    163 
    164     if (lhs.empty() && rhs.empty()) {
    165         return true;
    166     }
    167 
    168     if ( (lhs.mContent == NULL)
    169       || (rhs.mContent == NULL)
    170     ) {
    171         return false;
    172     }
    173 
    174     return *lhs.mContent == *rhs.mContent;
    175 }
    176 
    177 Value& Value::swap(Value &rhs)
    178 {
    179     std::swap(mContent, rhs.mContent);
    180     return *this;
    181 }
    182 
    183 Value& Value::operator=(const Value& rhs)
    184 {
    185     delete mContent;
    186     mContent = rhs.mContent
    187         ? rhs.mContent->clone()
    188         : NULL;
    189     return *this;
    190 }
    191 
    192 bool Value::empty() const
    193 {
    194     return mContent == NULL;
    195 }
    196 
    197 void Value::clear()
    198 {
    199     delete mContent;
    200     mContent = NULL;
    201 }
    202 
    203 int32_t Value::parcelType() const
    204 {
    205     const void* t_info(mContent ? mContent->type_ptr() : NULL);
    206 
    207     if (t_info == internal_type_ptr<bool>()) return VAL_BOOLEAN;
    208     if (t_info == internal_type_ptr<uint8_t>()) return VAL_BYTE;
    209     if (t_info == internal_type_ptr<int32_t>()) return VAL_INTEGER;
    210     if (t_info == internal_type_ptr<int64_t>()) return VAL_LONG;
    211     if (t_info == internal_type_ptr<double>()) return VAL_DOUBLE;
    212     if (t_info == internal_type_ptr<String16>()) return VAL_STRING;
    213 
    214     if (t_info == internal_type_ptr<vector<bool>>()) return VAL_BOOLEANARRAY;
    215     if (t_info == internal_type_ptr<vector<uint8_t>>()) return VAL_BYTEARRAY;
    216     if (t_info == internal_type_ptr<vector<int32_t>>()) return VAL_INTARRAY;
    217     if (t_info == internal_type_ptr<vector<int64_t>>()) return VAL_LONGARRAY;
    218     if (t_info == internal_type_ptr<vector<double>>()) return VAL_DOUBLEARRAY;
    219     if (t_info == internal_type_ptr<vector<String16>>()) return VAL_STRINGARRAY;
    220 
    221     if (t_info == internal_type_ptr<Map>()) return VAL_MAP;
    222     if (t_info == internal_type_ptr<PersistableBundle>()) return VAL_PERSISTABLEBUNDLE;
    223 
    224     return VAL_NULL;
    225 }
    226 
    227 #ifdef LIBBINDER_VALUE_SUPPORTS_TYPE_INFO
    228 const std::type_info& Value::type() const
    229 {
    230     return mContent != NULL
    231         ? mContent->type()
    232         : typeid(void);
    233 }
    234 #endif // ifdef LIBBINDER_VALUE_SUPPORTS_TYPE_INFO
    235 
    236 #define DEF_TYPE_ACCESSORS(T, TYPENAME)                      \
    237     bool Value::is ## TYPENAME() const                       \
    238     {                                                        \
    239         return mContent                                      \
    240             ? internal_type_ptr<T>() == mContent->type_ptr() \
    241             : false;                                         \
    242     }                                                        \
    243     bool Value::get ## TYPENAME(T* out) const                \
    244     {                                                        \
    245         return mContent                                      \
    246             ? mContent->get(out)                             \
    247             : false;                                         \
    248     }                                                        \
    249     void Value::put ## TYPENAME(const T& in)                 \
    250     {                                                        \
    251         *this = in;                                          \
    252     }                                                        \
    253     Value& Value::operator=(const T& rhs)                    \
    254     {                                                        \
    255         delete mContent;                                     \
    256         mContent = new Content< T >(rhs);                    \
    257         return *this;                                        \
    258     }                                                        \
    259     Value::Value(const T& value)                             \
    260         : mContent(new Content< T >(value))                  \
    261     { }
    262 
    263 DEF_TYPE_ACCESSORS(bool, Boolean)
    264 DEF_TYPE_ACCESSORS(int8_t, Byte)
    265 DEF_TYPE_ACCESSORS(int32_t, Int)
    266 DEF_TYPE_ACCESSORS(int64_t, Long)
    267 DEF_TYPE_ACCESSORS(double, Double)
    268 DEF_TYPE_ACCESSORS(String16, String)
    269 
    270 DEF_TYPE_ACCESSORS(std::vector<bool>, BooleanVector)
    271 DEF_TYPE_ACCESSORS(std::vector<uint8_t>, ByteVector)
    272 DEF_TYPE_ACCESSORS(std::vector<int32_t>, IntVector)
    273 DEF_TYPE_ACCESSORS(std::vector<int64_t>, LongVector)
    274 DEF_TYPE_ACCESSORS(std::vector<double>, DoubleVector)
    275 DEF_TYPE_ACCESSORS(std::vector<String16>, StringVector)
    276 
    277 DEF_TYPE_ACCESSORS(::android::binder::Map, Map)
    278 DEF_TYPE_ACCESSORS(PersistableBundle, PersistableBundle)
    279 
    280 bool Value::getString(String8* out) const
    281 {
    282     String16 val;
    283     bool ret = getString(&val);
    284     if (ret) {
    285         *out = String8(val);
    286     }
    287     return ret;
    288 }
    289 
    290 bool Value::getString(::std::string* out) const
    291 {
    292     String8 val;
    293     bool ret = getString(&val);
    294     if (ret) {
    295         *out = val.string();
    296     }
    297     return ret;
    298 }
    299 
    300 status_t Value::writeToParcel(Parcel* parcel) const
    301 {
    302     // This implementation needs to be kept in sync with the writeValue
    303     // implementation in frameworks/base/core/java/android/os/Parcel.java
    304 
    305 #define BEGIN_HANDLE_WRITE()                                                                      \
    306     do {                                                                                          \
    307         const void* t_info(mContent?mContent->type_ptr():NULL);                                   \
    308         if (false) { }
    309 #define HANDLE_WRITE_TYPE(T, TYPEVAL, TYPEMETHOD)                                                 \
    310     else if (t_info == internal_type_ptr<T>()) {                                                  \
    311         RETURN_IF_FAILED(parcel->writeInt32(TYPEVAL));                                            \
    312         RETURN_IF_FAILED(parcel->TYPEMETHOD(static_cast<const Content<T>*>(mContent)->mValue));   \
    313     }
    314 #define HANDLE_WRITE_PARCELABLE(T, TYPEVAL)                                                       \
    315     else if (t_info == internal_type_ptr<T>()) {                                                  \
    316         RETURN_IF_FAILED(parcel->writeInt32(TYPEVAL));                                            \
    317         RETURN_IF_FAILED(static_cast<const Content<T>*>(mContent)->mValue.writeToParcel(parcel)); \
    318     }
    319 #define END_HANDLE_WRITE()                                                                        \
    320         else {                                                                                    \
    321             ALOGE("writeToParcel: Type not supported");                                           \
    322             return BAD_TYPE;                                                                      \
    323         }                                                                                         \
    324     } while (false);
    325 
    326     BEGIN_HANDLE_WRITE()
    327 
    328     HANDLE_WRITE_TYPE(bool,     VAL_BOOLEAN, writeBool)
    329     HANDLE_WRITE_TYPE(int8_t,   VAL_BYTE,    writeByte)
    330     HANDLE_WRITE_TYPE(int8_t,   VAL_BYTE,    writeByte)
    331     HANDLE_WRITE_TYPE(int32_t,  VAL_INTEGER, writeInt32)
    332     HANDLE_WRITE_TYPE(int64_t,  VAL_LONG,    writeInt64)
    333     HANDLE_WRITE_TYPE(double,   VAL_DOUBLE,  writeDouble)
    334     HANDLE_WRITE_TYPE(String16, VAL_STRING,  writeString16)
    335 
    336     HANDLE_WRITE_TYPE(vector<bool>,     VAL_BOOLEANARRAY, writeBoolVector)
    337     HANDLE_WRITE_TYPE(vector<uint8_t>,  VAL_BYTEARRAY,    writeByteVector)
    338     HANDLE_WRITE_TYPE(vector<int8_t>,   VAL_BYTEARRAY,    writeByteVector)
    339     HANDLE_WRITE_TYPE(vector<int32_t>,  VAL_INTARRAY,     writeInt32Vector)
    340     HANDLE_WRITE_TYPE(vector<int64_t>,  VAL_LONGARRAY,    writeInt64Vector)
    341     HANDLE_WRITE_TYPE(vector<double>,   VAL_DOUBLEARRAY,  writeDoubleVector)
    342     HANDLE_WRITE_TYPE(vector<String16>, VAL_STRINGARRAY,  writeString16Vector)
    343 
    344     HANDLE_WRITE_PARCELABLE(PersistableBundle, VAL_PERSISTABLEBUNDLE)
    345 
    346     END_HANDLE_WRITE()
    347 
    348     return NO_ERROR;
    349 
    350 #undef BEGIN_HANDLE_WRITE
    351 #undef HANDLE_WRITE_TYPE
    352 #undef HANDLE_WRITE_PARCELABLE
    353 #undef END_HANDLE_WRITE
    354 }
    355 
    356 status_t Value::readFromParcel(const Parcel* parcel)
    357 {
    358     // This implementation needs to be kept in sync with the readValue
    359     // implementation in frameworks/base/core/java/android/os/Parcel.javai
    360 
    361 #define BEGIN_HANDLE_READ()                                                                      \
    362     switch(value_type) {                                                                         \
    363         default:                                                                                 \
    364             ALOGE("readFromParcel: Parcel type %d is not supported", value_type);                \
    365             return BAD_TYPE;
    366 #define HANDLE_READ_TYPE(T, TYPEVAL, TYPEMETHOD)                                                 \
    367         case TYPEVAL:                                                                            \
    368             mContent = new Content<T>();                                                         \
    369             RETURN_IF_FAILED(parcel->TYPEMETHOD(&static_cast<Content<T>*>(mContent)->mValue));   \
    370             break;
    371 #define HANDLE_READ_PARCELABLE(T, TYPEVAL)                                                       \
    372         case TYPEVAL:                                                                            \
    373             mContent = new Content<T>();                                                         \
    374             RETURN_IF_FAILED(static_cast<Content<T>*>(mContent)->mValue.readFromParcel(parcel)); \
    375             break;
    376 #define END_HANDLE_READ()                                                                        \
    377     }
    378 
    379     int32_t value_type = VAL_NULL;
    380 
    381     delete mContent;
    382     mContent = NULL;
    383 
    384     RETURN_IF_FAILED(parcel->readInt32(&value_type));
    385 
    386     BEGIN_HANDLE_READ()
    387 
    388     HANDLE_READ_TYPE(bool,     VAL_BOOLEAN, readBool)
    389     HANDLE_READ_TYPE(int8_t,   VAL_BYTE,    readByte)
    390     HANDLE_READ_TYPE(int32_t,  VAL_INTEGER, readInt32)
    391     HANDLE_READ_TYPE(int64_t,  VAL_LONG,    readInt64)
    392     HANDLE_READ_TYPE(double,   VAL_DOUBLE,  readDouble)
    393     HANDLE_READ_TYPE(String16, VAL_STRING,  readString16)
    394 
    395     HANDLE_READ_TYPE(vector<bool>,     VAL_BOOLEANARRAY, readBoolVector)
    396     HANDLE_READ_TYPE(vector<uint8_t>,  VAL_BYTEARRAY,    readByteVector)
    397     HANDLE_READ_TYPE(vector<int32_t>,  VAL_INTARRAY,     readInt32Vector)
    398     HANDLE_READ_TYPE(vector<int64_t>,  VAL_LONGARRAY,    readInt64Vector)
    399     HANDLE_READ_TYPE(vector<double>,   VAL_DOUBLEARRAY,  readDoubleVector)
    400     HANDLE_READ_TYPE(vector<String16>, VAL_STRINGARRAY,  readString16Vector)
    401 
    402     HANDLE_READ_PARCELABLE(PersistableBundle, VAL_PERSISTABLEBUNDLE)
    403 
    404     END_HANDLE_READ()
    405 
    406     return NO_ERROR;
    407 
    408 #undef BEGIN_HANDLE_READ
    409 #undef HANDLE_READ_TYPE
    410 #undef HANDLE_READ_PARCELABLE
    411 #undef END_HANDLE_READ
    412 }
    413 
    414 }  // namespace binder
    415 
    416 }  // namespace android
    417 
    418 /* vim: set ts=4 sw=4 tw=0 et :*/
    419