• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021, 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 "check_valid.h"
18 #include "aidl.h"
19 
20 #include <vector>
21 
22 namespace android {
23 namespace aidl {
24 
25 using TypePredicate = std::function<bool(const AidlTypeSpecifier&)>;
26 
27 namespace {
IsListOf(const AidlTypeSpecifier & type,TypePredicate pred)28 bool IsListOf(const AidlTypeSpecifier& type, TypePredicate pred) {
29   return type.GetName() == "List" && type.IsGeneric() && type.GetTypeParameters().size() == 1 &&
30          pred(*type.GetTypeParameters().at(0));
31 }
IsArrayOf(const AidlTypeSpecifier & type,TypePredicate pred)32 bool IsArrayOf(const AidlTypeSpecifier& type, TypePredicate pred) {
33   return type.IsArray() && pred(type);
34 }
IsInterface(const AidlTypeSpecifier & type)35 bool IsInterface(const AidlTypeSpecifier& type) {
36   return type.GetDefinedType() && type.GetDefinedType()->AsInterface();
37 }
38 }  // namespace
39 
40 struct CheckTypeVisitor : AidlVisitor {
41   bool success = true;
42   std::vector<TypePredicate> checkers;
43 
Visitandroid::aidl::CheckTypeVisitor44   void Visit(const AidlTypeSpecifier& type) override {
45     for (auto& checker : checkers) {
46       if (!checker(type)) {
47         success = false;
48       }
49     }
50   }
51 
Checkandroid::aidl::CheckTypeVisitor52   void Check(TypePredicate checker) { checkers.push_back(std::move(checker)); }
53 };
54 
CheckValid(const AidlDocument & doc,const Options & options)55 bool CheckValid(const AidlDocument& doc, const Options& options) {
56   const auto lang = options.TargetLanguage();
57   const auto min_sdk_version = options.GetMinSdkVersion();
58 
59   CheckTypeVisitor v;
60 
61   v.Check([&](const AidlTypeSpecifier& type) {
62     const auto valid_version = MinSdkVersionFromString("Tiramisu").value();
63     if ((IsListOf(type, IsInterface) || IsArrayOf(type, IsInterface)) &&
64         lang == Options::Language::JAVA && min_sdk_version < valid_version) {
65       const auto kind = IsListOf(type, IsInterface) ? "List" : "Array";
66       AIDL_ERROR(type) << kind << " of interfaces is available since SDK = " << valid_version
67                        << " in Java. Current min_sdk_version is " << min_sdk_version << ".";
68       return false;
69     }
70     return true;
71   });
72 
73   v.Check([&](const AidlTypeSpecifier& type) {
74     const auto valid_version = MinSdkVersionFromString("S").value();
75     if (type.GetName() == "ParcelableHolder" && min_sdk_version < valid_version) {
76       AIDL_ERROR(type) << " ParcelableHolder is available since SDK = " << valid_version
77                        << ". Current min_sdk_version is " << min_sdk_version << ".";
78       return false;
79     }
80     return true;
81   });
82 
83   VisitTopDown(v, doc);
84   return v.success;
85 }
86 
87 }  // namespace aidl
88 }  // namespace android
89