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