blob: 6c0a65cba6b5a64c3f44eb162b6b3394e6550fd0 [file] [log] [blame]
/*
**
** Copyright 2019, 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_NDEBUG 0
#define LOG_TAG "MediaPlayer2-JNI"
#include "utils/Log.h"
#include "jni.h"
#include <android/dlext.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <string.h>
extern "C" {
// Copied from GraphicsEnv.cpp
// TODO(b/37049319) Get this from a header once one exists
android_namespace_t* 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,
android_namespace_t* parent);
bool android_link_namespaces(android_namespace_t* from,
android_namespace_t* to,
const char* shared_libs_sonames);
enum {
ANDROID_NAMESPACE_TYPE_ISOLATED = 1,
};
} // extern "C"
static const char kApexLibPath[] = "/apex/com.android.media/lib"
#ifdef __LP64__
"64"
#endif
"/";
static const char kMediaPlayer2LibPath[] = "/apex/com.android.media/lib"
#ifdef __LP64__
"64"
#endif
"/libmediaplayer2_jni.so";
typedef jint (*Media2JniOnLoad)(JavaVM*, void*);
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
android_namespace_t *media2Ns = android_create_namespace("media2",
nullptr, // ld_library_path
kApexLibPath,
ANDROID_NAMESPACE_TYPE_ISOLATED,
nullptr, // permitted_when_isolated_path
nullptr); // parent
if (!android_link_namespaces(media2Ns, nullptr, LINKED_LIBRARIES)) {
ALOGE("Failed to link namespace. Failed to load extractor plug-ins in apex.");
return -1;
}
const android_dlextinfo dlextinfo = {
.flags = ANDROID_DLEXT_USE_NAMESPACE,
.library_namespace = media2Ns,
};
// load libmediaplayer2_jni and call JNI_OnLoad.
void *libHandle = android_dlopen_ext(kMediaPlayer2LibPath, RTLD_NOW | RTLD_LOCAL, &dlextinfo);
if (libHandle == NULL) {
ALOGW("couldn't dlopen(%s) %s", kMediaPlayer2LibPath, strerror(errno));
return -1;
}
Media2JniOnLoad media2JniOnLoad = (Media2JniOnLoad) dlsym(libHandle, "JNI_OnLoad");
if (!media2JniOnLoad) {
ALOGW("%s does not contain JNI_OnLoad()", kMediaPlayer2LibPath);
dlclose(libHandle);
return -1;
}
return media2JniOnLoad(vm, reserved);
}