| Robert Quattlebaum | 6316f5b | 2017-01-04 13:25:14 -0800 | [diff] [blame] | 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*)▮ | 
|  | 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 :*/ |