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

Commit 5425ade1 authored by Andy Hung's avatar Andy Hung Committed by Automerger Merge Worker
Browse files

MediaUtils: Use delayed / lazy library loading am: d426582c

parents 739a16a7 d426582c
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@ cc_library {
        "AImageReaderUtils.cpp",
        "BatteryNotifier.cpp",
        "ISchedulingPolicyService.cpp",
        "Library.cpp",
        "LimitProcessMemory.cpp",
        "MediaUtilsDelayed.cpp",
        "MemoryLeakTrackUtil.cpp",
        "MethodStatistics.cpp",
        "ProcessInfo.cpp",
@@ -49,7 +51,6 @@ cc_library {
        "libcutils",
        "liblog",
        "libutils",
        "libutilscallstack",
        "libhidlbase",
        "libpermission",
        "android.hardware.graphics.bufferqueue@1.0",
@@ -77,6 +78,10 @@ cc_library {
        "libpermission",
    ],

    required: [
        "libmediautils_delayed",  // lazy loaded
    ],

    include_dirs: [
        // For DEBUGGER_SIGNAL
        "system/core/debuggerd/include",
@@ -85,6 +90,23 @@ cc_library {
    export_include_dirs: ["include"],
}

cc_library {
    name: "libmediautils_delayed", // match with MEDIAUTILS_DELAYED_LIBRARY_NAME
    srcs: [
        "MediaUtilsDelayedLibrary.cpp",
    ],
    cflags: [
        "-Wall",
        "-Werror",
        "-Wextra",
    ],
    shared_libs: [
        "liblog",
        "libutils",
        "libutilscallstack",
    ],
}

cc_library {
    name: "libmediautils_vendor",
    vendor_available: true,  // required for platform/hardware/interfaces
+72 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.
 */

#define LOG_TAG "Library"
#include <utils/Log.h>
#include <mediautils/Library.h>

namespace {

std::string dlerrorIfPresent() {
    const char *dlerr = dlerror();
    if (dlerr == nullptr) return "dlerror: none";
    return std::string("dlerror: '").append(dlerr).append("'");
}

}
namespace android::mediautils {

std::shared_ptr<void> loadLibrary(const char *libraryName, int flags) {
    std::shared_ptr<void> library{
        dlopen(libraryName, flags),
        [](void *lib) {
            if (lib != nullptr) {
                const int ret = dlclose(lib);
                ALOGW_IF(ret !=0, "%s: dlclose(%p) == %d, %s",
                        __func__, lib, ret, dlerrorIfPresent().c_str());
            }
        }
    };

    if (!library) {
        ALOGW("%s: cannot load libraryName %s, %s",
            __func__, libraryName, dlerrorIfPresent().c_str());
        return {};
    }
    return library;
}

std::shared_ptr<void> getUntypedObjectFromLibrary(
        const char *objectName, const std::shared_ptr<void>& library) {
    if (!library) {
        ALOGW("%s: null library, cannot load objectName %s", __func__, objectName);
        return {};
    }
    void *ptr = dlsym(library.get(), objectName);
    if (ptr == nullptr) {
        ALOGW("%s: cannot load objectName %s, %s",
                __func__, objectName, dlerrorIfPresent().c_str());
        return {};
    }

    // Note: we use the "aliasing" constructor of the std:shared_ptr.
    //
    // https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
    //
    return { library, ptr };  // returns shared_ptr to ptr, but ref counted on library.
}

} // namespace android::mediautils
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.
 */

#include <mediautils/Library.h>
#include <mediautils/MediaUtilsDelayed.h>
#include "MediaUtilsDelayedLibrary.h"

#define LOG_TAG "MediaUtilsDelayed"
#include <utils/Log.h>
#include <memory>

namespace android::mediautils {

namespace {
//  Specific implementation details for MediaUtils Delayed Library.

// The following use static Meyer's singleton caches instead of letting
// refcounted management as provided above. This is for speed.
std::shared_ptr<void> getDelayedLibrary() {
    static std::shared_ptr<void> library = loadLibrary(MEDIAUTILS_DELAYED_LIBRARY_NAME);
    return library;
}

// Get the delayed dispatch table.  This is refcounted and keeps the underlying library alive.
std::shared_ptr<delayed_library::DelayedDispatchTable> getDelayedDispatchTable() {
    static auto delayedDispatchTable =
            getObjectFromLibrary<delayed_library::DelayedDispatchTable>(
                    MEDIAUTILS_DELAYED_DISPATCH_TABLE_SYMBOL_NAME, getDelayedLibrary());
    return delayedDispatchTable;
}

} // namespace

// Public implementations of methods here.

std::string getCallStackStringForTid(pid_t tid) {
    auto delayedDispatchTable = getDelayedDispatchTable();
    if (!delayedDispatchTable) return {};  // on failure, return empty string
    return delayedDispatchTable->getCallStackStringForTid(tid);
}

} // android::mediautils
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.
 */

#include "MediaUtilsDelayedLibrary.h"
#include <utils/CallStack.h>

// Methods that are dynamically linked.
namespace {

std::string getCallStackStringForTid(pid_t tid) {
    android::CallStack cs{};
    cs.update(0 /* ignoreDepth */, tid);
    return cs.toString().c_str();
}

} // namespace

// leave global, this is picked up from dynamic linking
android::mediautils::delayed_library::DelayedDispatchTable gDelayedDispatchTable {
    getCallStackStringForTid,
};
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.
 */

#pragma once

#include <string>
#include <unistd.h>

// This should not be directly included by clients.
// Use MediaUtilsDelayed.h instead.

namespace android::mediautils::delayed_library {

// Use a dispatch table to return methods from the delayed library
struct DelayedDispatchTable {
    std::string (*getCallStackStringForTid)(pid_t tid);
};

// Match with Android.bp and MediaUtilsDelayed.cpp.
#define MEDIAUTILS_DELAYED_LIBRARY_NAME "libmediautils_delayed.so"

// Match with MediaUtilsDelayed.cpp and MediaUtilsDelayedLibrary.cpp
#define MEDIAUTILS_DELAYED_DISPATCH_TABLE_SYMBOL_NAME "gDelayedDispatchTable"

} // namespace android::mediautils::delayed_library
Loading