Something went wrong. Try again.
The open source OpenXR runtime
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113// Copyright 2020, Collabora, Ltd.// SPDX-License-Identifier: BSL-1.0/*! * @file * @brief Implementation exposing Android-specific IPC client code to C. * @author Rylie Pavlik <rylie.pavlik@collabora.com> * @ingroup ipc_android */
#include "ipc_client_android.h"
#include "org.freedesktop.monado.ipc.hpp"
#include "xrt/xrt_config_android.h"#include "util/u_logging.h"
#include "android/android_load_class.hpp"#include "android/android_looper.h"
#include "wrap/android.app.h"
using wrap::android::app::Activity;using wrap::org::freedesktop::monado::ipc::Client;using xrt::auxiliary::android::loadClassFromRuntimeApk;
struct ipc_client_android{ ipc_client_android(struct _JavaVM *vm_, jobject act) : vm(vm_), activity(act) {} ~ipc_client_android(); struct _JavaVM *vm;
Activity activity{}; Client client{nullptr};};
ipc_client_android::~ipc_client_android(){
// Tell Java that native code is done with this. try { if (!client.isNull()) { client.markAsDiscardedByNative(); } } catch (std::exception const &e) { // Must catch and ignore any exceptions in the destructor! U_LOG_E("Failure while marking IPC client as discarded: %s", e.what()); }}
struct ipc_client_android *ipc_client_android_create(struct _JavaVM *vm, void *activity){
jni::init(vm); try { auto clazz = loadClassFromRuntimeApk((jobject)activity, Client::getFullyQualifiedTypeName()); if (clazz.isNull()) { U_LOG_E("Could not load class '%s' from package '%s'", Client::getFullyQualifiedTypeName(), XRT_ANDROID_PACKAGE); return nullptr; }
// Teach the wrapper our class before we start to use it. Client::staticInitClass((jclass)clazz.object().getHandle()); std::unique_ptr<ipc_client_android> ret = std::make_unique<ipc_client_android>(vm, (jobject)activity);
ret->client = Client::construct(ret.get());
return ret.release(); } catch (std::exception const &e) {
U_LOG_E("Could not start IPC client class: %s", e.what()); return nullptr; }}
intipc_client_android_blocking_connect(struct ipc_client_android *ica){ try { // Trick to avoid deadlock on main thread: only applicable to NativeActivity with app-glue. // blockingConnect will block until binder is ready, the app-glue code will deadlock without this. JavaVM *vm = ica->vm; android_looper_poll_until_activity_resumed(vm, ica->activity.object().getHandle()); int fd = ica->client.blockingConnect(ica->activity, XRT_ANDROID_PACKAGE); return fd; } catch (std::exception const &e) { U_LOG_E("Failure while connecting to IPC server: %s", e.what()); return -1; }}
voidipc_client_android_destroy(struct ipc_client_android **ptr_ica){
if (ptr_ica == NULL) { return; } struct ipc_client_android *ica = *ptr_ica; if (ica == NULL) { return; } try { delete ica; } catch (std::exception const &e) { // Must catch and ignore any exceptions in the destructor! U_LOG_E("Failure while destroying IPC clean: %s", e.what()); } *ptr_ica = NULL;}