@@ -682,7 +682,8 @@ XrResult RuntimeManifestFile::FindManifestFiles(const std::string &openxr_comman
682682
683683#if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
684684 Json::Value virtualManifest;
685- result = GetPlatformRuntimeVirtualManifest (virtualManifest);
685+ ManifestFileSource runtimeSource = ManifestFileSource::FROM_JSON_MANIFEST;
686+ result = GetPlatformRuntimeVirtualManifest (virtualManifest, runtimeSource);
686687 if (XR_SUCCESS == result) {
687688 RuntimeManifestFile::CreateIfValid (virtualManifest, " " , manifest_files);
688689 return result;
@@ -779,6 +780,134 @@ void ApiLayerManifestFile::AddManifestFilesAndroid(const std::string &openxr_com
779780}
780781#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
781782
783+ void ApiLayerManifestFile::CreateIfValid (ManifestFileType type, const Json::Value &root_node, const std::string &filename,
784+ std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
785+ std::ostringstream error_ss (" ApiLayerManifestFile::CreateIfValid " );
786+ JsonVersion file_version = {};
787+ if (!ManifestFile::IsValidJson (root_node, file_version)) {
788+ error_ss << " isValidJson indicates " << filename << " is not a valid manifest file." ;
789+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
790+ return ;
791+ }
792+
793+ Json::Value layer_root_node = root_node[" api_layer" ];
794+
795+ // The API Layer manifest file needs the "api_layer" root as well as other sub-nodes.
796+ // If any of those aren't there, fail.
797+ if (layer_root_node.isNull () || layer_root_node[" name" ].isNull () || !layer_root_node[" name" ].isString () ||
798+ layer_root_node[" api_version" ].isNull () || !layer_root_node[" api_version" ].isString () ||
799+ layer_root_node[" library_path" ].isNull () || !layer_root_node[" library_path" ].isString () ||
800+ layer_root_node[" implementation_version" ].isNull () || !layer_root_node[" implementation_version" ].isString ()) {
801+ error_ss << filename << " is missing required fields. Verify all proper fields exist." ;
802+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
803+ return ;
804+ }
805+ if (MANIFEST_TYPE_IMPLICIT_API_LAYER == type) {
806+ bool enabled = true ;
807+ // Implicit layers require the disable environment variable.
808+ if (layer_root_node[" disable_environment" ].isNull () || !layer_root_node[" disable_environment" ].isString ()) {
809+ error_ss << " Implicit layer " << filename << " is missing \" disable_environment\" " ;
810+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
811+ return ;
812+ }
813+ // Check if there's an enable environment variable provided
814+ if (!layer_root_node[" enable_environment" ].isNull () && layer_root_node[" enable_environment" ].isString ()) {
815+ std::string env_var = layer_root_node[" enable_environment" ].asString ();
816+ // If it's not set in the environment, disable the layer
817+ if (!PlatformUtilsGetEnvSet (env_var.c_str ())) {
818+ enabled = false ;
819+ }
820+ }
821+ // Check for the disable environment variable, which must be provided in the JSON
822+ std::string env_var = layer_root_node[" disable_environment" ].asString ();
823+ // If the env var is set, disable the layer. Disable env var overrides enable above
824+ if (PlatformUtilsGetEnvSet (env_var.c_str ())) {
825+ enabled = false ;
826+ }
827+
828+ #if defined(XR_OS_ANDROID)
829+ // Check if there's an system property to enable this API layer
830+ if (!layer_root_node[" enable_sys_prop" ].isNull () && layer_root_node[" enable_sys_prop" ].isString ()) {
831+ std::string enable_sys_prop = layer_root_node[" enable_sys_prop" ].asString ();
832+ // If it's not set to true, disable this layer
833+ if (!PlatformUtilsGetSysProp (enable_sys_prop.c_str (), true )) {
834+ enabled = false ;
835+ }
836+ }
837+
838+ std::string disable_sys_prop = layer_root_node[" disable_sys_prop" ].asString ();
839+ if (PlatformUtilsGetSysProp (disable_sys_prop.c_str (), false )) {
840+ enabled = false ;
841+ }
842+ #endif
843+
844+ // Not enabled, so pretend like it isn't even there.
845+ if (!enabled) {
846+ error_ss << " Implicit layer " << filename << " is disabled" ;
847+ LoaderLogger::LogInfoMessage (" " , error_ss.str ());
848+ return ;
849+ }
850+ }
851+ std::string layer_name = layer_root_node[" name" ].asString ();
852+ std::string api_version_string = layer_root_node[" api_version" ].asString ();
853+ JsonVersion api_version = {};
854+ const int num_fields = sscanf (api_version_string.c_str (), " %u.%u" , &api_version.major , &api_version.minor );
855+ api_version.patch = 0 ;
856+
857+ if ((num_fields != 2 ) || (api_version.major == 0 && api_version.minor == 0 ) ||
858+ api_version.major > XR_VERSION_MAJOR (XR_CURRENT_API_VERSION)) {
859+ error_ss << " layer " << filename << " has invalid API Version. Skipping layer." ;
860+ LoaderLogger::LogWarningMessage (" " , error_ss.str ());
861+ return ;
862+ }
863+
864+ char *end_ptr;
865+ uint32_t implementation_version = strtol (layer_root_node[" implementation_version" ].asString ().c_str (), &end_ptr, 10 );
866+ if (*end_ptr != ' \0 ' ) {
867+ error_ss << " layer " << filename << " has invalid implementation version." ;
868+ LoaderLogger::LogWarningMessage (" " , error_ss.str ());
869+ }
870+
871+ std::string library_path = layer_root_node[" library_path" ].asString ();
872+
873+ // If the library_path variable has no directory symbol, it's just a file name and should be accessible on the
874+ // global library path.
875+ if (library_path.find (' \\ ' ) != std::string::npos || library_path.find (' /' ) != std::string::npos) {
876+ // If the library_path is an absolute path, just use that if it exists
877+ if (FileSysUtilsIsAbsolutePath (library_path)) {
878+ if (!FileSysUtilsPathExists (library_path)) {
879+ error_ss << filename << " library " << library_path << " does not appear to exist" ;
880+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
881+ return ;
882+ }
883+ } else {
884+ // Otherwise, treat the library path as a relative path based on the JSON file.
885+ std::string combined_path;
886+ std::string file_parent;
887+ if (!FileSysUtilsGetParentPath (filename, file_parent) ||
888+ !FileSysUtilsCombinePaths (file_parent, library_path, combined_path) || !FileSysUtilsPathExists (combined_path)) {
889+ error_ss << filename << " library " << combined_path << " does not appear to exist" ;
890+ LoaderLogger::LogErrorMessage (" " , error_ss.str ());
891+ return ;
892+ }
893+ library_path = combined_path;
894+ }
895+ }
896+
897+ std::string description;
898+ if (!layer_root_node[" description" ].isNull () && layer_root_node[" description" ].isString ()) {
899+ description = layer_root_node[" description" ].asString ();
900+ }
901+
902+ // Add this layer manifest file
903+ manifest_files.emplace_back (
904+ new ApiLayerManifestFile (type, filename, layer_name, description, api_version, implementation_version, library_path));
905+
906+ // Add any extensions to it after the fact.
907+ // Handle any renamed functions
908+ manifest_files.back ()->ParseCommon (layer_root_node);
909+ }
910+
782911void ApiLayerManifestFile::CreateIfValid (ManifestFileType type, const std::string &filename, std::istream &json_stream,
783912 LibraryLocator locate_library,
784913 std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
@@ -892,6 +1021,7 @@ void ApiLayerManifestFile::CreateIfValid(ManifestFileType type, const std::strin
8921021 new ApiLayerManifestFile (type, filename, layer_name, description, api_version, implementation_version, library_path));
8931022
8941023 // Add any extensions to it after the fact.
1024+ // Handle any renamed functions
8951025 manifest_files.back ()->ParseCommon (layer_root_node);
8961026}
8971027
@@ -951,6 +1081,24 @@ void ApiLayerManifestFile::PopulateApiLayerProperties(XrApiLayerProperties &prop
9511081// Find all layer manifest files in the appropriate search paths/registries for the given type.
9521082XrResult ApiLayerManifestFile::FindManifestFiles (const std::string &openxr_command, ManifestFileType type,
9531083 std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files) {
1084+ bool search_json_layer = true ;
1085+ bool search_broker_layer = true ;
1086+
1087+ #if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
1088+ Json::Value virtualManifest;
1089+ bool systemBroker = true ;
1090+ ManifestFileSource runtimeSource = ManifestFileSource::FROM_JSON_MANIFEST;
1091+ XrResult result = GetPlatformRuntimeVirtualManifest (virtualManifest, runtimeSource);
1092+ if (XR_SUCCESS == result) {
1093+ if (runtimeSource == ManifestFileSource::FROM_INSTALLABLE_BROKER) {
1094+ systemBroker = false ;
1095+ search_json_layer = false ;
1096+ }
1097+ } else {
1098+ search_broker_layer = false ;
1099+ }
1100+ #endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
1101+
9541102 std::string relative_path;
9551103 std::string override_env_var;
9561104 std::string registry_location;
@@ -983,7 +1131,9 @@ XrResult ApiLayerManifestFile::FindManifestFiles(const std::string &openxr_comma
9831131
9841132 bool override_active = false ;
9851133 std::vector<std::string> filenames;
986- ReadDataFilesInSearchPaths (override_env_var, relative_path, override_active, filenames);
1134+ if (search_json_layer) {
1135+ ReadDataFilesInSearchPaths (override_env_var, relative_path, override_active, filenames);
1136+ }
9871137
9881138#ifdef XR_OS_WINDOWS
9891139 // Read the registry if the override wasn't active.
@@ -997,6 +1147,22 @@ XrResult ApiLayerManifestFile::FindManifestFiles(const std::string &openxr_comma
9971147 }
9981148
9991149#if defined(XR_KHR_LOADER_INIT_SUPPORT) && defined(XR_USE_PLATFORM_ANDROID)
1150+ if (search_broker_layer) {
1151+ std::vector<Json::Value> virtualManifests;
1152+ std::string layerType = (type == ManifestFileType::MANIFEST_TYPE_IMPLICIT_API_LAYER) ? " implicit" : " explicit" ;
1153+ result = GetPlatformApiLayerVirtualManifests (layerType, virtualManifests, systemBroker);
1154+ if (XR_SUCCESS == result) {
1155+ for (const auto &virtualManifest : virtualManifests) {
1156+ ApiLayerManifestFile::CreateIfValid (type, virtualManifest, " virtual manifest" , manifest_files);
1157+ }
1158+ } else {
1159+ LoaderLogger::LogErrorMessage (
1160+ " " ,
1161+ " ApiLayerManifestFile::FindManifestFiles - failed to get virtual manifest files from system/installable broker." );
1162+ assert (0 );
1163+ }
1164+ }
1165+
10001166 ApiLayerManifestFile::AddManifestFilesAndroid (openxr_command, type, manifest_files);
10011167#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_KHR_LOADER_INIT_SUPPORT)
10021168
0 commit comments