• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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