1 
2 /*
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "utils.h"
19 
20 #include <map>
21 #include <set>
22 #include <string>
23 #include <vector>
24 
25 #include <android-base/properties.h>
26 
27 using android::base::GetUintProperty;
28 
29 namespace android {
30 namespace vintf {
31 namespace testing {
32 
33 // Path to directory on target containing test data.
34 const string kDataDir = "/data/local/tmp/";
35 
36 // Name of file containing HAL hashes.
37 const string kHashFileName = "current.txt";
38 
39 // Map from package name to package root.
40 const map<string, string> kPackageRoot = {
41     {"android.frameworks", "frameworks/hardware/interfaces/"},
42     {"android.hardware", "hardware/interfaces/"},
43     {"android.hidl", "system/libhidl/transport/"},
44     {"android.system", "system/hardware/interfaces/"},
45 };
46 
47 // HALs that are allowed to be passthrough under Treble rules.
48 const set<string> kPassthroughHals = {
49     "android.hardware.graphics.mapper", "android.hardware.renderscript",
50     "android.hidl.memory",
51 };
52 
53 const uint64_t kCurrentApiLevel = 10000;
54 
ReadApiLevelProps(vector<string> api_level_props)55 uint64_t ReadApiLevelProps(vector<string> api_level_props) {
56   uint64_t api_level = kCurrentApiLevel;
57   for (const auto &api_level_prop : api_level_props) {
58     api_level = GetUintProperty<uint64_t>(api_level_prop, kCurrentApiLevel);
59     if (api_level != kCurrentApiLevel) {
60       break;
61     }
62   }
63   return api_level;
64 }
65 
GetBoardApiLevel()66 uint64_t GetBoardApiLevel() {
67   uint64_t device_api_level =
68       ReadApiLevelProps({"ro.product.first_api_level", "ro.build.version.sdk"});
69   uint64_t board_api_level =
70       ReadApiLevelProps({"ro.board.api_level", "ro.board.first_api_level",
71                          "ro.vendor.build.version.sdk"});
72   uint64_t api_level =
73       board_api_level < device_api_level ? board_api_level : device_api_level;
74   if (api_level == kCurrentApiLevel) {
75     return 0;
76   }
77   return api_level;
78 }
79 
80 // For a given interface returns package root if known. Returns empty string
81 // otherwise.
PackageRoot(const FQName & fq_iface_name)82 const string PackageRoot(const FQName &fq_iface_name) {
83   for (const auto &package_root : kPackageRoot) {
84     if (fq_iface_name.inPackage(package_root.first)) {
85       return package_root.second;
86     }
87   }
88   return "";
89 }
90 
91 // Returns true iff HAL interface is Android platform.
IsAndroidPlatformInterface(const FQName & fq_iface_name)92 bool IsAndroidPlatformInterface(const FQName &fq_iface_name) {
93   // Package roots are only known for Android platform packages.
94   return !PackageRoot(fq_iface_name).empty();
95 }
96 
97 // Returns the set of released hashes for a given HAL interface.
ReleasedHashes(const FQName & fq_iface_name)98 set<string> ReleasedHashes(const FQName &fq_iface_name) {
99   set<string> released_hashes{};
100   string err = "";
101 
102   string file_path = kDataDir + PackageRoot(fq_iface_name) + kHashFileName;
103   auto hashes = Hash::lookupHash(file_path, fq_iface_name.string(), &err);
104   released_hashes.insert(hashes.begin(), hashes.end());
105   return released_hashes;
106 }
107 
108 // Returns the partition that a HAL is associated with.
PartitionOfProcess(int32_t pid)109 Partition PartitionOfProcess(int32_t pid) {
110   auto partition = android::procpartition::getPartition(pid);
111 
112   // TODO(b/70033981): remove once ODM and Vendor manifests are distinguished
113   if (partition == Partition::ODM) {
114     partition = Partition::VENDOR;
115   }
116 
117   return partition;
118 }
119 
PartitionOfType(SchemaType type)120 Partition PartitionOfType(SchemaType type) {
121   switch (type) {
122     case SchemaType::DEVICE:
123       return Partition::VENDOR;
124     case SchemaType::FRAMEWORK:
125       return Partition::SYSTEM;
126   }
127   return Partition::UNKNOWN;
128 }
129 
130 }  // namespace testing
131 }  // namespace vintf
132 }  // namespace android
133 
134 namespace std {
PrintTo(const android::vintf::testing::HalManifestPtr & v,ostream * os)135 void PrintTo(const android::vintf::testing::HalManifestPtr &v, ostream *os) {
136   if (v == nullptr) {
137     *os << "nullptr";
138     return;
139   }
140   *os << to_string(v->type()) << " manifest";
141 }
142 }  // namespace std
143