diff --git a/src/external/CMakeLists.txt b/src/external/CMakeLists.txt index 04595cfdc..31a4d6c41 100644 --- a/src/external/CMakeLists.txt +++ b/src/external/CMakeLists.txt @@ -25,11 +25,21 @@ target_include_directories(xrt-external-glad INTERFACE ${CMAKE_CURRENT_SOURCE_DI add_library(xrt-external-hungarian INTERFACE) target_include_directories(xrt-external-hungarian INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/hungarian) -# JNIPP +# JNIPP and Android JNI wrappers if(ANDROID) add_library(xrt-external-jnipp STATIC jnipp/jnipp.cpp) target_include_directories(xrt-external-jnipp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/jnipp) + + file(GLOB WRAP_SOURCES android-jni-wrap/wrap/*.cpp) + add_library(xrt-external-jni-wrap STATIC + ${WRAP_SOURCES}) + target_include_directories(xrt-external-jni-wrap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/android-jni-wrap) + target_link_libraries(xrt-external-jni-wrap PUBLIC xrt-external-jnipp) + set_target_properties(xrt-external-jni-wrap + PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON) endif() # OpenXR diff --git a/src/external/android-jni-wrap/wrap/ObjectWrapperBase.h b/src/external/android-jni-wrap/wrap/ObjectWrapperBase.h new file mode 100644 index 000000000..5ced5d148 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/ObjectWrapperBase.h @@ -0,0 +1,319 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once +#include +#include + +namespace wrap { + +/*! + * Base class for types wrapping Java types. + * + * Derived types are encouraged to have a nested `struct Meta`, inheriting + * publicly from MetaBaseDroppable or MetaBase, with a singleton accessor named + * `data()`, and a private constructor (implemented in a .cpp file, not the + * header) that populates jni::method_t, jni::field_t, etc. members for each + * method, etc. of interest. + */ +class ObjectWrapperBase { + public: + /*! + * Default constructor. + */ + ObjectWrapperBase() = default; + + /*! + * Construct from a jni::Object. + */ + explicit ObjectWrapperBase(jni::Object obj) : obj_(std::move(obj)) {} + + /*! + * Construct from a nullptr. + */ + explicit ObjectWrapperBase(std::nullptr_t const &) : obj_() {} + + /*! + * Evaluate if this is non-null + */ + explicit operator bool() const noexcept { return !obj_.isNull(); } + + /*! + * Is this object null? + */ + bool isNull() const noexcept { return obj_.isNull(); } + + /*! + * Get the wrapped jni::Object + */ + jni::Object &object() noexcept { return obj_; } + + /*! + * Get the wrapped jni::Object (const overload) + */ + jni::Object const &object() const noexcept { return obj_; } + + private: + jni::Object obj_; +}; + +/*! + * Equality comparison for a wrapped Java object. + */ +static inline bool operator==(ObjectWrapperBase const &lhs, + ObjectWrapperBase const &rhs) noexcept { + return lhs.object() == rhs.object(); +} + +/*! + * Inequality comparison for a wrapped Java object. + */ +static inline bool operator!=(ObjectWrapperBase const &lhs, + ObjectWrapperBase const &rhs) noexcept { + return lhs.object() != rhs.object(); +} + +/*! + * Equality comparison between a wrapped Java object and @p nullptr. + */ +static inline bool operator==(ObjectWrapperBase const &obj, + std::nullptr_t) noexcept { + return obj.isNull(); +} + +/*! + * Equality comparison between a wrapped Java object and @p nullptr. + */ +static inline bool operator==(std::nullptr_t, + ObjectWrapperBase const &obj) noexcept { + return obj.isNull(); +} + +/*! + * Inequality comparison between a wrapped Java object and @p nullptr. + */ +static inline bool operator!=(ObjectWrapperBase const &obj, + std::nullptr_t) noexcept { + return !(obj == nullptr); +} + +/*! + * Inequality comparison between a wrapped Java object and @p nullptr. + */ +static inline bool operator!=(std::nullptr_t, + ObjectWrapperBase const &obj) noexcept { + return !(obj == nullptr); +} + +/*! + * Base class for Meta structs where you want the reference to the Class object + * to persist (indefinitely). + * + * Mostly for classes that would stick around anyway (e.g. + * @p java.lang.ClassLoader ) where many operations are on static + * methods/fields. Use of a non-static method or field does not require such a + * reference, use MetaBaseDroppable in those cases. + */ +class MetaBase { + public: + /*! + * Gets a reference to the class object. + * + * Unlike MetaBaseDroppable, here we know that the class object ref is + * alive. + */ + jni::Class const &clazz() const noexcept { return clazz_; } + /*! + * Gets a reference to the class object. + * + * Provided here for parallel API to MetaBaseDroppable, despite being + * synonymous with clazz() here. + */ + jni::Class const &classRef() const noexcept { return clazz_; } + + /*! + * Get the class name, with namespaces delimited by `/`. + */ + const char *className() const noexcept { return classname_; } + + protected: + /*! + * Construct. + * + * @param classname The class name, fully qualified, with namespaces + * delimited by `/`. + */ + explicit MetaBase(const char *classname) + : classname_(classname), clazz_(classname_) {} + + private: + const char *classname_; + jni::Class clazz_; +}; + +/*! + * Base class for Meta structs where you don't need the reference to the Class + * object to persist. (This is most uses.) + */ +class MetaBaseDroppable { + public: + /*! + * Gets the class object. + * + * Works regardless of whether dropClassRef() has been called - it's just + * slower if it has. + */ + jni::Class clazz() const { + if (clazz_.isNull()) { + return {classname_}; + } + return clazz_; + } + + /*! + * Get the class name, with namespaces delimited by `/`. + */ + const char *className() const noexcept { return classname_; } + + /*! + * May be called in/after the derived constructor, to drop the reference to + * the class object if it's no longer needed. + */ + void dropClassRef() { clazz_ = jni::Class{}; } + + protected: + /*! + * Construct. + * + * Once you are done constructing your derived struct, you may call + * dropClassRef() and still safely use non-static method and field IDs + * retrieved. + * + * @param classname The class name, fully qualified, with namespaces + * delimited by `/`. + */ + explicit MetaBaseDroppable(const char *classname) + : classname_(classname), clazz_(classname_) {} + + /*! + * Gets a reference to the class object, but is non-null only if it's still + * cached. + * + * Only for used in derived constructors/initializers, where you know you + * haven't dropped this yet. + */ + jni::Class const &classRef() const { return clazz_; } + + private: + const char *classname_; + jni::Class clazz_; +}; + +/*! + * Implementation namespace for these JNI wrappers. + * + * They can be ignored if you aren't adding/extending wrappers. + */ +namespace impl { +/*! + * Type-aware wrapper for a field ID. + * + * This is a smarter alternative to just using jni::field_t since it avoids + * having to repeat the type in the accessor, without using any more storage. + * + * @see StaticFieldId for the equivalent for static fields. + * @see WrappedFieldId for the equivalent for structures that we wrap. + */ +template struct FieldId { + public: + FieldId(jni::Class const &clazz, const char *name) + : id(clazz.getField(name)) {} + + const jni::field_t id; +}; + +/*! + * Get the value of field @p field in Java object @p obj. + * + * This is found by argument-dependent lookup and can be used unqualified. + * + * @relates FieldId + */ +template +static inline T get(FieldId const &field, jni::Object const &obj) { + assert(!obj.isNull()); + return obj.get(field.id); +} +/*! + * Type-aware wrapper for a static field ID. + * + * This is a smarter alternative to just using jni::field_t since it avoids + * having to repeat the type in the accessor, without using any more storage. + * + * @see FieldId + */ +template struct StaticFieldId { + public: + StaticFieldId(jni::Class const &clazz, const char *name) + : id(clazz.getStaticField(name)) {} + + const jni::field_t id; +}; + +/*! + * Get the value of static field @p field in Java type @p clazz. + * + * This is found by argument-dependent lookup and can be used unqualified. + * + * @relates FieldId + */ +template +static inline T get(StaticFieldId const &field, jni::Class const &clazz) { + assert(!clazz.isNull()); + return clazz.get(field.id); +} + +/*! + * Type-aware wrapper for a field ID of a wrapped structure type. + * + * This is a smarter alternative to just using jni::field_t since it avoids + * having to repeat the type in the accessor, without using any more storage. + * + * Requires that the structure wrapper provides + * `static constexpr const char *getTypeName() noexcept;` + * + * @see FieldId + */ +template struct WrappedFieldId { + public: + WrappedFieldId(jni::Class const &clazz, const char *name) + : id(lookupField(clazz, name)) {} + + const jni::field_t id; + + private: + /*! + * Helper for field ID lookup, mostly to avoid calling c_str() on a string + * temporary. + */ + static jni::field_t lookupField(jni::Class const &clazz, const char *name) { + std::string fullType = std::string("L") + T::getTypeName() + ";"; + return clazz.getField(name, fullType.c_str()); + } +}; + +/*! + * Get the value of field @p field in Java object @p obj. + * + * This is found by argument-dependent lookup and can be used unqualified. + * + * @relates WrappedFieldId + */ +template +static inline T get(WrappedFieldId const &field, jni::Object const &obj) { + assert(!obj.isNull()); + return T{obj.get(field.id)}; +} +} // namespace impl +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/README.md b/src/external/android-jni-wrap/wrap/README.md new file mode 100644 index 000000000..fec2ba349 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/README.md @@ -0,0 +1,29 @@ +# About these JNI Wrappers + + + +These are fairly simple wrappers around Java classes, using JNI and JNIPP to allow relatively-painless use of Java classes from C++. They are populated as-needed: if you need a method/property that's missing, add it! + +## Conventions + +All classes derive from ObjectWrapperBase or one of its subclasses. (Yes, you +can directly mirror inheritance in Java with inheritance in these wrappers.) + +All should have a public internal struct called `Meta` that derives publicly +from either `MetaBase` or `MetaBaseDroppable` (the more common option, when you +don't often need the class object itself), with a member for each method ID. +Only the `Meta()` constructor should be in the `.cpp` file for a given wrapper: +the rest lives in the header so it may be inlined and thus optimized away. + +## Finding signatures + +A command like the following can help you get the JNI signatures of methods: + +```sh +javap -s -classpath ~/Android/Sdk/platforms/android-26/android.jar android.service.vr.VrListenerService +``` + +Adjust the location of the SDK and the class under investigation as needed. diff --git a/src/external/android-jni-wrap/wrap/android.app.cpp b/src/external/android-jni-wrap/wrap/android.app.cpp new file mode 100644 index 000000000..66bb57a9e --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.app.cpp @@ -0,0 +1,21 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.app.h" + +namespace wrap { +namespace android::app { +Service::Meta::Meta() : MetaBaseDroppable(Service::getTypeName()) { + MetaBaseDroppable::dropClassRef(); +} +Activity::Meta::Meta() + : MetaBaseDroppable(Activity::getTypeName()), + getSystemService(classRef().getMethod( + "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;")), + setVrModeEnabled(classRef().getMethod( + "setVrModeEnabled", "(ZLandroid/content/ComponentName;)V")) { + MetaBaseDroppable::dropClassRef(); +} +} // namespace android::app +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.app.h b/src/external/android-jni-wrap/wrap/android.app.h new file mode 100644 index 000000000..c57dabdbd --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.app.h @@ -0,0 +1,100 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "android.content.h" + +namespace wrap { +namespace android::content { +class ComponentName; +} // namespace android::content + +} // namespace wrap + +namespace wrap { +namespace android::app { +/*! + * Wrapper for android.app.Service objects. + */ +class Service : public content::Context { + public: + using Context::Context; + static constexpr const char *getTypeName() noexcept { + return "android/app/Service"; + } + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.app.Activity objects. + */ +class Activity : public content::Context { + public: + using Context::Context; + static constexpr const char *getTypeName() noexcept { + return "android/app/Activity"; + } + + /*! + * Wrapper for the getSystemService method + * + * Java prototype: + * `public java.lang.Object getSystemService(java.lang.String);` + * + * JNI signature: (Ljava/lang/String;)Ljava/lang/Object; + * + */ + jni::Object getSystemService(std::string const &name); + + /*! + * Wrapper for the setVrModeEnabled method + * + * Java prototype: + * `public void setVrModeEnabled(boolean, android.content.ComponentName) + * throws android.content.pm.PackageManager$NameNotFoundException;` + * + * JNI signature: (ZLandroid/content/ComponentName;)V + * + */ + void setVrModeEnabled(bool enabled, + content::ComponentName const &requestedComponent); + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t getSystemService; + jni::method_t setVrModeEnabled; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::app +} // namespace wrap +#include "android.app.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.app.impl.h b/src/external/android-jni-wrap/wrap/android.app.impl.h new file mode 100644 index 000000000..b5853e0f1 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.app.impl.h @@ -0,0 +1,26 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "android.content.h" +#include + +namespace wrap { +namespace android::app { + +inline jni::Object Activity::getSystemService(std::string const &name) { + assert(!isNull()); + return object().call(Meta::data().getSystemService, name); +} + +inline void +Activity::setVrModeEnabled(bool enabled, + content::ComponentName const &requestedComponent) { + assert(!isNull()); + return object().call(Meta::data().setVrModeEnabled, enabled, + requestedComponent.object()); +} +} // namespace android::app +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.content.cpp b/src/external/android-jni-wrap/wrap/android.content.cpp new file mode 100644 index 000000000..7723d5f44 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.content.cpp @@ -0,0 +1,55 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.content.h" + +namespace wrap { +namespace android::content { +Context::Meta::Meta(bool deferDrop) + : MetaBaseDroppable(Context::getTypeName()), + DISPLAY_SERVICE(classRef(), "DISPLAY_SERVICE"), + WINDOW_SERVICE(classRef(), "WINDOW_SERVICE"), + getPackageManager(classRef().getMethod( + "getPackageManager", "()Landroid/content/pm/PackageManager;")), + getApplicationContext(classRef().getMethod( + "getApplicationContext", "()Landroid/content/Context;")), + getClassLoader( + classRef().getMethod("getClassLoader", "()Ljava/lang/ClassLoader;")), + startActivity( + classRef().getMethod("startActivity", "(Landroid/content/Intent;)V")), + startActivity1(classRef().getMethod( + "startActivity", "(Landroid/content/Intent;Landroid/os/Bundle;)V")), + createPackageContext(classRef().getMethod( + "createPackageContext", + "(Ljava/lang/String;I)Landroid/content/Context;")) { + if (!deferDrop) { + MetaBaseDroppable::dropClassRef(); + } +} +ComponentName::Meta::Meta() + : MetaBase(ComponentName::getTypeName()), + init(classRef().getMethod("", + "(Ljava/lang/String;Ljava/lang/String;)V")), + init1(classRef().getMethod( + "", "(Landroid/content/Context;Ljava/lang/String;)V")), + init2(classRef().getMethod( + "", "(Landroid/content/Context;Ljava/lang/Class;)V")), + init3(classRef().getMethod("", "(Landroid/os/Parcel;)V")) {} +Intent::Meta::Meta() + : MetaBase(Intent::getTypeName()), + FLAG_ACTIVITY_NEW_TASK(classRef(), "FLAG_ACTIVITY_NEW_TASK"), + init(classRef().getMethod("", "()V")), + init1(classRef().getMethod("", "(Landroid/content/Intent;)V")), + init2(classRef().getMethod("", "(Ljava/lang/String;)V")), + init3(classRef().getMethod("", + "(Ljava/lang/String;Landroid/net/Uri;)V")), + init4(classRef().getMethod( + "", "(Landroid/content/Context;Ljava/lang/Class;)V")), + init5(classRef().getMethod("", + "(Ljava/lang/String;Landroid/net/Uri;Landroid/" + "content/Context;Ljava/lang/Class;)V")), + setFlags( + classRef().getMethod("setFlags", "(I)Landroid/content/Intent;")) {} +} // namespace android::content +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.content.h b/src/external/android-jni-wrap/wrap/android.content.h new file mode 100644 index 000000000..339bd2fa3 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.content.h @@ -0,0 +1,379 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" +#include + +namespace wrap { +namespace android::content { +class ComponentName; +class Context; +class Intent; +} // namespace android::content + +namespace android::content::pm { +class PackageManager; +} // namespace android::content::pm + +namespace android::os { +class Bundle; +} // namespace android::os + +namespace java::lang { +class Class; +class ClassLoader; +} // namespace java::lang + +} // namespace wrap + +namespace wrap { +namespace android::content { +/*! + * Wrapper for android.content.Context objects. + */ +class Context : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/content/Context"; + } + + /*! + * Getter for the DISPLAY_SERVICE static field value + * + * Java prototype: + * `public static final java.lang.String DISPLAY_SERVICE;` + * + * JNI signature: Ljava/lang/String; + * + */ + static std::string DISPLAY_SERVICE(); + + /*! + * Getter for the WINDOW_SERVICE static field value + * + * Java prototype: + * `public static final java.lang.String WINDOW_SERVICE;` + * + * JNI signature: Ljava/lang/String; + * + */ + static std::string WINDOW_SERVICE(); + + /*! + * Wrapper for the getPackageManager method + * + * Java prototype: + * `public abstract android.content.pm.PackageManager getPackageManager();` + * + * JNI signature: ()Landroid/content/pm/PackageManager; + * + */ + pm::PackageManager getPackageManager(); + + /*! + * Wrapper for the getApplicationContext method + * + * Java prototype: + * `public abstract android.content.Context getApplicationContext();` + * + * JNI signature: ()Landroid/content/Context; + * + */ + Context getApplicationContext(); + + /*! + * Wrapper for the getClassLoader method + * + * Java prototype: + * `public abstract java.lang.ClassLoader getClassLoader();` + * + * JNI signature: ()Ljava/lang/ClassLoader; + * + */ + java::lang::ClassLoader getClassLoader(); + + /*! + * Wrapper for the startActivity method + * + * Java prototype: + * `public abstract void startActivity(android.content.Intent);` + * + * JNI signature: (Landroid/content/Intent;)V + * + */ + void startActivity(Intent const &intent); + + /*! + * Wrapper for the startActivity method + * + * Java prototype: + * `public abstract void startActivity(android.content.Intent, + * android.os.Bundle);` + * + * JNI signature: (Landroid/content/Intent;Landroid/os/Bundle;)V + * + */ + void startActivity(Intent const &intent, os::Bundle const &bundle); + + /*! + * Wrapper for the createPackageContext method + * + * Java prototype: + * `public abstract android.content.Context + * createPackageContext(java.lang.String, int) throws + * android.content.pm.PackageManager$NameNotFoundException;` + * + * JNI signature: (Ljava/lang/String;I)Landroid/content/Context; + * + */ + Context createPackageContext(std::string const &packageName, int32_t flags); + + enum { + CONTEXT_INCLUDE_CODE = 1, + CONTEXT_IGNORE_SECURITY = 2, + }; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + impl::StaticFieldId DISPLAY_SERVICE; + impl::StaticFieldId WINDOW_SERVICE; + jni::method_t getPackageManager; + jni::method_t getApplicationContext; + jni::method_t getClassLoader; + jni::method_t startActivity; + jni::method_t startActivity1; + jni::method_t createPackageContext; + + /*! + * Singleton accessor + */ + static Meta &data(bool deferDrop = false) { + static Meta instance{deferDrop}; + return instance; + } + + private: + explicit Meta(bool deferDrop); + }; +}; +/*! + * Wrapper for android.content.ComponentName objects. + */ +class ComponentName : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/content/ComponentName"; + } + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.ComponentName(java.lang.String, + * java.lang.String);` + * + * JNI signature: (Ljava/lang/String;Ljava/lang/String;)V + * + */ + static ComponentName construct(std::string const &pkg, + std::string const &cls); + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.ComponentName(android.content.Context, + * java.lang.String);` + * + * JNI signature: (Landroid/content/Context;Ljava/lang/String;)V + * + */ + static ComponentName construct(Context const &pkg, std::string const &cls); + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.ComponentName(android.content.Context, + * java.lang.Class);` + * + * JNI signature: (Landroid/content/Context;Ljava/lang/Class;)V + * + */ + static ComponentName construct(Context const &pkg, + java::lang::Class const &cls); + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.ComponentName(android.os.Parcel);` + * + * JNI signature: (Landroid/os/Parcel;)V + * + */ + static ComponentName construct(jni::Object const &parcel); + + /*! + * Class metadata + */ + struct Meta : public MetaBase { + jni::method_t init; + jni::method_t init1; + jni::method_t init2; + jni::method_t init3; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.content.Intent objects. + */ +class Intent : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/content/Intent"; + } + + /*! + * Getter for the FLAG_ACTIVITY_NEW_TASK static field value + * + * Java prototype: + * `public static final int FLAG_ACTIVITY_NEW_TASK;` + * + * JNI signature: I + * + */ + static int32_t FLAG_ACTIVITY_NEW_TASK(); + +#if 0 + // disabled because of zero-length array warning in jnipp + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.Intent();` + * + * JNI signature: ()V + * + */ + static Intent construct(); +#endif + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.Intent(android.content.Intent);` + * + * JNI signature: (Landroid/content/Intent;)V + * + */ + static Intent construct(Intent &intent); + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.Intent(java.lang.String);` + * + * JNI signature: (Ljava/lang/String;)V + * + */ + static Intent construct(std::string const &action); + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.Intent(java.lang.String, android.net.Uri);` + * + * JNI signature: (Ljava/lang/String;Landroid/net/Uri;)V + * + */ + static Intent construct(std::string const &action, jni::Object const &uri); + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.Intent(android.content.Context, + * java.lang.Class);` + * + * JNI signature: (Landroid/content/Context;Ljava/lang/Class;)V + * + */ + static Intent construct(Context const &context, + java::lang::Class const &classParam); + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public android.content.Intent(java.lang.String, android.net.Uri, + * android.content.Context, java.lang.Class);` + * + * JNI signature: + * (Ljava/lang/String;Landroid/net/Uri;Landroid/content/Context;Ljava/lang/Class;)V + * + */ + static Intent construct(std::string const &action, jni::Object const &uri, + Context const &context, + java::lang::Class const &classParam); + + /*! + * Wrapper for the setFlags method + * + * Java prototype: + * `public android.content.Intent setFlags(int);` + * + * JNI signature: (I)Landroid/content/Intent; + * + */ + Intent setFlags(int32_t flags); + + /*! + * Class metadata + */ + struct Meta : public MetaBase { + impl::StaticFieldId FLAG_ACTIVITY_NEW_TASK; + jni::method_t init; + jni::method_t init1; + jni::method_t init2; + jni::method_t init3; + jni::method_t init4; + jni::method_t init5; + jni::method_t setFlags; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::content +} // namespace wrap +#include "android.content.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.content.impl.h b/src/external/android-jni-wrap/wrap/android.content.impl.h new file mode 100644 index 000000000..f1e88b126 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.content.impl.h @@ -0,0 +1,135 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "android.content.pm.h" +#include "android.os.h" +#include "java.lang.h" +#include + +namespace wrap { +namespace android::content { +inline std::string Context::DISPLAY_SERVICE() { + // Defer dropping the class ref to avoid having to do two class lookups + // by name for this static field. Instead, drop it before we return. + auto &data = Meta::data(true); + auto ret = get(data.DISPLAY_SERVICE, data.clazz()); + data.dropClassRef(); + return ret; +} + +inline std::string Context::WINDOW_SERVICE() { + // Defer dropping the class ref to avoid having to do two class lookups + // by name for this static field. Instead, drop it before we return. + auto &data = Meta::data(true); + auto ret = get(data.WINDOW_SERVICE, data.clazz()); + data.dropClassRef(); + return ret; +} + +inline pm::PackageManager Context::getPackageManager() { + assert(!isNull()); + return pm::PackageManager( + object().call(Meta::data().getPackageManager)); +} + +inline Context Context::getApplicationContext() { + assert(!isNull()); + return Context( + object().call(Meta::data().getApplicationContext)); +} + +inline java::lang::ClassLoader Context::getClassLoader() { + assert(!isNull()); + return java::lang::ClassLoader( + object().call(Meta::data().getClassLoader)); +} + +inline void Context::startActivity(Intent const &intent) { + assert(!isNull()); + return object().call(Meta::data().startActivity, intent.object()); +} + +inline void Context::startActivity(Intent const &intent, + os::Bundle const &bundle) { + assert(!isNull()); + return object().call(Meta::data().startActivity1, intent.object(), + bundle.object()); +} + +inline Context Context::createPackageContext(std::string const &packageName, + int32_t flags) { + assert(!isNull()); + return Context(object().call(Meta::data().createPackageContext, + packageName, flags)); +} +inline ComponentName ComponentName::construct(std::string const &pkg, + std::string const &cls) { + return ComponentName( + Meta::data().clazz().newInstance(Meta::data().init, pkg, cls)); +} + +inline ComponentName ComponentName::construct(Context const &pkg, + std::string const &cls) { + return ComponentName(Meta::data().clazz().newInstance(Meta::data().init1, + pkg.object(), cls)); +} + +inline ComponentName ComponentName::construct(Context const &pkg, + java::lang::Class const &cls) { + return ComponentName(Meta::data().clazz().newInstance( + Meta::data().init2, pkg.object(), cls.object())); +} + +inline ComponentName ComponentName::construct(jni::Object const &parcel) { + return ComponentName( + Meta::data().clazz().newInstance(Meta::data().init3, parcel)); +} +inline int32_t Intent::FLAG_ACTIVITY_NEW_TASK() { + return get(Meta::data().FLAG_ACTIVITY_NEW_TASK, Meta::data().clazz()); +} + +#if 0 +// disabled because of zero-length array warning in jnipp +inline Intent Intent::construct() { + return Intent(Meta::data().clazz().newInstance(Meta::data().init)); +} +#endif + +inline Intent Intent::construct(Intent &intent) { + return Intent( + Meta::data().clazz().newInstance(Meta::data().init1, intent.object())); +} + +inline Intent Intent::construct(std::string const &action) { + return Intent(Meta::data().clazz().newInstance(Meta::data().init2, action)); +} + +inline Intent Intent::construct(std::string const &action, + jni::Object const &uri) { + return Intent( + Meta::data().clazz().newInstance(Meta::data().init3, action, uri)); +} + +inline Intent Intent::construct(Context const &context, + java::lang::Class const &classParam) { + return Intent(Meta::data().clazz().newInstance( + Meta::data().init4, context.object(), classParam.object())); +} + +inline Intent Intent::construct(std::string const &action, + jni::Object const &uri, Context const &context, + java::lang::Class const &classParam) { + return Intent(Meta::data().clazz().newInstance(Meta::data().init5, action, + uri, context.object(), + classParam.object())); +} + +inline Intent Intent::setFlags(int32_t flags) { + assert(!isNull()); + return Intent(object().call(Meta::data().setFlags, flags)); +} +} // namespace android::content +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.content.pm.cpp b/src/external/android-jni-wrap/wrap/android.content.pm.cpp new file mode 100644 index 000000000..3c378de67 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.content.pm.cpp @@ -0,0 +1,55 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.content.pm.h" + +namespace wrap { +namespace android::content::pm { +PackageItemInfo::Meta::Meta() + : MetaBaseDroppable(PackageItemInfo::getTypeName()), + metaData(classRef(), "metaData"), name(classRef(), "name"), + packageName(classRef(), "packageName") { + MetaBaseDroppable::dropClassRef(); +} +ComponentInfo::Meta::Meta() : MetaBaseDroppable(ComponentInfo::getTypeName()) { + MetaBaseDroppable::dropClassRef(); +} +ServiceInfo::Meta::Meta() : MetaBaseDroppable(ServiceInfo::getTypeName()) { + MetaBaseDroppable::dropClassRef(); +} +ApplicationInfo::Meta::Meta() + : MetaBaseDroppable(ApplicationInfo::getTypeName()), + nativeLibraryDir(classRef(), "nativeLibraryDir"), + publicSourceDir(classRef(), "publicSourceDir") { + MetaBaseDroppable::dropClassRef(); +} +PackageInfo::Meta::Meta() + : MetaBaseDroppable(PackageInfo::getTypeName()), + applicationInfo(classRef(), "applicationInfo"), + packageName(classRef(), "packageName") { + MetaBaseDroppable::dropClassRef(); +} +ResolveInfo::Meta::Meta() + : MetaBaseDroppable(ResolveInfo::getTypeName()), + serviceInfo(classRef(), "serviceInfo") { + MetaBaseDroppable::dropClassRef(); +} +PackageManager::Meta::Meta() + : MetaBaseDroppable(PackageManager::getTypeName()), + getPackageInfo(classRef().getMethod( + "getPackageInfo", + "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;")), + getPackageInfo1(classRef().getMethod( + "getPackageInfo", "(Landroid/content/pm/VersionedPackage;I)Landroid/" + "content/pm/PackageInfo;")), + getApplicationInfo(classRef().getMethod( + "getApplicationInfo", + "(Ljava/lang/String;I)Landroid/content/pm/ApplicationInfo;")), + queryIntentServices( + classRef().getMethod("queryIntentServices", + "(Landroid/content/Intent;I)Ljava/util/List;")) { + MetaBaseDroppable::dropClassRef(); +} +} // namespace android::content::pm +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.content.pm.h b/src/external/android-jni-wrap/wrap/android.content.pm.h new file mode 100644 index 000000000..81a872a87 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.content.pm.h @@ -0,0 +1,387 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" +#include "android.os.h" +#include + +namespace wrap { +namespace android::content { +class Intent; +} // namespace android::content + +namespace android::content::pm { +class ApplicationInfo; +class PackageInfo; +class ServiceInfo; +} // namespace android::content::pm + +namespace android::os { +class Bundle; +} // namespace android::os + +namespace java::util { +class List; +} // namespace java::util + +} // namespace wrap + +namespace wrap { +namespace android::content::pm { +/*! + * Wrapper for android.content.pm.PackageItemInfo objects. + */ +class PackageItemInfo : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/content/pm/PackageItemInfo"; + } + + /*! + * Getter for the metaData field value + * + * Java prototype: + * `public android.os.Bundle metaData;` + * + * JNI signature: Landroid/os/Bundle; + * + */ + os::Bundle getMetaData() const; + + /*! + * Getter for the name field value + * + * Java prototype: + * `public java.lang.String name;` + * + * JNI signature: Ljava/lang/String; + * + */ + std::string getName() const; + + /*! + * Getter for the packageName field value + * + * Java prototype: + * `public java.lang.String packageName;` + * + * JNI signature: Ljava/lang/String; + * + */ + std::string getPackageName() const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + impl::WrappedFieldId metaData; + impl::FieldId name; + impl::FieldId packageName; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.content.pm.ComponentInfo objects. + */ +class ComponentInfo : public PackageItemInfo { + public: + using PackageItemInfo::PackageItemInfo; + static constexpr const char *getTypeName() noexcept { + return "android/content/pm/ComponentInfo"; + } + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.content.pm.ServiceInfo objects. + */ +class ServiceInfo : public PackageItemInfo { + public: + using PackageItemInfo::PackageItemInfo; + static constexpr const char *getTypeName() noexcept { + return "android/content/pm/ServiceInfo"; + } + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.content.pm.ApplicationInfo objects. + */ +class ApplicationInfo : public PackageItemInfo { + public: + using PackageItemInfo::PackageItemInfo; + static constexpr const char *getTypeName() noexcept { + return "android/content/pm/ApplicationInfo"; + } + + /*! + * Getter for the nativeLibraryDir field value + * + * Java prototype: + * `public java.lang.String nativeLibraryDir;` + * + * JNI signature: Ljava/lang/String; + * + */ + std::string getNativeLibraryDir() const; + + /*! + * Getter for the publicSourceDir field value + * + * Java prototype: + * `public java.lang.String publicSourceDir;` + * + * JNI signature: Ljava/lang/String; + * + */ + std::string getPublicSourceDir() const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + impl::FieldId nativeLibraryDir; + impl::FieldId publicSourceDir; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.content.pm.PackageInfo objects. + */ +class PackageInfo : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/content/pm/PackageInfo"; + } + + /*! + * Getter for the applicationInfo field value + * + * Java prototype: + * `public android.content.pm.ApplicationInfo applicationInfo;` + * + * JNI signature: Landroid/content/pm/ApplicationInfo; + * + */ + ApplicationInfo getApplicationInfo() const; + + /*! + * Getter for the packageName field value + * + * Java prototype: + * `public java.lang.String packageName;` + * + * JNI signature: Ljava/lang/String; + * + */ + std::string getPackageName() const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + impl::WrappedFieldId applicationInfo; + impl::FieldId packageName; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.content.pm.ResolveInfo objects. + */ +class ResolveInfo : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/content/pm/ResolveInfo"; + } + + /*! + * Getter for the serviceInfo field value + * + * Java prototype: + * `public android.content.pm.ServiceInfo serviceInfo;` + * + * JNI signature: Landroid/content/pm/ServiceInfo; + * + */ + ServiceInfo getServiceInfo() const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + impl::WrappedFieldId serviceInfo; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.content.pm.PackageManager objects. + */ +class PackageManager : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/content/pm/PackageManager"; + } + + /*! + * Wrapper for the getPackageInfo method + * + * Java prototype: + * `public abstract android.content.pm.PackageInfo + * getPackageInfo(java.lang.String, int) throws + * android.content.pm.PackageManager$NameNotFoundException;` + * + * JNI signature: (Ljava/lang/String;I)Landroid/content/pm/PackageInfo; + * + */ + PackageInfo getPackageInfo(std::string const &name, int32_t flags); + +#if 0 + // Ambiguous overload until we wrap VersionedPackage + /*! + * Wrapper for the getPackageInfo method + * + * Java prototype: + * `public abstract android.content.pm.PackageInfo + * getPackageInfo(android.content.pm.VersionedPackage, int) throws + * android.content.pm.PackageManager$NameNotFoundException;` + * + * JNI signature: + * (Landroid/content/pm/VersionedPackage;I)Landroid/content/pm/PackageInfo; + * + */ + PackageInfo getPackageInfo(jni::Object &versionedPackage, int32_t flags); + +#endif + + /*! + * Wrapper for the getApplicationInfo method + * + * Java prototype: + * `public abstract android.content.pm.ApplicationInfo + * getApplicationInfo(java.lang.String, int) throws + * android.content.pm.PackageManager$NameNotFoundException;` + * + * JNI signature: (Ljava/lang/String;I)Landroid/content/pm/ApplicationInfo; + * + */ + ApplicationInfo getApplicationInfo(std::string const &packageName, + int32_t flags); + + /*! + * Wrapper for the queryIntentServices method + * + * Java prototype: + * `public abstract java.util.List + * queryIntentServices(android.content.Intent, int);` + * + * JNI signature: (Landroid/content/Intent;I)Ljava/util/List; + * + */ + java::util::List queryIntentServices(Intent &intent, int32_t intParam); + + enum { + GET_META_DATA = 128, + GET_SHARED_LIBRARY_FILES = 1024, + }; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t getPackageInfo; + jni::method_t getPackageInfo1; + jni::method_t getApplicationInfo; + jni::method_t queryIntentServices; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::content::pm +} // namespace wrap +#include "android.content.pm.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.content.pm.impl.h b/src/external/android-jni-wrap/wrap/android.content.pm.impl.h new file mode 100644 index 000000000..be6e5b377 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.content.pm.impl.h @@ -0,0 +1,83 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "android.content.h" +#include "java.util.h" +#include + +namespace wrap { +namespace android::content::pm { +inline os::Bundle PackageItemInfo::getMetaData() const { + assert(!isNull()); + return get(Meta::data().metaData, object()); +} + +inline std::string PackageItemInfo::getName() const { + assert(!isNull()); + return get(Meta::data().name, object()); +} + +inline std::string PackageItemInfo::getPackageName() const { + assert(!isNull()); + return get(Meta::data().packageName, object()); +} + +inline std::string ApplicationInfo::getNativeLibraryDir() const { + assert(!isNull()); + return get(Meta::data().nativeLibraryDir, object()); +} + +inline std::string ApplicationInfo::getPublicSourceDir() const { + assert(!isNull()); + return get(Meta::data().publicSourceDir, object()); +} +inline ApplicationInfo PackageInfo::getApplicationInfo() const { + assert(!isNull()); + return get(Meta::data().applicationInfo, object()); +} + +inline std::string PackageInfo::getPackageName() const { + assert(!isNull()); + return get(Meta::data().packageName, object()); +} +inline ServiceInfo ResolveInfo::getServiceInfo() const { + assert(!isNull()); + return get(Meta::data().serviceInfo, object()); +} +inline PackageInfo PackageManager::getPackageInfo(std::string const &name, + int32_t flags) { + assert(!isNull()); + return PackageInfo( + object().call(Meta::data().getPackageInfo, name, flags)); +} + +#if 0 +// Ambiguous overload until we wrap VersionedPackage +inline PackageInfo +PackageManager::getPackageInfo(jni::Object const &versionedPackage, + int32_t flags) { + assert(!isNull()); + return PackageInfo(object().call(Meta::data().getPackageInfo1, + versionedPackage, flags)); +} +#endif + +inline ApplicationInfo +PackageManager::getApplicationInfo(std::string const &packageName, + int32_t flags) { + assert(!isNull()); + return ApplicationInfo(object().call( + Meta::data().getApplicationInfo, packageName, flags)); +} + +inline java::util::List PackageManager::queryIntentServices(Intent &intent, + int32_t intParam) { + assert(!isNull()); + return java::util::List(object().call( + Meta::data().queryIntentServices, intent.object(), intParam)); +} +} // namespace android::content::pm +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.graphics.cpp b/src/external/android-jni-wrap/wrap/android.graphics.cpp new file mode 100644 index 000000000..99809b737 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.graphics.cpp @@ -0,0 +1,15 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.graphics.h" + +namespace wrap { +namespace android::graphics { +Point::Meta::Meta() + : MetaBaseDroppable(Point::getTypeName()), x(classRef(), "x"), + y(classRef(), "y") { + MetaBaseDroppable::dropClassRef(); +} +} // namespace android::graphics +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.graphics.h b/src/external/android-jni-wrap/wrap/android.graphics.h new file mode 100644 index 000000000..bbe35fa8a --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.graphics.h @@ -0,0 +1,64 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" + +namespace wrap { +namespace android::graphics { +/*! + * Wrapper for android.graphics.Point objects. + */ +class Point : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/graphics/Point"; + } + + /*! + * Getter for the x field value + * + * Java prototype: + * `public int x;` + * + * JNI signature: I + * + */ + int32_t getX() const; + + /*! + * Getter for the y field value + * + * Java prototype: + * `public int y;` + * + * JNI signature: I + * + */ + int32_t getY() const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + impl::FieldId x; + impl::FieldId y; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::graphics +} // namespace wrap +#include "android.graphics.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.graphics.impl.h b/src/external/android-jni-wrap/wrap/android.graphics.impl.h new file mode 100644 index 000000000..30ba5bcf5 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.graphics.impl.h @@ -0,0 +1,19 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +namespace wrap { +namespace android::graphics { +inline int32_t Point::getX() const { + assert(!isNull()); + return get(Meta::data().x, object()); +} + +inline int32_t Point::getY() const { + assert(!isNull()); + return get(Meta::data().y, object()); +} +} // namespace android::graphics +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.os.cpp b/src/external/android-jni-wrap/wrap/android.os.cpp new file mode 100644 index 000000000..bfa898305 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.os.cpp @@ -0,0 +1,33 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.os.h" + +namespace wrap { +namespace android::os { +BaseBundle::Meta::Meta() + : MetaBaseDroppable(BaseBundle::getTypeName()), + containsKey(classRef().getMethod("containsKey", "(Ljava/lang/String;)Z")), + getString(classRef().getMethod("getString", + "(Ljava/lang/String;)Ljava/lang/String;")), + getString1(classRef().getMethod( + "getString", + "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;")) { + MetaBaseDroppable::dropClassRef(); +} +Bundle::Meta::Meta() : MetaBaseDroppable(Bundle::getTypeName()) { + MetaBaseDroppable::dropClassRef(); +} +ParcelFileDescriptor::Meta::Meta() + : MetaBaseDroppable(ParcelFileDescriptor::getTypeName()), + adoptFd(classRef().getStaticMethod( + "adoptFd", "(I)Landroid/os/ParcelFileDescriptor;")), + getFd(classRef().getMethod("getFd", "()I")), + detachFd(classRef().getMethod("detachFd", "()I")), + close(classRef().getMethod("close", "()V")), + checkError(classRef().getMethod("checkError", "()V")) { + MetaBaseDroppable::dropClassRef(); +} +} // namespace android::os +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.os.h b/src/external/android-jni-wrap/wrap/android.os.h new file mode 100644 index 000000000..2ea3f5d4d --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.os.h @@ -0,0 +1,199 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" + +namespace wrap { +namespace android::os { +class ParcelFileDescriptor; +} // namespace android::os + +} // namespace wrap + +namespace wrap { +namespace android::os { +/*! + * Wrapper for android.os.BaseBundle objects. + */ +class BaseBundle : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/os/BaseBundle"; + } + + /*! + * Wrapper for the containsKey method + * + * Java prototype: + * `public boolean containsKey(java.lang.String);` + * + * JNI signature: (Ljava/lang/String;)Z + * + */ + bool containsKey(std::string const &key); + + /*! + * Wrapper for the getString method + * + * Java prototype: + * `public java.lang.String getString(java.lang.String);` + * + * JNI signature: (Ljava/lang/String;)Ljava/lang/String; + * + */ + std::string getString(std::string const &key); + + /*! + * Wrapper for the getString method + * + * Java prototype: + * `public java.lang.String getString(java.lang.String, java.lang.String);` + * + * JNI signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + * + */ + std::string getString(std::string const &key, + std::string const &defaultValue); + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t containsKey; + jni::method_t getString; + jni::method_t getString1; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.os.Bundle objects. + */ +class Bundle : public BaseBundle { + public: + using BaseBundle::BaseBundle; + static constexpr const char *getTypeName() noexcept { + return "android/os/Bundle"; + } + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; + +/*! + * Wrapper for android.os.ParcelFileDescriptor objects. + */ +class ParcelFileDescriptor : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/os/ParcelFileDescriptor"; + } + + /*! + * Wrapper for the adoptFd static method + * + * Java prototype: + * `public static android.os.ParcelFileDescriptor adoptFd(int);` + * + * JNI signature: (I)Landroid/os/ParcelFileDescriptor; + * + */ + static ParcelFileDescriptor adoptFd(int fd); + + /*! + * Wrapper for the getFd method + * + * Java prototype: + * `public int getFd();` + * + * JNI signature: ()I + * + */ + int getFd() const; + + /*! + * Wrapper for the detachFd method + * + * Java prototype: + * `public int detachFd();` + * + * JNI signature: ()I + * + */ + int detachFd(); + + /*! + * Wrapper for the close method + * + * Java prototype: + * `public void close() throws java.io.IOException;` + * + * JNI signature: ()V + * + */ + void close(); + + /*! + * Wrapper for the checkError method + * + * Java prototype: + * `public void checkError() throws java.io.IOException;` + * + * JNI signature: ()V + * + */ + void checkError() const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t adoptFd; + jni::method_t getFd; + jni::method_t detachFd; + jni::method_t close; + jni::method_t checkError; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::os +} // namespace wrap +#include "android.os.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.os.impl.h b/src/external/android-jni-wrap/wrap/android.os.impl.h new file mode 100644 index 000000000..6078d378e --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.os.impl.h @@ -0,0 +1,53 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include + +namespace wrap { +namespace android::os { +inline bool BaseBundle::containsKey(std::string const &key) { + assert(!isNull()); + return object().call(Meta::data().containsKey, key); +} + +inline std::string BaseBundle::getString(std::string const &key) { + assert(!isNull()); + return object().call(Meta::data().getString, key); +} + +inline std::string BaseBundle::getString(std::string const &key, + std::string const &defaultValue) { + assert(!isNull()); + return object().call(Meta::data().getString1, key, + defaultValue); +} + +inline ParcelFileDescriptor ParcelFileDescriptor::adoptFd(int fd) { + return ParcelFileDescriptor( + Meta::data().clazz().call(Meta::data().adoptFd, fd)); +} + +inline int ParcelFileDescriptor::getFd() const { + assert(!isNull()); + return object().call(Meta::data().getFd); +} + +inline int ParcelFileDescriptor::detachFd() { + assert(!isNull()); + return object().call(Meta::data().detachFd); +} + +inline void ParcelFileDescriptor::close() { + assert(!isNull()); + return object().call(Meta::data().close); +} + +inline void ParcelFileDescriptor::checkError() const { + assert(!isNull()); + return object().call(Meta::data().checkError); +} +} // namespace android::os +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.provider.cpp b/src/external/android-jni-wrap/wrap/android.provider.cpp new file mode 100644 index 000000000..2648c4b05 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.provider.cpp @@ -0,0 +1,13 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.provider.h" + +namespace wrap { +namespace android::provider { +Settings::Meta::Meta() + : MetaBase(Settings::getTypeName()), + ACTION_VR_LISTENER_SETTINGS(classRef(), "ACTION_VR_LISTENER_SETTINGS") {} +} // namespace android::provider +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.provider.h b/src/external/android-jni-wrap/wrap/android.provider.h new file mode 100644 index 000000000..e139e3151 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.provider.h @@ -0,0 +1,53 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" +#include + +namespace wrap { +namespace android::provider { +/*! + * Wrapper for android.provider.Settings objects. + */ +class Settings : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/provider/Settings"; + } + + /*! + * Getter for the ACTION_VR_LISTENER_SETTINGS static field value + * + * Java prototype: + * `public static final java.lang.String ACTION_VR_LISTENER_SETTINGS;` + * + * JNI signature: Ljava/lang/String; + * + */ + static std::string ACTION_VR_LISTENER_SETTINGS(); + + /*! + * Class metadata + */ + struct Meta : public MetaBase { + impl::StaticFieldId ACTION_VR_LISTENER_SETTINGS; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::provider +} // namespace wrap +#include "android.provider.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.provider.impl.h b/src/external/android-jni-wrap/wrap/android.provider.impl.h new file mode 100644 index 000000000..066782847 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.provider.impl.h @@ -0,0 +1,13 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +namespace wrap { +namespace android::provider { +inline std::string Settings::ACTION_VR_LISTENER_SETTINGS() { + return get(Meta::data().ACTION_VR_LISTENER_SETTINGS, Meta::data().clazz()); +} +} // namespace android::provider +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.service.vr.cpp b/src/external/android-jni-wrap/wrap/android.service.vr.cpp new file mode 100644 index 000000000..a1381a404 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.service.vr.cpp @@ -0,0 +1,15 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.service.vr.h" + +namespace wrap { +namespace android::service::vr { +VrListenerService::Meta::Meta() + : MetaBase(VrListenerService::getTypeName()), + isVrModePackageEnabled(classRef().getStaticMethod( + "isVrModePackageEnabled", + "(Landroid/content/Context;Landroid/content/ComponentName;)Z")) {} +} // namespace android::service::vr +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.service.vr.h b/src/external/android-jni-wrap/wrap/android.service.vr.h new file mode 100644 index 000000000..65fa9b705 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.service.vr.h @@ -0,0 +1,65 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "android.app.h" + +namespace wrap { +namespace android::content { +class ComponentName; +class Context; +} // namespace android::content + +} // namespace wrap + +namespace wrap { +namespace android::service::vr { +/*! + * Wrapper for android.service.vr.VrListenerService objects. + */ +class VrListenerService : public app::Service { + public: + using Service::Service; + static constexpr const char *getTypeName() noexcept { + return "android/service/vr/VrListenerService"; + } + + /*! + * Wrapper for the isVrModePackageEnabled static method + * + * Java prototype: + * `public static final boolean + * isVrModePackageEnabled(android.content.Context, + * android.content.ComponentName);` + * + * JNI signature: + * (Landroid/content/Context;Landroid/content/ComponentName;)Z + * + */ + static bool + isVrModePackageEnabled(content::Context const &context, + content::ComponentName const &componentName); + + /*! + * Class metadata + */ + struct Meta : public MetaBase { + jni::method_t isVrModePackageEnabled; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::service::vr +} // namespace wrap +#include "android.service.vr.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.service.vr.impl.h b/src/external/android-jni-wrap/wrap/android.service.vr.impl.h new file mode 100644 index 000000000..45b7304d6 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.service.vr.impl.h @@ -0,0 +1,19 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "android.content.h" + +namespace wrap { +namespace android::service::vr { +inline bool VrListenerService::isVrModePackageEnabled( + content::Context const &context, + content::ComponentName const &componentName) { + return Meta::data().clazz().call(Meta::data().isVrModePackageEnabled, + context.object(), + componentName.object()); +} +} // namespace android::service::vr +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.util.cpp b/src/external/android-jni-wrap/wrap/android.util.cpp new file mode 100644 index 000000000..3c96d69a0 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.util.cpp @@ -0,0 +1,16 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.util.h" + +namespace wrap { +namespace android::util { +DisplayMetrics::Meta::Meta() + : MetaBaseDroppable(DisplayMetrics::getTypeName()), + heightPixels(classRef(), "heightPixels"), + widthPixels(classRef(), "widthPixels") { + MetaBaseDroppable::dropClassRef(); +} +} // namespace android::util +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.util.h b/src/external/android-jni-wrap/wrap/android.util.h new file mode 100644 index 000000000..418b797f8 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.util.h @@ -0,0 +1,64 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" + +namespace wrap { +namespace android::util { +/*! + * Wrapper for android.util.DisplayMetrics objects. + */ +class DisplayMetrics : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/util/DisplayMetrics"; + } + + /*! + * Getter for the heightPixels field value + * + * Java prototype: + * `public int heightPixels;` + * + * JNI signature: I + * + */ + int32_t getHeightPixels() const; + + /*! + * Getter for the widthPixels field value + * + * Java prototype: + * `public int widthPixels;` + * + * JNI signature: I + * + */ + int32_t getWidthPixels() const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + impl::FieldId heightPixels; + impl::FieldId widthPixels; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::util +} // namespace wrap +#include "android.util.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.util.impl.h b/src/external/android-jni-wrap/wrap/android.util.impl.h new file mode 100644 index 000000000..adfc8b4f4 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.util.impl.h @@ -0,0 +1,19 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +namespace wrap { +namespace android::util { +inline int32_t DisplayMetrics::getHeightPixels() const { + assert(!isNull()); + return get(Meta::data().heightPixels, object()); +} + +inline int32_t DisplayMetrics::getWidthPixels() const { + assert(!isNull()); + return get(Meta::data().widthPixels, object()); +} +} // namespace android::util +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.view.cpp b/src/external/android-jni-wrap/wrap/android.view.cpp new file mode 100644 index 000000000..3934ea31e --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.view.cpp @@ -0,0 +1,29 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.view.h" + +namespace wrap { +namespace android::view { +Display::Meta::Meta() + : MetaBaseDroppable(Display::getTypeName()), + getRealSize( + classRef().getMethod("getRealSize", "(Landroid/graphics/Point;)V")), + getRealMetrics(classRef().getMethod("getRealMetrics", + "(Landroid/util/DisplayMetrics;)V")) { + MetaBaseDroppable::dropClassRef(); +} +Surface::Meta::Meta() + : MetaBaseDroppable(Surface::getTypeName()), + isValid(classRef().getMethod("isValid", "()Z")) { + MetaBaseDroppable::dropClassRef(); +} +SurfaceHolder::Meta::Meta() + : MetaBaseDroppable(SurfaceHolder::getTypeName()), + getSurface( + classRef().getMethod("getSurface", "()Landroid/view/Surface;")) { + MetaBaseDroppable::dropClassRef(); +} +} // namespace android::view +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.view.h b/src/external/android-jni-wrap/wrap/android.view.h new file mode 100644 index 000000000..f958085c9 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.view.h @@ -0,0 +1,157 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" + +namespace wrap { +namespace android::graphics { +class Point; +} // namespace android::graphics + +namespace android::util { +class DisplayMetrics; +} // namespace android::util + +namespace android::view { +class Surface; +} // namespace android::view + +} // namespace wrap + +namespace wrap { +namespace android::view { +/*! + * Wrapper for android.view.Display objects. + */ +class Display : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/view/Display"; + } + + /*! + * Wrapper for the getRealSize method + * + * Java prototype: + * `public void getRealSize(android.graphics.Point);` + * + * JNI signature: (Landroid/graphics/Point;)V + * + */ + void getRealSize(graphics::Point &out_size); + + /*! + * Wrapper for the getRealMetrics method + * + * Java prototype: + * `public void getRealMetrics(android.util.DisplayMetrics);` + * + * JNI signature: (Landroid/util/DisplayMetrics;)V + * + */ + void getRealMetrics(util::DisplayMetrics &out_displayMetrics); + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t getRealSize; + jni::method_t getRealMetrics; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.view.Surface objects. + */ +class Surface : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/view/Surface"; + } + + /*! + * Wrapper for the isValid method + * + * Java prototype: + * `public boolean isValid();` + * + * JNI signature: ()Z + * + */ + bool isValid() const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t isValid; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for android.view.SurfaceHolder objects. + */ +class SurfaceHolder : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/view/SurfaceHolder"; + } + + /*! + * Wrapper for the getSurface method + * + * Java prototype: + * `public abstract android.view.Surface getSurface();` + * + * JNI signature: ()Landroid/view/Surface; + * + */ + Surface getSurface(); + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t getSurface; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::view +} // namespace wrap +#include "android.view.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.view.impl.h b/src/external/android-jni-wrap/wrap/android.view.impl.h new file mode 100644 index 000000000..caf34c570 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.view.impl.h @@ -0,0 +1,31 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "android.graphics.h" +#include "android.util.h" + +namespace wrap { +namespace android::view { +inline void Display::getRealSize(graphics::Point &out_size) { + assert(!isNull()); + return object().call(Meta::data().getRealSize, out_size.object()); +} + +inline void Display::getRealMetrics(util::DisplayMetrics &out_displayMetrics) { + assert(!isNull()); + return object().call(Meta::data().getRealMetrics, + out_displayMetrics.object()); +} +inline bool Surface::isValid() const { + assert(!isNull()); + return object().call(Meta::data().isValid); +} +inline Surface SurfaceHolder::getSurface() { + assert(!isNull()); + return Surface(object().call(Meta::data().getSurface)); +} +} // namespace android::view +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.widget.cpp b/src/external/android-jni-wrap/wrap/android.widget.cpp new file mode 100644 index 000000000..8da994786 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.widget.cpp @@ -0,0 +1,19 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "android.widget.h" + +namespace wrap { +namespace android::widget { +Toast::Meta::Meta() + : MetaBase(Toast::getTypeName()), LENGTH_LONG(classRef(), "LENGTH_LONG"), + LENGTH_SHORT(classRef(), "LENGTH_SHORT"), + show(classRef().getMethod("show", "()V")), + makeText(classRef().getStaticMethod( + "makeText", "(Landroid/content/Context;Ljava/lang/" + "CharSequence;I)Landroid/widget/Toast;")), + makeText1(classRef().getStaticMethod( + "makeText", "(Landroid/content/Context;II)Landroid/widget/Toast;")) {} +} // namespace android::widget +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/android.widget.h b/src/external/android-jni-wrap/wrap/android.widget.h new file mode 100644 index 000000000..52289c2f3 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.widget.h @@ -0,0 +1,116 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" + +namespace wrap { +namespace android::content { +class Context; +} // namespace android::content + +namespace android::widget { +class Toast; +} // namespace android::widget + +} // namespace wrap + +namespace wrap { +namespace android::widget { +/*! + * Wrapper for android.widget.Toast objects. + */ +class Toast : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "android/widget/Toast"; + } + + /*! + * Getter for the LENGTH_LONG static field value + * + * Java prototype: + * `public static final int LENGTH_LONG;` + * + * JNI signature: I + * + */ + static int32_t LENGTH_LONG(); + + /*! + * Getter for the LENGTH_SHORT static field value + * + * Java prototype: + * `public static final int LENGTH_SHORT;` + * + * JNI signature: I + * + */ + static int32_t LENGTH_SHORT(); + + /*! + * Wrapper for the show method + * + * Java prototype: + * `public void show();` + * + * JNI signature: ()V + * + */ + void show() const; + + /*! + * Wrapper for the makeText static method + * + * Java prototype: + * `public static android.widget.Toast makeText(android.content.Context, + * java.lang.CharSequence, int);` + * + * JNI signature: + * (Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; + * + */ + static Toast makeText(content::Context const &context, + std::string const &stringParam, int32_t duration); + + /*! + * Wrapper for the makeText static method + * + * Java prototype: + * `public static android.widget.Toast makeText(android.content.Context, + * int, int) throws android.content.res.Resources$NotFoundException;` + * + * JNI signature: (Landroid/content/Context;II)Landroid/widget/Toast; + * + */ + static Toast makeText(content::Context &context, int32_t resId, + int32_t duration); + + /*! + * Class metadata + */ + struct Meta : public MetaBase { + impl::StaticFieldId LENGTH_LONG; + impl::StaticFieldId LENGTH_SHORT; + jni::method_t show; + jni::method_t makeText; + jni::method_t makeText1; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace android::widget +} // namespace wrap +#include "android.widget.impl.h" diff --git a/src/external/android-jni-wrap/wrap/android.widget.impl.h b/src/external/android-jni-wrap/wrap/android.widget.impl.h new file mode 100644 index 000000000..ecb511603 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/android.widget.impl.h @@ -0,0 +1,36 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "android.content.h" + +namespace wrap { +namespace android::widget { +inline int32_t Toast::LENGTH_LONG() { + return get(Meta::data().LENGTH_LONG, Meta::data().clazz()); +} + +inline int32_t Toast::LENGTH_SHORT() { + return get(Meta::data().LENGTH_SHORT, Meta::data().clazz()); +} + +inline void Toast::show() const { + assert(!isNull()); + return object().call(Meta::data().show); +} + +inline Toast Toast::makeText(content::Context const &context, + std::string const &stringParam, int32_t duration) { + return Toast(Meta::data().clazz().call( + Meta::data().makeText, context.object(), stringParam, duration)); +} + +inline Toast Toast::makeText(content::Context &context, int32_t resId, + int32_t duration) { + return Toast(Meta::data().clazz().call( + Meta::data().makeText1, context.object(), resId, duration)); +} +} // namespace android::widget +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/dalvik.system.cpp b/src/external/android-jni-wrap/wrap/dalvik.system.cpp new file mode 100644 index 000000000..671773395 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/dalvik.system.cpp @@ -0,0 +1,15 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "dalvik.system.h" + +namespace wrap { +namespace dalvik::system { +DexClassLoader::Meta::Meta() + : MetaBase(DexClassLoader::getTypeName()), + init(classRef().getMethod("", + "(Ljava/lang/String;Ljava/lang/String;Ljava/" + "lang/String;Ljava/lang/ClassLoader;)V")) {} +} // namespace dalvik::system +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/dalvik.system.h b/src/external/android-jni-wrap/wrap/dalvik.system.h new file mode 100644 index 000000000..b3775f9ac --- /dev/null +++ b/src/external/android-jni-wrap/wrap/dalvik.system.h @@ -0,0 +1,67 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" + +namespace wrap { +namespace dalvik::system { +class DexClassLoader; +} // namespace dalvik::system + +namespace java::lang { +class ClassLoader; +} // namespace java::lang + +} // namespace wrap + +namespace wrap { +namespace dalvik::system { +/*! + * Wrapper for dalvik.system.DexClassLoader objects. + */ +class DexClassLoader : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "dalvik/system/DexClassLoader"; + } + + /*! + * Wrapper for a constructor + * + * Java prototype: + * `public dalvik.system.DexClassLoader(java.lang.String, java.lang.String, + * java.lang.String, java.lang.ClassLoader);` + * + * JNI signature: + * (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V + * + */ + static DexClassLoader construct(std::string const &searchPath, + std::string const &nativeSearchPath, + jni::Object parentClassLoader); + + /*! + * Class metadata + */ + struct Meta : public MetaBase { + jni::method_t init; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace dalvik::system +} // namespace wrap +#include "dalvik.system.impl.h" diff --git a/src/external/android-jni-wrap/wrap/dalvik.system.impl.h b/src/external/android-jni-wrap/wrap/dalvik.system.impl.h new file mode 100644 index 000000000..c23a80839 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/dalvik.system.impl.h @@ -0,0 +1,21 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "java.lang.h" +#include + +namespace wrap { +namespace dalvik::system { +inline DexClassLoader +DexClassLoader::construct(std::string const &searchPath, + std::string const &nativeSearchPath, + jni::Object parentClassLoader) { + return DexClassLoader{ + Meta::data().clazz().newInstance(Meta::data().init, searchPath, "", + nativeSearchPath, parentClassLoader)}; +} +} // namespace dalvik::system +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/java.lang.cpp b/src/external/android-jni-wrap/wrap/java.lang.cpp new file mode 100644 index 000000000..523bbaaee --- /dev/null +++ b/src/external/android-jni-wrap/wrap/java.lang.cpp @@ -0,0 +1,34 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "java.lang.h" + +namespace wrap { +namespace java::lang { +Class::Meta::Meta() + : MetaBase(Class::getTypeName()), + forName(classRef().getStaticMethod( + "forName", "(Ljava/lang/String;)Ljava/lang/Class;")), + forName1(classRef().getStaticMethod( + "forName", + "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;")), + forName2(classRef().getStaticMethod( + "forName", + "(Ljava/lang/Module;Ljava/lang/String;)Ljava/lang/Class;")), + getCanonicalName( + classRef().getMethod("getCanonicalName", "()Ljava/lang/String;")) {} +ClassLoader::Meta::Meta() + : MetaBaseDroppable(ClassLoader::getTypeName()), + loadClass(classRef().getMethod("loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;")), + findLibrary(classRef().getMethod( + "findLibrary", "(Ljava/lang/String;)Ljava/lang/String;")) { + MetaBaseDroppable::dropClassRef(); +} +System::Meta::Meta() + : MetaBase(System::getTypeName()), + mapLibraryName(classRef().getStaticMethod( + "mapLibraryName", "(Ljava/lang/String;)Ljava/lang/String;")) {} +} // namespace java::lang +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/java.lang.h b/src/external/android-jni-wrap/wrap/java.lang.h new file mode 100644 index 000000000..56541411b --- /dev/null +++ b/src/external/android-jni-wrap/wrap/java.lang.h @@ -0,0 +1,195 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" + +namespace wrap { +namespace java::lang { +class Class; +class ClassLoader; +} // namespace java::lang + +} // namespace wrap + +namespace wrap { +namespace java::lang { +/*! + * Wrapper for java.lang.Class objects. + */ +class Class : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "java/lang/Class"; + } + + /*! + * Wrapper for the forName static method + * + * Java prototype: + * `public static java.lang.Class forName(java.lang.String) throws + * java.lang.ClassNotFoundException;` + * + * JNI signature: (Ljava/lang/String;)Ljava/lang/Class; + * + */ + static Class forName(std::string &stringParam); + + /*! + * Wrapper for the forName static method + * + * Java prototype: + * `public static java.lang.Class forName(java.lang.String, boolean, + * java.lang.ClassLoader) throws java.lang.ClassNotFoundException;` + * + * JNI signature: + * (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class; + * + */ + static Class forName(std::string const &name, bool initialize, + jni::Object classLoader); + + //! @overload + static Class forName(jstring name, bool initialize, + jni::Object classLoader); + /*! + * Wrapper for the forName static method + * + * Java prototype: + * `public static java.lang.Class forName(java.lang.Module, + * java.lang.String);` + * + * JNI signature: (Ljava/lang/Module;Ljava/lang/String;)Ljava/lang/Class; + * + */ + static Class forName(jni::Object const &module, std::string const &name); + + /*! + * Wrapper for the getCanonicalName method + * + * Java prototype: + * `public java.lang.String getCanonicalName();` + * + * JNI signature: ()Ljava/lang/String; + * + */ + std::string getCanonicalName(); + + /*! + * Class metadata + */ + struct Meta : public MetaBase { + jni::method_t forName; + jni::method_t forName1; + jni::method_t forName2; + jni::method_t getCanonicalName; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for java.lang.ClassLoader objects. + */ +class ClassLoader : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "java/lang/ClassLoader"; + } + + /*! + * Wrapper for the loadClass method + * + * Java prototype: + * `public java.lang.Class loadClass(java.lang.String) throws + * java.lang.ClassNotFoundException;` + * + * JNI signature: (Ljava/lang/String;)Ljava/lang/Class; + * + */ + Class loadClass(std::string const &name); + + //! @overload + Class loadClass(jstring name); + + /*! + * Wrapper for the findLibrary method + * + * JNI signature: (Ljava/lang/String;)Ljava/lang/String; + * + */ + std::string findLibrary(std::string const &name); + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t loadClass; + jni::method_t findLibrary; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +/*! + * Wrapper for java.lang.System objects. + */ +class System : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "java/lang/System"; + } + + /*! + * Wrapper for the mapLibraryName static method + * + * Java prototype: + * `public static native java.lang.String mapLibraryName(java.lang.String);` + * + * JNI signature: (Ljava/lang/String;)Ljava/lang/String; + * + */ + static std::string mapLibraryName(std::string const &name); + + /*! + * Class metadata + */ + struct Meta : public MetaBase { + jni::method_t mapLibraryName; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace java::lang +} // namespace wrap +#include "java.lang.impl.h" diff --git a/src/external/android-jni-wrap/wrap/java.lang.impl.h b/src/external/android-jni-wrap/wrap/java.lang.impl.h new file mode 100644 index 000000000..8c95ea8de --- /dev/null +++ b/src/external/android-jni-wrap/wrap/java.lang.impl.h @@ -0,0 +1,59 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include + +namespace wrap { +namespace java::lang { +inline Class Class::forName(std::string &stringParam) { + return Class(Meta::data().clazz().call(Meta::data().forName, + stringParam)); +} + +inline Class Class::forName(std::string const &name, bool initialize, + jni::Object classLoader) { + return Class(Meta::data().clazz().call( + Meta::data().forName1, name, initialize, classLoader)); +} + +inline Class Class::forName(jstring name, bool initialize, + jni::Object classLoader) { + return Class{Meta::data().clazz().call( + Meta::data().forName, name, initialize, classLoader)}; +} + +inline Class Class::forName(jni::Object const &module, + std::string const &name) { + return Class(Meta::data().clazz().call(Meta::data().forName2, + module, name)); +} + +inline std::string Class::getCanonicalName() { + assert(!isNull()); + return object().call(Meta::data().getCanonicalName); +} + +inline Class ClassLoader::loadClass(std::string const &name) { + assert(!isNull()); + return Class(object().call(Meta::data().loadClass, name)); +} + +inline Class ClassLoader::loadClass(jstring name) { + assert(!isNull()); + return Class{object().call(Meta::data().loadClass, name)}; +} + +inline std::string ClassLoader::findLibrary(std::string const &name) { + assert(!isNull()); + return object().call(Meta::data().findLibrary, name); +} + +inline std::string System::mapLibraryName(std::string const &name) { + return Meta::data().clazz().call(Meta::data().mapLibraryName, + name); +} +} // namespace java::lang +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/java.util.cpp b/src/external/android-jni-wrap/wrap/java.util.cpp new file mode 100644 index 000000000..1582bed56 --- /dev/null +++ b/src/external/android-jni-wrap/wrap/java.util.cpp @@ -0,0 +1,16 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#include "java.util.h" + +namespace wrap { +namespace java::util { +List::Meta::Meta() + : MetaBaseDroppable(List::getTypeName()), + size(classRef().getMethod("size", "()I")), + get(classRef().getMethod("get", "(I)Ljava/lang/Object;")) { + MetaBaseDroppable::dropClassRef(); +} +} // namespace java::util +} // namespace wrap diff --git a/src/external/android-jni-wrap/wrap/java.util.h b/src/external/android-jni-wrap/wrap/java.util.h new file mode 100644 index 000000000..1cda61aec --- /dev/null +++ b/src/external/android-jni-wrap/wrap/java.util.h @@ -0,0 +1,64 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +#include "ObjectWrapperBase.h" + +namespace wrap { +namespace java::util { +/*! + * Wrapper for java.util.List objects. + */ +class List : public ObjectWrapperBase { + public: + using ObjectWrapperBase::ObjectWrapperBase; + static constexpr const char *getTypeName() noexcept { + return "java/util/List"; + } + + /*! + * Wrapper for the size method + * + * Java prototype: + * `public abstract int size();` + * + * JNI signature: ()I + * + */ + int32_t size() const; + + /*! + * Wrapper for the get method + * + * Java prototype: + * `public abstract E get(int);` + * + * JNI signature: (I)Ljava/lang/Object; + * + */ + jni::Object get(int32_t index) const; + + /*! + * Class metadata + */ + struct Meta : public MetaBaseDroppable { + jni::method_t size; + jni::method_t get; + + /*! + * Singleton accessor + */ + static Meta &data() { + static Meta instance; + return instance; + } + + private: + Meta(); + }; +}; +} // namespace java::util +} // namespace wrap +#include "java.util.impl.h" diff --git a/src/external/android-jni-wrap/wrap/java.util.impl.h b/src/external/android-jni-wrap/wrap/java.util.impl.h new file mode 100644 index 000000000..d394388ee --- /dev/null +++ b/src/external/android-jni-wrap/wrap/java.util.impl.h @@ -0,0 +1,19 @@ +// Copyright 2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +// Author: Ryan Pavlik + +#pragma once + +namespace wrap { +namespace java::util { +inline int32_t List::size() const { + assert(!isNull()); + return object().call(Meta::data().size); +} + +inline jni::Object List::get(int32_t index) const { + assert(!isNull()); + return object().call(Meta::data().get, index); +} +} // namespace java::util +} // namespace wrap