Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f09ef9f authored by Dimitry Ivanov's avatar Dimitry Ivanov Committed by android-build-merger
Browse files

Merge "Load vendor public libraries to sphal namespace"

am: f653eaa3

Change-Id: I6c3f0dba56109c2c76fe5ed29add750937f62ae4
parents b2f12e42 f653eaa3
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -161,6 +161,9 @@ bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_n
// Use NativeBridgeLoadLibrary() instead in non-namespace scenario.
void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns);

// Returns vendor namespace if it is enabled for the device and null otherwise
native_bridge_namespace_t* NativeBridgeGetVendorNamespace();

// Native bridge interfaces to runtime.
struct NativeBridgeCallbacks {
  // Version number of the interface.
@@ -348,6 +351,15 @@ struct NativeBridgeCallbacks {
  // Starting with v3, NativeBridge has two scenarios: with/without namespace.
  // Use loadLibrary instead in non-namespace scenario.
  void* (*loadLibraryExt)(const char* libpath, int flag, native_bridge_namespace_t* ns);

  // Get native bridge version of vendor namespace.
  // The vendor namespace is the namespace used to load vendor public libraries.
  // With O release this namespace can be different from the default namespace.
  // For the devices without enable vendor namespaces this function should return null
  //
  // Returns:
  //   vendor namespace or null if it was not set up for the device
  native_bridge_namespace_t* (*getVendorNamespace)();
};

// Runtime interfaces to native bridge.
+16 −6
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ enum NativeBridgeImplementationVersion {
  SIGNAL_VERSION = 2,
  // The version which namespace semantic is introduced.
  NAMESPACE_VERSION = 3,
  // The version with vendor namespaces
  VENDOR_NAMESPACE_VERSION = 4,
};

// Whether we had an error at some point.
@@ -621,6 +623,14 @@ bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_n
  return false;
}

native_bridge_namespace_t* NativeBridgeGetVendorNamespace() {
  if (!NativeBridgeInitialized() || !isCompatibleWith(VENDOR_NAMESPACE_VERSION)) {
    return nullptr;
  }

  return callbacks->getVendorNamespace();
}

void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns) {
  if (NativeBridgeInitialized()) {
    if (isCompatibleWith(NAMESPACE_VERSION)) {
+2 −0
Original line number Diff line number Diff line
@@ -124,6 +124,8 @@ extern bool android_link_namespaces(android_namespace_t* from,
 */
extern void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size);

extern android_namespace_t* android_get_exported_namespace(const char* name);

__END_DECLS

#endif /* __ANDROID_DLEXT_NAMESPACES_H__ */
+41 −10
Original line number Diff line number Diff line
@@ -83,6 +83,12 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot =
static constexpr const char* kPublicNativeLibrariesVendorConfig =
                                  "/vendor/etc/public.libraries.txt";

// The device may be configured to have the vendor libraries loaded to a separate namespace.
// For historical reasons this namespace was named sphal but effectively it is intended
// to use to load vendor libraries to separate namespace with controlled interface between
// vendor and system namespaces.
static constexpr const char* kVendorNamespaceName = "sphal";

// (http://b/27588281) This is a workaround for apps using custom classloaders and calling
// System.load() with an absolute path which is outside of the classloader library search path.
// This list includes all directories app is allowed to access this way.
@@ -170,11 +176,23 @@ class LibraryNamespaces {
        return false;
      }

      if (!android_link_namespaces(ns, nullptr, public_libraries_.c_str())) {
      // Note that when vendor_ns is not configured this function will return nullptr
      // and it will result in linking vendor_public_libraries_ to the default namespace
      // which is expected behavior in this case.
      android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName);

      if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) {
        *error_msg = dlerror();
        return false;
      }

      if (!vendor_public_libraries_.empty()) {
        if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
          *error_msg = dlerror();
          return false;
        }
      }

      native_loader_ns = NativeLoaderNamespace(ns);
    } else {
      native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace",
@@ -183,15 +201,25 @@ class LibraryNamespaces {
                                                                  namespace_type,
                                                                  permitted_path.c_str(),
                                                                  parent_ns.get_native_bridge_ns());

      if (ns == nullptr) {
        *error_msg = NativeBridgeGetError();
        return false;
      }

      if (!NativeBridgeLinkNamespaces(ns, nullptr, public_libraries_.c_str())) {
      native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace();

      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) {
        *error_msg = NativeBridgeGetError();
        return false;
      }

      if (!vendor_public_libraries_.empty()) {
        if (!NativeBridgeLinkNamespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
          *error_msg = NativeBridgeGetError();
          return false;
        }
      }

      native_loader_ns = NativeLoaderNamespace(ns);
    }
@@ -249,9 +277,6 @@ class LibraryNamespaces {
      }
    }

    // This file is optional, quietly ignore if the file does not exist.
    ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);

    // android_init_namespaces() expects all the public libraries
    // to be loaded so that they can be found by soname alone.
    //
@@ -266,7 +291,13 @@ class LibraryNamespaces {
                          soname.c_str(), dlerror());
    }

    public_libraries_ = base::Join(sonames, ':');
    system_public_libraries_ = base::Join(sonames, ':');

    sonames.clear();
    // This file is optional, quietly ignore if the file does not exist.
    ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);

    vendor_public_libraries_ = base::Join(sonames, ':');
  }

  void Reset() {
@@ -325,7 +356,7 @@ class LibraryNamespaces {
    // code is one example) unknown to linker in which  case linker uses anonymous
    // namespace. The second argument specifies the search path for the anonymous
    // namespace which is the library_path of the classloader.
    initialized_ = android_init_anonymous_namespace(public_libraries_.c_str(),
    initialized_ = android_init_anonymous_namespace(system_public_libraries_.c_str(),
                                                    is_native_bridge ? nullptr : library_path);
    if (!initialized_) {
      *error_msg = dlerror();
@@ -334,7 +365,7 @@ class LibraryNamespaces {

    // and now initialize native bridge namespaces if necessary.
    if (NativeBridgeInitialized()) {
      initialized_ = NativeBridgeInitAnonymousNamespace(public_libraries_.c_str(),
      initialized_ = NativeBridgeInitAnonymousNamespace(system_public_libraries_.c_str(),
                                                        is_native_bridge ? library_path : nullptr);
      if (!initialized_) {
        *error_msg = NativeBridgeGetError();
@@ -371,8 +402,8 @@ class LibraryNamespaces {

  bool initialized_;
  std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
  std::string public_libraries_;

  std::string system_public_libraries_;
  std::string vendor_public_libraries_;

  DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
};