@@ -666,7 +666,8 @@ XrResult RuntimeManifestFile::FindManifestFiles(const std::string &openxr_comman
666666
667667#if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
668668 Json::Value virtualManifest;
669- result = GetPlatformRuntimeVirtualManifest (virtualManifest);
669+ ManifestFileSource runtimeSource = ManifestFileSource::FROM_JSON_MANIFEST;
670+ result = GetPlatformRuntimeVirtualManifest (virtualManifest, runtimeSource);
670671 if (XR_SUCCESS == result) {
671672 RuntimeManifestFile::CreateIfValid (virtualManifest, " " , manifest_files);
672673 return result;
@@ -763,6 +764,140 @@ void ApiLayerManifestFile::AddManifestFilesAndroid(const std::string &openxr_com
763764}
764765#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
765766
767+ void ApiLayerManifestFile::CreateIfValid (ManifestFileType type, const Json::Value &root_node, const std::string &filename,
768+ std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
769+ std::ostringstream error_ss (" ApiLayerManifestFile::CreateIfValid " );
770+ JsonVersion file_version = {};
771+ if (!ManifestFile::IsValidJson (root_node, file_version)) {
772+ error_ss << " isValidJson indicates " << filename << " is not a valid manifest file." ;
773+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
774+ return ;
775+ }
776+
777+ Json::Value layer_root_node = root_node[" api_layer" ];
778+
779+ // The API Layer manifest file needs the "api_layer" root as well as other sub-nodes.
780+ // If any of those aren't there, fail.
781+ if (layer_root_node.isNull () || layer_root_node[" name" ].isNull () || !layer_root_node[" name" ].isString () ||
782+ layer_root_node[" api_version" ].isNull () || !layer_root_node[" api_version" ].isString () ||
783+ layer_root_node[" library_path" ].isNull () || !layer_root_node[" library_path" ].isString () ||
784+ layer_root_node[" implementation_version" ].isNull () || !layer_root_node[" implementation_version" ].isString ()) {
785+ error_ss << filename << " is missing required fields. Verify all proper fields exist." ;
786+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
787+ return ;
788+ }
789+ if (MANIFEST_TYPE_IMPLICIT_API_LAYER == type) {
790+ bool enabled = true ;
791+ #if !defined(XR_OS_ANDROID)
792+ // Implicit layers require the disable environment variable.
793+ if (layer_root_node[" disable_environment" ].isNull () || !layer_root_node[" disable_environment" ].isString ()) {
794+ error_ss << " Implicit layer " << filename << " is missing \" disable_environment\" " ;
795+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
796+ return ;
797+ }
798+ // Check if there's an enable environment variable provided
799+ if (!layer_root_node[" enable_environment" ].isNull () && layer_root_node[" enable_environment" ].isString ()) {
800+ std::string env_var = layer_root_node[" enable_environment" ].asString ();
801+ // If it's not set in the environment, disable the layer
802+ if (!PlatformUtilsGetEnvSet (env_var.c_str ())) {
803+ enabled = false ;
804+ }
805+ }
806+ // Check for the disable environment variable, which must be provided in the JSON
807+ std::string env_var = layer_root_node[" disable_environment" ].asString ();
808+ // If the env var is set, disable the layer. Disable env var overrides enable above
809+ if (PlatformUtilsGetEnvSet (env_var.c_str ())) {
810+ enabled = false ;
811+ }
812+ #else
813+ // Implicit layers require system property to disable it on Android
814+ if (layer_root_node[" disable_sys_prop" ].isNull () || !layer_root_node[" disable_sys_prop" ].isString ()) {
815+ error_ss << " Implicit layer " << filename << " is missing \" disable_sys_prop\" " ;
816+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
817+ return ;
818+ }
819+ // Check if there's an system property to enable this API layer
820+ if (!layer_root_node[" enable_sys_prop" ].isNull () && layer_root_node[" enable_sys_prop" ].isString ()) {
821+ std::string enable_sys_prop = layer_root_node[" enable_sys_prop" ].asString ();
822+ // If it's not set to true, disable this layer
823+ if (!PlatformUtilsGetSysProp (enable_sys_prop.c_str (), true )) {
824+ enabled = false ;
825+ }
826+ }
827+
828+ std::string disable_sys_prop = layer_root_node[" disable_sys_prop" ].asString ();
829+ if (PlatformUtilsGetSysProp (disable_sys_prop.c_str (), false )) {
830+ enabled = false ;
831+ }
832+ #endif
833+
834+ // Not enabled, so pretend like it isn't even there.
835+ if (!enabled) {
836+ error_ss << " Implicit layer " << filename << " is disabled" ;
837+ LoaderLogger::LogInfoMessage (" " , error_ss.str ());
838+ return ;
839+ }
840+ }
841+ std::string layer_name = layer_root_node[" name" ].asString ();
842+ std::string api_version_string = layer_root_node[" api_version" ].asString ();
843+ JsonVersion api_version = {};
844+ const int num_fields = sscanf (api_version_string.c_str (), " %u.%u" , &api_version.major , &api_version.minor );
845+ api_version.patch = 0 ;
846+
847+ if ((num_fields != 2 ) || (api_version.major == 0 && api_version.minor == 0 ) ||
848+ api_version.major > XR_VERSION_MAJOR (XR_CURRENT_API_VERSION)) {
849+ error_ss << " layer " << filename << " has invalid API Version. Skipping layer." ;
850+ LoaderLogger::LogWarningMessage (" " , error_ss.str ());
851+ return ;
852+ }
853+
854+ char *end_ptr;
855+ uint32_t implementation_version = strtol (layer_root_node[" implementation_version" ].asString ().c_str (), &end_ptr, 10 );
856+ if (*end_ptr != ' \0 ' ) {
857+ error_ss << " layer " << filename << " has invalid implementation version." ;
858+ LoaderLogger::LogWarningMessage (" " , error_ss.str ());
859+ }
860+
861+ std::string library_path = layer_root_node[" library_path" ].asString ();
862+
863+ // If the library_path variable has no directory symbol, it's just a file name and should be accessible on the
864+ // global library path.
865+ if (library_path.find (' \\ ' ) != std::string::npos || library_path.find (' /' ) != std::string::npos) {
866+ // If the library_path is an absolute path, just use that if it exists
867+ if (FileSysUtilsIsAbsolutePath (library_path)) {
868+ if (!FileSysUtilsPathExists (library_path)) {
869+ error_ss << filename << " library " << library_path << " does not appear to exist" ;
870+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
871+ return ;
872+ }
873+ } else {
874+ // Otherwise, treat the library path as a relative path based on the JSON file.
875+ std::string combined_path;
876+ std::string file_parent;
877+ if (!FileSysUtilsGetParentPath (filename, file_parent) ||
878+ !FileSysUtilsCombinePaths (file_parent, library_path, combined_path) || !FileSysUtilsPathExists (combined_path)) {
879+ error_ss << filename << " library " << combined_path << " does not appear to exist" ;
880+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
881+ return ;
882+ }
883+ library_path = combined_path;
884+ }
885+ }
886+
887+ std::string description;
888+ if (!layer_root_node[" description" ].isNull () && layer_root_node[" description" ].isString ()) {
889+ description = layer_root_node[" description" ].asString ();
890+ }
891+
892+ // Add this layer manifest file
893+ manifest_files.emplace_back (
894+ new ApiLayerManifestFile (type, filename, layer_name, description, api_version, implementation_version, library_path));
895+
896+ // Add any extensions to it after the fact.
897+ // Handle any renamed functions
898+ manifest_files.back ()->ParseCommon (layer_root_node);
899+ }
900+
766901void ApiLayerManifestFile::CreateIfValid (ManifestFileType type, const std::string &filename, std::istream &json_stream,
767902 LibraryLocator locate_library,
768903 std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
@@ -876,6 +1011,7 @@ void ApiLayerManifestFile::CreateIfValid(ManifestFileType type, const std::strin
8761011 new ApiLayerManifestFile (type, filename, layer_name, description, api_version, implementation_version, library_path));
8771012
8781013 // Add any extensions to it after the fact.
1014+ // Handle any renamed functions
8791015 manifest_files.back ()->ParseCommon (layer_root_node);
8801016}
8811017
@@ -935,6 +1071,24 @@ void ApiLayerManifestFile::PopulateApiLayerProperties(XrApiLayerProperties &prop
9351071// Find all layer manifest files in the appropriate search paths/registries for the given type.
9361072XrResult ApiLayerManifestFile::FindManifestFiles (const std::string &openxr_command, ManifestFileType type,
9371073 std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
1074+ bool search_json_layer = true ;
1075+ bool search_broker_layer = true ;
1076+
1077+ #if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
1078+ Json::Value virtualManifest;
1079+ bool systemBroker = true ;
1080+ ManifestFileSource runtimeSource = ManifestFileSource::FROM_JSON_MANIFEST;
1081+ XrResult result = GetPlatformRuntimeVirtualManifest (virtualManifest, runtimeSource);
1082+ if (XR_SUCCESS == result) {
1083+ if (runtimeSource == ManifestFileSource::FROM_INSTALLABLE_BROKER) {
1084+ systemBroker = false ;
1085+ search_json_layer = false ;
1086+ }
1087+ } else {
1088+ search_broker_layer = false ;
1089+ }
1090+ #endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
1091+
9381092 std::string relative_path;
9391093 std::string override_env_var;
9401094 std::string registry_location;
@@ -967,7 +1121,9 @@ XrResult ApiLayerManifestFile::FindManifestFiles(const std::string &openxr_comma
9671121
9681122 bool override_active = false ;
9691123 std::vector<std::string> filenames;
970- ReadDataFilesInSearchPaths (override_env_var, relative_path, override_active, filenames);
1124+ if (search_json_layer) {
1125+ ReadDataFilesInSearchPaths (override_env_var, relative_path, override_active, filenames);
1126+ }
9711127
9721128#ifdef XR_OS_WINDOWS
9731129 // Read the registry if the override wasn't active.
@@ -981,6 +1137,22 @@ XrResult ApiLayerManifestFile::FindManifestFiles(const std::string &openxr_comma
9811137 }
9821138
9831139#if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
1140+ if (search_broker_layer) {
1141+ std::vector<Json::Value> virtualManifests;
1142+ std::string layerType = (type == ManifestFileType::MANIFEST_TYPE_IMPLICIT_API_LAYER) ? " implicit" : " explicit" ;
1143+ result = GetPlatformApiLayerVirtualManifests (layerType, virtualManifests, systemBroker);
1144+ if (XR_SUCCESS == result) {
1145+ for (const auto &virtualManifest : virtualManifests) {
1146+ ApiLayerManifestFile::CreateIfValid (type, virtualManifest, " virtual manifest" , manifest_files);
1147+ }
1148+ } else {
1149+ LoaderLogger::LogErrorMessage (
1150+ " " ,
1151+ " ApiLayerManifestFile::FindManifestFiles - failed to get virtual manifest files from system/installable broker." );
1152+ assert (0 );
1153+ }
1154+ }
1155+
9841156 ApiLayerManifestFile::AddManifestFilesAndroid (openxr_command, type, manifest_files);
9851157#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
9861158
0 commit comments