• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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. */
internal_type_ptr()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. */
internal_type_ptr(const T &)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;
Content(const T & value)100     explicit Content(const T & value) : mValue(value) { }
101 
102     virtual ~Content() = default;
103 
104 #ifdef LIBBINDER_VALUE_SUPPORTS_TYPE_INFO
type() const105     virtual const std::type_info &type() const override
106     {
107         return typeid(T);
108     }
109 #endif
110 
type_ptr() const111     virtual const void* type_ptr() const override
112     {
113         return internal_type_ptr<T>();
114     }
115 
clone() const116     virtual ContentBase * clone() const override
117     {
118         return new Content(mValue);
119     };
120 
operator ==(const ContentBase & rhs) const121     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 
get(T * out) const132 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 
Value()146 Value::Value() : mContent(nullptr)
147 {
148 }
149 
Value(const Value & value)150 Value::Value(const Value& value)
151     : mContent(value.mContent ? value.mContent->clone() : nullptr)
152 {
153 }
154 
~Value()155 Value::~Value()
156 {
157     delete mContent;
158 }
159 
operator ==(const Value & rhs) const160 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 == nullptr)
169       || (rhs.mContent == nullptr)
170     ) {
171         return false;
172     }
173 
174     return *lhs.mContent == *rhs.mContent;
175 }
176 
swap(Value & rhs)177 Value& Value::swap(Value &rhs)
178 {
179     std::swap(mContent, rhs.mContent);
180     return *this;
181 }
182 
operator =(const Value & rhs)183 Value& Value::operator=(const Value& rhs)
184 {
185     if (this != &rhs) {
186         delete mContent;
187         mContent = rhs.mContent
188             ? rhs.mContent->clone()
189             : nullptr;
190     }
191     return *this;
192 }
193 
empty() const194 bool Value::empty() const
195 {
196     return mContent == nullptr;
197 }
198 
clear()199 void Value::clear()
200 {
201     delete mContent;
202     mContent = nullptr;
203 }
204 
parcelType() const205 int32_t Value::parcelType() const
206 {
207     const void* t_info(mContent ? mContent->type_ptr() : nullptr);
208 
209     if (t_info == internal_type_ptr<bool>()) return VAL_BOOLEAN;
210     if (t_info == internal_type_ptr<uint8_t>()) return VAL_BYTE;
211     if (t_info == internal_type_ptr<int32_t>()) return VAL_INTEGER;
212     if (t_info == internal_type_ptr<int64_t>()) return VAL_LONG;
213     if (t_info == internal_type_ptr<double>()) return VAL_DOUBLE;
214     if (t_info == internal_type_ptr<String16>()) return VAL_STRING;
215 
216     if (t_info == internal_type_ptr<vector<bool>>()) return VAL_BOOLEANARRAY;
217     if (t_info == internal_type_ptr<vector<uint8_t>>()) return VAL_BYTEARRAY;
218     if (t_info == internal_type_ptr<vector<int32_t>>()) return VAL_INTARRAY;
219     if (t_info == internal_type_ptr<vector<int64_t>>()) return VAL_LONGARRAY;
220     if (t_info == internal_type_ptr<vector<double>>()) return VAL_DOUBLEARRAY;
221     if (t_info == internal_type_ptr<vector<String16>>()) return VAL_STRINGARRAY;
222 
223     if (t_info == internal_type_ptr<Map>()) return VAL_MAP;
224     if (t_info == internal_type_ptr<PersistableBundle>()) return VAL_PERSISTABLEBUNDLE;
225 
226     return VAL_NULL;
227 }
228 
229 #ifdef LIBBINDER_VALUE_SUPPORTS_TYPE_INFO
type() const230 const std::type_info& Value::type() const
231 {
232     return mContent != nullptr
233         ? mContent->type()
234         : typeid(void);
235 }
236 #endif // ifdef LIBBINDER_VALUE_SUPPORTS_TYPE_INFO
237 
238 #define DEF_TYPE_ACCESSORS(T, TYPENAME)                      \
239     bool Value::is ## TYPENAME() const                       \
240     {                                                        \
241         return mContent                                      \
242             ? internal_type_ptr<T>() == mContent->type_ptr() \
243             : false;                                         \
244     }                                                        \
245     bool Value::get ## TYPENAME(T* out) const                \
246     {                                                        \
247         return mContent                                      \
248             ? mContent->get(out)                             \
249             : false;                                         \
250     }                                                        \
251     void Value::put ## TYPENAME(const T& in)                 \
252     {                                                        \
253         *this = in;                                          \
254     }                                                        \
255     Value& Value::operator=(const T& rhs)                    \
256     {                                                        \
257         delete mContent;                                     \
258         mContent = new Content< T >(rhs);                    \
259         return *this;                                        \
260     }                                                        \
261     Value::Value(const T& value)                             \
262         : mContent(new Content< T >(value))                  \
263     { }
264 
DEF_TYPE_ACCESSORS(bool,Boolean)265 DEF_TYPE_ACCESSORS(bool, Boolean)
266 DEF_TYPE_ACCESSORS(int8_t, Byte)
267 DEF_TYPE_ACCESSORS(int32_t, Int)
268 DEF_TYPE_ACCESSORS(int64_t, Long)
269 DEF_TYPE_ACCESSORS(double, Double)
270 DEF_TYPE_ACCESSORS(String16, String)
271 
272 DEF_TYPE_ACCESSORS(std::vector<bool>, BooleanVector)
273 DEF_TYPE_ACCESSORS(std::vector<uint8_t>, ByteVector)
274 DEF_TYPE_ACCESSORS(std::vector<int32_t>, IntVector)
275 DEF_TYPE_ACCESSORS(std::vector<int64_t>, LongVector)
276 DEF_TYPE_ACCESSORS(std::vector<double>, DoubleVector)
277 DEF_TYPE_ACCESSORS(std::vector<String16>, StringVector)
278 
279 DEF_TYPE_ACCESSORS(::android::binder::Map, Map)
280 DEF_TYPE_ACCESSORS(PersistableBundle, PersistableBundle)
281 
282 bool Value::getString(String8* out) const
283 {
284     String16 val;
285     bool ret = getString(&val);
286     if (ret) {
287         *out = String8(val);
288     }
289     return ret;
290 }
291 
getString(::std::string * out) const292 bool Value::getString(::std::string* out) const
293 {
294     String8 val;
295     bool ret = getString(&val);
296     if (ret) {
297         *out = val.string();
298     }
299     return ret;
300 }
301 
writeToParcel(Parcel * parcel) const302 status_t Value::writeToParcel(Parcel* parcel) const
303 {
304     // This implementation needs to be kept in sync with the writeValue
305     // implementation in frameworks/base/core/java/android/os/Parcel.java
306 
307 #define BEGIN_HANDLE_WRITE()                                                                      \
308     do {                                                                                          \
309         const void* t_info(mContent?mContent->type_ptr():nullptr);                                \
310         if (false) { }
311 #define HANDLE_WRITE_TYPE(T, TYPEVAL, TYPEMETHOD)                                                 \
312     else if (t_info == internal_type_ptr<T>()) {                                                  \
313         RETURN_IF_FAILED(parcel->writeInt32(TYPEVAL));                                            \
314         RETURN_IF_FAILED(parcel->TYPEMETHOD(static_cast<const Content<T>*>(mContent)->mValue));   \
315     }
316 #define HANDLE_WRITE_PARCELABLE(T, TYPEVAL)                                                       \
317     else if (t_info == internal_type_ptr<T>()) {                                                  \
318         RETURN_IF_FAILED(parcel->writeInt32(TYPEVAL));                                            \
319         RETURN_IF_FAILED(static_cast<const Content<T>*>(mContent)->mValue.writeToParcel(parcel)); \
320     }
321 #define END_HANDLE_WRITE()                                                                        \
322         else {                                                                                    \
323             ALOGE("writeToParcel: Type not supported");                                           \
324             return BAD_TYPE;                                                                      \
325         }                                                                                         \
326     } while (false);
327 
328     BEGIN_HANDLE_WRITE()
329 
330     HANDLE_WRITE_TYPE(bool,     VAL_BOOLEAN, writeBool)
331     HANDLE_WRITE_TYPE(int8_t,   VAL_BYTE,    writeByte)
332     HANDLE_WRITE_TYPE(int8_t,   VAL_BYTE,    writeByte)
333     HANDLE_WRITE_TYPE(int32_t,  VAL_INTEGER, writeInt32)
334     HANDLE_WRITE_TYPE(int64_t,  VAL_LONG,    writeInt64)
335     HANDLE_WRITE_TYPE(double,   VAL_DOUBLE,  writeDouble)
336     HANDLE_WRITE_TYPE(String16, VAL_STRING,  writeString16)
337 
338     HANDLE_WRITE_TYPE(vector<bool>,     VAL_BOOLEANARRAY, writeBoolVector)
339     HANDLE_WRITE_TYPE(vector<uint8_t>,  VAL_BYTEARRAY,    writeByteVector)
340     HANDLE_WRITE_TYPE(vector<int8_t>,   VAL_BYTEARRAY,    writeByteVector)
341     HANDLE_WRITE_TYPE(vector<int32_t>,  VAL_INTARRAY,     writeInt32Vector)
342     HANDLE_WRITE_TYPE(vector<int64_t>,  VAL_LONGARRAY,    writeInt64Vector)
343     HANDLE_WRITE_TYPE(vector<double>,   VAL_DOUBLEARRAY,  writeDoubleVector)
344     HANDLE_WRITE_TYPE(vector<String16>, VAL_STRINGARRAY,  writeString16Vector)
345 
346     HANDLE_WRITE_PARCELABLE(PersistableBundle, VAL_PERSISTABLEBUNDLE)
347 
348     END_HANDLE_WRITE()
349 
350     return NO_ERROR;
351 
352 #undef BEGIN_HANDLE_WRITE
353 #undef HANDLE_WRITE_TYPE
354 #undef HANDLE_WRITE_PARCELABLE
355 #undef END_HANDLE_WRITE
356 }
357 
readFromParcel(const Parcel * parcel)358 status_t Value::readFromParcel(const Parcel* parcel)
359 {
360     // This implementation needs to be kept in sync with the readValue
361     // implementation in frameworks/base/core/java/android/os/Parcel.javai
362 
363 #define BEGIN_HANDLE_READ()                                                                      \
364     switch(value_type) {                                                                         \
365         default:                                                                                 \
366             ALOGE("readFromParcel: Parcel type %d is not supported", value_type);                \
367             return BAD_TYPE;
368 #define HANDLE_READ_TYPE(T, TYPEVAL, TYPEMETHOD)                                                 \
369         case TYPEVAL:                                                                            \
370             mContent = new Content<T>();                                                         \
371             RETURN_IF_FAILED(parcel->TYPEMETHOD(&static_cast<Content<T>*>(mContent)->mValue));   \
372             break;
373 #define HANDLE_READ_PARCELABLE(T, TYPEVAL)                                                       \
374         case TYPEVAL:                                                                            \
375             mContent = new Content<T>();                                                         \
376             RETURN_IF_FAILED(static_cast<Content<T>*>(mContent)->mValue.readFromParcel(parcel)); \
377             break;
378 #define END_HANDLE_READ()                                                                        \
379     }
380 
381     int32_t value_type = VAL_NULL;
382 
383     delete mContent;
384     mContent = nullptr;
385 
386     RETURN_IF_FAILED(parcel->readInt32(&value_type));
387 
388     BEGIN_HANDLE_READ()
389 
390     HANDLE_READ_TYPE(bool,     VAL_BOOLEAN, readBool)
391     HANDLE_READ_TYPE(int8_t,   VAL_BYTE,    readByte)
392     HANDLE_READ_TYPE(int32_t,  VAL_INTEGER, readInt32)
393     HANDLE_READ_TYPE(int64_t,  VAL_LONG,    readInt64)
394     HANDLE_READ_TYPE(double,   VAL_DOUBLE,  readDouble)
395     HANDLE_READ_TYPE(String16, VAL_STRING,  readString16)
396 
397     HANDLE_READ_TYPE(vector<bool>,     VAL_BOOLEANARRAY, readBoolVector)
398     HANDLE_READ_TYPE(vector<uint8_t>,  VAL_BYTEARRAY,    readByteVector)
399     HANDLE_READ_TYPE(vector<int32_t>,  VAL_INTARRAY,     readInt32Vector)
400     HANDLE_READ_TYPE(vector<int64_t>,  VAL_LONGARRAY,    readInt64Vector)
401     HANDLE_READ_TYPE(vector<double>,   VAL_DOUBLEARRAY,  readDoubleVector)
402     HANDLE_READ_TYPE(vector<String16>, VAL_STRINGARRAY,  readString16Vector)
403 
404     HANDLE_READ_PARCELABLE(PersistableBundle, VAL_PERSISTABLEBUNDLE)
405 
406     END_HANDLE_READ()
407 
408     return NO_ERROR;
409 
410 #undef BEGIN_HANDLE_READ
411 #undef HANDLE_READ_TYPE
412 #undef HANDLE_READ_PARCELABLE
413 #undef END_HANDLE_READ
414 }
415 
416 }  // namespace binder
417 
418 }  // namespace android
419 
420 /* vim: set ts=4 sw=4 tw=0 et :*/
421