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