1 /*
2 * Copyright (C) 2019 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 <gtest/gtest.h>
18
19 #include "HalInterfaces.h"
20 #include "Manager.h"
21 #include "NeuralNetworks.h"
22 #include "NeuralNetworksExtensions.h"
23 #include "SampleDriver.h"
24 #include "TypeManager.h"
25
26 namespace {
27
28 using DeviceManager = ::android::nn::DeviceManager;
29 using SampleDriver = ::android::nn::sample_driver::SampleDriver;
30 using TypeManager = ::android::nn::TypeManager;
31
32 const char* kTestDriverName = "extensions-test-driver";
33 const char* kTestExtension1 = "vendor.test.one";
34 const char* kTestExtension2 = "vendor.test.two";
35 const char* kTestExtension3 = "vendor.test.three";
36
37 class TestDriver : public SampleDriver {
38 public:
TestDriver()39 TestDriver() : SampleDriver(kTestDriverName) {}
~TestDriver()40 ~TestDriver() override {}
41
getSupportedExtensions(getSupportedExtensions_cb cb)42 Return<void> getSupportedExtensions(getSupportedExtensions_cb cb) override {
43 cb(ErrorStatus::NONE, {
44 {.name = kTestExtension1},
45 {.name = kTestExtension2},
46 {.name = kTestExtension3},
47 });
48 return Void();
49 }
50
getCapabilities_1_2(getCapabilities_1_2_cb cb)51 Return<void> getCapabilities_1_2(getCapabilities_1_2_cb cb) override {
52 cb(ErrorStatus::NONE, {/* Dummy zero-filled capabilities. */});
53 return Void();
54 }
55
getSupportedOperations_1_2(const Model &,getSupportedOperations_cb)56 Return<void> getSupportedOperations_1_2(const Model&, getSupportedOperations_cb) override {
57 CHECK(false) << "not implemented";
58 return Void();
59 }
60 };
61
62 class ExtensionsTest : public ::testing::Test {
63 protected:
SetUp()64 virtual void SetUp() {
65 // This is needed before we have the CPU fallback path being treated as a Device.
66 // TODO(miaowang): remove once b/72506261 is fixed.
67 if (DeviceManager::get()->getUseCpuOnly()) {
68 GTEST_SKIP();
69 }
70
71 DeviceManager::get()->forTest_registerDevice(kTestDriverName, new TestDriver());
72 // Discover extensions provided by registered devices.
73 TypeManager::get()->forTest_reset();
74 mDevice = getDeviceByName(kTestDriverName);
75 ASSERT_NE(mDevice, nullptr);
76 }
77
TearDown()78 virtual void TearDown() {
79 DeviceManager::get()->forTest_reInitializeDeviceList();
80 TypeManager::get()->forTest_reset();
81 }
82
getDeviceByName(const std::string & name)83 ANeuralNetworksDevice* getDeviceByName(const std::string& name) {
84 ANeuralNetworksDevice* result = nullptr;
85 uint32_t numDevices = 0;
86 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
87 EXPECT_GE(numDevices, 1u);
88 for (uint32_t i = 0; i < numDevices; i++) {
89 ANeuralNetworksDevice* device = nullptr;
90 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
91 const char* buffer = nullptr;
92 EXPECT_EQ(ANeuralNetworksDevice_getName(device, &buffer), ANEURALNETWORKS_NO_ERROR);
93 if (name.compare(buffer) == 0) {
94 EXPECT_EQ(result, nullptr) << "multiple devices named " << name;
95 result = device;
96 }
97 }
98 return result;
99 }
100
testDriverSupportsExtension(const char * extensionName)101 bool testDriverSupportsExtension(const char* extensionName) {
102 bool result;
103 EXPECT_EQ(ANeuralNetworksDevice_getExtensionSupport(mDevice, extensionName, &result),
104 ANEURALNETWORKS_NO_ERROR);
105 return result;
106 }
107
108 private:
109 ANeuralNetworksDevice* mDevice;
110 };
111
TEST_F(ExtensionsTest,DeviceReportsSupportedExtensions)112 TEST_F(ExtensionsTest, DeviceReportsSupportedExtensions) {
113 EXPECT_TRUE(testDriverSupportsExtension(kTestExtension1));
114 EXPECT_FALSE(testDriverSupportsExtension("vendor.test.unknown"));
115 EXPECT_FALSE(testDriverSupportsExtension("asdfasdfas"));
116 EXPECT_TRUE(testDriverSupportsExtension(kTestExtension2));
117 EXPECT_TRUE(testDriverSupportsExtension(kTestExtension3));
118 }
119
TEST_F(ExtensionsTest,TestAllowedNativeBinaries)120 TEST_F(ExtensionsTest, TestAllowedNativeBinaries) {
121 std::vector<std::string> allowlist = {"/data/foo", "/vendor/foo", "/odm/foo",
122 "/product/foo", "/system/allowlisted", "/foobar/foo"};
123
124 auto native_info =
125 [&](const std::string& binaryPath) -> android::nn::TypeManager::AppPackageInfo {
126 return {.binaryPath = binaryPath,
127 .appPackageName = "",
128 .appIsSystemApp = false,
129 .appIsOnVendorImage = false,
130 .appIsOnProductImage = false};
131 };
132
133 // No binary info
134 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info(""),
135 /* useOnProductImageEnabled = */ false,
136 allowlist));
137 // Non-approved top-level dir
138 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/foobar/foo"),
139 /* useOnProductImageEnabled = */ false,
140 allowlist));
141 // Allowlisted /data binary
142 EXPECT_TRUE(TypeManager::isExtensionsUseAllowed(native_info("/data/foo"),
143 /* useOnProductImageEnabled = */ false,
144 allowlist));
145 // Allowlisted /vendor binary
146 EXPECT_TRUE(TypeManager::isExtensionsUseAllowed(native_info("/vendor/foo"),
147 /* useOnProductImageEnabled = */ false,
148 allowlist));
149 // Allowlisted /odm binary
150 EXPECT_TRUE(TypeManager::isExtensionsUseAllowed(native_info("/odm/foo"),
151 /* useOnProductImageEnabled = */ false,
152 allowlist));
153 // Non-allowlisted /system binary
154 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/system/foo"),
155 /* useOnProductImageEnabled = */ false,
156 allowlist));
157 // allowlisted /system binary (can't be allowlisted)
158 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/system/allowlisted"),
159 /* useOnProductImageEnabled = */ false,
160 allowlist));
161 // Allowlisted /product binary, product disabled
162 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/product/foo"),
163 /* useOnProductImageEnabled = */ false,
164 allowlist));
165 // Allowlisted /product binary, product enabled
166 EXPECT_TRUE(TypeManager::isExtensionsUseAllowed(native_info("/product/foo"),
167 /* useOnProductImageEnabled = */ true,
168 allowlist));
169 // Non-allowlisted /product binary, product enabled
170 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/product/foo_not_allowlisted"),
171 /* useOnProductImageEnabled = */ true,
172 allowlist));
173 // Non-allowlisted /odm binary
174 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/odm/foo_not_allowlisted"),
175 /* useOnProductImageEnabled = */ false,
176 allowlist));
177 // Non-allowlisted /vendor binary
178 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/vendor/foo_not_allowlisted"),
179 /* useOnProductImageEnabled = */ false,
180 allowlist));
181 // Non-allowlisted /data binary
182 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/data/foo_not_allowlisted"),
183 /* useOnProductImageEnabled = */ false,
184 allowlist));
185 }
186
TEST_F(ExtensionsTest,TestAllowedApps)187 TEST_F(ExtensionsTest, TestAllowedApps) {
188 std::string app_process32 = "/system/bin/app_process32";
189 std::string app_process64 = "/system/bin/app_process64";
190 std::string other_binary = "/system/bin/foo";
191
192 std::string package = "com.foo";
193 std::string package_non_allowlisted = "com.foo2";
194
195 std::vector<std::string> allowlist = {"com.foo"};
196
197 auto test_app_process = [&](const std::string& binary) {
198 // /data app
199 EXPECT_TRUE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
200 .appPackageName = package,
201 .appIsSystemApp = false,
202 .appIsOnVendorImage = false,
203 .appIsOnProductImage = false},
204 /* useOnProductImageEnabled = */ false,
205 allowlist));
206
207 // /system app
208 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
209 .appPackageName = package,
210 .appIsSystemApp = true,
211 .appIsOnVendorImage = false,
212 .appIsOnProductImage = false},
213 /* useOnProductImageEnabled = */ false,
214 allowlist));
215
216 // /vendor || /odm app
217 EXPECT_TRUE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
218 .appPackageName = package,
219 .appIsSystemApp = true,
220 .appIsOnVendorImage = true,
221 .appIsOnProductImage = false},
222 /* useOnProductImageEnabled = */ false,
223 allowlist));
224
225 // /product app, disabled
226 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
227 .appPackageName = package,
228 .appIsSystemApp = true,
229 .appIsOnVendorImage = false,
230 .appIsOnProductImage = true},
231 /* useOnProductImageEnabled = */ false,
232 allowlist));
233
234 // /product app, enabled
235 EXPECT_TRUE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
236 .appPackageName = package,
237 .appIsSystemApp = true,
238 .appIsOnVendorImage = false,
239 .appIsOnProductImage = true},
240 /* useOnProductImageEnabled = */ true,
241 allowlist));
242
243 // /product app, enabled, package name not on allowlist
244 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
245 .appPackageName = package_non_allowlisted,
246 .appIsSystemApp = true,
247 .appIsOnVendorImage = false,
248 .appIsOnProductImage = true},
249 /* useOnProductImageEnabled = */ true,
250 allowlist));
251
252 // /data app, package name not on allowlist
253 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
254 .appPackageName = package_non_allowlisted,
255 .appIsSystemApp = false,
256 .appIsOnVendorImage = false,
257 .appIsOnProductImage = false},
258 /* useOnProductImageEnabled = */ false,
259 allowlist));
260
261 // /vendor || /odm app, package name not on allowlist
262 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
263 .appPackageName = package_non_allowlisted,
264 .appIsSystemApp = true,
265 .appIsOnVendorImage = true,
266 .appIsOnProductImage = false},
267 /* useOnProductImageEnabled = */ false,
268 allowlist));
269 };
270 test_app_process(app_process64);
271 test_app_process(app_process32);
272
273 // Test all positive cases fail if binary is not app_process32|64
274 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = other_binary,
275 .appPackageName = package,
276 .appIsSystemApp = false,
277 .appIsOnVendorImage = false,
278 .appIsOnProductImage = false},
279 /* useOnProductImageEnabled = */ false,
280 allowlist));
281 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = other_binary,
282 .appPackageName = package,
283 .appIsSystemApp = true,
284 .appIsOnVendorImage = true,
285 .appIsOnProductImage = false},
286 /* useOnProductImageEnabled = */ false,
287 allowlist));
288
289 EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = other_binary,
290 .appPackageName = package,
291 .appIsSystemApp = true,
292 .appIsOnVendorImage = false,
293 .appIsOnProductImage = true},
294 /* useOnProductImageEnabled = */ true,
295 allowlist));
296 }
297
298 } // namespace
299