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

Commit ad5ed892 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Support partners to expose their own system libs to Android apps"

parents 20bc9eb6 d1006fe6
Loading
Loading
Loading
Loading
+80 −18
Original line number Diff line number Diff line
@@ -24,12 +24,15 @@
#include "cutils/properties.h"
#include "log/log.h"
#endif
#include <dirent.h>
#include <sys/types.h>
#include "nativebridge/native_bridge.h"

#include <algorithm>
#include <vector>
#include <string>
#include <memory>
#include <mutex>
#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/macros.h>
@@ -82,16 +85,21 @@ class NativeLoaderNamespace {
  native_bridge_namespace_t* native_bridge_ns_;
};

static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot =
static constexpr const char kPublicNativeLibrariesSystemConfigPathFromRoot[] =
    "/etc/public.libraries.txt";
static constexpr const char* kPublicNativeLibrariesVendorConfig =
static constexpr const char kPublicNativeLibrariesExtensionConfigPrefix[] = "public.libraries-";
static constexpr const size_t kPublicNativeLibrariesExtensionConfigPrefixLen =
    sizeof(kPublicNativeLibrariesExtensionConfigPrefix) - 1;
static constexpr const char kPublicNativeLibrariesExtensionConfigSuffix[] = ".txt";
static constexpr const size_t kPublicNativeLibrariesExtensionConfigSuffixLen =
    sizeof(kPublicNativeLibrariesExtensionConfigSuffix) - 1;
static constexpr const char kPublicNativeLibrariesVendorConfig[] =
    "/vendor/etc/public.libraries.txt";
static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot =
static constexpr const char kLlndkNativeLibrariesSystemConfigPathFromRoot[] =
    "/etc/llndk.libraries.txt";
static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot =
static constexpr const char kVndkspNativeLibrariesSystemConfigPathFromRoot[] =
    "/etc/vndksp.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
@@ -133,6 +141,9 @@ static void insert_vndk_version_str(std::string* file_name) {
  file_name->insert(insert_pos, vndk_version_str());
}

static const std::function<bool(const std::string&, std::string*)> always_true =
    [](const std::string&, std::string*) { return true; };

class LibraryNamespaces {
 public:
  LibraryNamespaces() : initialized_(false) { }
@@ -337,10 +348,55 @@ class LibraryNamespaces {
            root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;

    std::string error_msg;
    LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg),
    LOG_ALWAYS_FATAL_IF(
        !ReadConfig(public_native_libraries_system_config, &sonames, always_true, &error_msg),
        "Error reading public native library list from \"%s\": %s",
        public_native_libraries_system_config.c_str(), error_msg.c_str());

    // read /system/etc/public.libraries-<companyname>.txt which contain partner defined
    // system libs that are exposed to apps. The libs in the txt files must be
    // named as lib<name>.<companyname>.so.
    std::string dirname = base::Dirname(public_native_libraries_system_config);
    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(dirname.c_str()), closedir);
    if (dir != nullptr) {
      // Failing to opening the dir is not an error, which can happen in
      // webview_zygote.
      struct dirent* ent;
      while ((ent = readdir(dir.get())) != nullptr) {
        if (ent->d_type != DT_REG && ent->d_type != DT_LNK) {
          continue;
        }
        const std::string filename(ent->d_name);
        if (android::base::StartsWith(filename, kPublicNativeLibrariesExtensionConfigPrefix) &&
            android::base::EndsWith(filename, kPublicNativeLibrariesExtensionConfigSuffix)) {
          const size_t start = kPublicNativeLibrariesExtensionConfigPrefixLen;
          const size_t end = filename.size() - kPublicNativeLibrariesExtensionConfigSuffixLen;
          const std::string company_name = filename.substr(start, end - start);
          const std::string config_file_path = dirname + "/" + filename;
          LOG_ALWAYS_FATAL_IF(
              company_name.empty(),
              "Error extracting company name from public native library list file path \"%s\"",
              config_file_path.c_str());
          LOG_ALWAYS_FATAL_IF(
              !ReadConfig(
                  config_file_path, &sonames,
                  [&company_name](const std::string& soname, std::string* error_msg) {
                    if (android::base::StartsWith(soname, "lib") &&
                        android::base::EndsWith(soname, ("." + company_name + ".so").c_str())) {
                      return true;
                    } else {
                      *error_msg = "Library name \"" + soname +
                                   "\" does not end with the company name: " + company_name + ".";
                      return false;
                    }
                  },
                  &error_msg),
              "Error reading public native library list from \"%s\": %s", config_file_path.c_str(),
              error_msg.c_str());
        }
      }
    }

    // Insert VNDK version to llndk and vndksp config file names.
    insert_vndk_version_str(&llndk_native_libraries_system_config);
    insert_vndk_version_str(&vndksp_native_libraries_system_config);
@@ -374,16 +430,16 @@ class LibraryNamespaces {
    system_public_libraries_ = base::Join(sonames, ':');

    sonames.clear();
    ReadConfig(llndk_native_libraries_system_config, &sonames);
    ReadConfig(llndk_native_libraries_system_config, &sonames, always_true);
    system_llndk_libraries_ = base::Join(sonames, ':');

    sonames.clear();
    ReadConfig(vndksp_native_libraries_system_config, &sonames);
    ReadConfig(vndksp_native_libraries_system_config, &sonames, always_true);
    system_vndksp_libraries_ = base::Join(sonames, ':');

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

    vendor_public_libraries_ = base::Join(sonames, ':');
  }
@@ -394,6 +450,8 @@ class LibraryNamespaces {

 private:
  bool ReadConfig(const std::string& configFile, std::vector<std::string>* sonames,
                  const std::function<bool(const std::string& /* soname */,
                                           std::string* /* error_msg */)>& check_soname,
                  std::string* error_msg = nullptr) {
    // Read list of public native libraries from the config file.
    std::string file_content;
@@ -430,7 +488,11 @@ class LibraryNamespaces {
        trimmed_line.resize(space_pos);
      }

      if (check_soname(trimmed_line, error_msg)) {
        sonames->push_back(trimmed_line);
      } else {
        return false;
      }
    }

    return true;
+48 −0
Original line number Diff line number Diff line
//
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

cc_library {
    name: "libfoo.oem1",
    srcs: ["test.cpp"],
    cflags : ["-DLIBNAME=\"libfoo.oem1.so\""],
    shared_libs: [
        "libbase",
    ],
}
cc_library {
    name: "libbar.oem1",
    srcs: ["test.cpp"],
    cflags : ["-DLIBNAME=\"libbar.oem1.so\""],
    shared_libs: [
        "libbase",
    ],
}
cc_library {
    name: "libfoo.oem2",
    srcs: ["test.cpp"],
    cflags : ["-DLIBNAME=\"libfoo.oem2.so\""],
    shared_libs: [
        "libbase",
    ],
}
cc_library {
    name: "libbar.oem2",
    srcs: ["test.cpp"],
    cflags : ["-DLIBNAME=\"libbar.oem2.so\""],
    shared_libs: [
        "libbase",
    ],
}
+30 −0
Original line number Diff line number Diff line
#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := public.libraries-oem1.txt
LOCAL_SRC_FILES:= $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)
LOCAL_MODULE := public.libraries-oem2.txt
LOCAL_SRC_FILES:= $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
include $(BUILD_PREBUILT)
+2 −0
Original line number Diff line number Diff line
libfoo.oem1.so
libbar.oem1.so
+2 −0
Original line number Diff line number Diff line
libfoo.oem2.so
libbar.oem2.so
Loading