• 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 #include "type_cpp.h"
18 
19 #include <algorithm>
20 #include <iostream>
21 #include <memory>
22 #include <vector>
23 
24 #include <android-base/stringprintf.h>
25 #include <android-base/strings.h>
26 
27 #include "logging.h"
28 
29 using std::string;
30 using std::vector;
31 
32 using android::base::Join;
33 using android::base::StringPrintf;
34 
35 namespace android {
36 namespace aidl {
37 namespace cpp {
38 namespace {
39 
40 const char kNoPackage[] = "";
41 const char kNoHeader[] = "";
42 const char kNoValidMethod[] = "";
43 Type* const kNoArrayType = nullptr;
44 Type* const kNoNullableType = nullptr;
45 
46 class VoidType : public Type {
47  public:
VoidType()48   VoidType() : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "void",
49                     {}, "void", kNoValidMethod, kNoValidMethod) {}
50   ~VoidType() override = default;
CanWriteToParcel() const51   bool CanWriteToParcel() const override { return false; }
52 };  // class VoidType
53 
54 class CppArrayType : public Type {
55  public:
CppArrayType(int kind,const std::string & package,const string & underlying_aidl_type,const string & cpp_header,const string & underlying_cpp_type,const string & underlying_cpp_type_nulllable,const string & read_method,const string & write_method,bool is_nullable,const string & src_file_name="")56   CppArrayType(int kind,  // from ValidatableType
57             const std::string& package,
58             const string& underlying_aidl_type,
59             const string& cpp_header,
60             const string& underlying_cpp_type,
61             const string& underlying_cpp_type_nulllable,
62             const string& read_method,
63             const string& write_method,
64             bool is_nullable,
65             const string& src_file_name = "")
66       : Type(kind, package,
67              underlying_aidl_type + "[]",
68              GetHeaders(is_nullable, cpp_header),
69              GetCppType(is_nullable, underlying_cpp_type),
70              read_method, write_method, kNoArrayType,
71              (is_nullable)
72                  ? kNoNullableType
73                  // All arrays are nullable.
74                  : new CppArrayType(kind, package, underlying_aidl_type,
75                                     cpp_header, underlying_cpp_type_nulllable,
76                                     underlying_cpp_type_nulllable,
77                                     read_method, write_method, true),
78              src_file_name) {}
79 
80  private:
GetHeaders(bool is_nullable,const string & cpp_header)81   static vector<string> GetHeaders(bool is_nullable, const string& cpp_header) {
82     vector<string> result = {"vector"};
83     if (is_nullable) {
84       result.push_back("memory");
85     }
86     if (!cpp_header.empty()) {
87       result.push_back(cpp_header);
88     }
89     return result;
90   }
91 
GetCppType(bool is_nullable,const string & underlying_cpp_type)92   static string GetCppType(bool is_nullable,
93                            const string& underlying_cpp_type) {
94     if (is_nullable)
95       return StringPrintf("::std::unique_ptr<::std::vector<%s>>",
96                           underlying_cpp_type.c_str());
97     return StringPrintf("::std::vector<%s>",
98                         underlying_cpp_type.c_str());
99   }
100 
101   DISALLOW_COPY_AND_ASSIGN(CppArrayType);
102 };  // class CppArrayType
103 
104 class PrimitiveType : public Type {
105  public:
PrimitiveType(const std::string & aidl_type,const std::string & header,const std::string & cpp_type,const std::string & read_method,const std::string & write_method,const std::string & read_array_method,const std::string & write_array_method)106   PrimitiveType(const std::string& aidl_type,
107                 const std::string& header,
108                 const std::string& cpp_type,
109                 const std::string& read_method,
110                 const std::string& write_method,
111                 const std::string& read_array_method,
112                 const std::string& write_array_method)
113       : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, aidl_type, {header},
114              cpp_type, read_method, write_method,
115              new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
116                               aidl_type, header, cpp_type, cpp_type,
117                               read_array_method, write_array_method,
118                               false)) {}
119 
120   ~PrimitiveType() override = default;
IsCppPrimitive() const121   bool IsCppPrimitive() const override { return true; }
122 
123  private:
124   DISALLOW_COPY_AND_ASSIGN(PrimitiveType);
125 };  // class PrimitiveType
126 
127 // Unfortunately, bytes in Java are signed.  However, most C authors would
128 // say that a byte is not in fact signed.  Compromise: customize this otherwise
129 // normal primitive to use signed single bytes, but unsigned byte arrays.
130 class ByteType : public Type {
131  public:
ByteType()132   ByteType()
133       : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "byte",
134              {"cstdint"}, "int8_t", "readByte", "writeByte",
135              new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
136                               "byte", "cstdint", "uint8_t", "uint8_t",
137                               "readByteVector", "writeByteVector",
138                               false)) {}
139 
140   ~ByteType() override = default;
IsCppPrimitive() const141   bool IsCppPrimitive() const override { return true; }
142 
143  private:
144   DISALLOW_COPY_AND_ASSIGN(ByteType);
145 };  // class PrimitiveType
146 
GetCppHeader(const AidlDefinedType & defined_type)147 static string GetCppHeader(const AidlDefinedType& defined_type) {
148   vector<string> name = defined_type.GetSplitPackage();
149   name.push_back(defined_type.GetName());
150   return Join(name, '/') + ".h";
151 }
152 
153 class BinderType : public Type {
154  public:
BinderType(const AidlInterface & interface,const std::string & src_file_name)155   BinderType(const AidlInterface& interface, const std::string& src_file_name)
156       : BinderType(interface, src_file_name,
157                    new BinderType(interface, src_file_name, kNoNullableType,
158                                   "readNullableStrongBinder"),
159                    "readStrongBinder") {}
160   ~BinderType() override = default;
161 
WriteCast(const string & val) const162   string WriteCast(const string& val) const override {
163     return write_cast_ + "(" + val + ")";
164   }
165 
166  private:
BinderType(const AidlInterface & interface,const std::string & src_file_name,Type * nullable_type,const std::string & read)167   BinderType(const AidlInterface& interface, const std::string& src_file_name, Type* nullable_type,
168              const std::string& read)
169       : Type(ValidatableType::KIND_GENERATED, interface.GetPackage(), interface.GetName(),
170              {GetCppHeader(interface)}, GetCppName(interface), read, "writeStrongBinder",
171              kNoArrayType, nullable_type, src_file_name),
172         write_cast_(GetRawCppName(interface) + "::asBinder") {}
173 
GetCppName(const AidlInterface & interface)174   static string GetCppName(const AidlInterface& interface) {
175     return "::android::sp<" + GetRawCppName(interface) + ">";
176   }
177 
GetRawCppName(const AidlInterface & interface)178   static string GetRawCppName(const AidlInterface& interface) {
179     vector<string> name = interface.GetSplitPackage();
180     string ret;
181 
182     name.push_back(interface.GetName());
183 
184     for (const auto& term : name) {
185       ret += "::" + term;
186     }
187 
188     return ret;
189   }
190 
191   std::string write_cast_;
192 };
193 
194 class NullableParcelableType : public Type {
195  public:
NullableParcelableType(const AidlParcelable & parcelable,const std::string & cpp_header,const std::string & src_file_name)196   NullableParcelableType(const AidlParcelable& parcelable, const std::string& cpp_header,
197                          const std::string& src_file_name)
198       : Type(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(), parcelable.GetName(),
199              {cpp_header}, GetCppName(parcelable), "readParcelable", "writeNullableParcelable",
200              kNoArrayType, kNoNullableType, src_file_name) {}
201   ~NullableParcelableType() override = default;
202 
203  private:
GetCppName(const AidlParcelable & parcelable)204   static string GetCppName(const AidlParcelable& parcelable) {
205     return "::std::unique_ptr<::" + Join(parcelable.GetSplitPackage(), "::") +
206         "::" + parcelable.GetCppName() + ">";
207   }
208 };
209 
210 class ParcelableType : public Type {
211  public:
ParcelableType(const AidlParcelable & parcelable,const std::string & cpp_header,const std::string & src_file_name)212   ParcelableType(const AidlParcelable& parcelable, const std::string& cpp_header,
213                  const std::string& src_file_name)
214       : Type(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(), parcelable.GetName(),
215              {cpp_header}, GetCppName(parcelable), "readParcelable", "writeParcelable",
216              new CppArrayType(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(),
217                               parcelable.GetName(), cpp_header, GetCppName(parcelable),
218                               GetCppName(parcelable), "readParcelableVector",
219                               "writeParcelableVector", false, src_file_name),
220              new NullableParcelableType(parcelable, cpp_header, src_file_name), src_file_name) {}
221   ~ParcelableType() override = default;
222 
223  private:
GetCppName(const AidlParcelable & parcelable)224   static string GetCppName(const AidlParcelable& parcelable) {
225     return "::" + Join(parcelable.GetSplitPackage(), "::") +
226         "::" + parcelable.GetCppName();
227   }
228 };
229 
230 class NullableMap : public Type {
231  public:
NullableMap()232   NullableMap()
233       : Type(ValidatableType::KIND_BUILT_IN,
234              "java.util", "Map",
235              {"binder/Map.h", "binder/Value.h"},
236              "::std::unique_ptr<::android::binder::Map>",
237              "readNullableMap", "writeNullableMap") {}
238   ~NullableMap() override = default;
239 };
240 
241 
242 class MapType : public Type {
243  public:
MapType()244   MapType()
245       : Type(ValidatableType::KIND_BUILT_IN,
246              "java.util", "Map",
247              {"binder/Map.h","binder/Value.h"},
248              "::android::binder::Map",
249              "readMap", "writeMap",
250              kNoArrayType,
251              new NullableMap() ) {}
252   ~MapType() override = default;
253 
254  private:
255   DISALLOW_COPY_AND_ASSIGN(MapType);
256 };  // class MapType
257 
258 class NullableStringListType : public Type {
259  public:
NullableStringListType()260   NullableStringListType()
261       : Type(ValidatableType::KIND_BUILT_IN,
262              "java.util", "List<" + string(kStringCanonicalName) + ">",
263              {"utils/String16.h", "memory", "vector"},
264              "::std::unique_ptr<::std::vector<std::unique_ptr<::android::String16>>>",
265              "readString16Vector", "writeString16Vector") {}
266   ~NullableStringListType() override = default;
267 
268  private:
269   DISALLOW_COPY_AND_ASSIGN(NullableStringListType);
270 };  // class NullableStringListType
271 
272 class StringListType : public Type {
273  public:
StringListType()274   StringListType()
275       : Type(ValidatableType::KIND_BUILT_IN,
276              "java.util", "List<" + string(kStringCanonicalName) + ">",
277              {"utils/String16.h", "vector"},
278              "::std::vector<::android::String16>",
279              "readString16Vector", "writeString16Vector",
280              kNoArrayType, new NullableStringListType()) {}
281   ~StringListType() override = default;
282 
283  private:
284   DISALLOW_COPY_AND_ASSIGN(StringListType);
285 };  // class StringListType
286 
287 class NullableUtf8InCppStringListType : public Type {
288  public:
NullableUtf8InCppStringListType()289   NullableUtf8InCppStringListType()
290       : Type(ValidatableType::KIND_BUILT_IN,
291              "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
292              {"memory", "string", "vector"},
293              "::std::unique_ptr<::std::vector<std::unique_ptr<::std::string>>>",
294              "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector") {}
295   ~NullableUtf8InCppStringListType() override = default;
296 
297  private:
298   DISALLOW_COPY_AND_ASSIGN(NullableUtf8InCppStringListType);
299 };  // class NullableUtf8InCppStringListType
300 
301 class Utf8InCppStringListType : public Type {
302  public:
Utf8InCppStringListType()303   Utf8InCppStringListType()
304       : Type(ValidatableType::KIND_BUILT_IN,
305              "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
306              {"string", "vector"},
307              "::std::vector<::std::string>",
308              "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
309              kNoArrayType, new NullableUtf8InCppStringListType()) {}
310   ~Utf8InCppStringListType() override = default;
311 
312  private:
313   DISALLOW_COPY_AND_ASSIGN(Utf8InCppStringListType);
314 };  // class Utf8InCppStringListType
315 
316 class NullableBinderListType : public Type {
317  public:
NullableBinderListType()318   NullableBinderListType()
319       : Type(ValidatableType::KIND_BUILT_IN, "java.util",
320              "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
321              "::std::unique_ptr<::std::vector<::android::sp<::android::IBinder>>>",
322              "readStrongBinderVector", "writeStrongBinderVector") {}
323   ~NullableBinderListType() override = default;
324 
325  private:
326   DISALLOW_COPY_AND_ASSIGN(NullableBinderListType);
327 };  // class NullableBinderListType
328 
329 class BinderListType : public Type {
330  public:
BinderListType()331   BinderListType()
332       : Type(ValidatableType::KIND_BUILT_IN, "java.util",
333              "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
334              "::std::vector<::android::sp<::android::IBinder>>",
335              "readStrongBinderVector", "writeStrongBinderVector",
336              kNoArrayType, new NullableBinderListType()) {}
337   ~BinderListType() override = default;
338 
339  private:
340   DISALLOW_COPY_AND_ASSIGN(BinderListType);
341 };  // class BinderListType
342 
343 }  // namespace
344 
Type(int kind,const std::string & package,const std::string & aidl_type,const vector<string> & headers,const string & cpp_type,const string & read_method,const string & write_method,Type * array_type,Type * nullable_type,const string & src_file_name,int line)345 Type::Type(int kind,
346            const std::string& package,
347            const std::string& aidl_type,
348            const vector<string>& headers,
349            const string& cpp_type,
350            const string& read_method,
351            const string& write_method,
352            Type* array_type,
353            Type* nullable_type,
354            const string& src_file_name,
355            int line)
356     : ValidatableType(kind, package, aidl_type, src_file_name, line),
357       headers_(headers),
358       aidl_type_(aidl_type),
359       cpp_type_(cpp_type),
360       parcel_read_method_(read_method),
361       parcel_write_method_(write_method),
362       array_type_(array_type),
363       nullable_type_(nullable_type) {}
364 
CanWriteToParcel() const365 bool Type::CanWriteToParcel() const { return true; }
366 
Init()367 void TypeNamespace::Init() {
368   Add(std::make_unique<ByteType>());
369   Add(std::make_unique<PrimitiveType>("int", "cstdint", "int32_t", "readInt32", "writeInt32",
370                                       "readInt32Vector", "writeInt32Vector"));
371   Add(std::make_unique<PrimitiveType>("long", "cstdint", "int64_t", "readInt64", "writeInt64",
372                                       "readInt64Vector", "writeInt64Vector"));
373   Add(std::make_unique<PrimitiveType>("float", kNoHeader, "float", "readFloat", "writeFloat",
374                                       "readFloatVector", "writeFloatVector"));
375   Add(std::make_unique<PrimitiveType>("double", kNoHeader, "double", "readDouble", "writeDouble",
376                                       "readDoubleVector", "writeDoubleVector"));
377   Add(std::make_unique<PrimitiveType>("boolean", kNoHeader, "bool", "readBool", "writeBool",
378                                       "readBoolVector", "writeBoolVector"));
379   // C++11 defines the char16_t type as a built in for Unicode characters.
380   Add(std::make_unique<PrimitiveType>("char", kNoHeader, "char16_t", "readChar", "writeChar",
381                                       "readCharVector", "writeCharVector"));
382 
383   Type* string_array_type = new CppArrayType(
384       ValidatableType::KIND_BUILT_IN, "java.lang", "String",
385       "utils/String16.h", "::android::String16",
386       "::std::unique_ptr<::android::String16>", "readString16Vector",
387       "writeString16Vector", false);
388 
389   Type* nullable_string_type =
390       new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
391                {"memory", "utils/String16.h"}, "::std::unique_ptr<::android::String16>",
392                "readString16", "writeString16");
393 
394   AddAndSetMember(&string_type_,
395                   std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
396                                          std::vector<std::string>{"utils/String16.h"},
397                                          "::android::String16", "readString16", "writeString16",
398                                          string_array_type, nullable_string_type));
399 
400   using ::android::aidl::kAidlReservedTypePackage;
401   using ::android::aidl::kUtf8InCppStringClass;
402 
403   // This type is a Utf16 string in the parcel, but deserializes to
404   // a std::string in Utf8 format when we use it in C++.
405   Type* cpp_utf8_string_array = new CppArrayType(
406       ValidatableType::KIND_BUILT_IN,
407       kAidlReservedTypePackage, kUtf8InCppStringClass,
408       "string", "::std::string", "::std::unique_ptr<::std::string>",
409       "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
410       false);
411   Type* nullable_cpp_utf8_string_type =
412       new Type(ValidatableType::KIND_BUILT_IN, kAidlReservedTypePackage, kUtf8InCppStringClass,
413                std::vector<std::string>{"string", "memory"}, "::std::unique_ptr<::std::string>",
414                "readUtf8FromUtf16", "writeUtf8AsUtf16");
415   Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, kAidlReservedTypePackage,
416                              kUtf8InCppStringClass, std::vector<std::string>{"string"},
417                              "::std::string", "readUtf8FromUtf16", "writeUtf8AsUtf16",
418                              cpp_utf8_string_array, nullable_cpp_utf8_string_type));
419 
420   Type* nullable_ibinder = new Type(
421       ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
422       {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
423       "readNullableStrongBinder", "writeStrongBinder");
424 
425   AddAndSetMember(&ibinder_type_,
426                   std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
427                                          std::vector<std::string>{"binder/IBinder.h"},
428                                          "::android::sp<::android::IBinder>", "readStrongBinder",
429                                          "writeStrongBinder", kNoArrayType, nullable_ibinder));
430 
431   Add(std::make_unique<MapType>());
432 
433   Add(std::make_unique<BinderListType>());
434   Add(std::make_unique<StringListType>());
435   Add(std::make_unique<Utf8InCppStringListType>());
436 
437   Type* fd_vector_type = new CppArrayType(
438       ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
439       "android-base/unique_fd.h",
440       "::android::base::unique_fd", "::android::base::unique_fd",
441       "readUniqueFileDescriptorVector", "writeUniqueFileDescriptorVector",
442       false);
443 
444   Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
445                              std::vector<std::string>{"android-base/unique_fd.h"},
446                              "::android::base::unique_fd", "readUniqueFileDescriptor",
447                              "writeUniqueFileDescriptor", fd_vector_type));
448 
449   Type* pfd_vector_type =
450       new CppArrayType(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
451                        "binder/ParcelFileDescriptor.h", "::android::os::ParcelFileDescriptor",
452                        "::android::os::ParcelFileDescriptor", "readParcelableVector",
453                        "writeParcelableVector", false);
454 
455   Type* nullable_pfd_type =
456       new Type(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
457                std::vector<std::string>{"memory", "binder/ParcelFileDescriptor.h"},
458                "::std::unique_ptr<::android::os::ParcelFileDescriptor>", "readParcelable",
459                "writeNullableParcelable");
460 
461   Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
462                              std::vector<std::string>{"binder/ParcelFileDescriptor.h"},
463                              "::android::os::ParcelFileDescriptor", "readParcelable",
464                              "writeParcelable", pfd_vector_type, nullable_pfd_type));
465 
466   // Qualify VoidType so we don't get collisions with the VoidType method
467   AddAndSetMember(&void_type_, std::make_unique<class VoidType>());
468 }
469 
AddParcelableType(const AidlParcelable & p,const std::string & filename)470 bool TypeNamespace::AddParcelableType(const AidlParcelable& p, const std::string& filename) {
471   const std::string cpp_header = p.AsStructuredParcelable() ? GetCppHeader(p) : p.GetCppHeader();
472 
473   if (cpp_header.empty()) {
474     AIDL_ERROR(p) << "Parcelable " << p.GetCanonicalName() << " has no C++ header defined.";
475     return false;
476   }
477 
478   Add(std::make_unique<ParcelableType>(p, cpp_header, filename));
479   return true;
480 }
481 
AddBinderType(const AidlInterface & b,const std::string & filename)482 bool TypeNamespace::AddBinderType(const AidlInterface& b, const std::string& filename) {
483   Add(std::make_unique<BinderType>(b, filename));
484   return true;
485 }
486 
AddListType(const std::string & type_name)487 bool TypeNamespace::AddListType(const std::string& type_name) {
488   const Type* contained_type = FindTypeByCanonicalName(type_name);
489   if (!contained_type) {
490     LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
491                   "type cannot be found or is invalid.";
492     return false;
493   }
494   if (contained_type->IsCppPrimitive()) {
495     LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
496                   "type is a primitive in Java and Java List cannot hold "
497                   "primitives.";
498     return false;
499   }
500 
501   if (contained_type->CanonicalName() == kStringCanonicalName ||
502       contained_type->CanonicalName() == kUtf8InCppStringCanonicalName ||
503       contained_type == IBinderType()) {
504     return true;
505   }
506 
507   // TODO Support lists of parcelables b/23600712
508 
509   LOG(ERROR) << "aidl-cpp does not yet support List<" << type_name << ">";
510   return false;
511 }
512 
AddMapType(const std::string &,const std::string &)513 bool TypeNamespace::AddMapType(const std::string& /* key_type_name */,
514                                const std::string& /* value_type_name */) {
515   // TODO Support list types b/25242025
516   LOG(ERROR) << "aidl does not implement support for typed maps!";
517   return false;
518 }
519 
GetArgType(const AidlArgument & a,int arg_index,const AidlDefinedType & context) const520 const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a, int arg_index,
521                                                  const AidlDefinedType& context) const {
522   return ::android::aidl::TypeNamespace::GetArgType(a, arg_index, context);
523 }
524 
525 }  // namespace cpp
526 }  // namespace aidl
527 }  // namespace android
528