@@ -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,125 @@ 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+ std::string sys_prop = layer_root_node[" sys_prop" ].asString ();
814+ if (PlatformUtilsGetSysProp (sys_prop.c_str ())) {
815+ enabled = false ;
816+ }
817+ #endif
818+
819+ // Not enabled, so pretend like it isn't even there.
820+ if (!enabled) {
821+ error_ss << " Implicit layer " << filename << " is disabled" ;
822+ LoaderLogger::LogInfoMessage (" " , error_ss.str ());
823+ return ;
824+ }
825+ }
826+ std::string layer_name = layer_root_node[" name" ].asString ();
827+ std::string api_version_string = layer_root_node[" api_version" ].asString ();
828+ JsonVersion api_version = {};
829+ const int num_fields = sscanf (api_version_string.c_str (), " %u.%u" , &api_version.major , &api_version.minor );
830+ api_version.patch = 0 ;
831+
832+ if ((num_fields != 2 ) || (api_version.major == 0 && api_version.minor == 0 ) ||
833+ api_version.major > XR_VERSION_MAJOR (XR_CURRENT_API_VERSION)) {
834+ error_ss << " layer " << filename << " has invalid API Version. Skipping layer." ;
835+ LoaderLogger::LogWarningMessage (" " , error_ss.str ());
836+ return ;
837+ }
838+
839+ char *end_ptr;
840+ uint32_t implementation_version = strtol (layer_root_node[" implementation_version" ].asString ().c_str (), &end_ptr, 10 );
841+ if (*end_ptr != ' \0 ' ) {
842+ error_ss << " layer " << filename << " has invalid implementation version." ;
843+ LoaderLogger::LogWarningMessage (" " , error_ss.str ());
844+ }
845+
846+ std::string library_path = layer_root_node[" library_path" ].asString ();
847+
848+ // If the library_path variable has no directory symbol, it's just a file name and should be accessible on the
849+ // global library path.
850+ if (library_path.find (' \\ ' ) != std::string::npos || library_path.find (' /' ) != std::string::npos) {
851+ // If the library_path is an absolute path, just use that if it exists
852+ if (FileSysUtilsIsAbsolutePath (library_path)) {
853+ if (!FileSysUtilsPathExists (library_path)) {
854+ error_ss << filename << " library " << library_path << " does not appear to exist" ;
855+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
856+ return ;
857+ }
858+ } else {
859+ // Otherwise, treat the library path as a relative path based on the JSON file.
860+ std::string combined_path;
861+ std::string file_parent;
862+ if (!FileSysUtilsGetParentPath (filename, file_parent) ||
863+ !FileSysUtilsCombinePaths (file_parent, library_path, combined_path) || !FileSysUtilsPathExists (combined_path)) {
864+ error_ss << filename << " library " << combined_path << " does not appear to exist" ;
865+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
866+ return ;
867+ }
868+ library_path = combined_path;
869+ }
870+ }
871+
872+ std::string description;
873+ if (!layer_root_node[" description" ].isNull () && layer_root_node[" description" ].isString ()) {
874+ description = layer_root_node[" description" ].asString ();
875+ }
876+
877+ // Add this layer manifest file
878+ manifest_files.emplace_back (
879+ new ApiLayerManifestFile (type, filename, layer_name, description, api_version, implementation_version, library_path));
880+
881+ // Add any extensions to it after the fact.
882+ // Handle any renamed functions
883+ manifest_files.back ()->ParseCommon (layer_root_node);
884+ }
885+
766886void ApiLayerManifestFile::CreateIfValid (ManifestFileType type, const std::string &filename, std::istream &json_stream,
767887 LibraryLocator locate_library,
768888 std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
@@ -876,6 +996,7 @@ void ApiLayerManifestFile::CreateIfValid(ManifestFileType type, const std::strin
876996 new ApiLayerManifestFile (type, filename, layer_name, description, api_version, implementation_version, library_path));
877997
878998 // Add any extensions to it after the fact.
999+ // Handle any renamed functions
8791000 manifest_files.back ()->ParseCommon (layer_root_node);
8801001}
8811002
@@ -935,6 +1056,24 @@ void ApiLayerManifestFile::PopulateApiLayerProperties(XrApiLayerProperties &prop
9351056// Find all layer manifest files in the appropriate search paths/registries for the given type.
9361057XrResult ApiLayerManifestFile::FindManifestFiles (const std::string &openxr_command, ManifestFileType type,
9371058 std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
1059+ bool search_json_layer = true ;
1060+ bool search_broker_layer = true ;
1061+
1062+ #if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
1063+ Json::Value virtualManifest;
1064+ bool systemBroker = true ;
1065+ ManifestFileSource runtimeSource = ManifestFileSource::FROM_JSON_MANIFEST;
1066+ XrResult result = GetPlatformRuntimeVirtualManifest (virtualManifest, runtimeSource);
1067+ if (XR_SUCCESS == result) {
1068+ if (runtimeSource == ManifestFileSource::FROM_INSTALLABLE_BROKER) {
1069+ systemBroker = false ;
1070+ search_json_layer = false ;
1071+ }
1072+ } else {
1073+ search_broker_layer = false ;
1074+ }
1075+ #endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
1076+
9381077 std::string relative_path;
9391078 std::string override_env_var;
9401079 std::string registry_location;
@@ -967,7 +1106,9 @@ XrResult ApiLayerManifestFile::FindManifestFiles(const std::string &openxr_comma
9671106
9681107 bool override_active = false ;
9691108 std::vector<std::string> filenames;
970- ReadDataFilesInSearchPaths (override_env_var, relative_path, override_active, filenames);
1109+ if (search_json_layer) {
1110+ ReadDataFilesInSearchPaths (override_env_var, relative_path, override_active, filenames);
1111+ }
9711112
9721113#ifdef XR_OS_WINDOWS
9731114 // Read the registry if the override wasn't active.
@@ -981,6 +1122,22 @@ XrResult ApiLayerManifestFile::FindManifestFiles(const std::string &openxr_comma
9811122 }
9821123
9831124#if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
1125+ if (search_broker_layer) {
1126+ std::vector<Json::Value> virtualManifests;
1127+ std::string layerType = (type == ManifestFileType::MANIFEST_TYPE_IMPLICIT_API_LAYER) ? " implicit" : " explicit" ;
1128+ result = GetPlatformApiLayerVirtualManifests (layerType, virtualManifests, systemBroker);
1129+ if (XR_SUCCESS == result) {
1130+ for (const auto &virtualManifest : virtualManifests) {
1131+ ApiLayerManifestFile::CreateIfValid (type, virtualManifest, " virtual manifest" , manifest_files);
1132+ }
1133+ } else {
1134+ LoaderLogger::LogErrorMessage (
1135+ " " ,
1136+ " ApiLayerManifestFile::FindManifestFiles - failed to get virtual manifest files from system/installable broker." );
1137+ assert (0 );
1138+ }
1139+ }
1140+
9841141 ApiLayerManifestFile::AddManifestFilesAndroid (openxr_command, type, manifest_files);
9851142#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
9861143
0 commit comments