mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-11 17:35:27 +00:00
78 lines
2.4 KiB
C++
78 lines
2.4 KiB
C++
|
// Copyright 2020, Collabora, Ltd.
|
||
|
// SPDX-License-Identifier: BSL-1.0
|
||
|
// Author: Ryan Pavlik <ryan.pavlik@collabora.com>
|
||
|
|
||
|
#include "android_load_class.h"
|
||
|
|
||
|
#include "util/u_logging.h"
|
||
|
|
||
|
#include "wrap/android.content.h"
|
||
|
#include "wrap/dalvik.system.h"
|
||
|
|
||
|
#include "jni.h"
|
||
|
|
||
|
using wrap::android::content::Context;
|
||
|
using wrap::android::content::pm::ApplicationInfo;
|
||
|
using wrap::android::content::pm::PackageManager;
|
||
|
|
||
|
static ApplicationInfo
|
||
|
getAppInfo(std::string const &packageName, jobject application_context)
|
||
|
{
|
||
|
try {
|
||
|
auto context = Context{application_context};
|
||
|
auto packageManager =
|
||
|
PackageManager{context.getPackageManager()};
|
||
|
auto packageInfo = packageManager.getPackageInfo(
|
||
|
packageName, PackageManager::GET_META_DATA |
|
||
|
PackageManager::GET_SHARED_LIBRARY_FILES);
|
||
|
return packageInfo.getApplicationInfo();
|
||
|
} catch (std::exception const &e) {
|
||
|
return {};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static wrap::java::lang::Class
|
||
|
loadClassFromPackage(ApplicationInfo applicationInfo,
|
||
|
jobject application_context,
|
||
|
const char *clazz_name)
|
||
|
{
|
||
|
auto context = Context{application_context}.getApplicationContext();
|
||
|
auto pkgContext = context.createPackageContext(
|
||
|
applicationInfo.getPackageName(),
|
||
|
Context::CONTEXT_IGNORE_SECURITY | Context::CONTEXT_INCLUDE_CODE);
|
||
|
|
||
|
// Not using ClassLoader.loadClass because it expects a /-delimited
|
||
|
// class name, while we have a .-delimited class name.
|
||
|
// This does work
|
||
|
wrap::java::lang::ClassLoader pkgClassLoader =
|
||
|
pkgContext.getClassLoader();
|
||
|
|
||
|
auto loadedClass = wrap::java::lang::Class::forName(
|
||
|
clazz_name, true, pkgClassLoader.object());
|
||
|
return loadedClass;
|
||
|
}
|
||
|
|
||
|
void *
|
||
|
android_load_class_from_package(struct _JavaVM *vm,
|
||
|
const char *pkgname,
|
||
|
void *application_context,
|
||
|
const char *classname)
|
||
|
{
|
||
|
jni::init(vm);
|
||
|
Context context((jobject)application_context);
|
||
|
auto info = getAppInfo(pkgname, (jobject)application_context);
|
||
|
if (info.isNull()) {
|
||
|
U_LOG_E("Could not get application info for package '%s'",
|
||
|
pkgname);
|
||
|
return nullptr;
|
||
|
}
|
||
|
auto clazz =
|
||
|
loadClassFromPackage(info, (jobject)application_context, classname);
|
||
|
if (clazz.isNull()) {
|
||
|
U_LOG_E("Could not load class '%s' from package '%s'",
|
||
|
classname, pkgname);
|
||
|
return nullptr;
|
||
|
}
|
||
|
return clazz.object().getHandle();
|
||
|
}
|