xref: /aosp_15_r20/art/libnativeloader/native_loader_test.cpp (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "native_loader_test.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <functional>
20*795d594fSAndroid Build Coastguard Worker #include <map>
21*795d594fSAndroid Build Coastguard Worker #include <memory>
22*795d594fSAndroid Build Coastguard Worker #include <string>
23*795d594fSAndroid Build Coastguard Worker #include <unordered_map>
24*795d594fSAndroid Build Coastguard Worker #include <vector>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "android-base/properties.h"
27*795d594fSAndroid Build Coastguard Worker #include "android-base/result.h"
28*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
29*795d594fSAndroid Build Coastguard Worker #include "android-base/strings.h"
30*795d594fSAndroid Build Coastguard Worker #include "dlfcn.h"
31*795d594fSAndroid Build Coastguard Worker #include "gmock/gmock.h"
32*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
33*795d594fSAndroid Build Coastguard Worker #include "jni.h"
34*795d594fSAndroid Build Coastguard Worker #include "native_loader_namespace.h"
35*795d594fSAndroid Build Coastguard Worker #include "nativehelper/scoped_utf_chars.h"
36*795d594fSAndroid Build Coastguard Worker #include "nativeloader/dlext_namespaces.h"
37*795d594fSAndroid Build Coastguard Worker #include "nativeloader/native_loader.h"
38*795d594fSAndroid Build Coastguard Worker #include "public_libraries.h"
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker namespace android {
41*795d594fSAndroid Build Coastguard Worker namespace nativeloader {
42*795d594fSAndroid Build Coastguard Worker 
43*795d594fSAndroid Build Coastguard Worker using internal::ConfigEntry;  // NOLINT - ConfigEntry is actually used
44*795d594fSAndroid Build Coastguard Worker using internal::ParseApexLibrariesConfig;
45*795d594fSAndroid Build Coastguard Worker using internal::ParseConfig;
46*795d594fSAndroid Build Coastguard Worker using ::testing::_;
47*795d594fSAndroid Build Coastguard Worker using ::testing::Eq;
48*795d594fSAndroid Build Coastguard Worker using ::testing::NotNull;
49*795d594fSAndroid Build Coastguard Worker using ::testing::Return;
50*795d594fSAndroid Build Coastguard Worker using ::testing::StartsWith;
51*795d594fSAndroid Build Coastguard Worker using ::testing::StrEq;
52*795d594fSAndroid Build Coastguard Worker 
53*795d594fSAndroid Build Coastguard Worker #if defined(__LP64__)
54*795d594fSAndroid Build Coastguard Worker #define LIB_DIR "lib64"
55*795d594fSAndroid Build Coastguard Worker #else
56*795d594fSAndroid Build Coastguard Worker #define LIB_DIR "lib"
57*795d594fSAndroid Build Coastguard Worker #endif
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker // gmock interface that represents interesting platform APIs in libdl_android and libnativebridge
60*795d594fSAndroid Build Coastguard Worker class Platform {
61*795d594fSAndroid Build Coastguard Worker  public:
~Platform()62*795d594fSAndroid Build Coastguard Worker   virtual ~Platform() {}
63*795d594fSAndroid Build Coastguard Worker 
64*795d594fSAndroid Build Coastguard Worker   // These mock_* are the APIs semantically the same across libdl_android and libnativebridge.
65*795d594fSAndroid Build Coastguard Worker   // Instead of having two set of mock APIs for the two, define only one set with an additional
66*795d594fSAndroid Build Coastguard Worker   // argument 'bool bridged' to identify the context (i.e., called for libdl_android or
67*795d594fSAndroid Build Coastguard Worker   // libnativebridge).
68*795d594fSAndroid Build Coastguard Worker   using mock_namespace_handle = char*;
69*795d594fSAndroid Build Coastguard Worker   virtual bool mock_init_anonymous_namespace(bool bridged,
70*795d594fSAndroid Build Coastguard Worker                                              const char* sonames,
71*795d594fSAndroid Build Coastguard Worker                                              const char* search_paths) = 0;
72*795d594fSAndroid Build Coastguard Worker   virtual mock_namespace_handle mock_create_namespace(bool bridged,
73*795d594fSAndroid Build Coastguard Worker                                                       const char* name,
74*795d594fSAndroid Build Coastguard Worker                                                       const char* ld_library_path,
75*795d594fSAndroid Build Coastguard Worker                                                       const char* default_library_path,
76*795d594fSAndroid Build Coastguard Worker                                                       uint64_t type,
77*795d594fSAndroid Build Coastguard Worker                                                       const char* permitted_when_isolated_path,
78*795d594fSAndroid Build Coastguard Worker                                                       mock_namespace_handle parent) = 0;
79*795d594fSAndroid Build Coastguard Worker   virtual bool mock_link_namespaces(bool bridged,
80*795d594fSAndroid Build Coastguard Worker                                     mock_namespace_handle from,
81*795d594fSAndroid Build Coastguard Worker                                     mock_namespace_handle to,
82*795d594fSAndroid Build Coastguard Worker                                     const char* sonames) = 0;
83*795d594fSAndroid Build Coastguard Worker   virtual mock_namespace_handle mock_get_exported_namespace(bool bridged, const char* name) = 0;
84*795d594fSAndroid Build Coastguard Worker   virtual void* mock_dlopen_ext(bool bridged,
85*795d594fSAndroid Build Coastguard Worker                                 const char* filename,
86*795d594fSAndroid Build Coastguard Worker                                 int flags,
87*795d594fSAndroid Build Coastguard Worker                                 mock_namespace_handle ns) = 0;
88*795d594fSAndroid Build Coastguard Worker 
89*795d594fSAndroid Build Coastguard Worker   // libnativebridge APIs for which libdl_android has no corresponding APIs
90*795d594fSAndroid Build Coastguard Worker   virtual bool NativeBridgeInitialized() = 0;
91*795d594fSAndroid Build Coastguard Worker   virtual const char* NativeBridgeGetError() = 0;
92*795d594fSAndroid Build Coastguard Worker   virtual bool NativeBridgeIsPathSupported(const char*) = 0;
93*795d594fSAndroid Build Coastguard Worker   virtual bool NativeBridgeIsSupported(const char*) = 0;
94*795d594fSAndroid Build Coastguard Worker };
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker // The mock does not actually create a namespace object. But simply casts the pointer to the
97*795d594fSAndroid Build Coastguard Worker // string for the namespace name as the handle to the namespace object.
98*795d594fSAndroid Build Coastguard Worker #define TO_ANDROID_NAMESPACE(str) \
99*795d594fSAndroid Build Coastguard Worker   reinterpret_cast<struct android_namespace_t*>(const_cast<char*>(str))
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker #define TO_BRIDGED_NAMESPACE(str) \
102*795d594fSAndroid Build Coastguard Worker   reinterpret_cast<struct native_bridge_namespace_t*>(const_cast<char*>(str))
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker #define TO_MOCK_NAMESPACE(ns) reinterpret_cast<Platform::mock_namespace_handle>(ns)
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker // These represents built-in namespaces created by the linker according to ld.config.txt
107*795d594fSAndroid Build Coastguard Worker static std::unordered_map<std::string, Platform::mock_namespace_handle> namespaces = {
108*795d594fSAndroid Build Coastguard Worker #define NAMESPACE_ENTRY(ns) \
109*795d594fSAndroid Build Coastguard Worker   { ns, TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE(ns)) }
110*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("com_android_i18n"),
111*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("com_android_neuralnetworks"),
112*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("com_android_art"),
113*795d594fSAndroid Build Coastguard Worker 
114*795d594fSAndroid Build Coastguard Worker     // TODO(b/191644631) This can be removed when the test becomes more test-friendly.
115*795d594fSAndroid Build Coastguard Worker     // This is added so that the test can exercise the JNI lib related behavior.
116*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("com_android_conscrypt"),
117*795d594fSAndroid Build Coastguard Worker 
118*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("default"),
119*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("sphal"),
120*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("product"),
121*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("system"),
122*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("vndk"),
123*795d594fSAndroid Build Coastguard Worker     NAMESPACE_ENTRY("vndk_product"),
124*795d594fSAndroid Build Coastguard Worker #undef NAMESPACE_ENTRY
125*795d594fSAndroid Build Coastguard Worker };
126*795d594fSAndroid Build Coastguard Worker 
127*795d594fSAndroid Build Coastguard Worker // The actual gmock object
128*795d594fSAndroid Build Coastguard Worker class MockPlatform : public Platform {
129*795d594fSAndroid Build Coastguard Worker  public:
MockPlatform(bool is_bridged)130*795d594fSAndroid Build Coastguard Worker   explicit MockPlatform(bool is_bridged) : is_bridged_(is_bridged) {
131*795d594fSAndroid Build Coastguard Worker     ON_CALL(*this, NativeBridgeIsSupported(_)).WillByDefault(Return(is_bridged_));
132*795d594fSAndroid Build Coastguard Worker     ON_CALL(*this, NativeBridgeIsPathSupported(_)).WillByDefault(Return(is_bridged_));
133*795d594fSAndroid Build Coastguard Worker     ON_CALL(*this, mock_get_exported_namespace(_, _))
134*795d594fSAndroid Build Coastguard Worker         .WillByDefault(testing::Invoke([](bool, const char* name) -> mock_namespace_handle {
135*795d594fSAndroid Build Coastguard Worker           if (namespaces.find(name) != namespaces.end()) {
136*795d594fSAndroid Build Coastguard Worker             return namespaces[name];
137*795d594fSAndroid Build Coastguard Worker           }
138*795d594fSAndroid Build Coastguard Worker           std::string msg = android::base::StringPrintf("(namespace %s not found)", name);
139*795d594fSAndroid Build Coastguard Worker           // The strdup'ed string will leak, but the test is already failing if we get here.
140*795d594fSAndroid Build Coastguard Worker           return TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE(strdup(msg.c_str())));
141*795d594fSAndroid Build Coastguard Worker         }));
142*795d594fSAndroid Build Coastguard Worker   }
143*795d594fSAndroid Build Coastguard Worker 
144*795d594fSAndroid Build Coastguard Worker   // Mocking the common APIs
145*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD3(mock_init_anonymous_namespace, bool(bool, const char*, const char*));
146*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD7(mock_create_namespace,
147*795d594fSAndroid Build Coastguard Worker                mock_namespace_handle(bool,
148*795d594fSAndroid Build Coastguard Worker                                      const char*,
149*795d594fSAndroid Build Coastguard Worker                                      const char*,
150*795d594fSAndroid Build Coastguard Worker                                      const char*,
151*795d594fSAndroid Build Coastguard Worker                                      uint64_t,
152*795d594fSAndroid Build Coastguard Worker                                      const char*,
153*795d594fSAndroid Build Coastguard Worker                                      mock_namespace_handle));
154*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD4(mock_link_namespaces,
155*795d594fSAndroid Build Coastguard Worker                bool(bool, mock_namespace_handle, mock_namespace_handle, const char*));
156*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD2(mock_get_exported_namespace, mock_namespace_handle(bool, const char*));
157*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD4(mock_dlopen_ext, void*(bool, const char*, int, mock_namespace_handle));
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   // Mocking libnativebridge APIs
160*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD0(NativeBridgeInitialized, bool());
161*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD0(NativeBridgeGetError, const char*());
162*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD1(NativeBridgeIsPathSupported, bool(const char*));
163*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD1(NativeBridgeIsSupported, bool(const char*));
164*795d594fSAndroid Build Coastguard Worker 
165*795d594fSAndroid Build Coastguard Worker  private:
166*795d594fSAndroid Build Coastguard Worker   bool is_bridged_;
167*795d594fSAndroid Build Coastguard Worker };
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker static std::unique_ptr<MockPlatform> mock;
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker // Provide C wrappers for the mock object. These symbols must be exported by ld
172*795d594fSAndroid Build Coastguard Worker // to be able to override the real symbols in the shared libs.
173*795d594fSAndroid Build Coastguard Worker extern "C" {
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker // libdl_android APIs
176*795d594fSAndroid Build Coastguard Worker 
android_init_anonymous_namespace(const char * sonames,const char * search_path)177*795d594fSAndroid Build Coastguard Worker bool android_init_anonymous_namespace(const char* sonames, const char* search_path) {
178*795d594fSAndroid Build Coastguard Worker   return mock->mock_init_anonymous_namespace(false, sonames, search_path);
179*795d594fSAndroid Build Coastguard Worker }
180*795d594fSAndroid Build Coastguard Worker 
android_create_namespace(const char * name,const char * ld_library_path,const char * default_library_path,uint64_t type,const char * permitted_when_isolated_path,struct android_namespace_t * parent)181*795d594fSAndroid Build Coastguard Worker struct android_namespace_t* android_create_namespace(const char* name,
182*795d594fSAndroid Build Coastguard Worker                                                      const char* ld_library_path,
183*795d594fSAndroid Build Coastguard Worker                                                      const char* default_library_path,
184*795d594fSAndroid Build Coastguard Worker                                                      uint64_t type,
185*795d594fSAndroid Build Coastguard Worker                                                      const char* permitted_when_isolated_path,
186*795d594fSAndroid Build Coastguard Worker                                                      struct android_namespace_t* parent) {
187*795d594fSAndroid Build Coastguard Worker   return TO_ANDROID_NAMESPACE(mock->mock_create_namespace(false,
188*795d594fSAndroid Build Coastguard Worker                                                           name,
189*795d594fSAndroid Build Coastguard Worker                                                           ld_library_path,
190*795d594fSAndroid Build Coastguard Worker                                                           default_library_path,
191*795d594fSAndroid Build Coastguard Worker                                                           type,
192*795d594fSAndroid Build Coastguard Worker                                                           permitted_when_isolated_path,
193*795d594fSAndroid Build Coastguard Worker                                                           TO_MOCK_NAMESPACE(parent)));
194*795d594fSAndroid Build Coastguard Worker }
195*795d594fSAndroid Build Coastguard Worker 
android_link_namespaces(struct android_namespace_t * from,struct android_namespace_t * to,const char * sonames)196*795d594fSAndroid Build Coastguard Worker bool android_link_namespaces(struct android_namespace_t* from,
197*795d594fSAndroid Build Coastguard Worker                              struct android_namespace_t* to,
198*795d594fSAndroid Build Coastguard Worker                              const char* sonames) {
199*795d594fSAndroid Build Coastguard Worker   return mock->mock_link_namespaces(false, TO_MOCK_NAMESPACE(from), TO_MOCK_NAMESPACE(to), sonames);
200*795d594fSAndroid Build Coastguard Worker }
201*795d594fSAndroid Build Coastguard Worker 
android_get_exported_namespace(const char * name)202*795d594fSAndroid Build Coastguard Worker struct android_namespace_t* android_get_exported_namespace(const char* name) {
203*795d594fSAndroid Build Coastguard Worker   return TO_ANDROID_NAMESPACE(mock->mock_get_exported_namespace(false, name));
204*795d594fSAndroid Build Coastguard Worker }
205*795d594fSAndroid Build Coastguard Worker 
android_dlopen_ext(const char * filename,int flags,const android_dlextinfo * info)206*795d594fSAndroid Build Coastguard Worker void* android_dlopen_ext(const char* filename, int flags, const android_dlextinfo* info) {
207*795d594fSAndroid Build Coastguard Worker   return mock->mock_dlopen_ext(false, filename, flags, TO_MOCK_NAMESPACE(info->library_namespace));
208*795d594fSAndroid Build Coastguard Worker }
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker // libnativebridge APIs
211*795d594fSAndroid Build Coastguard Worker 
NativeBridgeIsSupported(const char * libpath)212*795d594fSAndroid Build Coastguard Worker bool NativeBridgeIsSupported(const char* libpath) { return mock->NativeBridgeIsSupported(libpath); }
213*795d594fSAndroid Build Coastguard Worker 
NativeBridgeGetExportedNamespace(const char * name)214*795d594fSAndroid Build Coastguard Worker struct native_bridge_namespace_t* NativeBridgeGetExportedNamespace(const char* name) {
215*795d594fSAndroid Build Coastguard Worker   return TO_BRIDGED_NAMESPACE(mock->mock_get_exported_namespace(true, name));
216*795d594fSAndroid Build Coastguard Worker }
217*795d594fSAndroid Build Coastguard Worker 
NativeBridgeCreateNamespace(const char * name,const char * ld_library_path,const char * default_library_path,uint64_t type,const char * permitted_when_isolated_path,struct native_bridge_namespace_t * parent)218*795d594fSAndroid Build Coastguard Worker struct native_bridge_namespace_t* NativeBridgeCreateNamespace(
219*795d594fSAndroid Build Coastguard Worker     const char* name,
220*795d594fSAndroid Build Coastguard Worker     const char* ld_library_path,
221*795d594fSAndroid Build Coastguard Worker     const char* default_library_path,
222*795d594fSAndroid Build Coastguard Worker     uint64_t type,
223*795d594fSAndroid Build Coastguard Worker     const char* permitted_when_isolated_path,
224*795d594fSAndroid Build Coastguard Worker     struct native_bridge_namespace_t* parent) {
225*795d594fSAndroid Build Coastguard Worker   return TO_BRIDGED_NAMESPACE(mock->mock_create_namespace(true,
226*795d594fSAndroid Build Coastguard Worker                                                           name,
227*795d594fSAndroid Build Coastguard Worker                                                           ld_library_path,
228*795d594fSAndroid Build Coastguard Worker                                                           default_library_path,
229*795d594fSAndroid Build Coastguard Worker                                                           type,
230*795d594fSAndroid Build Coastguard Worker                                                           permitted_when_isolated_path,
231*795d594fSAndroid Build Coastguard Worker                                                           TO_MOCK_NAMESPACE(parent)));
232*795d594fSAndroid Build Coastguard Worker }
233*795d594fSAndroid Build Coastguard Worker 
NativeBridgeLinkNamespaces(struct native_bridge_namespace_t * from,struct native_bridge_namespace_t * to,const char * sonames)234*795d594fSAndroid Build Coastguard Worker bool NativeBridgeLinkNamespaces(struct native_bridge_namespace_t* from,
235*795d594fSAndroid Build Coastguard Worker                                 struct native_bridge_namespace_t* to,
236*795d594fSAndroid Build Coastguard Worker                                 const char* sonames) {
237*795d594fSAndroid Build Coastguard Worker   return mock->mock_link_namespaces(true, TO_MOCK_NAMESPACE(from), TO_MOCK_NAMESPACE(to), sonames);
238*795d594fSAndroid Build Coastguard Worker }
239*795d594fSAndroid Build Coastguard Worker 
NativeBridgeLoadLibraryExt(const char * libpath,int flag,struct native_bridge_namespace_t * ns)240*795d594fSAndroid Build Coastguard Worker void* NativeBridgeLoadLibraryExt(const char* libpath,
241*795d594fSAndroid Build Coastguard Worker                                  int flag,
242*795d594fSAndroid Build Coastguard Worker                                  struct native_bridge_namespace_t* ns) {
243*795d594fSAndroid Build Coastguard Worker   return mock->mock_dlopen_ext(true, libpath, flag, TO_MOCK_NAMESPACE(ns));
244*795d594fSAndroid Build Coastguard Worker }
245*795d594fSAndroid Build Coastguard Worker 
NativeBridgeInitialized()246*795d594fSAndroid Build Coastguard Worker bool NativeBridgeInitialized() { return mock->NativeBridgeInitialized(); }
247*795d594fSAndroid Build Coastguard Worker 
NativeBridgeInitAnonymousNamespace(const char * public_ns_sonames,const char * anon_ns_library_path)248*795d594fSAndroid Build Coastguard Worker bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames,
249*795d594fSAndroid Build Coastguard Worker                                         const char* anon_ns_library_path) {
250*795d594fSAndroid Build Coastguard Worker   return mock->mock_init_anonymous_namespace(true, public_ns_sonames, anon_ns_library_path);
251*795d594fSAndroid Build Coastguard Worker }
252*795d594fSAndroid Build Coastguard Worker 
NativeBridgeGetError()253*795d594fSAndroid Build Coastguard Worker const char* NativeBridgeGetError() { return mock->NativeBridgeGetError(); }
254*795d594fSAndroid Build Coastguard Worker 
NativeBridgeIsPathSupported(const char * path)255*795d594fSAndroid Build Coastguard Worker bool NativeBridgeIsPathSupported(const char* path) {
256*795d594fSAndroid Build Coastguard Worker   return mock->NativeBridgeIsPathSupported(path);
257*795d594fSAndroid Build Coastguard Worker }
258*795d594fSAndroid Build Coastguard Worker 
259*795d594fSAndroid Build Coastguard Worker }  // extern "C"
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker static void* const any_nonnull = reinterpret_cast<void*>(0x12345678);
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker // Custom matcher for comparing namespace handles
264*795d594fSAndroid Build Coastguard Worker MATCHER_P(NsEq, other, "") {
265*795d594fSAndroid Build Coastguard Worker   *result_listener << "comparing " << reinterpret_cast<const char*>(arg) << " and " << other;
266*795d594fSAndroid Build Coastguard Worker   return strcmp(reinterpret_cast<const char*>(arg), reinterpret_cast<const char*>(other)) == 0;
267*795d594fSAndroid Build Coastguard Worker }
268*795d594fSAndroid Build Coastguard Worker 
269*795d594fSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////
270*795d594fSAndroid Build Coastguard Worker 
271*795d594fSAndroid Build Coastguard Worker // Test fixture
272*795d594fSAndroid Build Coastguard Worker class NativeLoaderTest : public ::testing::TestWithParam<bool> {
273*795d594fSAndroid Build Coastguard Worker  protected:
IsBridged()274*795d594fSAndroid Build Coastguard Worker   bool IsBridged() { return GetParam(); }
275*795d594fSAndroid Build Coastguard Worker 
SetUp()276*795d594fSAndroid Build Coastguard Worker   void SetUp() override {
277*795d594fSAndroid Build Coastguard Worker     mock = std::make_unique<testing::NiceMock<MockPlatform>>(IsBridged());
278*795d594fSAndroid Build Coastguard Worker     jni_mock = std::make_unique<testing::NiceMock<MockJni>>();
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker     env = std::make_unique<JNIEnv>();
281*795d594fSAndroid Build Coastguard Worker     env->functions = CreateJNINativeInterface();
282*795d594fSAndroid Build Coastguard Worker   }
283*795d594fSAndroid Build Coastguard Worker 
SetExpectations()284*795d594fSAndroid Build Coastguard Worker   void SetExpectations() {
285*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> default_public_libs =
286*795d594fSAndroid Build Coastguard Worker         android::base::Split(preloadable_public_libraries(), ":");
287*795d594fSAndroid Build Coastguard Worker     for (const std::string& l : default_public_libs) {
288*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock,
289*795d594fSAndroid Build Coastguard Worker                   mock_dlopen_ext(false, StrEq(l.c_str()), RTLD_NOW | RTLD_NODELETE, NotNull()))
290*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(any_nonnull));
291*795d594fSAndroid Build Coastguard Worker     }
292*795d594fSAndroid Build Coastguard Worker   }
293*795d594fSAndroid Build Coastguard Worker 
RunTest()294*795d594fSAndroid Build Coastguard Worker   void RunTest() { InitializeNativeLoader(); }
295*795d594fSAndroid Build Coastguard Worker 
TearDown()296*795d594fSAndroid Build Coastguard Worker   void TearDown() override {
297*795d594fSAndroid Build Coastguard Worker     ResetNativeLoader();
298*795d594fSAndroid Build Coastguard Worker     delete env->functions;
299*795d594fSAndroid Build Coastguard Worker     mock.reset();
300*795d594fSAndroid Build Coastguard Worker   }
301*795d594fSAndroid Build Coastguard Worker 
302*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<JNIEnv> env;
303*795d594fSAndroid Build Coastguard Worker };
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////
306*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest,InitializeLoadsDefaultPublicLibraries)307*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest, InitializeLoadsDefaultPublicLibraries) {
308*795d594fSAndroid Build Coastguard Worker   SetExpectations();
309*795d594fSAndroid Build Coastguard Worker   RunTest();
310*795d594fSAndroid Build Coastguard Worker }
311*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest,OpenNativeLibraryWithoutClassloaderInApex)312*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest, OpenNativeLibraryWithoutClassloaderInApex) {
313*795d594fSAndroid Build Coastguard Worker   const char* test_lib_path = "libfoo.so";
314*795d594fSAndroid Build Coastguard Worker   void* fake_handle = &fake_handle;  // Arbitrary non-null value
315*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*mock,
316*795d594fSAndroid Build Coastguard Worker               mock_dlopen_ext(false, StrEq(test_lib_path), RTLD_NOW, NsEq("com_android_art")))
317*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(fake_handle));
318*795d594fSAndroid Build Coastguard Worker 
319*795d594fSAndroid Build Coastguard Worker   bool needs_native_bridge = false;
320*795d594fSAndroid Build Coastguard Worker   char* errmsg = nullptr;
321*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(fake_handle,
322*795d594fSAndroid Build Coastguard Worker             OpenNativeLibrary(env.get(),
323*795d594fSAndroid Build Coastguard Worker                               /*target_sdk_version=*/17,
324*795d594fSAndroid Build Coastguard Worker                               test_lib_path,
325*795d594fSAndroid Build Coastguard Worker                               /*class_loader=*/nullptr,
326*795d594fSAndroid Build Coastguard Worker                               /*caller_location=*/"/apex/com.android.art/javalib/myloadinglib.jar",
327*795d594fSAndroid Build Coastguard Worker                               /*library_path=*/nullptr,
328*795d594fSAndroid Build Coastguard Worker                               &needs_native_bridge,
329*795d594fSAndroid Build Coastguard Worker                               &errmsg));
330*795d594fSAndroid Build Coastguard Worker   // OpenNativeLibrary never uses nativebridge when there's no classloader. That
331*795d594fSAndroid Build Coastguard Worker   // should maybe change.
332*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(needs_native_bridge, false);
333*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(errmsg, nullptr);
334*795d594fSAndroid Build Coastguard Worker }
335*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest,OpenNativeLibraryWithoutClassloaderInFramework)336*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest, OpenNativeLibraryWithoutClassloaderInFramework) {
337*795d594fSAndroid Build Coastguard Worker   const char* test_lib_path = "libfoo.so";
338*795d594fSAndroid Build Coastguard Worker   void* fake_handle = &fake_handle;  // Arbitrary non-null value
339*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*mock, mock_dlopen_ext(false, StrEq(test_lib_path), RTLD_NOW, NsEq("system")))
340*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(fake_handle));
341*795d594fSAndroid Build Coastguard Worker 
342*795d594fSAndroid Build Coastguard Worker   bool needs_native_bridge = false;
343*795d594fSAndroid Build Coastguard Worker   char* errmsg = nullptr;
344*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(fake_handle,
345*795d594fSAndroid Build Coastguard Worker             OpenNativeLibrary(env.get(),
346*795d594fSAndroid Build Coastguard Worker                               /*target_sdk_version=*/17,
347*795d594fSAndroid Build Coastguard Worker                               test_lib_path,
348*795d594fSAndroid Build Coastguard Worker                               /*class_loader=*/nullptr,
349*795d594fSAndroid Build Coastguard Worker                               /*caller_location=*/"/system/framework/framework.jar!classes1.dex",
350*795d594fSAndroid Build Coastguard Worker                               /*library_path=*/nullptr,
351*795d594fSAndroid Build Coastguard Worker                               &needs_native_bridge,
352*795d594fSAndroid Build Coastguard Worker                               &errmsg));
353*795d594fSAndroid Build Coastguard Worker   // OpenNativeLibrary never uses nativebridge when there's no classloader. That
354*795d594fSAndroid Build Coastguard Worker   // should maybe change.
355*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(needs_native_bridge, false);
356*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(errmsg, nullptr);
357*795d594fSAndroid Build Coastguard Worker }
358*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest,OpenNativeLibraryWithoutClassloaderAndCallerLocation)359*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest, OpenNativeLibraryWithoutClassloaderAndCallerLocation) {
360*795d594fSAndroid Build Coastguard Worker   const char* test_lib_path = "libfoo.so";
361*795d594fSAndroid Build Coastguard Worker   void* fake_handle = &fake_handle;  // Arbitrary non-null value
362*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*mock, mock_dlopen_ext(false, StrEq(test_lib_path), RTLD_NOW, NsEq("system")))
363*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(fake_handle));
364*795d594fSAndroid Build Coastguard Worker 
365*795d594fSAndroid Build Coastguard Worker   bool needs_native_bridge = false;
366*795d594fSAndroid Build Coastguard Worker   char* errmsg = nullptr;
367*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(fake_handle,
368*795d594fSAndroid Build Coastguard Worker             OpenNativeLibrary(env.get(),
369*795d594fSAndroid Build Coastguard Worker                               /*target_sdk_version=*/17,
370*795d594fSAndroid Build Coastguard Worker                               test_lib_path,
371*795d594fSAndroid Build Coastguard Worker                               /*class_loader=*/nullptr,
372*795d594fSAndroid Build Coastguard Worker                               /*caller_location=*/nullptr,
373*795d594fSAndroid Build Coastguard Worker                               /*library_path=*/nullptr,
374*795d594fSAndroid Build Coastguard Worker                               &needs_native_bridge,
375*795d594fSAndroid Build Coastguard Worker                               &errmsg));
376*795d594fSAndroid Build Coastguard Worker   // OpenNativeLibrary never uses nativebridge when there's no classloader. That
377*795d594fSAndroid Build Coastguard Worker   // should maybe change.
378*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(needs_native_bridge, false);
379*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(errmsg, nullptr);
380*795d594fSAndroid Build Coastguard Worker }
381*795d594fSAndroid Build Coastguard Worker 
382*795d594fSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(NativeLoaderTests, NativeLoaderTest, testing::Bool());
383*795d594fSAndroid Build Coastguard Worker 
384*795d594fSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////
385*795d594fSAndroid Build Coastguard Worker 
append_extended_libraries(const std::string & libs)386*795d594fSAndroid Build Coastguard Worker std::string append_extended_libraries(const std::string& libs) {
387*795d594fSAndroid Build Coastguard Worker   const std::string& ext_libs = extended_public_libraries();
388*795d594fSAndroid Build Coastguard Worker   if (!ext_libs.empty()) {
389*795d594fSAndroid Build Coastguard Worker     return libs + ":" + ext_libs;
390*795d594fSAndroid Build Coastguard Worker   }
391*795d594fSAndroid Build Coastguard Worker   return libs;
392*795d594fSAndroid Build Coastguard Worker }
393*795d594fSAndroid Build Coastguard Worker 
default_public_and_extended_libraries()394*795d594fSAndroid Build Coastguard Worker std::string default_public_and_extended_libraries() {
395*795d594fSAndroid Build Coastguard Worker   return append_extended_libraries(default_public_libraries());
396*795d594fSAndroid Build Coastguard Worker }
397*795d594fSAndroid Build Coastguard Worker 
398*795d594fSAndroid Build Coastguard Worker class NativeLoaderTest_Create : public NativeLoaderTest {
399*795d594fSAndroid Build Coastguard Worker  protected:
400*795d594fSAndroid Build Coastguard Worker   // Test inputs (initialized to the default values). Overriding these
401*795d594fSAndroid Build Coastguard Worker   // must be done before calling SetExpectations() and RunTest().
402*795d594fSAndroid Build Coastguard Worker   uint32_t target_sdk_version = 29;
403*795d594fSAndroid Build Coastguard Worker   std::string class_loader = "my_classloader";
404*795d594fSAndroid Build Coastguard Worker   bool is_shared = false;
405*795d594fSAndroid Build Coastguard Worker   std::string dex_path = "/data/app/foo/classes.dex";
406*795d594fSAndroid Build Coastguard Worker   std::string library_path = "/data/app/foo/" LIB_DIR "/arm";
407*795d594fSAndroid Build Coastguard Worker   std::string permitted_path = "/data/app/foo/" LIB_DIR;
408*795d594fSAndroid Build Coastguard Worker 
409*795d594fSAndroid Build Coastguard Worker   // expected output (.. for the default test inputs)
410*795d594fSAndroid Build Coastguard Worker   std::string expected_namespace_prefix = "clns";
411*795d594fSAndroid Build Coastguard Worker   uint64_t expected_namespace_flags =
412*795d594fSAndroid Build Coastguard Worker       ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS;
413*795d594fSAndroid Build Coastguard Worker   std::string expected_library_path = library_path;
414*795d594fSAndroid Build Coastguard Worker   std::string expected_permitted_path = std::string("/data:/mnt/expand:") + permitted_path;
415*795d594fSAndroid Build Coastguard Worker   std::string expected_parent_namespace = "system";
416*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_platform_ns = true;
417*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_art_ns = true;
418*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_i18n_ns = true;
419*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_conscrypt_ns = false;
420*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_sphal_ns = !vendor_public_libraries().empty();
421*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_product_ns = !product_public_libraries().empty();
422*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_vndk_ns = false;
423*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_vndk_product_ns = false;
424*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_default_ns = false;
425*795d594fSAndroid Build Coastguard Worker   bool expected_link_with_neuralnetworks_ns = true;
426*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_platform_ns = default_public_and_extended_libraries();
427*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_art_ns = apex_public_libraries().at("com_android_art");
428*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_i18n_ns = apex_public_libraries().at("com_android_i18n");
429*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_conscrypt_ns = apex_jni_libraries("com_android_conscrypt");
430*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_sphal_ns = vendor_public_libraries();
431*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_product_ns = product_public_libraries();
432*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_vndk_ns = vndksp_libraries_vendor();
433*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_vndk_product_ns = vndksp_libraries_product();
434*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_default_ns = default_public_and_extended_libraries();
435*795d594fSAndroid Build Coastguard Worker   std::string expected_shared_libs_to_neuralnetworks_ns = apex_public_libraries().at("com_android_neuralnetworks");
436*795d594fSAndroid Build Coastguard Worker 
SetExpectations()437*795d594fSAndroid Build Coastguard Worker   void SetExpectations() {
438*795d594fSAndroid Build Coastguard Worker     NativeLoaderTest::SetExpectations();
439*795d594fSAndroid Build Coastguard Worker 
440*795d594fSAndroid Build Coastguard Worker     ON_CALL(*jni_mock, JniObject_getParent(StrEq(class_loader))).WillByDefault(Return(nullptr));
441*795d594fSAndroid Build Coastguard Worker 
442*795d594fSAndroid Build Coastguard Worker     EXPECT_CALL(*mock, NativeBridgeIsPathSupported(_)).Times(testing::AnyNumber());
443*795d594fSAndroid Build Coastguard Worker     EXPECT_CALL(*mock, NativeBridgeInitialized()).Times(testing::AnyNumber());
444*795d594fSAndroid Build Coastguard Worker 
445*795d594fSAndroid Build Coastguard Worker     EXPECT_CALL(*mock, mock_create_namespace(
446*795d594fSAndroid Build Coastguard Worker                            Eq(IsBridged()), StartsWith(expected_namespace_prefix + "-"), nullptr,
447*795d594fSAndroid Build Coastguard Worker                            StrEq(expected_library_path), expected_namespace_flags,
448*795d594fSAndroid Build Coastguard Worker                            StrEq(expected_permitted_path), NsEq(expected_parent_namespace.c_str())))
449*795d594fSAndroid Build Coastguard Worker         .WillOnce(Return(TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE(dex_path.c_str()))));
450*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_platform_ns) {
451*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("system"),
452*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_platform_ns)))
453*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
454*795d594fSAndroid Build Coastguard Worker     }
455*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_art_ns) {
456*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("com_android_art"),
457*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_art_ns)))
458*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
459*795d594fSAndroid Build Coastguard Worker     }
460*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_i18n_ns) {
461*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("com_android_i18n"),
462*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_i18n_ns)))
463*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
464*795d594fSAndroid Build Coastguard Worker     }
465*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_sphal_ns) {
466*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("sphal"),
467*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_sphal_ns)))
468*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
469*795d594fSAndroid Build Coastguard Worker     }
470*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_product_ns) {
471*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("product"),
472*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_product_ns)))
473*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
474*795d594fSAndroid Build Coastguard Worker     }
475*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_vndk_ns) {
476*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("vndk"),
477*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_vndk_ns)))
478*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
479*795d594fSAndroid Build Coastguard Worker     }
480*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_vndk_product_ns) {
481*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("vndk_product"),
482*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_vndk_product_ns)))
483*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
484*795d594fSAndroid Build Coastguard Worker     }
485*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_default_ns) {
486*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("default"),
487*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_default_ns)))
488*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
489*795d594fSAndroid Build Coastguard Worker     }
490*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_neuralnetworks_ns) {
491*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("com_android_neuralnetworks"),
492*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_neuralnetworks_ns)))
493*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
494*795d594fSAndroid Build Coastguard Worker     }
495*795d594fSAndroid Build Coastguard Worker     if (expected_link_with_conscrypt_ns) {
496*795d594fSAndroid Build Coastguard Worker       EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("com_android_conscrypt"),
497*795d594fSAndroid Build Coastguard Worker                                               StrEq(expected_shared_libs_to_conscrypt_ns)))
498*795d594fSAndroid Build Coastguard Worker           .WillOnce(Return(true));
499*795d594fSAndroid Build Coastguard Worker     }
500*795d594fSAndroid Build Coastguard Worker   }
501*795d594fSAndroid Build Coastguard Worker 
RunTest()502*795d594fSAndroid Build Coastguard Worker   void RunTest() {
503*795d594fSAndroid Build Coastguard Worker     NativeLoaderTest::RunTest();
504*795d594fSAndroid Build Coastguard Worker 
505*795d594fSAndroid Build Coastguard Worker     jstring err = CreateClassLoaderNamespace(
506*795d594fSAndroid Build Coastguard Worker         env(), target_sdk_version, env()->NewStringUTF(class_loader.c_str()), is_shared,
507*795d594fSAndroid Build Coastguard Worker         env()->NewStringUTF(dex_path.c_str()), env()->NewStringUTF(library_path.c_str()),
508*795d594fSAndroid Build Coastguard Worker         env()->NewStringUTF(permitted_path.c_str()), /*uses_library_list=*/ nullptr);
509*795d594fSAndroid Build Coastguard Worker 
510*795d594fSAndroid Build Coastguard Worker     // no error
511*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(err, nullptr) << "Error is: " << std::string(ScopedUtfChars(env(), err).c_str());
512*795d594fSAndroid Build Coastguard Worker 
513*795d594fSAndroid Build Coastguard Worker     if (!IsBridged()) {
514*795d594fSAndroid Build Coastguard Worker       struct android_namespace_t* ns =
515*795d594fSAndroid Build Coastguard Worker           FindNamespaceByClassLoader(env(), env()->NewStringUTF(class_loader.c_str()));
516*795d594fSAndroid Build Coastguard Worker 
517*795d594fSAndroid Build Coastguard Worker       // The created namespace is for this apk
518*795d594fSAndroid Build Coastguard Worker       EXPECT_EQ(dex_path.c_str(), reinterpret_cast<const char*>(ns));
519*795d594fSAndroid Build Coastguard Worker     } else {
520*795d594fSAndroid Build Coastguard Worker       struct NativeLoaderNamespace* ns =
521*795d594fSAndroid Build Coastguard Worker           FindNativeLoaderNamespaceByClassLoader(env(), env()->NewStringUTF(class_loader.c_str()));
522*795d594fSAndroid Build Coastguard Worker 
523*795d594fSAndroid Build Coastguard Worker       // The created namespace is for the this apk
524*795d594fSAndroid Build Coastguard Worker       EXPECT_STREQ(dex_path.c_str(),
525*795d594fSAndroid Build Coastguard Worker                    reinterpret_cast<const char*>(ns->ToRawNativeBridgeNamespace()));
526*795d594fSAndroid Build Coastguard Worker     }
527*795d594fSAndroid Build Coastguard Worker   }
528*795d594fSAndroid Build Coastguard Worker 
env()529*795d594fSAndroid Build Coastguard Worker   JNIEnv* env() { return NativeLoaderTest::env.get(); }
530*795d594fSAndroid Build Coastguard Worker };
531*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,DownloadedApp)532*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, DownloadedApp) {
533*795d594fSAndroid Build Coastguard Worker   SetExpectations();
534*795d594fSAndroid Build Coastguard Worker   RunTest();
535*795d594fSAndroid Build Coastguard Worker }
536*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,BundledSystemApp)537*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, BundledSystemApp) {
538*795d594fSAndroid Build Coastguard Worker   dex_path = "/system/app/foo/foo.apk";
539*795d594fSAndroid Build Coastguard Worker   is_shared = true;
540*795d594fSAndroid Build Coastguard Worker 
541*795d594fSAndroid Build Coastguard Worker   expected_namespace_prefix = "clns-shared";
542*795d594fSAndroid Build Coastguard Worker   expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
543*795d594fSAndroid Build Coastguard Worker   SetExpectations();
544*795d594fSAndroid Build Coastguard Worker   RunTest();
545*795d594fSAndroid Build Coastguard Worker }
546*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,BundledVendorApp)547*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, BundledVendorApp) {
548*795d594fSAndroid Build Coastguard Worker   dex_path = "/vendor/app/foo/foo.apk";
549*795d594fSAndroid Build Coastguard Worker   is_shared = true;
550*795d594fSAndroid Build Coastguard Worker 
551*795d594fSAndroid Build Coastguard Worker   expected_namespace_prefix = "clns-shared";
552*795d594fSAndroid Build Coastguard Worker   expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
553*795d594fSAndroid Build Coastguard Worker   SetExpectations();
554*795d594fSAndroid Build Coastguard Worker   RunTest();
555*795d594fSAndroid Build Coastguard Worker }
556*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,UnbundledVendorApp)557*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, UnbundledVendorApp) {
558*795d594fSAndroid Build Coastguard Worker   dex_path = "/vendor/app/foo/foo.apk";
559*795d594fSAndroid Build Coastguard Worker   is_shared = false;
560*795d594fSAndroid Build Coastguard Worker 
561*795d594fSAndroid Build Coastguard Worker   expected_namespace_prefix = "vendor-clns";
562*795d594fSAndroid Build Coastguard Worker   expected_library_path = expected_library_path + ":/vendor/" LIB_DIR;
563*795d594fSAndroid Build Coastguard Worker   expected_permitted_path = expected_permitted_path + ":/vendor/" LIB_DIR;
564*795d594fSAndroid Build Coastguard Worker   expected_shared_libs_to_platform_ns =
565*795d594fSAndroid Build Coastguard Worker       default_public_libraries() + ":" + llndk_libraries_vendor();
566*795d594fSAndroid Build Coastguard Worker   if (android::base::GetProperty("ro.vndk.version", "") != "") {
567*795d594fSAndroid Build Coastguard Worker     expected_link_with_vndk_ns = true;
568*795d594fSAndroid Build Coastguard Worker   }
569*795d594fSAndroid Build Coastguard Worker   SetExpectations();
570*795d594fSAndroid Build Coastguard Worker   RunTest();
571*795d594fSAndroid Build Coastguard Worker }
572*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,BundledProductApp)573*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, BundledProductApp) {
574*795d594fSAndroid Build Coastguard Worker   dex_path = "/product/app/foo/foo.apk";
575*795d594fSAndroid Build Coastguard Worker   is_shared = true;
576*795d594fSAndroid Build Coastguard Worker 
577*795d594fSAndroid Build Coastguard Worker   expected_namespace_prefix = "clns-shared";
578*795d594fSAndroid Build Coastguard Worker   expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
579*795d594fSAndroid Build Coastguard Worker   SetExpectations();
580*795d594fSAndroid Build Coastguard Worker   RunTest();
581*795d594fSAndroid Build Coastguard Worker }
582*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,SystemServerWithApexJars)583*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, SystemServerWithApexJars) {
584*795d594fSAndroid Build Coastguard Worker   dex_path = "/system/framework/services.jar:/apex/com.android.conscrypt/javalib/service-foo.jar";
585*795d594fSAndroid Build Coastguard Worker   is_shared = true;
586*795d594fSAndroid Build Coastguard Worker 
587*795d594fSAndroid Build Coastguard Worker   expected_namespace_prefix = "clns-shared";
588*795d594fSAndroid Build Coastguard Worker   expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
589*795d594fSAndroid Build Coastguard Worker   expected_link_with_conscrypt_ns = true;
590*795d594fSAndroid Build Coastguard Worker   SetExpectations();
591*795d594fSAndroid Build Coastguard Worker   RunTest();
592*795d594fSAndroid Build Coastguard Worker }
593*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,UnbundledProductApp)594*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, UnbundledProductApp) {
595*795d594fSAndroid Build Coastguard Worker   dex_path = "/product/app/foo/foo.apk";
596*795d594fSAndroid Build Coastguard Worker   is_shared = false;
597*795d594fSAndroid Build Coastguard Worker 
598*795d594fSAndroid Build Coastguard Worker   if (is_product_treblelized()) {
599*795d594fSAndroid Build Coastguard Worker     expected_namespace_prefix = "product-clns";
600*795d594fSAndroid Build Coastguard Worker     expected_library_path =
601*795d594fSAndroid Build Coastguard Worker         expected_library_path + ":/product/" LIB_DIR ":/system/product/" LIB_DIR;
602*795d594fSAndroid Build Coastguard Worker     expected_permitted_path =
603*795d594fSAndroid Build Coastguard Worker         expected_permitted_path + ":/product/" LIB_DIR ":/system/product/" LIB_DIR;
604*795d594fSAndroid Build Coastguard Worker     expected_shared_libs_to_platform_ns =
605*795d594fSAndroid Build Coastguard Worker         append_extended_libraries(default_public_libraries() + ":" + llndk_libraries_product());
606*795d594fSAndroid Build Coastguard Worker     if (android::base::GetProperty("ro.product.vndk.version", "") != "") {
607*795d594fSAndroid Build Coastguard Worker       expected_link_with_vndk_product_ns = true;
608*795d594fSAndroid Build Coastguard Worker     }
609*795d594fSAndroid Build Coastguard Worker   }
610*795d594fSAndroid Build Coastguard Worker 
611*795d594fSAndroid Build Coastguard Worker   SetExpectations();
612*795d594fSAndroid Build Coastguard Worker   RunTest();
613*795d594fSAndroid Build Coastguard Worker }
614*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,NamespaceForSharedLibIsNotUsedAsAnonymousNamespace)615*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, NamespaceForSharedLibIsNotUsedAsAnonymousNamespace) {
616*795d594fSAndroid Build Coastguard Worker   if (IsBridged()) {
617*795d594fSAndroid Build Coastguard Worker     // There is no shared lib in translated arch
618*795d594fSAndroid Build Coastguard Worker     // TODO(jiyong): revisit this
619*795d594fSAndroid Build Coastguard Worker     return;
620*795d594fSAndroid Build Coastguard Worker   }
621*795d594fSAndroid Build Coastguard Worker   // compared to apks, for java shared libs, library_path is empty; java shared
622*795d594fSAndroid Build Coastguard Worker   // libs don't have their own native libs. They use platform's.
623*795d594fSAndroid Build Coastguard Worker   library_path = "";
624*795d594fSAndroid Build Coastguard Worker   expected_library_path = library_path;
625*795d594fSAndroid Build Coastguard Worker   // no ALSO_USED_AS_ANONYMOUS
626*795d594fSAndroid Build Coastguard Worker   expected_namespace_flags = ANDROID_NAMESPACE_TYPE_ISOLATED;
627*795d594fSAndroid Build Coastguard Worker   SetExpectations();
628*795d594fSAndroid Build Coastguard Worker   RunTest();
629*795d594fSAndroid Build Coastguard Worker }
630*795d594fSAndroid Build Coastguard Worker 
TEST_P(NativeLoaderTest_Create,TwoApks)631*795d594fSAndroid Build Coastguard Worker TEST_P(NativeLoaderTest_Create, TwoApks) {
632*795d594fSAndroid Build Coastguard Worker   SetExpectations();
633*795d594fSAndroid Build Coastguard Worker   const uint32_t second_app_target_sdk_version = 29;
634*795d594fSAndroid Build Coastguard Worker   const std::string second_app_class_loader = "second_app_classloader";
635*795d594fSAndroid Build Coastguard Worker   const bool second_app_is_shared = false;
636*795d594fSAndroid Build Coastguard Worker   const std::string second_app_dex_path = "/data/app/bar/classes.dex";
637*795d594fSAndroid Build Coastguard Worker   const std::string second_app_library_path = "/data/app/bar/" LIB_DIR "/arm";
638*795d594fSAndroid Build Coastguard Worker   const std::string second_app_permitted_path = "/data/app/bar/" LIB_DIR;
639*795d594fSAndroid Build Coastguard Worker   const std::string expected_second_app_permitted_path =
640*795d594fSAndroid Build Coastguard Worker       std::string("/data:/mnt/expand:") + second_app_permitted_path;
641*795d594fSAndroid Build Coastguard Worker   const std::string expected_second_app_parent_namespace = "clns";
642*795d594fSAndroid Build Coastguard Worker   // no ALSO_USED_AS_ANONYMOUS
643*795d594fSAndroid Build Coastguard Worker   const uint64_t expected_second_namespace_flags = ANDROID_NAMESPACE_TYPE_ISOLATED;
644*795d594fSAndroid Build Coastguard Worker 
645*795d594fSAndroid Build Coastguard Worker   // The scenario is that second app is loaded by the first app.
646*795d594fSAndroid Build Coastguard Worker   // So the first app's classloader (`classloader`) is parent of the second
647*795d594fSAndroid Build Coastguard Worker   // app's classloader.
648*795d594fSAndroid Build Coastguard Worker   ON_CALL(*jni_mock, JniObject_getParent(StrEq(second_app_class_loader)))
649*795d594fSAndroid Build Coastguard Worker       .WillByDefault(Return(class_loader.c_str()));
650*795d594fSAndroid Build Coastguard Worker 
651*795d594fSAndroid Build Coastguard Worker   // namespace for the second app is created. Its parent is set to the namespace
652*795d594fSAndroid Build Coastguard Worker   // of the first app.
653*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*mock, mock_create_namespace(
654*795d594fSAndroid Build Coastguard Worker                          Eq(IsBridged()), StartsWith(expected_namespace_prefix + "-"), nullptr,
655*795d594fSAndroid Build Coastguard Worker                          StrEq(second_app_library_path), expected_second_namespace_flags,
656*795d594fSAndroid Build Coastguard Worker                          StrEq(expected_second_app_permitted_path), NsEq(dex_path.c_str())))
657*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE(second_app_dex_path.c_str()))));
658*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), NsEq(second_app_dex_path.c_str()), _, _))
659*795d594fSAndroid Build Coastguard Worker       .WillRepeatedly(Return(true));
660*795d594fSAndroid Build Coastguard Worker 
661*795d594fSAndroid Build Coastguard Worker   RunTest();
662*795d594fSAndroid Build Coastguard Worker   jstring err = CreateClassLoaderNamespace(
663*795d594fSAndroid Build Coastguard Worker       env(), second_app_target_sdk_version, env()->NewStringUTF(second_app_class_loader.c_str()),
664*795d594fSAndroid Build Coastguard Worker       second_app_is_shared, env()->NewStringUTF(second_app_dex_path.c_str()),
665*795d594fSAndroid Build Coastguard Worker       env()->NewStringUTF(second_app_library_path.c_str()),
666*795d594fSAndroid Build Coastguard Worker       env()->NewStringUTF(second_app_permitted_path.c_str()), /*uses_library_list=*/ nullptr);
667*795d594fSAndroid Build Coastguard Worker 
668*795d594fSAndroid Build Coastguard Worker   // success
669*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(err, nullptr) << "Error is: " << std::string(ScopedUtfChars(env(), err).c_str());
670*795d594fSAndroid Build Coastguard Worker 
671*795d594fSAndroid Build Coastguard Worker   if (!IsBridged()) {
672*795d594fSAndroid Build Coastguard Worker     struct android_namespace_t* ns =
673*795d594fSAndroid Build Coastguard Worker         FindNamespaceByClassLoader(env(), env()->NewStringUTF(second_app_class_loader.c_str()));
674*795d594fSAndroid Build Coastguard Worker 
675*795d594fSAndroid Build Coastguard Worker     // The created namespace is for the second apk
676*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(second_app_dex_path.c_str(), reinterpret_cast<const char*>(ns));
677*795d594fSAndroid Build Coastguard Worker   } else {
678*795d594fSAndroid Build Coastguard Worker     struct NativeLoaderNamespace* ns = FindNativeLoaderNamespaceByClassLoader(
679*795d594fSAndroid Build Coastguard Worker         env(), env()->NewStringUTF(second_app_class_loader.c_str()));
680*795d594fSAndroid Build Coastguard Worker 
681*795d594fSAndroid Build Coastguard Worker     // The created namespace is for the second apk
682*795d594fSAndroid Build Coastguard Worker     EXPECT_STREQ(second_app_dex_path.c_str(),
683*795d594fSAndroid Build Coastguard Worker                  reinterpret_cast<const char*>(ns->ToRawNativeBridgeNamespace()));
684*795d594fSAndroid Build Coastguard Worker   }
685*795d594fSAndroid Build Coastguard Worker }
686*795d594fSAndroid Build Coastguard Worker 
687*795d594fSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(NativeLoaderTests_Create, NativeLoaderTest_Create, testing::Bool());
688*795d594fSAndroid Build Coastguard Worker 
689*795d594fSAndroid Build Coastguard Worker const std::function<Result<bool>(const struct ConfigEntry&)> always_true =
__anon3afa237c0202(const struct ConfigEntry&) 690*795d594fSAndroid Build Coastguard Worker     [](const struct ConfigEntry&) -> Result<bool> { return true; };
691*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderConfigParser,NamesAndComments)692*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderConfigParser, NamesAndComments) {
693*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
694*795d594fSAndroid Build Coastguard Worker ######
695*795d594fSAndroid Build Coastguard Worker 
696*795d594fSAndroid Build Coastguard Worker libA.so
697*795d594fSAndroid Build Coastguard Worker #libB.so
698*795d594fSAndroid Build Coastguard Worker 
699*795d594fSAndroid Build Coastguard Worker 
700*795d594fSAndroid Build Coastguard Worker       libC.so
701*795d594fSAndroid Build Coastguard Worker libD.so
702*795d594fSAndroid Build Coastguard Worker     #### libE.so
703*795d594fSAndroid Build Coastguard Worker )";
704*795d594fSAndroid Build Coastguard Worker   const std::vector<std::string> expected_result = {"libA.so", "libC.so", "libD.so"};
705*795d594fSAndroid Build Coastguard Worker   Result<std::vector<std::string>> result = ParseConfig(file_content, always_true);
706*795d594fSAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
707*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_result, *result);
708*795d594fSAndroid Build Coastguard Worker }
709*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderConfigParser,WithBitness)710*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderConfigParser, WithBitness) {
711*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
712*795d594fSAndroid Build Coastguard Worker libA.so 32
713*795d594fSAndroid Build Coastguard Worker libB.so 64
714*795d594fSAndroid Build Coastguard Worker libC.so
715*795d594fSAndroid Build Coastguard Worker )";
716*795d594fSAndroid Build Coastguard Worker #if defined(__LP64__)
717*795d594fSAndroid Build Coastguard Worker   const std::vector<std::string> expected_result = {"libB.so", "libC.so"};
718*795d594fSAndroid Build Coastguard Worker #else
719*795d594fSAndroid Build Coastguard Worker   const std::vector<std::string> expected_result = {"libA.so", "libC.so"};
720*795d594fSAndroid Build Coastguard Worker #endif
721*795d594fSAndroid Build Coastguard Worker   Result<std::vector<std::string>> result = ParseConfig(file_content, always_true);
722*795d594fSAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
723*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_result, *result);
724*795d594fSAndroid Build Coastguard Worker }
725*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderConfigParser,WithNoPreload)726*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderConfigParser, WithNoPreload) {
727*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
728*795d594fSAndroid Build Coastguard Worker libA.so nopreload
729*795d594fSAndroid Build Coastguard Worker libB.so nopreload
730*795d594fSAndroid Build Coastguard Worker libC.so
731*795d594fSAndroid Build Coastguard Worker )";
732*795d594fSAndroid Build Coastguard Worker 
733*795d594fSAndroid Build Coastguard Worker   const std::vector<std::string> expected_result = {"libC.so"};
734*795d594fSAndroid Build Coastguard Worker   Result<std::vector<std::string>> result =
735*795d594fSAndroid Build Coastguard Worker       ParseConfig(file_content,
736*795d594fSAndroid Build Coastguard Worker                   [](const struct ConfigEntry& entry) -> Result<bool> { return !entry.nopreload; });
737*795d594fSAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
738*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_result, *result);
739*795d594fSAndroid Build Coastguard Worker }
740*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderConfigParser,WithNoPreloadAndBitness)741*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderConfigParser, WithNoPreloadAndBitness) {
742*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
743*795d594fSAndroid Build Coastguard Worker libA.so nopreload 32
744*795d594fSAndroid Build Coastguard Worker libB.so 64 nopreload
745*795d594fSAndroid Build Coastguard Worker libC.so 32
746*795d594fSAndroid Build Coastguard Worker libD.so 64
747*795d594fSAndroid Build Coastguard Worker libE.so nopreload
748*795d594fSAndroid Build Coastguard Worker )";
749*795d594fSAndroid Build Coastguard Worker 
750*795d594fSAndroid Build Coastguard Worker #if defined(__LP64__)
751*795d594fSAndroid Build Coastguard Worker   const std::vector<std::string> expected_result = {"libD.so"};
752*795d594fSAndroid Build Coastguard Worker #else
753*795d594fSAndroid Build Coastguard Worker   const std::vector<std::string> expected_result = {"libC.so"};
754*795d594fSAndroid Build Coastguard Worker #endif
755*795d594fSAndroid Build Coastguard Worker   Result<std::vector<std::string>> result =
756*795d594fSAndroid Build Coastguard Worker       ParseConfig(file_content,
757*795d594fSAndroid Build Coastguard Worker                   [](const struct ConfigEntry& entry) -> Result<bool> { return !entry.nopreload; });
758*795d594fSAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
759*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_result, *result);
760*795d594fSAndroid Build Coastguard Worker }
761*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderConfigParser,RejectMalformed)762*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderConfigParser, RejectMalformed) {
763*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ParseConfig("libA.so 32 64", always_true).ok());
764*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ParseConfig("libA.so 32 32", always_true).ok());
765*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ParseConfig("libA.so 32 nopreload 64", always_true).ok());
766*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ParseConfig("32 libA.so nopreload", always_true).ok());
767*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ParseConfig("nopreload libA.so 32", always_true).ok());
768*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ParseConfig("libA.so nopreload # comment", always_true).ok());
769*795d594fSAndroid Build Coastguard Worker }
770*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderApexLibrariesConfigParser,BasicLoading)771*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderApexLibrariesConfigParser, BasicLoading) {
772*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
773*795d594fSAndroid Build Coastguard Worker # comment
774*795d594fSAndroid Build Coastguard Worker jni com_android_foo libfoo.so
775*795d594fSAndroid Build Coastguard Worker # Empty line is ignored
776*795d594fSAndroid Build Coastguard Worker 
777*795d594fSAndroid Build Coastguard Worker jni com_android_bar libbar.so:libbar2.so
778*795d594fSAndroid Build Coastguard Worker 
779*795d594fSAndroid Build Coastguard Worker   public com_android_bar libpublic.so
780*795d594fSAndroid Build Coastguard Worker )";
781*795d594fSAndroid Build Coastguard Worker 
782*795d594fSAndroid Build Coastguard Worker   Result<std::map<std::string, std::string>> jni_libs =
783*795d594fSAndroid Build Coastguard Worker       ParseApexLibrariesConfig(file_content, "jni");
784*795d594fSAndroid Build Coastguard Worker   ASSERT_RESULT_OK(jni_libs);
785*795d594fSAndroid Build Coastguard Worker   std::map<std::string, std::string> expected_jni_libs {
786*795d594fSAndroid Build Coastguard Worker     {"com_android_foo", "libfoo.so"},
787*795d594fSAndroid Build Coastguard Worker     {"com_android_bar", "libbar.so:libbar2.so"},
788*795d594fSAndroid Build Coastguard Worker   };
789*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_jni_libs, *jni_libs);
790*795d594fSAndroid Build Coastguard Worker 
791*795d594fSAndroid Build Coastguard Worker   Result<std::map<std::string, std::string>> public_libs =
792*795d594fSAndroid Build Coastguard Worker       ParseApexLibrariesConfig(file_content, "public");
793*795d594fSAndroid Build Coastguard Worker   ASSERT_RESULT_OK(public_libs);
794*795d594fSAndroid Build Coastguard Worker   std::map<std::string, std::string> expected_public_libs {
795*795d594fSAndroid Build Coastguard Worker     {"com_android_bar", "libpublic.so"},
796*795d594fSAndroid Build Coastguard Worker   };
797*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_public_libs, *public_libs);
798*795d594fSAndroid Build Coastguard Worker }
799*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderApexLibrariesConfigParser,RejectMalformedLine)800*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderApexLibrariesConfigParser, RejectMalformedLine) {
801*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
802*795d594fSAndroid Build Coastguard Worker jni com_android_foo libfoo
803*795d594fSAndroid Build Coastguard Worker # missing <library list>
804*795d594fSAndroid Build Coastguard Worker jni com_android_bar
805*795d594fSAndroid Build Coastguard Worker )";
806*795d594fSAndroid Build Coastguard Worker   Result<std::map<std::string, std::string>> result = ParseApexLibrariesConfig(file_content, "jni");
807*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
808*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ("Malformed line \"jni com_android_bar\"", result.error().message());
809*795d594fSAndroid Build Coastguard Worker }
810*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderApexLibrariesConfigParser,RejectInvalidTag)811*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderApexLibrariesConfigParser, RejectInvalidTag) {
812*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
813*795d594fSAndroid Build Coastguard Worker jni apex1 lib
814*795d594fSAndroid Build Coastguard Worker public apex2 lib
815*795d594fSAndroid Build Coastguard Worker # unknown tag
816*795d594fSAndroid Build Coastguard Worker unknown com_android_foo libfoo
817*795d594fSAndroid Build Coastguard Worker )";
818*795d594fSAndroid Build Coastguard Worker   Result<std::map<std::string, std::string>> result = ParseApexLibrariesConfig(file_content, "jni");
819*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
820*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ("Invalid tag \"unknown com_android_foo libfoo\"", result.error().message());
821*795d594fSAndroid Build Coastguard Worker }
822*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderApexLibrariesConfigParser,RejectInvalidApexNamespace)823*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderApexLibrariesConfigParser, RejectInvalidApexNamespace) {
824*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
825*795d594fSAndroid Build Coastguard Worker # apex linker namespace should be mangled ('.' -> '_')
826*795d594fSAndroid Build Coastguard Worker jni com.android.foo lib
827*795d594fSAndroid Build Coastguard Worker )";
828*795d594fSAndroid Build Coastguard Worker   Result<std::map<std::string, std::string>> result = ParseApexLibrariesConfig(file_content, "jni");
829*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
830*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ("Invalid apex_namespace \"jni com.android.foo lib\"", result.error().message());
831*795d594fSAndroid Build Coastguard Worker }
832*795d594fSAndroid Build Coastguard Worker 
TEST(NativeLoaderApexLibrariesConfigParser,RejectInvalidLibraryList)833*795d594fSAndroid Build Coastguard Worker TEST(NativeLoaderApexLibrariesConfigParser, RejectInvalidLibraryList) {
834*795d594fSAndroid Build Coastguard Worker   const char file_content[] = R"(
835*795d594fSAndroid Build Coastguard Worker # library list is ":" separated list of filenames
836*795d594fSAndroid Build Coastguard Worker jni com_android_foo lib64/libfoo.so
837*795d594fSAndroid Build Coastguard Worker )";
838*795d594fSAndroid Build Coastguard Worker   Result<std::map<std::string, std::string>> result = ParseApexLibrariesConfig(file_content, "jni");
839*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
840*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ("Invalid library_list \"jni com_android_foo lib64/libfoo.so\"", result.error().message());
841*795d594fSAndroid Build Coastguard Worker }
842*795d594fSAndroid Build Coastguard Worker 
843*795d594fSAndroid Build Coastguard Worker }  // namespace nativeloader
844*795d594fSAndroid Build Coastguard Worker }  // namespace android
845