xref: /aosp_15_r20/frameworks/av/media/utils/Library.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "Library"
18*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
19*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/Library.h>
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker namespace {
22*ec779b8eSAndroid Build Coastguard Worker 
dlerrorIfPresent()23*ec779b8eSAndroid Build Coastguard Worker std::string dlerrorIfPresent() {
24*ec779b8eSAndroid Build Coastguard Worker     const char *dlerr = dlerror();
25*ec779b8eSAndroid Build Coastguard Worker     if (dlerr == nullptr) return "dlerror: none";
26*ec779b8eSAndroid Build Coastguard Worker     return std::string("dlerror: '").append(dlerr).append("'");
27*ec779b8eSAndroid Build Coastguard Worker }
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker }
30*ec779b8eSAndroid Build Coastguard Worker namespace android::mediautils {
31*ec779b8eSAndroid Build Coastguard Worker 
loadLibrary(const char * libraryName,int flags)32*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<void> loadLibrary(const char *libraryName, int flags) {
33*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<void> library{
34*ec779b8eSAndroid Build Coastguard Worker         dlopen(libraryName, flags),
35*ec779b8eSAndroid Build Coastguard Worker         [](void *lib) {
36*ec779b8eSAndroid Build Coastguard Worker             if (lib != nullptr) {
37*ec779b8eSAndroid Build Coastguard Worker                 const int ret = dlclose(lib);
38*ec779b8eSAndroid Build Coastguard Worker                 ALOGW_IF(ret !=0, "%s: dlclose(%p) == %d, %s",
39*ec779b8eSAndroid Build Coastguard Worker                         __func__, lib, ret, dlerrorIfPresent().c_str());
40*ec779b8eSAndroid Build Coastguard Worker             }
41*ec779b8eSAndroid Build Coastguard Worker         }
42*ec779b8eSAndroid Build Coastguard Worker     };
43*ec779b8eSAndroid Build Coastguard Worker 
44*ec779b8eSAndroid Build Coastguard Worker     if (!library) {
45*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: cannot load libraryName %s, %s",
46*ec779b8eSAndroid Build Coastguard Worker             __func__, libraryName, dlerrorIfPresent().c_str());
47*ec779b8eSAndroid Build Coastguard Worker         return {};
48*ec779b8eSAndroid Build Coastguard Worker     }
49*ec779b8eSAndroid Build Coastguard Worker     return library;
50*ec779b8eSAndroid Build Coastguard Worker }
51*ec779b8eSAndroid Build Coastguard Worker 
getUntypedObjectFromLibrary(const char * objectName,const std::shared_ptr<void> & library)52*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<void> getUntypedObjectFromLibrary(
53*ec779b8eSAndroid Build Coastguard Worker         const char *objectName, const std::shared_ptr<void>& library) {
54*ec779b8eSAndroid Build Coastguard Worker     if (!library) {
55*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: null library, cannot load objectName %s", __func__, objectName);
56*ec779b8eSAndroid Build Coastguard Worker         return {};
57*ec779b8eSAndroid Build Coastguard Worker     }
58*ec779b8eSAndroid Build Coastguard Worker     void *ptr = dlsym(library.get(), objectName);
59*ec779b8eSAndroid Build Coastguard Worker     if (ptr == nullptr) {
60*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: cannot load objectName %s, %s",
61*ec779b8eSAndroid Build Coastguard Worker                 __func__, objectName, dlerrorIfPresent().c_str());
62*ec779b8eSAndroid Build Coastguard Worker         return {};
63*ec779b8eSAndroid Build Coastguard Worker     }
64*ec779b8eSAndroid Build Coastguard Worker 
65*ec779b8eSAndroid Build Coastguard Worker     // Note: we use the "aliasing" constructor of the std:shared_ptr.
66*ec779b8eSAndroid Build Coastguard Worker     //
67*ec779b8eSAndroid Build Coastguard Worker     // https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
68*ec779b8eSAndroid Build Coastguard Worker     //
69*ec779b8eSAndroid Build Coastguard Worker     return { library, ptr };  // returns shared_ptr to ptr, but ref counted on library.
70*ec779b8eSAndroid Build Coastguard Worker }
71*ec779b8eSAndroid Build Coastguard Worker 
72*ec779b8eSAndroid Build Coastguard Worker } // namespace android::mediautils
73