The open source OpenXR runtime
at v21.0.0 108 lines 2.7 kB view raw
1// Copyright 2020, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Implementation exposing Android-specific IPC client code to C. 6 * @author Ryan Pavlik <ryan.pavlik@collabora.com> 7 * @ingroup ipc_android 8 */ 9 10#include "ipc_client_android.h" 11 12#include "org.freedesktop.monado.ipc.hpp" 13#include "wrap/android.app.h" 14 15 16#include "xrt/xrt_config_android.h" 17#include "android/android_load_class.hpp" 18#include "util/u_logging.h" 19 20using wrap::android::app::Activity; 21using wrap::org::freedesktop::monado::ipc::Client; 22 23struct ipc_client_android 24{ 25 ipc_client_android(jobject act) : activity(act) {} 26 ~ipc_client_android(); 27 28 Activity activity{}; 29 Client client{nullptr}; 30}; 31 32ipc_client_android::~ipc_client_android() 33{ 34 35 // Tell Java that native code is done with this. 36 try { 37 if (!client.isNull()) { 38 client.markAsDiscardedByNative(); 39 } 40 } catch (std::exception const &e) { 41 // Must catch and ignore any exceptions in the destructor! 42 U_LOG_E("Failure while marking IPC client as discarded: %s", e.what()); 43 } 44} 45 46struct ipc_client_android * 47ipc_client_android_create(struct _JavaVM *vm, void *activity) 48{ 49 50 jni::init(vm); 51 try { 52 auto info = getAppInfo(XRT_ANDROID_PACKAGE, (jobject)activity); 53 if (info.isNull()) { 54 U_LOG_E("Could not get application info for package '%s'", 55 "org.freedesktop.monado.openxr_runtime"); 56 return nullptr; 57 } 58 59 auto clazz = loadClassFromPackage(info, (jobject)activity, Client::getFullyQualifiedTypeName()); 60 61 if (clazz.isNull()) { 62 U_LOG_E("Could not load class '%s' from package '%s'", Client::getFullyQualifiedTypeName(), 63 XRT_ANDROID_PACKAGE); 64 return nullptr; 65 } 66 67 // Teach the wrapper our class before we start to use it. 68 Client::staticInitClass((jclass)clazz.object().getHandle()); 69 std::unique_ptr<ipc_client_android> ret = std::make_unique<ipc_client_android>((jobject)activity); 70 71 ret->client = Client::construct(ret.get()); 72 73 return ret.release(); 74 } catch (std::exception const &e) { 75 76 U_LOG_E("Could not start IPC client class: %s", e.what()); 77 return nullptr; 78 } 79} 80 81int 82ipc_client_android_blocking_connect(struct ipc_client_android *ica) 83{ 84 try { 85 int fd = ica->client.blockingConnect(ica->activity, XRT_ANDROID_PACKAGE); 86 return fd; 87 } catch (std::exception const &e) { 88 // Must catch and ignore any exceptions in the destructor! 89 U_LOG_E("Failure while connecting to IPC server: %s", e.what()); 90 return -1; 91 } 92} 93 94 95void 96ipc_client_android_destroy(struct ipc_client_android **ptr_ica) 97{ 98 99 if (ptr_ica == NULL) { 100 return; 101 } 102 struct ipc_client_android *ica = *ptr_ica; 103 if (ica == NULL) { 104 return; 105 } 106 delete ica; 107 *ptr_ica = NULL; 108}