@@ -36,8 +36,12 @@ constexpr auto SYSTEM_AUTHORITY = "org.khronos.openxr.system_runtime_broker";
3636constexpr auto BASE_PATH = " openxr" ;
3737constexpr auto ABI_PATH = " abi" ;
3838constexpr auto RUNTIMES_PATH = " runtimes" ;
39+ constexpr auto API_LAYERS_PATH = " api_layers" ;
40+ constexpr auto IMP_LAYER = " implicit" ;
41+ constexpr auto EXP_LAYER = " explicit" ;
3942
4043constexpr const char *getBrokerAuthority (bool systemBroker) { return systemBroker ? SYSTEM_AUTHORITY : AUTHORITY; }
44+ constexpr const char *getLayerTypePath (bool implicitLayer) { return implicitLayer ? IMP_LAYER : EXP_LAYER; }
4145
4246struct BaseColumns {
4347 /* *
@@ -148,6 +152,33 @@ static Uri makeRuntimeContentUri(bool systemBroker, int majorVersion, std::strin
148152 return builder.build ();
149153}
150154
155+ /* *
156+ * Create a content URI for querying all rows of the API Layer function remapping data for a given
157+ * runtime package, major version of OpenXR, and layer name,
158+ *
159+ * @param systemBroker If the system runtime broker (instead of the installable one) should be queried.
160+ * @param majorVer The major version of OpenXR.
161+ * @param packageName The package name of the runtime.
162+ * @param abi The Android ABI name in use.
163+ * @param layerName The name of the API layer.
164+ * @return A content URI for the entire table: the function remapping for that runtime and layer.
165+ */
166+ static Uri makeLayerContentUri (bool systemBroker, int majorVersion, std::string const &packageName, const char *abi,
167+ std::string const &layerName) {
168+ auto builder = Uri_Builder::construct ();
169+ builder.scheme (" content" )
170+ .authority (getBrokerAuthority (systemBroker))
171+ .appendPath (BASE_PATH)
172+ .appendPath (std::to_string (majorVersion))
173+ .appendPath (ABI_PATH)
174+ .appendPath (abi)
175+ .appendPath (API_LAYERS_PATH)
176+ .appendPath (packageName)
177+ .appendPath (layerName)
178+ .appendPath (TABLE_PATH);
179+ return builder.build ();
180+ }
181+
151182struct Columns : BaseColumns {
152183 /* *
153184 * Constant for the FUNCTION_NAME column name
@@ -161,6 +192,94 @@ struct Columns : BaseColumns {
161192};
162193} // namespace functions
163194
195+ namespace instance_extensions {
196+ /* *
197+ * Final path component to this URI.
198+ */
199+ static constexpr auto TABLE_PATH = " instance_extensions" ;
200+
201+ /* *
202+ * Create a content URI for querying all rows of the instance extensions supported by a given
203+ * API layer.
204+ *
205+ * @param systemBroker If the system runtime broker (instead of the installable one) should be queried.
206+ * @param majorVer The major version of OpenXR.
207+ * @param packageName The package name of the runtime.
208+ * @param abi The Android ABI name in use.
209+ * @param layerName The API layer name.
210+ * @return A content URI for the entire table: the function remapping for that runtime.
211+ */
212+ static Uri makeContentUri (bool systemBroker, int majorVersion, std::string const &packageName, const char *abi,
213+ std::string const &layerName) {
214+ auto builder = Uri_Builder::construct ();
215+ builder.scheme (" content" )
216+ .authority (getBrokerAuthority (systemBroker))
217+ .appendPath (BASE_PATH)
218+ .appendPath (std::to_string (majorVersion))
219+ .appendPath (ABI_PATH)
220+ .appendPath (abi)
221+ .appendPath (API_LAYERS_PATH)
222+ .appendPath (packageName)
223+ .appendPath (layerName)
224+ .appendPath (TABLE_PATH);
225+ return builder.build ();
226+ }
227+ struct Columns : BaseColumns {
228+ /* *
229+ * Constant for the INSTANCE_EXTENSION_NAMES column name
230+ */
231+ static constexpr auto INSTANCE_EXTENSION_NAMES = " instance_extension_names" ;
232+
233+ /* *
234+ * Constant for the INSTANCE_EXTENSION_VERSIONS column name
235+ */
236+ static constexpr auto INSTANCE_EXTENSION_VERSIONS = " instance_extension_versions" ;
237+ };
238+ } // namespace instance_extensions
239+
240+ namespace api_layer {
241+
242+ /* *
243+ * Create a content URI for querying all rows of the implicit/explicit API layer data for a given
244+ * runtime package and major version of OpenXR.
245+ *
246+ * @param systemBroker If the system runtime broker (instead of the installable one) should be queried.
247+ * @param majorVer The major version of OpenXR.
248+ * @param layerType The layer type of the API layer.
249+ * @param abi The Android ABI name in use.
250+ * @return A content URI for the entire table: the API layers for that runtime.
251+ */
252+ static Uri makeContentUri (bool systemBroker, int majorVersion, std::string const &layerType, const char *abi) {
253+ auto builder = Uri_Builder::construct ();
254+ builder.scheme (" content" )
255+ .authority (getBrokerAuthority (systemBroker))
256+ .appendPath (BASE_PATH)
257+ .appendPath (std::to_string (majorVersion))
258+ .appendPath (ABI_PATH)
259+ .appendPath (abi)
260+ .appendPath (API_LAYERS_PATH)
261+ .appendPath (getLayerTypePath (layerType == IMP_LAYER));
262+ return builder.build ();
263+ }
264+ struct Columns : BaseColumns {
265+ // implicit or explicit
266+ static constexpr auto PACKAGE_NAME = " package_name" ;
267+ static constexpr auto FILE_FORMAT_VERSION = " file_format_version" ;
268+ static constexpr auto NAME = " name" ;
269+ static constexpr auto NATIVE_LIB_DIR = " native_lib_dir" ;
270+ static constexpr auto SO_FILENAME = " so_filename" ;
271+ static constexpr auto API_VERSION = " api_version" ;
272+ static constexpr auto IMPLEMENTATION_VERSION = " implementation_version" ;
273+ static constexpr auto DESCRIPTION = " description" ;
274+ static constexpr auto DISABLE_ENVIRONMENT = " disable_environment" ;
275+ static constexpr auto ENABLE_ENVIRONMENT = " enable_environment" ;
276+ static constexpr auto DISABLE_SYS_PROP = " disable_sys_prop" ;
277+ static constexpr auto ENABLE_SYS_PROP = " enable_sys_prop" ;
278+ static constexpr auto HAS_FUNCTIONS = " has_functions" ;
279+ static constexpr auto HAS_INSTANCE_EXTENSIONS = " has_instance_extensions" ;
280+ };
281+ } // namespace api_layer
282+
164283} // namespace
165284
166285static inline jni::Array<std::string> makeArray (std::initializer_list<const char *> &&list) {
@@ -332,6 +451,157 @@ int getActiveRuntimeVirtualManifest(wrap::android::content::Context const &conte
332451 cursor.close ();
333452 return -1 ;
334453}
454+
455+ static int populateApiLayerFunctions (wrap::android::content::Context const &context, bool systemBroker,
456+ const std::string &packageName, std::string const &layerName, Json::Value &rootNode) {
457+ const jni::Array<std::string> projection = makeArray ({functions::Columns::FUNCTION_NAME, functions::Columns::SYMBOL_NAME});
458+
459+ auto uri = functions::makeLayerContentUri (systemBroker, XR_VERSION_MAJOR (XR_CURRENT_API_VERSION), packageName, ABI, layerName);
460+ ALOGI (" populateApiLayerFunctions: Querying URI: %s" , uri.toString ().c_str ());
461+
462+ Cursor cursor;
463+ if (!getCursor (context, projection, uri, systemBroker, " API layer functions" , cursor)) {
464+ return -1 ;
465+ }
466+
467+ auto functionIndex = cursor.getColumnIndex (functions::Columns::FUNCTION_NAME);
468+ auto symbolIndex = cursor.getColumnIndex (functions::Columns::SYMBOL_NAME);
469+ while (cursor.moveToNext ()) {
470+ rootNode[" api_layer" ][" functions" ][cursor.getString (functionIndex)] = cursor.getString (symbolIndex);
471+ }
472+
473+ cursor.close ();
474+ return 0 ;
475+ }
476+
477+ static int populateApiLayerInstanceExtensions (wrap::android::content::Context const &context, bool systemBroker,
478+ const std::string &packageName, std::string const &layerName, Json::Value &rootNode) {
479+ const jni::Array<std::string> projection = makeArray (
480+ {instance_extensions::Columns::INSTANCE_EXTENSION_NAMES, instance_extensions::Columns::INSTANCE_EXTENSION_VERSIONS});
481+
482+ auto uri =
483+ instance_extensions::makeContentUri (systemBroker, XR_VERSION_MAJOR (XR_CURRENT_API_VERSION), packageName, ABI, layerName);
484+ ALOGI (" populateApiLayerInstanceExtensions: Querying URI: %s" , uri.toString ().c_str ());
485+
486+ Cursor cursor;
487+ if (!getCursor (context, projection, uri, systemBroker, " API layer instance extensions" , cursor)) {
488+ return -1 ;
489+ }
490+
491+ auto nameIndex = cursor.getColumnIndex (instance_extensions::Columns::INSTANCE_EXTENSION_NAMES);
492+ auto versionIndex = cursor.getColumnIndex (instance_extensions::Columns::INSTANCE_EXTENSION_VERSIONS);
493+ Json::Value extension (Json::objectValue);
494+ while (cursor.moveToNext ()) {
495+ extension[" name" ] = cursor.getString (nameIndex);
496+ extension[" extension_version" ] = cursor.getString (versionIndex);
497+ rootNode[" api_layer" ][" instance_extensions" ].append (extension);
498+ }
499+
500+ cursor.close ();
501+ return 0 ;
502+ }
503+
504+ // / Get cursor for API layers, parameterized by whether or not we use the system broker
505+ static bool getApiLayerCursor (wrap::android::content::Context const &context, jni::Array<std::string> const &projection,
506+ std::string const &targetType, bool systemBroker, Cursor &cursor) {
507+ auto uri = api_layer::makeContentUri (systemBroker, XR_VERSION_MAJOR (XR_CURRENT_API_VERSION), targetType, ABI);
508+ ALOGI (" getApiLayerCursor: Querying URI: %s" , uri.toString ().c_str ());
509+ return getCursor (context, projection, uri, systemBroker, " API Layer" , cursor);
510+ }
511+
512+ static Json::Value makeApiLayerManifest (bool systemBroker, std::string layerType, wrap::android::content::Context const &context,
513+ Cursor &cursor) {
514+ auto packageName = cursor.getString (cursor.getColumnIndex (api_layer::Columns::PACKAGE_NAME));
515+ auto fileFormatVersion = cursor.getString (cursor.getColumnIndex (api_layer::Columns::FILE_FORMAT_VERSION));
516+ auto name = cursor.getString (cursor.getColumnIndex (api_layer::Columns::NAME));
517+ auto libDir = cursor.getString (cursor.getColumnIndex (active_runtime::Columns::NATIVE_LIB_DIR));
518+ auto fileName = cursor.getString (cursor.getColumnIndex (api_layer::Columns::SO_FILENAME));
519+ auto apiVersion = cursor.getString (cursor.getColumnIndex (api_layer::Columns::API_VERSION));
520+ auto implementationVersion = cursor.getString (cursor.getColumnIndex (api_layer::Columns::IMPLEMENTATION_VERSION));
521+ auto description = cursor.getString (cursor.getColumnIndex (api_layer::Columns::DESCRIPTION));
522+ auto disable_environment = cursor.getString (cursor.getColumnIndex (api_layer::Columns::DISABLE_ENVIRONMENT));
523+ auto enable_environment = cursor.getString (cursor.getColumnIndex (api_layer::Columns::ENABLE_ENVIRONMENT));
524+ auto disable_sys_prop = cursor.getString (cursor.getColumnIndex (api_layer::Columns::DISABLE_SYS_PROP));
525+ auto enable_sys_prop = cursor.getString (cursor.getColumnIndex (api_layer::Columns::ENABLE_SYS_PROP));
526+ auto has_instance_extensions = cursor.getString (cursor.getColumnIndex (api_layer::Columns::HAS_INSTANCE_EXTENSIONS));
527+ auto has_functions = cursor.getString (cursor.getColumnIndex (api_layer::Columns::HAS_FUNCTIONS));
528+
529+ ALOGI (" Got api layer: type: %s, name: %s, native lib dir: %s, fileName: %s" , layerType.c_str (), name.c_str (), libDir.c_str (),
530+ fileName.c_str ());
531+
532+ Json::Value rootNode (Json::objectValue);
533+ rootNode[" file_format_version" ] = fileFormatVersion;
534+ rootNode[" api_layer" ] = Json::objectValue;
535+ rootNode[" api_layer" ][" name" ] = name;
536+ rootNode[" api_layer" ][" library_path" ] = libDir + " /" + fileName;
537+ rootNode[" api_layer" ][" api_version" ] = apiVersion;
538+ rootNode[" api_layer" ][" implementation_version" ] = implementationVersion;
539+ rootNode[" api_layer" ][" description" ] = description;
540+ rootNode[" api_layer" ][" disable_environment" ] = disable_environment;
541+ rootNode[" api_layer" ][" enable_environment" ] = enable_environment;
542+ rootNode[" api_layer" ][" disable_sys_prop" ] = disable_sys_prop;
543+ rootNode[" api_layer" ][" enable_sys_prop" ] = enable_sys_prop;
544+ if (has_functions == " true" ) {
545+ rootNode[" api_layer" ][" functions" ] = Json::Value (Json::objectValue);
546+ populateApiLayerFunctions (context, systemBroker, packageName, name, rootNode);
547+ }
548+ if (has_instance_extensions == " true" ) {
549+ rootNode[" api_layer" ][" instance_extensions" ] = Json::Value (Json::arrayValue);
550+ populateApiLayerInstanceExtensions (context, systemBroker, packageName, name, rootNode);
551+ }
552+
553+ return rootNode;
554+ }
555+
556+ static int enumerateApiLayerManifests (std::string layerType, wrap::android::content::Context const &context,
557+ const jni::Array<std::string> &projection, std::vector<Json::Value> &virtualManifests,
558+ bool systemBroker) {
559+ Cursor cursor;
560+
561+ if (!getApiLayerCursor (context, projection, layerType, systemBroker, cursor)) {
562+ return -1 ;
563+ }
564+
565+ cursor.moveToFirst ();
566+ const int32_t n = cursor.getCount ();
567+ virtualManifests.reserve (virtualManifests.size () + n);
568+
569+ for (int32_t i = 0 ; i < n; ++i) {
570+ virtualManifests.emplace_back (makeApiLayerManifest (systemBroker, layerType, context, cursor));
571+ cursor.moveToNext ();
572+ }
573+
574+ cursor.close ();
575+ return 0 ;
576+ }
577+
578+ int getApiLayerVirtualManifests (std::string layerType, wrap::android::content::Context const &context,
579+ std::vector<Json::Value> &virtualManifests, bool systemBroker) {
580+ ALOGI (" Try to get %s API layer from broker" , layerType.c_str ());
581+ const jni::Array<std::string> projection = makeArray (
582+ {api_layer::Columns::PACKAGE_NAME, api_layer::Columns::FILE_FORMAT_VERSION, api_layer::Columns::NAME,
583+ api_layer::Columns::NATIVE_LIB_DIR, api_layer::Columns::SO_FILENAME, api_layer::Columns::API_VERSION,
584+ api_layer::Columns::IMPLEMENTATION_VERSION, api_layer::Columns::DESCRIPTION, api_layer::Columns::DISABLE_ENVIRONMENT,
585+ api_layer::Columns::ENABLE_ENVIRONMENT, api_layer::Columns::DISABLE_SYS_PROP, api_layer::Columns::ENABLE_SYS_PROP,
586+ api_layer::Columns::HAS_FUNCTIONS, api_layer::Columns::HAS_INSTANCE_EXTENSIONS});
587+
588+ if (layerType == IMP_LAYER) {
589+ std::vector<Json::Value> implicitLayerManifest;
590+ if (0 != enumerateApiLayerManifests (IMP_LAYER, context, projection, implicitLayerManifest, systemBroker)) {
591+ return -1 ;
592+ }
593+ virtualManifests = std::move (implicitLayerManifest);
594+ } else {
595+ std::vector<Json::Value> explicitLayerManifest;
596+ if (0 != enumerateApiLayerManifests (EXP_LAYER, context, projection, explicitLayerManifest, systemBroker)) {
597+ return -1 ;
598+ }
599+ virtualManifests = std::move (explicitLayerManifest);
600+ }
601+
602+ return 0 ;
603+ }
604+
335605} // namespace openxr_android
336606
337607#endif // __ANDROID__
0 commit comments